cpu-aarch64.c revision 1.1 1 1.1 christos /* BFD support for AArch64.
2 1.1 christos Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
3 1.1 christos Contributed by ARM Ltd.
4 1.1 christos
5 1.1 christos This file is part of BFD, the Binary File Descriptor library.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program; see the file COPYING3. If not,
19 1.1 christos see <http://www.gnu.org/licenses/>. */
20 1.1 christos
21 1.1 christos #include "sysdep.h"
22 1.1 christos #include "bfd.h"
23 1.1 christos #include "libbfd.h"
24 1.1 christos #include "libiberty.h"
25 1.1 christos
26 1.1 christos /* This routine is provided two arch_infos and works out which Aarch64
27 1.1 christos machine which would be compatible with both and returns a pointer
28 1.1 christos to its info structure. */
29 1.1 christos
30 1.1 christos static const bfd_arch_info_type *
31 1.1 christos compatible (const bfd_arch_info_type * a, const bfd_arch_info_type * b)
32 1.1 christos {
33 1.1 christos /* If a & b are for different architecture we can do nothing. */
34 1.1 christos if (a->arch != b->arch)
35 1.1 christos return NULL;
36 1.1 christos
37 1.1 christos /* If a & b are for the same machine then all is well. */
38 1.1 christos if (a->mach == b->mach)
39 1.1 christos return a;
40 1.1 christos
41 1.1 christos /* Don't allow mixing ilp32 with lp64. */
42 1.1 christos if ((a->mach & bfd_mach_aarch64_ilp32) != (b->mach & bfd_mach_aarch64_ilp32))
43 1.1 christos return NULL;
44 1.1 christos
45 1.1 christos /* Otherwise if either a or b is the 'default' machine
46 1.1 christos then it can be polymorphed into the other. */
47 1.1 christos if (a->the_default)
48 1.1 christos return b;
49 1.1 christos
50 1.1 christos if (b->the_default)
51 1.1 christos return a;
52 1.1 christos
53 1.1 christos /* So far all newer cores are
54 1.1 christos supersets of previous cores. */
55 1.1 christos if (a->mach < b->mach)
56 1.1 christos return b;
57 1.1 christos else if (a->mach > b->mach)
58 1.1 christos return a;
59 1.1 christos
60 1.1 christos /* Never reached! */
61 1.1 christos return NULL;
62 1.1 christos }
63 1.1 christos
64 1.1 christos static struct
65 1.1 christos {
66 1.1 christos unsigned int mach;
67 1.1 christos char *name;
68 1.1 christos }
69 1.1 christos processors[] =
70 1.1 christos {
71 1.1 christos /* These two are example CPUs supported in GCC, once we have real
72 1.1 christos CPUs they will be removed. */
73 1.1 christos { bfd_mach_aarch64, "example-1" },
74 1.1 christos { bfd_mach_aarch64, "example-2" }
75 1.1 christos };
76 1.1 christos
77 1.1 christos static bfd_boolean
78 1.1 christos scan (const struct bfd_arch_info *info, const char *string)
79 1.1 christos {
80 1.1 christos int i;
81 1.1 christos
82 1.1 christos /* First test for an exact match. */
83 1.1 christos if (strcasecmp (string, info->printable_name) == 0)
84 1.1 christos return TRUE;
85 1.1 christos
86 1.1 christos /* Next check for a processor name instead of an Architecture name. */
87 1.1 christos for (i = sizeof (processors) / sizeof (processors[0]); i--;)
88 1.1 christos {
89 1.1 christos if (strcasecmp (string, processors[i].name) == 0)
90 1.1 christos break;
91 1.1 christos }
92 1.1 christos
93 1.1 christos if (i != -1 && info->mach == processors[i].mach)
94 1.1 christos return TRUE;
95 1.1 christos
96 1.1 christos /* Finally check for the default architecture. */
97 1.1 christos if (strcasecmp (string, "aarch64") == 0)
98 1.1 christos return info->the_default;
99 1.1 christos
100 1.1 christos return FALSE;
101 1.1 christos }
102 1.1 christos
103 1.1 christos #define N(NUMBER, PRINT, DEFAULT, NEXT) \
104 1.1 christos { 64, 64, 8, bfd_arch_aarch64, NUMBER, \
105 1.1 christos "aarch64", PRINT, 4, DEFAULT, compatible, scan, \
106 1.1 christos bfd_arch_default_fill, NEXT }
107 1.1 christos
108 1.1 christos static const bfd_arch_info_type bfd_aarch64_arch_ilp32 =
109 1.1 christos N (bfd_mach_aarch64_ilp32, "aarch64:ilp32", FALSE, NULL);
110 1.1 christos
111 1.1 christos const bfd_arch_info_type bfd_aarch64_arch =
112 1.1 christos N (0, "aarch64", TRUE, &bfd_aarch64_arch_ilp32);
113 1.1 christos
114 1.1 christos bfd_boolean
115 1.1 christos bfd_is_aarch64_special_symbol_name (const char *name, int type)
116 1.1 christos {
117 1.1 christos if (!name || name[0] != '$')
118 1.1 christos return FALSE;
119 1.1 christos if (name[1] == 'x' || name[1] == 'd')
120 1.1 christos type &= BFD_AARCH64_SPECIAL_SYM_TYPE_MAP;
121 1.1 christos else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
122 1.1 christos type &= BFD_AARCH64_SPECIAL_SYM_TYPE_TAG;
123 1.1 christos else
124 1.1 christos return FALSE;
125 1.1 christos
126 1.1 christos return (type != 0 && (name[2] == 0 || name[2] == '.'));
127 1.1 christos }
128