tc-arc.c revision 1.1.1.8 1 1.1 skrll /* tc-arc.c -- Assembler for the ARC
2 1.1.1.8 christos Copyright (C) 1994-2022 Free Software Foundation, Inc.
3 1.1.1.3 christos
4 1.1.1.3 christos Contributor: Claudiu Zissulescu <claziss (at) synopsys.com>
5 1.1 skrll
6 1.1 skrll This file is part of GAS, the GNU Assembler.
7 1.1 skrll
8 1.1 skrll GAS is free software; you can redistribute it and/or modify
9 1.1 skrll it under the terms of the GNU General Public License as published by
10 1.1 skrll the Free Software Foundation; either version 3, or (at your option)
11 1.1 skrll any later version.
12 1.1 skrll
13 1.1 skrll GAS is distributed in the hope that it will be useful,
14 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
15 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 1.1 skrll GNU General Public License for more details.
17 1.1 skrll
18 1.1 skrll You should have received a copy of the GNU General Public License
19 1.1 skrll along with GAS; see the file COPYING. If not, write to the Free
20 1.1 skrll Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 1.1 skrll 02110-1301, USA. */
22 1.1 skrll
23 1.1 skrll #include "as.h"
24 1.1.1.3 christos #include "subsegs.h"
25 1.1.1.3 christos #include "dwarf2dbg.h"
26 1.1.1.5 christos #include "dw2gencfi.h"
27 1.1 skrll #include "safe-ctype.h"
28 1.1.1.3 christos
29 1.1 skrll #include "opcode/arc.h"
30 1.1.1.6 christos #include "opcode/arc-attrs.h"
31 1.1 skrll #include "elf/arc.h"
32 1.1.1.5 christos #include "../opcodes/arc-ext.h"
33 1.1 skrll
34 1.1.1.3 christos /* Defines section. */
35 1.1 skrll
36 1.1.1.3 christos #define MAX_INSN_FIXUPS 2
37 1.1.1.3 christos #define MAX_CONSTR_STR 20
38 1.1.1.5 christos #define FRAG_MAX_GROWTH 8
39 1.1.1.3 christos
40 1.1.1.3 christos #ifdef DEBUG
41 1.1.1.3 christos # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
42 1.1.1.3 christos #else
43 1.1.1.3 christos # define pr_debug(fmt, args...)
44 1.1.1.3 christos #endif
45 1.1.1.3 christos
46 1.1.1.3 christos #define MAJOR_OPCODE(x) (((x) & 0xF8000000) >> 27)
47 1.1.1.3 christos #define SUB_OPCODE(x) (((x) & 0x003F0000) >> 16)
48 1.1.1.6 christos #define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) \
49 1.1.1.6 christos && (SUB_OPCODE (x) == 0x28))
50 1.1.1.3 christos
51 1.1.1.5 christos #ifndef TARGET_WITH_CPU
52 1.1.1.5 christos #define TARGET_WITH_CPU "arc700"
53 1.1.1.5 christos #endif /* TARGET_WITH_CPU */
54 1.1.1.5 christos
55 1.1.1.6 christos #define ARC_GET_FLAG(s) (*symbol_get_tc (s))
56 1.1.1.6 christos #define ARC_SET_FLAG(s,v) (*symbol_get_tc (s) |= (v))
57 1.1.1.6 christos #define streq(a, b) (strcmp (a, b) == 0)
58 1.1.1.6 christos
59 1.1.1.5 christos /* Enum used to enumerate the relaxable ins operands. */
60 1.1.1.5 christos enum rlx_operand_type
61 1.1.1.5 christos {
62 1.1.1.5 christos EMPTY = 0,
63 1.1.1.5 christos REGISTER,
64 1.1.1.5 christos REGISTER_S, /* Register for short instruction(s). */
65 1.1.1.5 christos REGISTER_NO_GP, /* Is a register but not gp register specifically. */
66 1.1.1.5 christos REGISTER_DUP, /* Duplication of previous operand of type register. */
67 1.1.1.5 christos IMMEDIATE,
68 1.1.1.5 christos BRACKET
69 1.1.1.5 christos };
70 1.1.1.5 christos
71 1.1.1.5 christos enum arc_rlx_types
72 1.1.1.5 christos {
73 1.1.1.5 christos ARC_RLX_NONE = 0,
74 1.1.1.5 christos ARC_RLX_BL_S,
75 1.1.1.5 christos ARC_RLX_BL,
76 1.1.1.5 christos ARC_RLX_B_S,
77 1.1.1.5 christos ARC_RLX_B,
78 1.1.1.5 christos ARC_RLX_ADD_U3,
79 1.1.1.5 christos ARC_RLX_ADD_U6,
80 1.1.1.5 christos ARC_RLX_ADD_LIMM,
81 1.1.1.5 christos ARC_RLX_LD_U7,
82 1.1.1.5 christos ARC_RLX_LD_S9,
83 1.1.1.5 christos ARC_RLX_LD_LIMM,
84 1.1.1.5 christos ARC_RLX_MOV_U8,
85 1.1.1.5 christos ARC_RLX_MOV_S12,
86 1.1.1.5 christos ARC_RLX_MOV_LIMM,
87 1.1.1.5 christos ARC_RLX_SUB_U3,
88 1.1.1.5 christos ARC_RLX_SUB_U6,
89 1.1.1.5 christos ARC_RLX_SUB_LIMM,
90 1.1.1.5 christos ARC_RLX_MPY_U6,
91 1.1.1.5 christos ARC_RLX_MPY_LIMM,
92 1.1.1.5 christos ARC_RLX_MOV_RU6,
93 1.1.1.5 christos ARC_RLX_MOV_RLIMM,
94 1.1.1.5 christos ARC_RLX_ADD_RRU6,
95 1.1.1.5 christos ARC_RLX_ADD_RRLIMM,
96 1.1.1.5 christos };
97 1.1.1.5 christos
98 1.1.1.3 christos /* Macros section. */
99 1.1.1.3 christos
100 1.1.1.3 christos #define regno(x) ((x) & 0x3F)
101 1.1.1.3 christos #define is_ir_num(x) (((x) & ~0x3F) == 0)
102 1.1.1.5 christos #define is_code_density_p(sc) (((sc) == CD1 || (sc) == CD2))
103 1.1.1.5 christos #define is_spfp_p(op) (((sc) == SPX))
104 1.1.1.5 christos #define is_dpfp_p(op) (((sc) == DPX))
105 1.1.1.5 christos #define is_fpuda_p(op) (((sc) == DPA))
106 1.1.1.6 christos #define is_br_jmp_insn_p(op) (((op)->insn_class == BRANCH \
107 1.1.1.6 christos || (op)->insn_class == JUMP \
108 1.1.1.6 christos || (op)->insn_class == BRCC \
109 1.1.1.6 christos || (op)->insn_class == BBIT0 \
110 1.1.1.6 christos || (op)->insn_class == BBIT1 \
111 1.1.1.6 christos || (op)->insn_class == BI \
112 1.1.1.6 christos || (op)->insn_class == EI \
113 1.1.1.6 christos || (op)->insn_class == ENTER \
114 1.1.1.6 christos || (op)->insn_class == JLI \
115 1.1.1.6 christos || (op)->insn_class == LOOP \
116 1.1.1.6 christos || (op)->insn_class == LEAVE \
117 1.1.1.6 christos ))
118 1.1.1.5 christos #define is_kernel_insn_p(op) (((op)->insn_class == KERNEL))
119 1.1.1.5 christos #define is_nps400_p(op) (((sc) == NPS400))
120 1.1 skrll
121 1.1.1.3 christos /* Generic assembler global variables which must be defined by all
122 1.1.1.3 christos targets. */
123 1.1 skrll
124 1.1.1.3 christos /* Characters which always start a comment. */
125 1.1 skrll const char comment_chars[] = "#;";
126 1.1 skrll
127 1.1.1.3 christos /* Characters which start a comment at the beginning of a line. */
128 1.1 skrll const char line_comment_chars[] = "#";
129 1.1 skrll
130 1.1.1.3 christos /* Characters which may be used to separate multiple commands on a
131 1.1.1.3 christos single line. */
132 1.1.1.3 christos const char line_separator_chars[] = "`";
133 1.1 skrll
134 1.1.1.3 christos /* Characters which are used to indicate an exponent in a floating
135 1.1.1.3 christos point number. */
136 1.1 skrll const char EXP_CHARS[] = "eE";
137 1.1 skrll
138 1.1 skrll /* Chars that mean this number is a floating point constant
139 1.1 skrll As in 0f12.456 or 0d1.2345e12. */
140 1.1 skrll const char FLT_CHARS[] = "rRsSfFdD";
141 1.1 skrll
142 1.1 skrll /* Byte order. */
143 1.1 skrll extern int target_big_endian;
144 1.1 skrll const char *arc_target_format = DEFAULT_TARGET_FORMAT;
145 1.1 skrll static int byte_order = DEFAULT_BYTE_ORDER;
146 1.1 skrll
147 1.1.1.5 christos /* Arc extension section. */
148 1.1.1.5 christos static segT arcext_section;
149 1.1.1.5 christos
150 1.1.1.5 christos /* By default relaxation is disabled. */
151 1.1.1.5 christos static int relaxation_state = 0;
152 1.1.1.5 christos
153 1.1.1.3 christos extern int arc_get_mach (char *);
154 1.1 skrll
155 1.1.1.5 christos /* Forward declarations. */
156 1.1.1.3 christos static void arc_lcomm (int);
157 1.1.1.3 christos static void arc_option (int);
158 1.1.1.3 christos static void arc_extra_reloc (int);
159 1.1.1.5 christos static void arc_extinsn (int);
160 1.1.1.5 christos static void arc_extcorereg (int);
161 1.1.1.6 christos static void arc_attribute (int);
162 1.1 skrll
163 1.1.1.3 christos const pseudo_typeS md_pseudo_table[] =
164 1.1.1.3 christos {
165 1.1.1.3 christos /* Make sure that .word is 32 bits. */
166 1.1.1.3 christos { "word", cons, 4 },
167 1.1 skrll
168 1.1.1.3 christos { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */
169 1.1.1.3 christos { "lcomm", arc_lcomm, 0 },
170 1.1.1.3 christos { "lcommon", arc_lcomm, 0 },
171 1.1.1.3 christos { "cpu", arc_option, 0 },
172 1.1.1.3 christos
173 1.1.1.6 christos { "arc_attribute", arc_attribute, 0 },
174 1.1.1.5 christos { "extinstruction", arc_extinsn, 0 },
175 1.1.1.5 christos { "extcoreregister", arc_extcorereg, EXT_CORE_REGISTER },
176 1.1.1.5 christos { "extauxregister", arc_extcorereg, EXT_AUX_REGISTER },
177 1.1.1.5 christos { "extcondcode", arc_extcorereg, EXT_COND_CODE },
178 1.1.1.5 christos
179 1.1.1.3 christos { "tls_gd_ld", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD },
180 1.1.1.3 christos { "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL },
181 1.1.1.3 christos
182 1.1.1.3 christos { NULL, NULL, 0 }
183 1.1.1.3 christos };
184 1.1 skrll
185 1.1 skrll const char *md_shortopts = "";
186 1.1 skrll
187 1.1 skrll enum options
188 1.1 skrll {
189 1.1 skrll OPTION_EB = OPTION_MD_BASE,
190 1.1 skrll OPTION_EL,
191 1.1.1.3 christos
192 1.1.1.3 christos OPTION_ARC600,
193 1.1.1.3 christos OPTION_ARC601,
194 1.1.1.3 christos OPTION_ARC700,
195 1.1.1.3 christos OPTION_ARCEM,
196 1.1.1.3 christos OPTION_ARCHS,
197 1.1.1.3 christos
198 1.1.1.3 christos OPTION_MCPU,
199 1.1.1.3 christos OPTION_CD,
200 1.1.1.5 christos OPTION_RELAX,
201 1.1.1.5 christos OPTION_NPS400,
202 1.1.1.5 christos
203 1.1.1.5 christos OPTION_SPFP,
204 1.1.1.5 christos OPTION_DPFP,
205 1.1.1.5 christos OPTION_FPUDA,
206 1.1.1.3 christos
207 1.1.1.3 christos /* The following options are deprecated and provided here only for
208 1.1.1.3 christos compatibility reasons. */
209 1.1.1.3 christos OPTION_USER_MODE,
210 1.1.1.3 christos OPTION_LD_EXT_MASK,
211 1.1.1.3 christos OPTION_SWAP,
212 1.1.1.3 christos OPTION_NORM,
213 1.1.1.3 christos OPTION_BARREL_SHIFT,
214 1.1.1.3 christos OPTION_MIN_MAX,
215 1.1.1.3 christos OPTION_NO_MPY,
216 1.1.1.3 christos OPTION_EA,
217 1.1.1.3 christos OPTION_MUL64,
218 1.1.1.3 christos OPTION_SIMD,
219 1.1.1.3 christos OPTION_XMAC_D16,
220 1.1.1.3 christos OPTION_XMAC_24,
221 1.1.1.3 christos OPTION_DSP_PACKA,
222 1.1.1.3 christos OPTION_CRC,
223 1.1.1.3 christos OPTION_DVBF,
224 1.1.1.3 christos OPTION_TELEPHONY,
225 1.1.1.3 christos OPTION_XYMEMORY,
226 1.1.1.3 christos OPTION_LOCK,
227 1.1.1.3 christos OPTION_SWAPE,
228 1.1.1.5 christos OPTION_RTSC
229 1.1 skrll };
230 1.1 skrll
231 1.1 skrll struct option md_longopts[] =
232 1.1 skrll {
233 1.1.1.3 christos { "EB", no_argument, NULL, OPTION_EB },
234 1.1.1.3 christos { "EL", no_argument, NULL, OPTION_EL },
235 1.1.1.3 christos { "mcpu", required_argument, NULL, OPTION_MCPU },
236 1.1.1.3 christos { "mA6", no_argument, NULL, OPTION_ARC600 },
237 1.1.1.5 christos { "mARC600", no_argument, NULL, OPTION_ARC600 },
238 1.1.1.5 christos { "mARC601", no_argument, NULL, OPTION_ARC601 },
239 1.1.1.5 christos { "mARC700", no_argument, NULL, OPTION_ARC700 },
240 1.1.1.3 christos { "mA7", no_argument, NULL, OPTION_ARC700 },
241 1.1.1.3 christos { "mEM", no_argument, NULL, OPTION_ARCEM },
242 1.1.1.3 christos { "mHS", no_argument, NULL, OPTION_ARCHS },
243 1.1.1.3 christos { "mcode-density", no_argument, NULL, OPTION_CD },
244 1.1.1.5 christos { "mrelax", no_argument, NULL, OPTION_RELAX },
245 1.1.1.5 christos { "mnps400", no_argument, NULL, OPTION_NPS400 },
246 1.1.1.5 christos
247 1.1.1.5 christos /* Floating point options */
248 1.1.1.5 christos { "mspfp", no_argument, NULL, OPTION_SPFP},
249 1.1.1.5 christos { "mspfp-compact", no_argument, NULL, OPTION_SPFP},
250 1.1.1.5 christos { "mspfp_compact", no_argument, NULL, OPTION_SPFP},
251 1.1.1.5 christos { "mspfp-fast", no_argument, NULL, OPTION_SPFP},
252 1.1.1.5 christos { "mspfp_fast", no_argument, NULL, OPTION_SPFP},
253 1.1.1.5 christos { "mdpfp", no_argument, NULL, OPTION_DPFP},
254 1.1.1.5 christos { "mdpfp-compact", no_argument, NULL, OPTION_DPFP},
255 1.1.1.5 christos { "mdpfp_compact", no_argument, NULL, OPTION_DPFP},
256 1.1.1.5 christos { "mdpfp-fast", no_argument, NULL, OPTION_DPFP},
257 1.1.1.5 christos { "mdpfp_fast", no_argument, NULL, OPTION_DPFP},
258 1.1.1.5 christos { "mfpuda", no_argument, NULL, OPTION_FPUDA},
259 1.1.1.3 christos
260 1.1.1.3 christos /* The following options are deprecated and provided here only for
261 1.1.1.3 christos compatibility reasons. */
262 1.1.1.3 christos { "mav2em", no_argument, NULL, OPTION_ARCEM },
263 1.1.1.3 christos { "mav2hs", no_argument, NULL, OPTION_ARCHS },
264 1.1.1.3 christos { "muser-mode-only", no_argument, NULL, OPTION_USER_MODE },
265 1.1.1.3 christos { "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK },
266 1.1.1.3 christos { "mswap", no_argument, NULL, OPTION_SWAP },
267 1.1.1.3 christos { "mnorm", no_argument, NULL, OPTION_NORM },
268 1.1.1.3 christos { "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
269 1.1.1.3 christos { "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
270 1.1.1.3 christos { "mmin-max", no_argument, NULL, OPTION_MIN_MAX },
271 1.1.1.3 christos { "mmin_max", no_argument, NULL, OPTION_MIN_MAX },
272 1.1.1.3 christos { "mno-mpy", no_argument, NULL, OPTION_NO_MPY },
273 1.1.1.3 christos { "mea", no_argument, NULL, OPTION_EA },
274 1.1.1.3 christos { "mEA", no_argument, NULL, OPTION_EA },
275 1.1.1.3 christos { "mmul64", no_argument, NULL, OPTION_MUL64 },
276 1.1.1.3 christos { "msimd", no_argument, NULL, OPTION_SIMD},
277 1.1.1.3 christos { "mmac-d16", no_argument, NULL, OPTION_XMAC_D16},
278 1.1.1.3 christos { "mmac_d16", no_argument, NULL, OPTION_XMAC_D16},
279 1.1.1.3 christos { "mmac-24", no_argument, NULL, OPTION_XMAC_24},
280 1.1.1.3 christos { "mmac_24", no_argument, NULL, OPTION_XMAC_24},
281 1.1.1.3 christos { "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA},
282 1.1.1.3 christos { "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA},
283 1.1.1.3 christos { "mcrc", no_argument, NULL, OPTION_CRC},
284 1.1.1.3 christos { "mdvbf", no_argument, NULL, OPTION_DVBF},
285 1.1.1.3 christos { "mtelephony", no_argument, NULL, OPTION_TELEPHONY},
286 1.1.1.3 christos { "mxy", no_argument, NULL, OPTION_XYMEMORY},
287 1.1.1.3 christos { "mlock", no_argument, NULL, OPTION_LOCK},
288 1.1.1.3 christos { "mswape", no_argument, NULL, OPTION_SWAPE},
289 1.1.1.3 christos { "mrtsc", no_argument, NULL, OPTION_RTSC},
290 1.1.1.3 christos
291 1.1.1.3 christos { NULL, no_argument, NULL, 0 }
292 1.1 skrll };
293 1.1.1.3 christos
294 1.1 skrll size_t md_longopts_size = sizeof (md_longopts);
295 1.1 skrll
296 1.1.1.3 christos /* Local data and data types. */
297 1.1.1.3 christos
298 1.1.1.3 christos /* Used since new relocation types are introduced in this
299 1.1.1.3 christos file (DUMMY_RELOC_LITUSE_*). */
300 1.1.1.3 christos typedef int extended_bfd_reloc_code_real_type;
301 1.1.1.3 christos
302 1.1.1.3 christos struct arc_fixup
303 1.1.1.3 christos {
304 1.1.1.3 christos expressionS exp;
305 1.1 skrll
306 1.1.1.3 christos extended_bfd_reloc_code_real_type reloc;
307 1.1 skrll
308 1.1.1.3 christos /* index into arc_operands. */
309 1.1.1.3 christos unsigned int opindex;
310 1.1 skrll
311 1.1.1.3 christos /* PC-relative, used by internals fixups. */
312 1.1.1.3 christos unsigned char pcrel;
313 1.1.1.3 christos
314 1.1.1.3 christos /* TRUE if this fixup is for LIMM operand. */
315 1.1.1.8 christos bool islong;
316 1.1.1.3 christos };
317 1.1.1.3 christos
318 1.1.1.3 christos struct arc_insn
319 1.1 skrll {
320 1.1.1.6 christos unsigned long long int insn;
321 1.1.1.3 christos int nfixups;
322 1.1.1.3 christos struct arc_fixup fixups[MAX_INSN_FIXUPS];
323 1.1.1.3 christos long limm;
324 1.1.1.8 christos unsigned int len; /* Length of instruction in bytes. */
325 1.1.1.8 christos bool has_limm; /* Boolean value: TRUE if limm field is valid. */
326 1.1.1.8 christos bool relax; /* Boolean value: TRUE if needs relaxation. */
327 1.1.1.3 christos };
328 1.1 skrll
329 1.1.1.3 christos /* Structure to hold any last two instructions. */
330 1.1.1.3 christos static struct arc_last_insn
331 1.1 skrll {
332 1.1.1.3 christos /* Saved instruction opcode. */
333 1.1.1.3 christos const struct arc_opcode *opcode;
334 1.1 skrll
335 1.1.1.3 christos /* Boolean value: TRUE if current insn is short. */
336 1.1.1.8 christos bool has_limm;
337 1.1 skrll
338 1.1.1.3 christos /* Boolean value: TRUE if current insn has delay slot. */
339 1.1.1.8 christos bool has_delay_slot;
340 1.1.1.3 christos } arc_last_insns[2];
341 1.1.1.3 christos
342 1.1.1.5 christos /* Extension instruction suffix classes. */
343 1.1.1.5 christos typedef struct
344 1.1.1.5 christos {
345 1.1.1.5 christos const char *name;
346 1.1.1.5 christos int len;
347 1.1.1.5 christos int attr_class;
348 1.1.1.5 christos } attributes_t;
349 1.1.1.5 christos
350 1.1.1.5 christos static const attributes_t suffixclass[] =
351 1.1.1.5 christos {
352 1.1.1.5 christos { "SUFFIX_FLAG", 11, ARC_SUFFIX_FLAG },
353 1.1.1.5 christos { "SUFFIX_COND", 11, ARC_SUFFIX_COND },
354 1.1.1.5 christos { "SUFFIX_NONE", 11, ARC_SUFFIX_NONE }
355 1.1.1.5 christos };
356 1.1.1.5 christos
357 1.1.1.5 christos /* Extension instruction syntax classes. */
358 1.1.1.5 christos static const attributes_t syntaxclass[] =
359 1.1.1.5 christos {
360 1.1.1.5 christos { "SYNTAX_3OP", 10, ARC_SYNTAX_3OP },
361 1.1.1.5 christos { "SYNTAX_2OP", 10, ARC_SYNTAX_2OP },
362 1.1.1.5 christos { "SYNTAX_1OP", 10, ARC_SYNTAX_1OP },
363 1.1.1.5 christos { "SYNTAX_NOP", 10, ARC_SYNTAX_NOP }
364 1.1.1.5 christos };
365 1.1.1.5 christos
366 1.1.1.5 christos /* Extension instruction syntax classes modifiers. */
367 1.1.1.5 christos static const attributes_t syntaxclassmod[] =
368 1.1.1.5 christos {
369 1.1.1.5 christos { "OP1_IMM_IMPLIED" , 15, ARC_OP1_IMM_IMPLIED },
370 1.1.1.5 christos { "OP1_MUST_BE_IMM" , 15, ARC_OP1_MUST_BE_IMM }
371 1.1.1.5 christos };
372 1.1.1.5 christos
373 1.1.1.5 christos /* Extension register type. */
374 1.1.1.5 christos typedef struct
375 1.1.1.5 christos {
376 1.1.1.5 christos char *name;
377 1.1.1.5 christos int number;
378 1.1.1.5 christos int imode;
379 1.1.1.5 christos } extRegister_t;
380 1.1.1.5 christos
381 1.1.1.5 christos /* A structure to hold the additional conditional codes. */
382 1.1.1.5 christos static struct
383 1.1.1.5 christos {
384 1.1.1.5 christos struct arc_flag_operand *arc_ext_condcode;
385 1.1.1.5 christos int size;
386 1.1.1.5 christos } ext_condcode = { NULL, 0 };
387 1.1.1.5 christos
388 1.1.1.5 christos /* Structure to hold an entry in ARC_OPCODE_HASH. */
389 1.1.1.5 christos struct arc_opcode_hash_entry
390 1.1.1.5 christos {
391 1.1.1.5 christos /* The number of pointers in the OPCODE list. */
392 1.1.1.5 christos size_t count;
393 1.1.1.5 christos
394 1.1.1.5 christos /* Points to a list of opcode pointers. */
395 1.1.1.5 christos const struct arc_opcode **opcode;
396 1.1.1.5 christos };
397 1.1.1.5 christos
398 1.1.1.5 christos /* Structure used for iterating through an arc_opcode_hash_entry. */
399 1.1.1.5 christos struct arc_opcode_hash_entry_iterator
400 1.1.1.5 christos {
401 1.1.1.5 christos /* Index into the OPCODE element of the arc_opcode_hash_entry. */
402 1.1.1.5 christos size_t index;
403 1.1.1.5 christos
404 1.1.1.5 christos /* The specific ARC_OPCODE from the ARC_OPCODES table that was last
405 1.1.1.5 christos returned by this iterator. */
406 1.1.1.5 christos const struct arc_opcode *opcode;
407 1.1.1.5 christos };
408 1.1.1.5 christos
409 1.1.1.5 christos /* Forward declaration. */
410 1.1.1.5 christos static void assemble_insn
411 1.1.1.5 christos (const struct arc_opcode *, const expressionS *, int,
412 1.1.1.5 christos const struct arc_flags *, int, struct arc_insn *);
413 1.1.1.5 christos
414 1.1.1.6 christos /* The selection of the machine type can come from different sources. This
415 1.1.1.6 christos enum is used to track how the selection was made in order to perform
416 1.1.1.6 christos error checks. */
417 1.1.1.6 christos enum mach_selection_type
418 1.1.1.6 christos {
419 1.1.1.6 christos MACH_SELECTION_NONE,
420 1.1.1.6 christos MACH_SELECTION_FROM_DEFAULT,
421 1.1.1.6 christos MACH_SELECTION_FROM_CPU_DIRECTIVE,
422 1.1.1.6 christos MACH_SELECTION_FROM_COMMAND_LINE
423 1.1.1.6 christos };
424 1.1 skrll
425 1.1.1.6 christos /* How the current machine type was selected. */
426 1.1.1.6 christos static enum mach_selection_type mach_selection_mode = MACH_SELECTION_NONE;
427 1.1 skrll
428 1.1.1.3 christos /* The hash table of instruction opcodes. */
429 1.1.1.8 christos static htab_t arc_opcode_hash;
430 1.1 skrll
431 1.1.1.3 christos /* The hash table of register symbols. */
432 1.1.1.8 christos static htab_t arc_reg_hash;
433 1.1.1.3 christos
434 1.1.1.5 christos /* The hash table of aux register symbols. */
435 1.1.1.8 christos static htab_t arc_aux_hash;
436 1.1.1.5 christos
437 1.1.1.6 christos /* The hash table of address types. */
438 1.1.1.8 christos static htab_t arc_addrtype_hash;
439 1.1.1.6 christos
440 1.1.1.6 christos #define ARC_CPU_TYPE_A6xx(NAME,EXTRA) \
441 1.1.1.6 christos { #NAME, ARC_OPCODE_ARC600, bfd_mach_arc_arc600, \
442 1.1.1.6 christos E_ARC_MACH_ARC600, EXTRA}
443 1.1.1.6 christos #define ARC_CPU_TYPE_A7xx(NAME,EXTRA) \
444 1.1.1.6 christos { #NAME, ARC_OPCODE_ARC700, bfd_mach_arc_arc700, \
445 1.1.1.6 christos E_ARC_MACH_ARC700, EXTRA}
446 1.1.1.6 christos #define ARC_CPU_TYPE_AV2EM(NAME,EXTRA) \
447 1.1.1.6 christos { #NAME, ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2, \
448 1.1.1.6 christos EF_ARC_CPU_ARCV2EM, EXTRA}
449 1.1.1.6 christos #define ARC_CPU_TYPE_AV2HS(NAME,EXTRA) \
450 1.1.1.6 christos { #NAME, ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2, \
451 1.1.1.6 christos EF_ARC_CPU_ARCV2HS, EXTRA}
452 1.1.1.6 christos #define ARC_CPU_TYPE_NONE \
453 1.1.1.6 christos { 0, 0, 0, 0, 0 }
454 1.1.1.6 christos
455 1.1.1.3 christos /* A table of CPU names and opcode sets. */
456 1.1.1.3 christos static const struct cpu_type
457 1.1 skrll {
458 1.1.1.3 christos const char *name;
459 1.1.1.3 christos unsigned flags;
460 1.1.1.3 christos int mach;
461 1.1.1.3 christos unsigned eflags;
462 1.1.1.3 christos unsigned features;
463 1.1.1.3 christos }
464 1.1.1.3 christos cpu_types[] =
465 1.1.1.3 christos {
466 1.1.1.6 christos #include "elf/arc-cpu.def"
467 1.1.1.3 christos };
468 1.1 skrll
469 1.1.1.6 christos /* Information about the cpu/variant we're assembling for. */
470 1.1.1.6 christos static struct cpu_type selected_cpu = { 0, 0, 0, E_ARC_OSABI_CURRENT, 0 };
471 1.1.1.6 christos
472 1.1.1.7 christos /* TRUE if current assembly code uses RF16 only registers. */
473 1.1.1.8 christos static bool rf16_only = true;
474 1.1.1.7 christos
475 1.1.1.6 christos /* MPY option. */
476 1.1.1.6 christos static unsigned mpy_option = 0;
477 1.1.1.6 christos
478 1.1.1.6 christos /* Use PIC. */
479 1.1.1.6 christos static unsigned pic_option = 0;
480 1.1.1.6 christos
481 1.1.1.6 christos /* Use small data. */
482 1.1.1.6 christos static unsigned sda_option = 0;
483 1.1.1.6 christos
484 1.1.1.6 christos /* Use TLS. */
485 1.1.1.6 christos static unsigned tls_option = 0;
486 1.1.1.6 christos
487 1.1.1.6 christos /* Command line given features. */
488 1.1.1.6 christos static unsigned cl_features = 0;
489 1.1.1.6 christos
490 1.1.1.3 christos /* Used by the arc_reloc_op table. Order is important. */
491 1.1.1.3 christos #define O_gotoff O_md1 /* @gotoff relocation. */
492 1.1.1.3 christos #define O_gotpc O_md2 /* @gotpc relocation. */
493 1.1.1.3 christos #define O_plt O_md3 /* @plt relocation. */
494 1.1.1.3 christos #define O_sda O_md4 /* @sda relocation. */
495 1.1.1.3 christos #define O_pcl O_md5 /* @pcl relocation. */
496 1.1.1.3 christos #define O_tlsgd O_md6 /* @tlsgd relocation. */
497 1.1.1.3 christos #define O_tlsie O_md7 /* @tlsie relocation. */
498 1.1.1.3 christos #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
499 1.1.1.3 christos #define O_tpoff O_md9 /* @tpoff relocation. */
500 1.1.1.3 christos #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
501 1.1.1.3 christos #define O_dtpoff O_md11 /* @dtpoff relocation. */
502 1.1.1.3 christos #define O_last O_dtpoff
503 1.1.1.3 christos
504 1.1.1.3 christos /* Used to define a bracket as operand in tokens. */
505 1.1.1.3 christos #define O_bracket O_md32
506 1.1.1.3 christos
507 1.1.1.6 christos /* Used to define a colon as an operand in tokens. */
508 1.1.1.6 christos #define O_colon O_md31
509 1.1.1.6 christos
510 1.1.1.6 christos /* Used to define address types in nps400. */
511 1.1.1.6 christos #define O_addrtype O_md30
512 1.1.1.6 christos
513 1.1.1.3 christos /* Dummy relocation, to be sorted out. */
514 1.1.1.3 christos #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
515 1.1.1.3 christos
516 1.1.1.3 christos #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
517 1.1.1.3 christos
518 1.1.1.3 christos /* A table to map the spelling of a relocation operand into an appropriate
519 1.1.1.3 christos bfd_reloc_code_real_type type. The table is assumed to be ordered such
520 1.1.1.3 christos that op-O_literal indexes into it. */
521 1.1.1.3 christos #define ARC_RELOC_TABLE(op) \
522 1.1.1.3 christos (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
523 1.1.1.3 christos ? (abort (), 0) \
524 1.1.1.3 christos : (int) (op) - (int) O_gotoff) ])
525 1.1.1.3 christos
526 1.1.1.3 christos #define DEF(NAME, RELOC, REQ) \
527 1.1.1.3 christos { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
528 1.1.1.3 christos
529 1.1.1.3 christos static const struct arc_reloc_op_tag
530 1.1.1.3 christos {
531 1.1.1.3 christos /* String to lookup. */
532 1.1.1.3 christos const char *name;
533 1.1.1.3 christos /* Size of the string. */
534 1.1.1.3 christos size_t length;
535 1.1.1.3 christos /* Which operator to use. */
536 1.1.1.3 christos operatorT op;
537 1.1.1.3 christos extended_bfd_reloc_code_real_type reloc;
538 1.1.1.3 christos /* Allows complex relocation expression like identifier@reloc +
539 1.1.1.3 christos const. */
540 1.1.1.3 christos unsigned int complex_expr : 1;
541 1.1.1.3 christos }
542 1.1.1.3 christos arc_reloc_op[] =
543 1.1.1.3 christos {
544 1.1.1.3 christos DEF (gotoff, BFD_RELOC_ARC_GOTOFF, 1),
545 1.1.1.3 christos DEF (gotpc, BFD_RELOC_ARC_GOTPC32, 0),
546 1.1.1.3 christos DEF (plt, BFD_RELOC_ARC_PLT32, 0),
547 1.1.1.3 christos DEF (sda, DUMMY_RELOC_ARC_ENTRY, 1),
548 1.1.1.3 christos DEF (pcl, BFD_RELOC_ARC_PC32, 1),
549 1.1.1.3 christos DEF (tlsgd, BFD_RELOC_ARC_TLS_GD_GOT, 0),
550 1.1.1.3 christos DEF (tlsie, BFD_RELOC_ARC_TLS_IE_GOT, 0),
551 1.1.1.3 christos DEF (tpoff9, BFD_RELOC_ARC_TLS_LE_S9, 0),
552 1.1.1.5 christos DEF (tpoff, BFD_RELOC_ARC_TLS_LE_32, 1),
553 1.1.1.3 christos DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9, 0),
554 1.1.1.6 christos DEF (dtpoff, BFD_RELOC_ARC_TLS_DTPOFF, 1),
555 1.1.1.3 christos };
556 1.1 skrll
557 1.1.1.3 christos static const int arc_num_reloc_op
558 1.1.1.3 christos = sizeof (arc_reloc_op) / sizeof (*arc_reloc_op);
559 1.1.1.3 christos
560 1.1.1.5 christos /* Structure for relaxable instruction that have to be swapped with a
561 1.1.1.5 christos smaller alternative instruction. */
562 1.1.1.5 christos struct arc_relaxable_ins
563 1.1.1.5 christos {
564 1.1.1.5 christos /* Mnemonic that should be checked. */
565 1.1.1.5 christos const char *mnemonic_r;
566 1.1.1.5 christos
567 1.1.1.5 christos /* Operands that should be checked.
568 1.1.1.5 christos Indexes of operands from operand array. */
569 1.1.1.5 christos enum rlx_operand_type operands[6];
570 1.1.1.5 christos
571 1.1.1.5 christos /* Flags that should be checked. */
572 1.1.1.5 christos unsigned flag_classes[5];
573 1.1.1.5 christos
574 1.1.1.5 christos /* Mnemonic (smaller) alternative to be used later for relaxation. */
575 1.1.1.5 christos const char *mnemonic_alt;
576 1.1.1.5 christos
577 1.1.1.5 christos /* Index of operand that generic relaxation has to check. */
578 1.1.1.5 christos unsigned opcheckidx;
579 1.1.1.5 christos
580 1.1.1.5 christos /* Base subtype index used. */
581 1.1.1.5 christos enum arc_rlx_types subtype;
582 1.1.1.5 christos };
583 1.1.1.5 christos
584 1.1.1.5 christos #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \
585 1.1.1.5 christos { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \
586 1.1.1.5 christos (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \
587 1.1.1.5 christos (SIZE), \
588 1.1.1.5 christos (NEXT) } \
589 1.1.1.5 christos
590 1.1.1.5 christos #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \
591 1.1.1.5 christos { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \
592 1.1.1.5 christos (ISSIGNED) ? -(0x7FFFFFFF) : 0, \
593 1.1.1.5 christos (SIZE), \
594 1.1.1.5 christos (NEXT) } \
595 1.1.1.5 christos
596 1.1.1.5 christos
597 1.1.1.5 christos /* ARC relaxation table. */
598 1.1.1.5 christos const relax_typeS md_relax_table[] =
599 1.1.1.5 christos {
600 1.1.1.5 christos /* Fake entry. */
601 1.1.1.5 christos {0, 0, 0, 0},
602 1.1.1.5 christos
603 1.1.1.5 christos /* BL_S s13 ->
604 1.1.1.5 christos BL s25. */
605 1.1.1.6 christos RELAX_TABLE_ENTRY (13, 1, 2, ARC_RLX_BL),
606 1.1.1.6 christos RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE),
607 1.1.1.5 christos
608 1.1.1.5 christos /* B_S s10 ->
609 1.1.1.5 christos B s25. */
610 1.1.1.6 christos RELAX_TABLE_ENTRY (10, 1, 2, ARC_RLX_B),
611 1.1.1.6 christos RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE),
612 1.1.1.5 christos
613 1.1.1.5 christos /* ADD_S c,b, u3 ->
614 1.1.1.5 christos ADD<.f> a,b,u6 ->
615 1.1.1.5 christos ADD<.f> a,b,limm. */
616 1.1.1.6 christos RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_ADD_U6),
617 1.1.1.6 christos RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_LIMM),
618 1.1.1.6 christos RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
619 1.1.1.5 christos
620 1.1.1.5 christos /* LD_S a, [b, u7] ->
621 1.1.1.5 christos LD<zz><.x><.aa><.di> a, [b, s9] ->
622 1.1.1.5 christos LD<zz><.x><.aa><.di> a, [b, limm] */
623 1.1.1.6 christos RELAX_TABLE_ENTRY (7, 0, 2, ARC_RLX_LD_S9),
624 1.1.1.6 christos RELAX_TABLE_ENTRY (9, 1, 4, ARC_RLX_LD_LIMM),
625 1.1.1.6 christos RELAX_TABLE_ENTRY_MAX (1, 8, ARC_RLX_NONE),
626 1.1.1.5 christos
627 1.1.1.5 christos /* MOV_S b, u8 ->
628 1.1.1.5 christos MOV<.f> b, s12 ->
629 1.1.1.5 christos MOV<.f> b, limm. */
630 1.1.1.6 christos RELAX_TABLE_ENTRY (8, 0, 2, ARC_RLX_MOV_S12),
631 1.1.1.6 christos RELAX_TABLE_ENTRY (8, 0, 4, ARC_RLX_MOV_LIMM),
632 1.1.1.6 christos RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
633 1.1.1.5 christos
634 1.1.1.5 christos /* SUB_S c, b, u3 ->
635 1.1.1.5 christos SUB<.f> a, b, u6 ->
636 1.1.1.5 christos SUB<.f> a, b, limm. */
637 1.1.1.6 christos RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_SUB_U6),
638 1.1.1.6 christos RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_SUB_LIMM),
639 1.1.1.6 christos RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
640 1.1.1.5 christos
641 1.1.1.5 christos /* MPY<.f> a, b, u6 ->
642 1.1.1.5 christos MPY<.f> a, b, limm. */
643 1.1.1.6 christos RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MPY_LIMM),
644 1.1.1.6 christos RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
645 1.1.1.5 christos
646 1.1.1.5 christos /* MOV<.f><.cc> b, u6 ->
647 1.1.1.5 christos MOV<.f><.cc> b, limm. */
648 1.1.1.6 christos RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MOV_RLIMM),
649 1.1.1.6 christos RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
650 1.1.1.5 christos
651 1.1.1.5 christos /* ADD<.f><.cc> b, b, u6 ->
652 1.1.1.5 christos ADD<.f><.cc> b, b, limm. */
653 1.1.1.6 christos RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_RRLIMM),
654 1.1.1.6 christos RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
655 1.1.1.5 christos };
656 1.1.1.5 christos
657 1.1.1.5 christos /* Order of this table's entries matters! */
658 1.1.1.5 christos const struct arc_relaxable_ins arc_relaxable_insns[] =
659 1.1.1.5 christos {
660 1.1.1.5 christos { "bl", { IMMEDIATE }, { 0 }, "bl_s", 0, ARC_RLX_BL_S },
661 1.1.1.5 christos { "b", { IMMEDIATE }, { 0 }, "b_s", 0, ARC_RLX_B_S },
662 1.1.1.5 christos { "add", { REGISTER, REGISTER_DUP, IMMEDIATE }, { 5, 1, 0 }, "add",
663 1.1.1.5 christos 2, ARC_RLX_ADD_RRU6},
664 1.1.1.5 christos { "add", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "add_s", 2,
665 1.1.1.5 christos ARC_RLX_ADD_U3 },
666 1.1.1.5 christos { "add", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "add", 2,
667 1.1.1.5 christos ARC_RLX_ADD_U6 },
668 1.1.1.5 christos { "ld", { REGISTER_S, BRACKET, REGISTER_S, IMMEDIATE, BRACKET },
669 1.1.1.5 christos { 0 }, "ld_s", 3, ARC_RLX_LD_U7 },
670 1.1.1.5 christos { "ld", { REGISTER, BRACKET, REGISTER_NO_GP, IMMEDIATE, BRACKET },
671 1.1.1.5 christos { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9 },
672 1.1.1.5 christos { "mov", { REGISTER_S, IMMEDIATE }, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8 },
673 1.1.1.5 christos { "mov", { REGISTER, IMMEDIATE }, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12 },
674 1.1.1.5 christos { "mov", { REGISTER, IMMEDIATE }, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6 },
675 1.1.1.5 christos { "sub", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "sub_s", 2,
676 1.1.1.5 christos ARC_RLX_SUB_U3 },
677 1.1.1.5 christos { "sub", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "sub", 2,
678 1.1.1.5 christos ARC_RLX_SUB_U6 },
679 1.1.1.5 christos { "mpy", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "mpy", 2,
680 1.1.1.5 christos ARC_RLX_MPY_U6 },
681 1.1.1.5 christos };
682 1.1.1.5 christos
683 1.1.1.5 christos const unsigned arc_num_relaxable_ins = ARRAY_SIZE (arc_relaxable_insns);
684 1.1.1.5 christos
685 1.1.1.3 christos /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
686 1.1.1.3 christos symbolS * GOT_symbol = 0;
687 1.1 skrll
688 1.1.1.3 christos /* Set to TRUE when we assemble instructions. */
689 1.1.1.8 christos static bool assembling_insn = false;
690 1.1.1.3 christos
691 1.1.1.6 christos /* List with attributes set explicitly. */
692 1.1.1.8 christos static bool attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES];
693 1.1.1.6 christos
694 1.1.1.5 christos /* Functions implementation. */
695 1.1.1.3 christos
696 1.1.1.5 christos /* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all
697 1.1.1.5 christos ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if there
698 1.1.1.5 christos are no matching entries in ARC_OPCODE_HASH. */
699 1.1.1.5 christos
700 1.1.1.5 christos static const struct arc_opcode_hash_entry *
701 1.1.1.5 christos arc_find_opcode (const char *name)
702 1.1.1.5 christos {
703 1.1.1.5 christos const struct arc_opcode_hash_entry *entry;
704 1.1.1.5 christos
705 1.1.1.8 christos entry = str_hash_find (arc_opcode_hash, name);
706 1.1.1.5 christos return entry;
707 1.1.1.5 christos }
708 1.1.1.5 christos
709 1.1.1.5 christos /* Initialise the iterator ITER. */
710 1.1.1.5 christos
711 1.1.1.5 christos static void
712 1.1.1.5 christos arc_opcode_hash_entry_iterator_init (struct arc_opcode_hash_entry_iterator *iter)
713 1.1.1.5 christos {
714 1.1.1.5 christos iter->index = 0;
715 1.1.1.5 christos iter->opcode = NULL;
716 1.1.1.5 christos }
717 1.1.1.5 christos
718 1.1.1.5 christos /* Return the next ARC_OPCODE from ENTRY, using ITER to hold state between
719 1.1.1.5 christos calls to this function. Return NULL when all ARC_OPCODE entries have
720 1.1.1.5 christos been returned. */
721 1.1.1.5 christos
722 1.1.1.5 christos static const struct arc_opcode *
723 1.1.1.5 christos arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry *entry,
724 1.1.1.5 christos struct arc_opcode_hash_entry_iterator *iter)
725 1.1.1.5 christos {
726 1.1.1.5 christos if (iter->opcode == NULL && iter->index == 0)
727 1.1.1.5 christos {
728 1.1.1.5 christos gas_assert (entry->count > 0);
729 1.1.1.5 christos iter->opcode = entry->opcode[iter->index];
730 1.1.1.5 christos }
731 1.1.1.5 christos else if (iter->opcode != NULL)
732 1.1.1.5 christos {
733 1.1.1.5 christos const char *old_name = iter->opcode->name;
734 1.1.1.5 christos
735 1.1.1.5 christos iter->opcode++;
736 1.1.1.5 christos if (iter->opcode->name == NULL
737 1.1.1.5 christos || strcmp (old_name, iter->opcode->name) != 0)
738 1.1.1.5 christos {
739 1.1.1.5 christos iter->index++;
740 1.1.1.5 christos if (iter->index == entry->count)
741 1.1.1.5 christos iter->opcode = NULL;
742 1.1.1.5 christos else
743 1.1.1.5 christos iter->opcode = entry->opcode[iter->index];
744 1.1.1.5 christos }
745 1.1.1.5 christos }
746 1.1.1.5 christos
747 1.1.1.5 christos return iter->opcode;
748 1.1.1.5 christos }
749 1.1.1.5 christos
750 1.1.1.5 christos /* Insert an opcode into opcode hash structure. */
751 1.1.1.5 christos
752 1.1.1.5 christos static void
753 1.1.1.5 christos arc_insert_opcode (const struct arc_opcode *opcode)
754 1.1.1.5 christos {
755 1.1.1.8 christos const char *name;
756 1.1.1.5 christos struct arc_opcode_hash_entry *entry;
757 1.1.1.5 christos name = opcode->name;
758 1.1.1.5 christos
759 1.1.1.8 christos entry = str_hash_find (arc_opcode_hash, name);
760 1.1.1.5 christos if (entry == NULL)
761 1.1.1.5 christos {
762 1.1.1.5 christos entry = XNEW (struct arc_opcode_hash_entry);
763 1.1.1.5 christos entry->count = 0;
764 1.1.1.5 christos entry->opcode = NULL;
765 1.1.1.5 christos
766 1.1.1.8 christos if (str_hash_insert (arc_opcode_hash, name, entry, 0) != NULL)
767 1.1.1.8 christos as_fatal (_("duplicate %s"), name);
768 1.1.1.5 christos }
769 1.1.1.5 christos
770 1.1.1.5 christos entry->opcode = XRESIZEVEC (const struct arc_opcode *, entry->opcode,
771 1.1.1.5 christos entry->count + 1);
772 1.1.1.5 christos
773 1.1.1.5 christos entry->opcode[entry->count] = opcode;
774 1.1.1.5 christos entry->count++;
775 1.1.1.5 christos }
776 1.1.1.3 christos
777 1.1.1.3 christos
778 1.1.1.6 christos /* Like md_number_to_chars but for middle-endian values. The 4-byte limm
779 1.1.1.6 christos value, is encoded as 'middle-endian' for a little-endian target. This
780 1.1.1.6 christos function is used for regular 4, 6, and 8 byte instructions as well. */
781 1.1 skrll
782 1.1.1.3 christos static void
783 1.1.1.6 christos md_number_to_chars_midend (char *buf, unsigned long long val, int n)
784 1.1.1.3 christos {
785 1.1.1.6 christos switch (n)
786 1.1 skrll {
787 1.1.1.6 christos case 2:
788 1.1.1.6 christos md_number_to_chars (buf, val, n);
789 1.1.1.6 christos break;
790 1.1.1.6 christos case 6:
791 1.1.1.7 christos md_number_to_chars (buf, (val & 0xffff00000000ull) >> 32, 2);
792 1.1.1.6 christos md_number_to_chars_midend (buf + 2, (val & 0xffffffff), 4);
793 1.1.1.6 christos break;
794 1.1.1.6 christos case 4:
795 1.1.1.3 christos md_number_to_chars (buf, (val & 0xffff0000) >> 16, 2);
796 1.1.1.3 christos md_number_to_chars (buf + 2, (val & 0xffff), 2);
797 1.1.1.6 christos break;
798 1.1.1.6 christos case 8:
799 1.1.1.7 christos md_number_to_chars_midend (buf, (val & 0xffffffff00000000ull) >> 32, 4);
800 1.1.1.6 christos md_number_to_chars_midend (buf + 4, (val & 0xffffffff), 4);
801 1.1.1.6 christos break;
802 1.1.1.6 christos default:
803 1.1.1.6 christos abort ();
804 1.1.1.3 christos }
805 1.1.1.6 christos }
806 1.1.1.6 christos
807 1.1.1.6 christos /* Check if a feature is allowed for a specific CPU. */
808 1.1.1.6 christos
809 1.1.1.6 christos static void
810 1.1.1.6 christos arc_check_feature (void)
811 1.1.1.6 christos {
812 1.1.1.6 christos unsigned i;
813 1.1.1.6 christos
814 1.1.1.6 christos if (!selected_cpu.features
815 1.1.1.6 christos || !selected_cpu.name)
816 1.1.1.6 christos return;
817 1.1.1.6 christos
818 1.1.1.6 christos for (i = 0; i < ARRAY_SIZE (feature_list); i++)
819 1.1.1.6 christos if ((selected_cpu.features & feature_list[i].feature)
820 1.1.1.6 christos && !(selected_cpu.flags & feature_list[i].cpus))
821 1.1.1.6 christos as_bad (_("invalid %s option for %s cpu"), feature_list[i].name,
822 1.1.1.6 christos selected_cpu.name);
823 1.1.1.6 christos
824 1.1.1.6 christos for (i = 0; i < ARRAY_SIZE (conflict_list); i++)
825 1.1.1.6 christos if ((selected_cpu.features & conflict_list[i]) == conflict_list[i])
826 1.1.1.6 christos as_bad(_("conflicting ISA extension attributes."));
827 1.1.1.3 christos }
828 1.1 skrll
829 1.1.1.5 christos /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
830 1.1.1.6 christos the relevant static global variables. Parameter SEL describes where
831 1.1.1.6 christos this selection originated from. */
832 1.1.1.5 christos
833 1.1.1.5 christos static void
834 1.1.1.6 christos arc_select_cpu (const char *arg, enum mach_selection_type sel)
835 1.1.1.5 christos {
836 1.1.1.5 christos int i;
837 1.1.1.7 christos static struct cpu_type old_cpu = { 0, 0, 0, E_ARC_OSABI_CURRENT, 0 };
838 1.1.1.5 christos
839 1.1.1.6 christos /* We should only set a default if we've not made a selection from some
840 1.1.1.6 christos other source. */
841 1.1.1.6 christos gas_assert (sel != MACH_SELECTION_FROM_DEFAULT
842 1.1.1.6 christos || mach_selection_mode == MACH_SELECTION_NONE);
843 1.1.1.6 christos
844 1.1.1.6 christos if ((mach_selection_mode == MACH_SELECTION_FROM_CPU_DIRECTIVE)
845 1.1.1.6 christos && (sel == MACH_SELECTION_FROM_CPU_DIRECTIVE))
846 1.1.1.6 christos as_bad (_("Multiple .cpu directives found"));
847 1.1.1.6 christos
848 1.1.1.6 christos /* Look for a matching entry in CPU_TYPES array. */
849 1.1.1.5 christos for (i = 0; cpu_types[i].name; ++i)
850 1.1.1.5 christos {
851 1.1.1.5 christos if (!strcasecmp (cpu_types[i].name, arg))
852 1.1.1.5 christos {
853 1.1.1.6 christos /* If a previous selection was made on the command line, then we
854 1.1.1.6 christos allow later selections on the command line to override earlier
855 1.1.1.6 christos ones. However, a selection from a '.cpu NAME' directive must
856 1.1.1.6 christos match the command line selection, or we give a warning. */
857 1.1.1.6 christos if (mach_selection_mode == MACH_SELECTION_FROM_COMMAND_LINE)
858 1.1.1.6 christos {
859 1.1.1.6 christos gas_assert (sel == MACH_SELECTION_FROM_COMMAND_LINE
860 1.1.1.6 christos || sel == MACH_SELECTION_FROM_CPU_DIRECTIVE);
861 1.1.1.6 christos if (sel == MACH_SELECTION_FROM_CPU_DIRECTIVE
862 1.1.1.6 christos && selected_cpu.mach != cpu_types[i].mach)
863 1.1.1.6 christos {
864 1.1.1.6 christos as_warn (_("Command-line value overrides \".cpu\" directive"));
865 1.1.1.6 christos }
866 1.1.1.6 christos return;
867 1.1.1.6 christos }
868 1.1.1.6 christos /* Initialise static global data about selected machine type. */
869 1.1.1.6 christos selected_cpu.flags = cpu_types[i].flags;
870 1.1.1.6 christos selected_cpu.name = cpu_types[i].name;
871 1.1.1.6 christos selected_cpu.features = cpu_types[i].features | cl_features;
872 1.1.1.6 christos selected_cpu.mach = cpu_types[i].mach;
873 1.1.1.6 christos selected_cpu.eflags = ((selected_cpu.eflags & ~EF_ARC_MACH_MSK)
874 1.1.1.6 christos | cpu_types[i].eflags);
875 1.1.1.5 christos break;
876 1.1.1.5 christos }
877 1.1.1.5 christos }
878 1.1.1.5 christos
879 1.1.1.5 christos if (!cpu_types[i].name)
880 1.1.1.5 christos as_fatal (_("unknown architecture: %s\n"), arg);
881 1.1.1.6 christos
882 1.1.1.6 christos /* Check if set features are compatible with the chosen CPU. */
883 1.1.1.6 christos arc_check_feature ();
884 1.1.1.6 christos
885 1.1.1.7 christos /* If we change the CPU, we need to re-init the bfd. */
886 1.1.1.7 christos if (mach_selection_mode != MACH_SELECTION_NONE
887 1.1.1.7 christos && (old_cpu.mach != selected_cpu.mach))
888 1.1.1.7 christos {
889 1.1.1.7 christos bfd_find_target (arc_target_format, stdoutput);
890 1.1.1.7 christos if (! bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
891 1.1.1.7 christos as_warn (_("Could not set architecture and machine"));
892 1.1.1.7 christos }
893 1.1.1.7 christos
894 1.1.1.6 christos mach_selection_mode = sel;
895 1.1.1.7 christos old_cpu = selected_cpu;
896 1.1.1.5 christos }
897 1.1.1.5 christos
898 1.1.1.3 christos /* Here ends all the ARCompact extension instruction assembling
899 1.1.1.3 christos stuff. */
900 1.1 skrll
901 1.1.1.3 christos static void
902 1.1.1.3 christos arc_extra_reloc (int r_type)
903 1.1.1.3 christos {
904 1.1.1.3 christos char *sym_name, c;
905 1.1.1.3 christos symbolS *sym, *lab = NULL;
906 1.1 skrll
907 1.1.1.3 christos if (*input_line_pointer == '@')
908 1.1.1.3 christos input_line_pointer++;
909 1.1.1.3 christos c = get_symbol_name (&sym_name);
910 1.1.1.3 christos sym = symbol_find_or_make (sym_name);
911 1.1.1.3 christos restore_line_pointer (c);
912 1.1.1.3 christos if (c == ',' && r_type == BFD_RELOC_ARC_TLS_GD_LD)
913 1.1.1.3 christos {
914 1.1.1.3 christos ++input_line_pointer;
915 1.1.1.3 christos char *lab_name;
916 1.1.1.3 christos c = get_symbol_name (&lab_name);
917 1.1.1.3 christos lab = symbol_find_or_make (lab_name);
918 1.1.1.3 christos restore_line_pointer (c);
919 1.1.1.3 christos }
920 1.1.1.5 christos
921 1.1.1.5 christos /* These relocations exist as a mechanism for the compiler to tell the
922 1.1.1.5 christos linker how to patch the code if the tls model is optimised. However,
923 1.1.1.5 christos the relocation itself does not require any space within the assembler
924 1.1.1.5 christos fragment, and so we pass a size of 0.
925 1.1.1.5 christos
926 1.1.1.5 christos The lines that generate these relocations look like this:
927 1.1.1.5 christos
928 1.1.1.5 christos .tls_gd_ld @.tdata`bl __tls_get_addr@plt
929 1.1.1.5 christos
930 1.1.1.5 christos The '.tls_gd_ld @.tdata' is processed first and generates the
931 1.1.1.5 christos additional relocation, while the 'bl __tls_get_addr@plt' is processed
932 1.1.1.5 christos second and generates the additional branch.
933 1.1.1.5 christos
934 1.1.1.5 christos It is possible that the additional relocation generated by the
935 1.1.1.5 christos '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
936 1.1.1.5 christos while the 'bl __tls_get_addr@plt' will be generated as the first thing
937 1.1.1.5 christos in the next fragment. This will be fine; both relocations will still
938 1.1.1.5 christos appear to be at the same address in the generated object file.
939 1.1.1.5 christos However, this only works as the additional relocation is generated
940 1.1.1.5 christos with size of 0 bytes. */
941 1.1.1.3 christos fixS *fixP
942 1.1.1.3 christos = fix_new (frag_now, /* Which frag? */
943 1.1.1.3 christos frag_now_fix (), /* Where in that frag? */
944 1.1.1.5 christos 0, /* size: 1, 2, or 4 usually. */
945 1.1.1.3 christos sym, /* X_add_symbol. */
946 1.1.1.3 christos 0, /* X_add_number. */
947 1.1.1.8 christos false, /* TRUE if PC-relative relocation. */
948 1.1.1.3 christos r_type /* Relocation type. */);
949 1.1.1.3 christos fixP->fx_subsy = lab;
950 1.1.1.3 christos }
951 1.1.1.3 christos
952 1.1.1.3 christos static symbolS *
953 1.1.1.3 christos arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED,
954 1.1.1.3 christos symbolS *symbolP, addressT size)
955 1.1.1.3 christos {
956 1.1.1.3 christos addressT align = 0;
957 1.1.1.3 christos SKIP_WHITESPACE ();
958 1.1 skrll
959 1.1.1.3 christos if (*input_line_pointer == ',')
960 1.1 skrll {
961 1.1.1.3 christos align = parse_align (1);
962 1.1 skrll
963 1.1.1.3 christos if (align == (addressT) -1)
964 1.1.1.3 christos return NULL;
965 1.1 skrll }
966 1.1 skrll else
967 1.1.1.3 christos {
968 1.1.1.3 christos if (size >= 8)
969 1.1.1.3 christos align = 3;
970 1.1.1.3 christos else if (size >= 4)
971 1.1.1.3 christos align = 2;
972 1.1.1.3 christos else if (size >= 2)
973 1.1.1.3 christos align = 1;
974 1.1.1.3 christos else
975 1.1.1.3 christos align = 0;
976 1.1.1.3 christos }
977 1.1 skrll
978 1.1.1.3 christos bss_alloc (symbolP, size, align);
979 1.1.1.3 christos S_CLEAR_EXTERNAL (symbolP);
980 1.1 skrll
981 1.1.1.3 christos return symbolP;
982 1.1.1.3 christos }
983 1.1 skrll
984 1.1.1.3 christos static void
985 1.1.1.3 christos arc_lcomm (int ignore)
986 1.1 skrll {
987 1.1.1.3 christos symbolS *symbolP = s_comm_internal (ignore, arc_lcomm_internal);
988 1.1 skrll
989 1.1.1.3 christos if (symbolP)
990 1.1.1.3 christos symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
991 1.1.1.3 christos }
992 1.1 skrll
993 1.1.1.3 christos /* Select the cpu we're assembling for. */
994 1.1 skrll
995 1.1.1.3 christos static void
996 1.1.1.3 christos arc_option (int ignore ATTRIBUTE_UNUSED)
997 1.1.1.3 christos {
998 1.1.1.3 christos char c;
999 1.1.1.3 christos char *cpu;
1000 1.1.1.6 christos const char *cpu_name;
1001 1.1 skrll
1002 1.1.1.3 christos c = get_symbol_name (&cpu);
1003 1.1 skrll
1004 1.1.1.6 christos cpu_name = cpu;
1005 1.1.1.6 christos if ((!strcmp ("ARC600", cpu))
1006 1.1.1.6 christos || (!strcmp ("ARC601", cpu))
1007 1.1.1.6 christos || (!strcmp ("A6", cpu)))
1008 1.1.1.6 christos cpu_name = "arc600";
1009 1.1.1.6 christos else if ((!strcmp ("ARC700", cpu))
1010 1.1.1.6 christos || (!strcmp ("A7", cpu)))
1011 1.1.1.6 christos cpu_name = "arc700";
1012 1.1.1.6 christos else if (!strcmp ("EM", cpu))
1013 1.1.1.6 christos cpu_name = "arcem";
1014 1.1.1.6 christos else if (!strcmp ("HS", cpu))
1015 1.1.1.6 christos cpu_name = "archs";
1016 1.1.1.6 christos else if (!strcmp ("NPS400", cpu))
1017 1.1.1.6 christos cpu_name = "nps400";
1018 1.1 skrll
1019 1.1.1.6 christos arc_select_cpu (cpu_name, MACH_SELECTION_FROM_CPU_DIRECTIVE);
1020 1.1 skrll
1021 1.1.1.5 christos restore_line_pointer (c);
1022 1.1.1.3 christos demand_empty_rest_of_line ();
1023 1.1.1.3 christos }
1024 1.1 skrll
1025 1.1.1.3 christos /* Smartly print an expression. */
1026 1.1 skrll
1027 1.1.1.3 christos static void
1028 1.1.1.3 christos debug_exp (expressionS *t)
1029 1.1.1.3 christos {
1030 1.1.1.3 christos const char *name ATTRIBUTE_UNUSED;
1031 1.1.1.3 christos const char *namemd ATTRIBUTE_UNUSED;
1032 1.1 skrll
1033 1.1.1.3 christos pr_debug ("debug_exp: ");
1034 1.1 skrll
1035 1.1.1.3 christos switch (t->X_op)
1036 1.1 skrll {
1037 1.1.1.3 christos default: name = "unknown"; break;
1038 1.1.1.3 christos case O_illegal: name = "O_illegal"; break;
1039 1.1.1.3 christos case O_absent: name = "O_absent"; break;
1040 1.1.1.3 christos case O_constant: name = "O_constant"; break;
1041 1.1.1.3 christos case O_symbol: name = "O_symbol"; break;
1042 1.1.1.3 christos case O_symbol_rva: name = "O_symbol_rva"; break;
1043 1.1.1.3 christos case O_register: name = "O_register"; break;
1044 1.1.1.3 christos case O_big: name = "O_big"; break;
1045 1.1.1.3 christos case O_uminus: name = "O_uminus"; break;
1046 1.1.1.3 christos case O_bit_not: name = "O_bit_not"; break;
1047 1.1.1.3 christos case O_logical_not: name = "O_logical_not"; break;
1048 1.1.1.3 christos case O_multiply: name = "O_multiply"; break;
1049 1.1.1.3 christos case O_divide: name = "O_divide"; break;
1050 1.1.1.3 christos case O_modulus: name = "O_modulus"; break;
1051 1.1.1.3 christos case O_left_shift: name = "O_left_shift"; break;
1052 1.1.1.3 christos case O_right_shift: name = "O_right_shift"; break;
1053 1.1.1.3 christos case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
1054 1.1.1.3 christos case O_bit_or_not: name = "O_bit_or_not"; break;
1055 1.1.1.3 christos case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
1056 1.1.1.3 christos case O_bit_and: name = "O_bit_and"; break;
1057 1.1.1.3 christos case O_add: name = "O_add"; break;
1058 1.1.1.3 christos case O_subtract: name = "O_subtract"; break;
1059 1.1.1.3 christos case O_eq: name = "O_eq"; break;
1060 1.1.1.3 christos case O_ne: name = "O_ne"; break;
1061 1.1.1.3 christos case O_lt: name = "O_lt"; break;
1062 1.1.1.3 christos case O_le: name = "O_le"; break;
1063 1.1.1.3 christos case O_ge: name = "O_ge"; break;
1064 1.1.1.3 christos case O_gt: name = "O_gt"; break;
1065 1.1.1.3 christos case O_logical_and: name = "O_logical_and"; break;
1066 1.1.1.3 christos case O_logical_or: name = "O_logical_or"; break;
1067 1.1.1.3 christos case O_index: name = "O_index"; break;
1068 1.1.1.3 christos case O_bracket: name = "O_bracket"; break;
1069 1.1.1.6 christos case O_colon: name = "O_colon"; break;
1070 1.1.1.6 christos case O_addrtype: name = "O_addrtype"; break;
1071 1.1.1.3 christos }
1072 1.1.1.3 christos
1073 1.1.1.3 christos switch (t->X_md)
1074 1.1.1.3 christos {
1075 1.1.1.3 christos default: namemd = "unknown"; break;
1076 1.1.1.3 christos case O_gotoff: namemd = "O_gotoff"; break;
1077 1.1.1.3 christos case O_gotpc: namemd = "O_gotpc"; break;
1078 1.1.1.3 christos case O_plt: namemd = "O_plt"; break;
1079 1.1.1.3 christos case O_sda: namemd = "O_sda"; break;
1080 1.1.1.3 christos case O_pcl: namemd = "O_pcl"; break;
1081 1.1.1.3 christos case O_tlsgd: namemd = "O_tlsgd"; break;
1082 1.1.1.3 christos case O_tlsie: namemd = "O_tlsie"; break;
1083 1.1.1.3 christos case O_tpoff9: namemd = "O_tpoff9"; break;
1084 1.1.1.3 christos case O_tpoff: namemd = "O_tpoff"; break;
1085 1.1.1.3 christos case O_dtpoff9: namemd = "O_dtpoff9"; break;
1086 1.1.1.3 christos case O_dtpoff: namemd = "O_dtpoff"; break;
1087 1.1.1.3 christos }
1088 1.1.1.3 christos
1089 1.1.1.3 christos pr_debug ("%s (%s, %s, %d, %s)", name,
1090 1.1.1.3 christos (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
1091 1.1.1.3 christos (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
1092 1.1.1.3 christos (int) t->X_add_number,
1093 1.1.1.3 christos (t->X_md) ? namemd : "--");
1094 1.1.1.3 christos pr_debug ("\n");
1095 1.1.1.3 christos fflush (stderr);
1096 1.1.1.3 christos }
1097 1.1 skrll
1098 1.1.1.7 christos /* Helper for parsing an argument, used for sorting out the relocation
1099 1.1.1.7 christos type. */
1100 1.1.1.7 christos
1101 1.1.1.7 christos static void
1102 1.1.1.7 christos parse_reloc_symbol (expressionS *resultP)
1103 1.1.1.7 christos {
1104 1.1.1.7 christos char *reloc_name, c, *sym_name;
1105 1.1.1.7 christos size_t len;
1106 1.1.1.7 christos int i;
1107 1.1.1.7 christos const struct arc_reloc_op_tag *r;
1108 1.1.1.7 christos expressionS right;
1109 1.1.1.7 christos symbolS *base;
1110 1.1.1.7 christos
1111 1.1.1.7 christos /* A relocation operand has the following form
1112 1.1.1.7 christos @identifier@relocation_type. The identifier is already in
1113 1.1.1.7 christos tok! */
1114 1.1.1.7 christos if (resultP->X_op != O_symbol)
1115 1.1.1.7 christos {
1116 1.1.1.7 christos as_bad (_("No valid label relocation operand"));
1117 1.1.1.7 christos resultP->X_op = O_illegal;
1118 1.1.1.7 christos return;
1119 1.1.1.7 christos }
1120 1.1.1.7 christos
1121 1.1.1.7 christos /* Parse @relocation_type. */
1122 1.1.1.7 christos input_line_pointer++;
1123 1.1.1.7 christos c = get_symbol_name (&reloc_name);
1124 1.1.1.7 christos len = input_line_pointer - reloc_name;
1125 1.1.1.7 christos if (len == 0)
1126 1.1.1.7 christos {
1127 1.1.1.7 christos as_bad (_("No relocation operand"));
1128 1.1.1.7 christos resultP->X_op = O_illegal;
1129 1.1.1.7 christos return;
1130 1.1.1.7 christos }
1131 1.1.1.7 christos
1132 1.1.1.7 christos /* Go through known relocation and try to find a match. */
1133 1.1.1.7 christos r = &arc_reloc_op[0];
1134 1.1.1.7 christos for (i = arc_num_reloc_op - 1; i >= 0; i--, r++)
1135 1.1.1.7 christos if (len == r->length
1136 1.1.1.7 christos && memcmp (reloc_name, r->name, len) == 0)
1137 1.1.1.7 christos break;
1138 1.1.1.7 christos if (i < 0)
1139 1.1.1.7 christos {
1140 1.1.1.7 christos as_bad (_("Unknown relocation operand: @%s"), reloc_name);
1141 1.1.1.7 christos resultP->X_op = O_illegal;
1142 1.1.1.7 christos return;
1143 1.1.1.7 christos }
1144 1.1.1.7 christos
1145 1.1.1.7 christos *input_line_pointer = c;
1146 1.1.1.7 christos SKIP_WHITESPACE_AFTER_NAME ();
1147 1.1.1.7 christos /* Extra check for TLS: base. */
1148 1.1.1.7 christos if (*input_line_pointer == '@')
1149 1.1.1.7 christos {
1150 1.1.1.7 christos if (resultP->X_op_symbol != NULL
1151 1.1.1.7 christos || resultP->X_op != O_symbol)
1152 1.1.1.7 christos {
1153 1.1.1.7 christos as_bad (_("Unable to parse TLS base: %s"),
1154 1.1.1.7 christos input_line_pointer);
1155 1.1.1.7 christos resultP->X_op = O_illegal;
1156 1.1.1.7 christos return;
1157 1.1.1.7 christos }
1158 1.1.1.7 christos input_line_pointer++;
1159 1.1.1.7 christos c = get_symbol_name (&sym_name);
1160 1.1.1.7 christos base = symbol_find_or_make (sym_name);
1161 1.1.1.7 christos resultP->X_op = O_subtract;
1162 1.1.1.7 christos resultP->X_op_symbol = base;
1163 1.1.1.7 christos restore_line_pointer (c);
1164 1.1.1.7 christos right.X_add_number = 0;
1165 1.1.1.7 christos }
1166 1.1.1.7 christos
1167 1.1.1.7 christos if ((*input_line_pointer != '+')
1168 1.1.1.7 christos && (*input_line_pointer != '-'))
1169 1.1.1.7 christos right.X_add_number = 0;
1170 1.1.1.7 christos else
1171 1.1.1.7 christos {
1172 1.1.1.7 christos /* Parse the constant of a complex relocation expression
1173 1.1.1.7 christos like @identifier@reloc +/- const. */
1174 1.1.1.7 christos if (! r->complex_expr)
1175 1.1.1.7 christos {
1176 1.1.1.7 christos as_bad (_("@%s is not a complex relocation."), r->name);
1177 1.1.1.7 christos resultP->X_op = O_illegal;
1178 1.1.1.7 christos return;
1179 1.1.1.7 christos }
1180 1.1.1.7 christos expression (&right);
1181 1.1.1.7 christos if (right.X_op != O_constant)
1182 1.1.1.7 christos {
1183 1.1.1.7 christos as_bad (_("Bad expression: @%s + %s."),
1184 1.1.1.7 christos r->name, input_line_pointer);
1185 1.1.1.7 christos resultP->X_op = O_illegal;
1186 1.1.1.7 christos return;
1187 1.1.1.7 christos }
1188 1.1.1.7 christos }
1189 1.1.1.7 christos
1190 1.1.1.7 christos resultP->X_md = r->op;
1191 1.1.1.7 christos resultP->X_add_number = right.X_add_number;
1192 1.1.1.7 christos }
1193 1.1.1.7 christos
1194 1.1.1.3 christos /* Parse the arguments to an opcode. */
1195 1.1 skrll
1196 1.1.1.3 christos static int
1197 1.1.1.3 christos tokenize_arguments (char *str,
1198 1.1.1.3 christos expressionS *tok,
1199 1.1.1.3 christos int ntok)
1200 1.1.1.3 christos {
1201 1.1.1.3 christos char *old_input_line_pointer;
1202 1.1.1.8 christos bool saw_comma = false;
1203 1.1.1.8 christos bool saw_arg = false;
1204 1.1.1.3 christos int brk_lvl = 0;
1205 1.1.1.3 christos int num_args = 0;
1206 1.1.1.3 christos
1207 1.1.1.3 christos memset (tok, 0, sizeof (*tok) * ntok);
1208 1.1.1.3 christos
1209 1.1.1.3 christos /* Save and restore input_line_pointer around this function. */
1210 1.1.1.3 christos old_input_line_pointer = input_line_pointer;
1211 1.1.1.3 christos input_line_pointer = str;
1212 1.1 skrll
1213 1.1.1.3 christos while (*input_line_pointer)
1214 1.1 skrll {
1215 1.1 skrll SKIP_WHITESPACE ();
1216 1.1.1.3 christos switch (*input_line_pointer)
1217 1.1 skrll {
1218 1.1.1.3 christos case '\0':
1219 1.1.1.3 christos goto fini;
1220 1.1 skrll
1221 1.1.1.3 christos case ',':
1222 1.1.1.3 christos input_line_pointer++;
1223 1.1.1.3 christos if (saw_comma || !saw_arg)
1224 1.1.1.3 christos goto err;
1225 1.1.1.8 christos saw_comma = true;
1226 1.1.1.3 christos break;
1227 1.1 skrll
1228 1.1.1.3 christos case '}':
1229 1.1.1.3 christos case ']':
1230 1.1.1.3 christos ++input_line_pointer;
1231 1.1.1.3 christos --brk_lvl;
1232 1.1.1.5 christos if (!saw_arg || num_args == ntok)
1233 1.1.1.3 christos goto err;
1234 1.1.1.3 christos tok->X_op = O_bracket;
1235 1.1.1.3 christos ++tok;
1236 1.1.1.3 christos ++num_args;
1237 1.1.1.3 christos break;
1238 1.1.1.3 christos
1239 1.1.1.3 christos case '{':
1240 1.1.1.3 christos case '[':
1241 1.1.1.3 christos input_line_pointer++;
1242 1.1.1.5 christos if (brk_lvl || num_args == ntok)
1243 1.1.1.3 christos goto err;
1244 1.1.1.3 christos ++brk_lvl;
1245 1.1.1.3 christos tok->X_op = O_bracket;
1246 1.1.1.3 christos ++tok;
1247 1.1.1.3 christos ++num_args;
1248 1.1.1.3 christos break;
1249 1.1.1.3 christos
1250 1.1.1.6 christos case ':':
1251 1.1.1.6 christos input_line_pointer++;
1252 1.1.1.6 christos if (!saw_arg || num_args == ntok)
1253 1.1.1.6 christos goto err;
1254 1.1.1.6 christos tok->X_op = O_colon;
1255 1.1.1.8 christos saw_arg = false;
1256 1.1.1.6 christos ++tok;
1257 1.1.1.6 christos ++num_args;
1258 1.1.1.6 christos break;
1259 1.1.1.6 christos
1260 1.1.1.3 christos case '@':
1261 1.1.1.3 christos /* We have labels, function names and relocations, all
1262 1.1.1.3 christos starting with @ symbol. Sort them out. */
1263 1.1.1.5 christos if ((saw_arg && !saw_comma) || num_args == ntok)
1264 1.1.1.3 christos goto err;
1265 1.1.1.3 christos
1266 1.1.1.3 christos /* Parse @label. */
1267 1.1.1.7 christos input_line_pointer++;
1268 1.1.1.3 christos tok->X_op = O_symbol;
1269 1.1.1.3 christos tok->X_md = O_absent;
1270 1.1.1.3 christos expression (tok);
1271 1.1.1.3 christos
1272 1.1.1.3 christos if (*input_line_pointer == '@')
1273 1.1.1.7 christos parse_reloc_symbol (tok);
1274 1.1 skrll
1275 1.1.1.3 christos debug_exp (tok);
1276 1.1 skrll
1277 1.1.1.7 christos if (tok->X_op == O_illegal
1278 1.1.1.7 christos || tok->X_op == O_absent
1279 1.1.1.7 christos || num_args == ntok)
1280 1.1.1.7 christos goto err;
1281 1.1.1.7 christos
1282 1.1.1.8 christos saw_comma = false;
1283 1.1.1.8 christos saw_arg = true;
1284 1.1.1.3 christos tok++;
1285 1.1.1.3 christos num_args++;
1286 1.1.1.3 christos break;
1287 1.1 skrll
1288 1.1.1.3 christos case '%':
1289 1.1.1.3 christos /* Can be a register. */
1290 1.1.1.3 christos ++input_line_pointer;
1291 1.1.1.3 christos /* Fall through. */
1292 1.1.1.3 christos default:
1293 1.1.1.3 christos
1294 1.1.1.5 christos if ((saw_arg && !saw_comma) || num_args == ntok)
1295 1.1.1.3 christos goto err;
1296 1.1.1.3 christos
1297 1.1.1.3 christos tok->X_op = O_absent;
1298 1.1.1.3 christos tok->X_md = O_absent;
1299 1.1.1.3 christos expression (tok);
1300 1.1.1.3 christos
1301 1.1.1.3 christos /* Legacy: There are cases when we have
1302 1.1.1.3 christos identifier@relocation_type, if it is the case parse the
1303 1.1.1.3 christos relocation type as well. */
1304 1.1.1.3 christos if (*input_line_pointer == '@')
1305 1.1.1.7 christos parse_reloc_symbol (tok);
1306 1.1.1.3 christos
1307 1.1.1.3 christos debug_exp (tok);
1308 1.1.1.3 christos
1309 1.1.1.5 christos if (tok->X_op == O_illegal
1310 1.1.1.5 christos || tok->X_op == O_absent
1311 1.1.1.5 christos || num_args == ntok)
1312 1.1.1.3 christos goto err;
1313 1.1.1.3 christos
1314 1.1.1.8 christos saw_comma = false;
1315 1.1.1.8 christos saw_arg = true;
1316 1.1.1.3 christos tok++;
1317 1.1.1.3 christos num_args++;
1318 1.1.1.3 christos break;
1319 1.1 skrll }
1320 1.1 skrll }
1321 1.1 skrll
1322 1.1.1.3 christos fini:
1323 1.1.1.3 christos if (saw_comma || brk_lvl)
1324 1.1.1.3 christos goto err;
1325 1.1.1.3 christos input_line_pointer = old_input_line_pointer;
1326 1.1.1.3 christos
1327 1.1.1.3 christos return num_args;
1328 1.1.1.3 christos
1329 1.1.1.3 christos err:
1330 1.1.1.3 christos if (brk_lvl)
1331 1.1.1.3 christos as_bad (_("Brackets in operand field incorrect"));
1332 1.1.1.3 christos else if (saw_comma)
1333 1.1.1.3 christos as_bad (_("extra comma"));
1334 1.1.1.3 christos else if (!saw_arg)
1335 1.1.1.3 christos as_bad (_("missing argument"));
1336 1.1.1.3 christos else
1337 1.1.1.3 christos as_bad (_("missing comma or colon"));
1338 1.1.1.3 christos input_line_pointer = old_input_line_pointer;
1339 1.1.1.3 christos return -1;
1340 1.1.1.3 christos }
1341 1.1 skrll
1342 1.1.1.3 christos /* Parse the flags to a structure. */
1343 1.1 skrll
1344 1.1.1.3 christos static int
1345 1.1.1.3 christos tokenize_flags (const char *str,
1346 1.1.1.3 christos struct arc_flags flags[],
1347 1.1.1.3 christos int nflg)
1348 1.1.1.3 christos {
1349 1.1.1.3 christos char *old_input_line_pointer;
1350 1.1.1.8 christos bool saw_flg = false;
1351 1.1.1.8 christos bool saw_dot = false;
1352 1.1.1.3 christos int num_flags = 0;
1353 1.1.1.3 christos size_t flgnamelen;
1354 1.1.1.3 christos
1355 1.1.1.3 christos memset (flags, 0, sizeof (*flags) * nflg);
1356 1.1.1.3 christos
1357 1.1.1.3 christos /* Save and restore input_line_pointer around this function. */
1358 1.1.1.3 christos old_input_line_pointer = input_line_pointer;
1359 1.1.1.3 christos input_line_pointer = (char *) str;
1360 1.1.1.3 christos
1361 1.1.1.3 christos while (*input_line_pointer)
1362 1.1.1.3 christos {
1363 1.1.1.3 christos switch (*input_line_pointer)
1364 1.1.1.3 christos {
1365 1.1.1.3 christos case ' ':
1366 1.1.1.3 christos case '\0':
1367 1.1.1.3 christos goto fini;
1368 1.1.1.3 christos
1369 1.1.1.3 christos case '.':
1370 1.1.1.3 christos input_line_pointer++;
1371 1.1.1.3 christos if (saw_dot)
1372 1.1.1.3 christos goto err;
1373 1.1.1.8 christos saw_dot = true;
1374 1.1.1.8 christos saw_flg = false;
1375 1.1.1.3 christos break;
1376 1.1 skrll
1377 1.1.1.3 christos default:
1378 1.1.1.3 christos if (saw_flg && !saw_dot)
1379 1.1.1.3 christos goto err;
1380 1.1 skrll
1381 1.1.1.3 christos if (num_flags >= nflg)
1382 1.1.1.3 christos goto err;
1383 1.1 skrll
1384 1.1.1.5 christos flgnamelen = strspn (input_line_pointer,
1385 1.1.1.5 christos "abcdefghijklmnopqrstuvwxyz0123456789");
1386 1.1.1.5 christos if (flgnamelen > MAX_FLAG_NAME_LENGTH)
1387 1.1.1.3 christos goto err;
1388 1.1.1.3 christos
1389 1.1.1.3 christos memcpy (flags->name, input_line_pointer, flgnamelen);
1390 1.1.1.3 christos
1391 1.1.1.3 christos input_line_pointer += flgnamelen;
1392 1.1.1.3 christos flags++;
1393 1.1.1.8 christos saw_dot = false;
1394 1.1.1.8 christos saw_flg = true;
1395 1.1.1.3 christos num_flags++;
1396 1.1.1.3 christos break;
1397 1.1.1.3 christos }
1398 1.1 skrll }
1399 1.1 skrll
1400 1.1.1.3 christos fini:
1401 1.1.1.3 christos input_line_pointer = old_input_line_pointer;
1402 1.1.1.3 christos return num_flags;
1403 1.1.1.3 christos
1404 1.1.1.3 christos err:
1405 1.1.1.3 christos if (saw_dot)
1406 1.1.1.3 christos as_bad (_("extra dot"));
1407 1.1.1.3 christos else if (!saw_flg)
1408 1.1.1.3 christos as_bad (_("unrecognized flag"));
1409 1.1.1.3 christos else
1410 1.1.1.3 christos as_bad (_("failed to parse flags"));
1411 1.1.1.3 christos input_line_pointer = old_input_line_pointer;
1412 1.1.1.3 christos return -1;
1413 1.1 skrll }
1414 1.1 skrll
1415 1.1.1.5 christos /* Apply the fixups in order. */
1416 1.1.1.3 christos
1417 1.1.1.5 christos static void
1418 1.1.1.5 christos apply_fixups (struct arc_insn *insn, fragS *fragP, int fix)
1419 1.1 skrll {
1420 1.1.1.5 christos int i;
1421 1.1 skrll
1422 1.1.1.5 christos for (i = 0; i < insn->nfixups; i++)
1423 1.1 skrll {
1424 1.1.1.5 christos struct arc_fixup *fixup = &insn->fixups[i];
1425 1.1.1.5 christos int size, pcrel, offset = 0;
1426 1.1 skrll
1427 1.1.1.5 christos /* FIXME! the reloc size is wrong in the BFD file.
1428 1.1.1.5 christos When it is fixed please delete me. */
1429 1.1.1.6 christos size = ((insn->len == 2) && !fixup->islong) ? 2 : 4;
1430 1.1 skrll
1431 1.1.1.5 christos if (fixup->islong)
1432 1.1.1.6 christos offset = insn->len;
1433 1.1 skrll
1434 1.1.1.5 christos /* Some fixups are only used internally, thus no howto. */
1435 1.1.1.5 christos if ((int) fixup->reloc == 0)
1436 1.1.1.5 christos as_fatal (_("Unhandled reloc type"));
1437 1.1 skrll
1438 1.1.1.5 christos if ((int) fixup->reloc < 0)
1439 1.1.1.5 christos {
1440 1.1.1.5 christos /* FIXME! the reloc size is wrong in the BFD file.
1441 1.1.1.5 christos When it is fixed please enable me.
1442 1.1.1.6 christos size = ((insn->len == 2 && !fixup->islong) ? 2 : 4; */
1443 1.1.1.5 christos pcrel = fixup->pcrel;
1444 1.1.1.5 christos }
1445 1.1.1.5 christos else
1446 1.1.1.5 christos {
1447 1.1.1.5 christos reloc_howto_type *reloc_howto =
1448 1.1.1.5 christos bfd_reloc_type_lookup (stdoutput,
1449 1.1.1.5 christos (bfd_reloc_code_real_type) fixup->reloc);
1450 1.1.1.5 christos gas_assert (reloc_howto);
1451 1.1 skrll
1452 1.1.1.5 christos /* FIXME! the reloc size is wrong in the BFD file.
1453 1.1.1.5 christos When it is fixed please enable me.
1454 1.1.1.5 christos size = bfd_get_reloc_size (reloc_howto); */
1455 1.1.1.5 christos pcrel = reloc_howto->pc_relative;
1456 1.1.1.5 christos }
1457 1.1 skrll
1458 1.1.1.5 christos pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1459 1.1.1.5 christos offset %d + %d\n",
1460 1.1.1.5 christos fragP->fr_file, fragP->fr_line,
1461 1.1.1.5 christos (fixup->reloc < 0) ? "Internal" :
1462 1.1.1.5 christos bfd_get_reloc_code_name (fixup->reloc),
1463 1.1.1.5 christos pcrel ? "Y" : "N",
1464 1.1.1.5 christos size, fix, offset);
1465 1.1.1.5 christos fix_new_exp (fragP, fix + offset,
1466 1.1.1.5 christos size, &fixup->exp, pcrel, fixup->reloc);
1467 1.1 skrll
1468 1.1.1.5 christos /* Check for ZOLs, and update symbol info if any. */
1469 1.1.1.5 christos if (LP_INSN (insn->insn))
1470 1.1 skrll {
1471 1.1.1.5 christos gas_assert (fixup->exp.X_add_symbol);
1472 1.1.1.5 christos ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL);
1473 1.1 skrll }
1474 1.1 skrll }
1475 1.1.1.3 christos }
1476 1.1 skrll
1477 1.1.1.5 christos /* Actually output an instruction with its fixup. */
1478 1.1 skrll
1479 1.1.1.5 christos static void
1480 1.1.1.8 christos emit_insn0 (struct arc_insn *insn, char *where, bool relax)
1481 1.1.1.3 christos {
1482 1.1.1.5 christos char *f = where;
1483 1.1.1.6 christos size_t total_len;
1484 1.1 skrll
1485 1.1.1.6 christos pr_debug ("Emit insn : 0x%llx\n", insn->insn);
1486 1.1.1.8 christos pr_debug ("\tLength : %d\n", insn->len);
1487 1.1.1.5 christos pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
1488 1.1 skrll
1489 1.1.1.5 christos /* Write out the instruction. */
1490 1.1.1.6 christos total_len = insn->len + (insn->has_limm ? 4 : 0);
1491 1.1.1.6 christos if (!relax)
1492 1.1.1.6 christos f = frag_more (total_len);
1493 1.1.1.6 christos
1494 1.1.1.6 christos md_number_to_chars_midend(f, insn->insn, insn->len);
1495 1.1.1.6 christos
1496 1.1.1.6 christos if (insn->has_limm)
1497 1.1.1.6 christos md_number_to_chars_midend (f + insn->len, insn->limm, 4);
1498 1.1.1.6 christos dwarf2_emit_insn (total_len);
1499 1.1 skrll
1500 1.1.1.5 christos if (!relax)
1501 1.1.1.5 christos apply_fixups (insn, frag_now, (f - frag_now->fr_literal));
1502 1.1.1.5 christos }
1503 1.1.1.3 christos
1504 1.1.1.5 christos static void
1505 1.1.1.5 christos emit_insn1 (struct arc_insn *insn)
1506 1.1.1.5 christos {
1507 1.1.1.5 christos /* How frag_var's args are currently configured:
1508 1.1.1.5 christos - rs_machine_dependent, to dictate it's a relaxation frag.
1509 1.1.1.5 christos - FRAG_MAX_GROWTH, maximum size of instruction
1510 1.1.1.5 christos - 0, variable size that might grow...unused by generic relaxation.
1511 1.1.1.5 christos - frag_now->fr_subtype, fr_subtype starting value, set previously.
1512 1.1.1.5 christos - s, opand expression.
1513 1.1.1.5 christos - 0, offset but it's unused.
1514 1.1.1.5 christos - 0, opcode but it's unused. */
1515 1.1.1.5 christos symbolS *s = make_expr_symbol (&insn->fixups[0].exp);
1516 1.1.1.5 christos frag_now->tc_frag_data.pcrel = insn->fixups[0].pcrel;
1517 1.1.1.5 christos
1518 1.1.1.5 christos if (frag_room () < FRAG_MAX_GROWTH)
1519 1.1.1.5 christos {
1520 1.1.1.5 christos /* Handle differently when frag literal memory is exhausted.
1521 1.1.1.5 christos This is used because when there's not enough memory left in
1522 1.1.1.5 christos the current frag, a new frag is created and the information
1523 1.1.1.5 christos we put into frag_now->tc_frag_data is disregarded. */
1524 1.1.1.5 christos
1525 1.1.1.5 christos struct arc_relax_type relax_info_copy;
1526 1.1.1.5 christos relax_substateT subtype = frag_now->fr_subtype;
1527 1.1.1.5 christos
1528 1.1.1.5 christos memcpy (&relax_info_copy, &frag_now->tc_frag_data,
1529 1.1.1.5 christos sizeof (struct arc_relax_type));
1530 1.1 skrll
1531 1.1.1.5 christos frag_wane (frag_now);
1532 1.1.1.5 christos frag_grow (FRAG_MAX_GROWTH);
1533 1.1 skrll
1534 1.1.1.5 christos memcpy (&frag_now->tc_frag_data, &relax_info_copy,
1535 1.1.1.5 christos sizeof (struct arc_relax_type));
1536 1.1.1.3 christos
1537 1.1.1.5 christos frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1538 1.1.1.5 christos subtype, s, 0, 0);
1539 1.1.1.5 christos }
1540 1.1.1.5 christos else
1541 1.1.1.5 christos frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1542 1.1.1.5 christos frag_now->fr_subtype, s, 0, 0);
1543 1.1 skrll }
1544 1.1 skrll
1545 1.1.1.5 christos static void
1546 1.1.1.5 christos emit_insn (struct arc_insn *insn)
1547 1.1 skrll {
1548 1.1.1.5 christos if (insn->relax)
1549 1.1.1.5 christos emit_insn1 (insn);
1550 1.1 skrll else
1551 1.1.1.8 christos emit_insn0 (insn, NULL, false);
1552 1.1 skrll }
1553 1.1 skrll
1554 1.1.1.5 christos /* Check whether a symbol involves a register. */
1555 1.1 skrll
1556 1.1.1.8 christos static bool
1557 1.1.1.5 christos contains_register (symbolS *sym)
1558 1.1 skrll {
1559 1.1.1.5 christos if (sym)
1560 1.1.1.5 christos {
1561 1.1.1.5 christos expressionS *ex = symbol_get_value_expression (sym);
1562 1.1.1.5 christos
1563 1.1.1.5 christos return ((O_register == ex->X_op)
1564 1.1.1.5 christos && !contains_register (ex->X_add_symbol)
1565 1.1.1.5 christos && !contains_register (ex->X_op_symbol));
1566 1.1.1.5 christos }
1567 1.1 skrll
1568 1.1.1.8 christos return false;
1569 1.1 skrll }
1570 1.1 skrll
1571 1.1.1.5 christos /* Returns the register number within a symbol. */
1572 1.1 skrll
1573 1.1.1.5 christos static int
1574 1.1.1.5 christos get_register (symbolS *sym)
1575 1.1 skrll {
1576 1.1.1.5 christos if (!contains_register (sym))
1577 1.1.1.5 christos return -1;
1578 1.1 skrll
1579 1.1.1.5 christos expressionS *ex = symbol_get_value_expression (sym);
1580 1.1.1.5 christos return regno (ex->X_add_number);
1581 1.1.1.5 christos }
1582 1.1 skrll
1583 1.1.1.5 christos /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1584 1.1.1.5 christos simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1585 1.1 skrll
1586 1.1.1.8 christos static bool
1587 1.1.1.5 christos generic_reloc_p (extended_bfd_reloc_code_real_type reloc)
1588 1.1.1.5 christos {
1589 1.1.1.5 christos if (!reloc)
1590 1.1.1.8 christos return false;
1591 1.1 skrll
1592 1.1.1.5 christos switch (reloc)
1593 1.1 skrll {
1594 1.1.1.5 christos case BFD_RELOC_ARC_SDA_LDST:
1595 1.1.1.5 christos case BFD_RELOC_ARC_SDA_LDST1:
1596 1.1.1.5 christos case BFD_RELOC_ARC_SDA_LDST2:
1597 1.1.1.5 christos case BFD_RELOC_ARC_SDA16_LD:
1598 1.1.1.5 christos case BFD_RELOC_ARC_SDA16_LD1:
1599 1.1.1.5 christos case BFD_RELOC_ARC_SDA16_LD2:
1600 1.1.1.5 christos case BFD_RELOC_ARC_SDA16_ST2:
1601 1.1.1.5 christos case BFD_RELOC_ARC_SDA32_ME:
1602 1.1.1.8 christos return false;
1603 1.1.1.5 christos default:
1604 1.1.1.8 christos return true;
1605 1.1 skrll }
1606 1.1 skrll }
1607 1.1 skrll
1608 1.1.1.5 christos /* Allocates a tok entry. */
1609 1.1 skrll
1610 1.1.1.5 christos static int
1611 1.1.1.5 christos allocate_tok (expressionS *tok, int ntok, int cidx)
1612 1.1 skrll {
1613 1.1.1.5 christos if (ntok > MAX_INSN_ARGS - 2)
1614 1.1.1.5 christos return 0; /* No space left. */
1615 1.1 skrll
1616 1.1.1.5 christos if (cidx > ntok)
1617 1.1.1.6 christos return 0; /* Incorrect args. */
1618 1.1.1.5 christos
1619 1.1.1.5 christos memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok));
1620 1.1.1.5 christos
1621 1.1.1.5 christos if (cidx == ntok)
1622 1.1.1.5 christos return 1; /* Success. */
1623 1.1.1.5 christos return allocate_tok (tok, ntok - 1, cidx);
1624 1.1 skrll }
1625 1.1 skrll
1626 1.1.1.5 christos /* Check if an particular ARC feature is enabled. */
1627 1.1 skrll
1628 1.1.1.8 christos static bool
1629 1.1.1.5 christos check_cpu_feature (insn_subclass_t sc)
1630 1.1.1.3 christos {
1631 1.1.1.6 christos if (is_code_density_p (sc) && !(selected_cpu.features & CD))
1632 1.1.1.8 christos return false;
1633 1.1.1.3 christos
1634 1.1.1.6 christos if (is_spfp_p (sc) && !(selected_cpu.features & SPX))
1635 1.1.1.8 christos return false;
1636 1.1.1.3 christos
1637 1.1.1.6 christos if (is_dpfp_p (sc) && !(selected_cpu.features & DPX))
1638 1.1.1.8 christos return false;
1639 1.1.1.3 christos
1640 1.1.1.6 christos if (is_fpuda_p (sc) && !(selected_cpu.features & DPA))
1641 1.1.1.8 christos return false;
1642 1.1.1.3 christos
1643 1.1.1.6 christos if (is_nps400_p (sc) && !(selected_cpu.features & NPS400))
1644 1.1.1.8 christos return false;
1645 1.1.1.3 christos
1646 1.1.1.8 christos return true;
1647 1.1.1.5 christos }
1648 1.1.1.5 christos
1649 1.1.1.5 christos /* Parse the flags described by FIRST_PFLAG and NFLGS against the flag
1650 1.1.1.5 christos operands in OPCODE. Stores the matching OPCODES into the FIRST_PFLAG
1651 1.1.1.5 christos array and returns TRUE if the flag operands all match, otherwise,
1652 1.1.1.5 christos returns FALSE, in which case the FIRST_PFLAG array may have been
1653 1.1.1.5 christos modified. */
1654 1.1.1.5 christos
1655 1.1.1.8 christos static bool
1656 1.1.1.5 christos parse_opcode_flags (const struct arc_opcode *opcode,
1657 1.1.1.5 christos int nflgs,
1658 1.1.1.5 christos struct arc_flags *first_pflag)
1659 1.1.1.5 christos {
1660 1.1.1.5 christos int lnflg, i;
1661 1.1.1.5 christos const unsigned char *flgidx;
1662 1.1.1.5 christos
1663 1.1.1.5 christos lnflg = nflgs;
1664 1.1.1.5 christos for (i = 0; i < nflgs; i++)
1665 1.1.1.5 christos first_pflag[i].flgp = NULL;
1666 1.1.1.5 christos
1667 1.1.1.5 christos /* Check the flags. Iterate over the valid flag classes. */
1668 1.1.1.5 christos for (flgidx = opcode->flags; *flgidx; ++flgidx)
1669 1.1.1.5 christos {
1670 1.1.1.5 christos /* Get a valid flag class. */
1671 1.1.1.5 christos const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
1672 1.1.1.5 christos const unsigned *flgopridx;
1673 1.1.1.5 christos int cl_matches = 0;
1674 1.1.1.5 christos struct arc_flags *pflag = NULL;
1675 1.1.1.5 christos
1676 1.1.1.6 christos /* Check if opcode has implicit flag classes. */
1677 1.1.1.6 christos if (cl_flags->flag_class & F_CLASS_IMPLICIT)
1678 1.1.1.6 christos continue;
1679 1.1.1.6 christos
1680 1.1.1.5 christos /* Check for extension conditional codes. */
1681 1.1.1.5 christos if (ext_condcode.arc_ext_condcode
1682 1.1.1.5 christos && cl_flags->flag_class & F_CLASS_EXTEND)
1683 1.1.1.5 christos {
1684 1.1.1.5 christos struct arc_flag_operand *pf = ext_condcode.arc_ext_condcode;
1685 1.1.1.5 christos while (pf->name)
1686 1.1.1.5 christos {
1687 1.1.1.5 christos pflag = first_pflag;
1688 1.1.1.5 christos for (i = 0; i < nflgs; i++, pflag++)
1689 1.1.1.5 christos {
1690 1.1.1.5 christos if (!strcmp (pf->name, pflag->name))
1691 1.1.1.5 christos {
1692 1.1.1.5 christos if (pflag->flgp != NULL)
1693 1.1.1.8 christos return false;
1694 1.1.1.5 christos /* Found it. */
1695 1.1.1.5 christos cl_matches++;
1696 1.1.1.5 christos pflag->flgp = pf;
1697 1.1.1.5 christos lnflg--;
1698 1.1.1.5 christos break;
1699 1.1.1.5 christos }
1700 1.1.1.5 christos }
1701 1.1.1.5 christos pf++;
1702 1.1.1.5 christos }
1703 1.1.1.5 christos }
1704 1.1.1.5 christos
1705 1.1.1.5 christos for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
1706 1.1.1.5 christos {
1707 1.1.1.5 christos const struct arc_flag_operand *flg_operand;
1708 1.1.1.5 christos
1709 1.1.1.5 christos pflag = first_pflag;
1710 1.1.1.5 christos flg_operand = &arc_flag_operands[*flgopridx];
1711 1.1.1.5 christos for (i = 0; i < nflgs; i++, pflag++)
1712 1.1.1.5 christos {
1713 1.1.1.5 christos /* Match against the parsed flags. */
1714 1.1.1.5 christos if (!strcmp (flg_operand->name, pflag->name))
1715 1.1.1.5 christos {
1716 1.1.1.5 christos if (pflag->flgp != NULL)
1717 1.1.1.8 christos return false;
1718 1.1.1.5 christos cl_matches++;
1719 1.1.1.5 christos pflag->flgp = flg_operand;
1720 1.1.1.5 christos lnflg--;
1721 1.1.1.5 christos break; /* goto next flag class and parsed flag. */
1722 1.1.1.5 christos }
1723 1.1.1.5 christos }
1724 1.1.1.5 christos }
1725 1.1.1.5 christos
1726 1.1.1.5 christos if ((cl_flags->flag_class & F_CLASS_REQUIRED) && cl_matches == 0)
1727 1.1.1.8 christos return false;
1728 1.1.1.5 christos if ((cl_flags->flag_class & F_CLASS_OPTIONAL) && cl_matches > 1)
1729 1.1.1.8 christos return false;
1730 1.1 skrll }
1731 1.1.1.3 christos
1732 1.1.1.5 christos /* Did I check all the parsed flags? */
1733 1.1.1.8 christos return lnflg == 0;
1734 1.1.1.5 christos }
1735 1.1.1.5 christos
1736 1.1.1.5 christos
1737 1.1.1.5 christos /* Search forward through all variants of an opcode looking for a
1738 1.1.1.5 christos syntax match. */
1739 1.1.1.5 christos
1740 1.1.1.5 christos static const struct arc_opcode *
1741 1.1.1.5 christos find_opcode_match (const struct arc_opcode_hash_entry *entry,
1742 1.1.1.5 christos expressionS *tok,
1743 1.1.1.5 christos int *pntok,
1744 1.1.1.5 christos struct arc_flags *first_pflag,
1745 1.1.1.5 christos int nflgs,
1746 1.1.1.6 christos int *pcpumatch,
1747 1.1.1.6 christos const char **errmsg)
1748 1.1.1.5 christos {
1749 1.1.1.5 christos const struct arc_opcode *opcode;
1750 1.1.1.5 christos struct arc_opcode_hash_entry_iterator iter;
1751 1.1.1.5 christos int ntok = *pntok;
1752 1.1.1.5 christos int got_cpu_match = 0;
1753 1.1.1.5 christos expressionS bktok[MAX_INSN_ARGS];
1754 1.1.1.8 christos int bkntok, maxerridx = 0;
1755 1.1.1.5 christos expressionS emptyE;
1756 1.1.1.8 christos const char *tmpmsg = NULL;
1757 1.1.1.5 christos
1758 1.1.1.5 christos arc_opcode_hash_entry_iterator_init (&iter);
1759 1.1.1.5 christos memset (&emptyE, 0, sizeof (emptyE));
1760 1.1.1.5 christos memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
1761 1.1.1.5 christos bkntok = ntok;
1762 1.1.1.5 christos
1763 1.1.1.5 christos for (opcode = arc_opcode_hash_entry_iterator_next (entry, &iter);
1764 1.1.1.5 christos opcode != NULL;
1765 1.1.1.5 christos opcode = arc_opcode_hash_entry_iterator_next (entry, &iter))
1766 1.1 skrll {
1767 1.1.1.5 christos const unsigned char *opidx;
1768 1.1.1.5 christos int tokidx = 0;
1769 1.1.1.5 christos const expressionS *t = &emptyE;
1770 1.1.1.5 christos
1771 1.1.1.6 christos pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08llX ",
1772 1.1.1.5 christos frag_now->fr_file, frag_now->fr_line, opcode->opcode);
1773 1.1.1.5 christos
1774 1.1.1.5 christos /* Don't match opcodes that don't exist on this
1775 1.1.1.5 christos architecture. */
1776 1.1.1.6 christos if (!(opcode->cpu & selected_cpu.flags))
1777 1.1.1.5 christos goto match_failed;
1778 1.1.1.5 christos
1779 1.1.1.5 christos if (!check_cpu_feature (opcode->subclass))
1780 1.1.1.5 christos goto match_failed;
1781 1.1.1.5 christos
1782 1.1.1.5 christos got_cpu_match = 1;
1783 1.1.1.5 christos pr_debug ("cpu ");
1784 1.1.1.5 christos
1785 1.1.1.5 christos /* Check the operands. */
1786 1.1.1.5 christos for (opidx = opcode->operands; *opidx; ++opidx)
1787 1.1.1.3 christos {
1788 1.1.1.5 christos const struct arc_operand *operand = &arc_operands[*opidx];
1789 1.1.1.5 christos
1790 1.1.1.5 christos /* Only take input from real operands. */
1791 1.1.1.6 christos if (ARC_OPERAND_IS_FAKE (operand))
1792 1.1.1.5 christos continue;
1793 1.1.1.5 christos
1794 1.1.1.5 christos /* When we expect input, make sure we have it. */
1795 1.1.1.5 christos if (tokidx >= ntok)
1796 1.1.1.5 christos goto match_failed;
1797 1.1.1.5 christos
1798 1.1.1.5 christos /* Match operand type with expression type. */
1799 1.1.1.5 christos switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
1800 1.1.1.5 christos {
1801 1.1.1.6 christos case ARC_OPERAND_ADDRTYPE:
1802 1.1.1.6 christos {
1803 1.1.1.8 christos tmpmsg = NULL;
1804 1.1.1.6 christos
1805 1.1.1.6 christos /* Check to be an address type. */
1806 1.1.1.6 christos if (tok[tokidx].X_op != O_addrtype)
1807 1.1.1.6 christos goto match_failed;
1808 1.1.1.6 christos
1809 1.1.1.6 christos /* All address type operands need to have an insert
1810 1.1.1.6 christos method in order to check that we have the correct
1811 1.1.1.6 christos address type. */
1812 1.1.1.6 christos gas_assert (operand->insert != NULL);
1813 1.1.1.6 christos (*operand->insert) (0, tok[tokidx].X_add_number,
1814 1.1.1.8 christos &tmpmsg);
1815 1.1.1.8 christos if (tmpmsg != NULL)
1816 1.1.1.6 christos goto match_failed;
1817 1.1.1.6 christos }
1818 1.1.1.6 christos break;
1819 1.1.1.6 christos
1820 1.1.1.5 christos case ARC_OPERAND_IR:
1821 1.1.1.5 christos /* Check to be a register. */
1822 1.1.1.5 christos if ((tok[tokidx].X_op != O_register
1823 1.1.1.5 christos || !is_ir_num (tok[tokidx].X_add_number))
1824 1.1.1.5 christos && !(operand->flags & ARC_OPERAND_IGNORE))
1825 1.1.1.5 christos goto match_failed;
1826 1.1.1.5 christos
1827 1.1.1.5 christos /* If expect duplicate, make sure it is duplicate. */
1828 1.1.1.5 christos if (operand->flags & ARC_OPERAND_DUPLICATE)
1829 1.1.1.5 christos {
1830 1.1.1.5 christos /* Check for duplicate. */
1831 1.1.1.5 christos if (t->X_op != O_register
1832 1.1.1.5 christos || !is_ir_num (t->X_add_number)
1833 1.1.1.5 christos || (regno (t->X_add_number) !=
1834 1.1.1.5 christos regno (tok[tokidx].X_add_number)))
1835 1.1.1.5 christos goto match_failed;
1836 1.1.1.5 christos }
1837 1.1.1.5 christos
1838 1.1.1.5 christos /* Special handling? */
1839 1.1.1.5 christos if (operand->insert)
1840 1.1.1.5 christos {
1841 1.1.1.8 christos tmpmsg = NULL;
1842 1.1.1.5 christos (*operand->insert)(0,
1843 1.1.1.5 christos regno (tok[tokidx].X_add_number),
1844 1.1.1.8 christos &tmpmsg);
1845 1.1.1.8 christos if (tmpmsg)
1846 1.1.1.5 christos {
1847 1.1.1.5 christos if (operand->flags & ARC_OPERAND_IGNORE)
1848 1.1.1.5 christos {
1849 1.1.1.5 christos /* Missing argument, create one. */
1850 1.1.1.5 christos if (!allocate_tok (tok, ntok - 1, tokidx))
1851 1.1.1.5 christos goto match_failed;
1852 1.1.1.5 christos
1853 1.1.1.5 christos tok[tokidx].X_op = O_absent;
1854 1.1.1.5 christos ++ntok;
1855 1.1.1.5 christos }
1856 1.1.1.5 christos else
1857 1.1.1.5 christos goto match_failed;
1858 1.1.1.5 christos }
1859 1.1.1.5 christos }
1860 1.1.1.5 christos
1861 1.1.1.5 christos t = &tok[tokidx];
1862 1.1.1.5 christos break;
1863 1.1.1.5 christos
1864 1.1.1.5 christos case ARC_OPERAND_BRAKET:
1865 1.1.1.5 christos /* Check if bracket is also in opcode table as
1866 1.1.1.5 christos operand. */
1867 1.1.1.5 christos if (tok[tokidx].X_op != O_bracket)
1868 1.1.1.5 christos goto match_failed;
1869 1.1.1.5 christos break;
1870 1.1.1.5 christos
1871 1.1.1.6 christos case ARC_OPERAND_COLON:
1872 1.1.1.6 christos /* Check if colon is also in opcode table as operand. */
1873 1.1.1.6 christos if (tok[tokidx].X_op != O_colon)
1874 1.1.1.6 christos goto match_failed;
1875 1.1.1.6 christos break;
1876 1.1.1.6 christos
1877 1.1.1.5 christos case ARC_OPERAND_LIMM:
1878 1.1.1.5 christos case ARC_OPERAND_SIGNED:
1879 1.1.1.5 christos case ARC_OPERAND_UNSIGNED:
1880 1.1.1.5 christos switch (tok[tokidx].X_op)
1881 1.1.1.5 christos {
1882 1.1.1.5 christos case O_illegal:
1883 1.1.1.5 christos case O_absent:
1884 1.1.1.5 christos case O_register:
1885 1.1.1.5 christos goto match_failed;
1886 1.1.1.5 christos
1887 1.1.1.5 christos case O_bracket:
1888 1.1.1.5 christos /* Got an (too) early bracket, check if it is an
1889 1.1.1.5 christos ignored operand. N.B. This procedure works only
1890 1.1.1.5 christos when bracket is the last operand! */
1891 1.1.1.5 christos if (!(operand->flags & ARC_OPERAND_IGNORE))
1892 1.1.1.5 christos goto match_failed;
1893 1.1.1.5 christos /* Insert the missing operand. */
1894 1.1.1.5 christos if (!allocate_tok (tok, ntok - 1, tokidx))
1895 1.1.1.5 christos goto match_failed;
1896 1.1.1.5 christos
1897 1.1.1.5 christos tok[tokidx].X_op = O_absent;
1898 1.1.1.5 christos ++ntok;
1899 1.1.1.5 christos break;
1900 1.1.1.5 christos
1901 1.1.1.5 christos case O_symbol:
1902 1.1.1.5 christos {
1903 1.1.1.5 christos const char *p;
1904 1.1.1.7 christos char *tmpp, *pp;
1905 1.1.1.5 christos const struct arc_aux_reg *auxr;
1906 1.1.1.5 christos
1907 1.1.1.5 christos if (opcode->insn_class != AUXREG)
1908 1.1.1.5 christos goto de_fault;
1909 1.1.1.5 christos p = S_GET_NAME (tok[tokidx].X_add_symbol);
1910 1.1.1.5 christos
1911 1.1.1.7 christos /* For compatibility reasons, an aux register can
1912 1.1.1.7 christos be spelled with upper or lower case
1913 1.1.1.7 christos letters. */
1914 1.1.1.7 christos tmpp = strdup (p);
1915 1.1.1.7 christos for (pp = tmpp; *pp; ++pp) *pp = TOLOWER (*pp);
1916 1.1.1.7 christos
1917 1.1.1.8 christos auxr = str_hash_find (arc_aux_hash, tmpp);
1918 1.1.1.5 christos if (auxr)
1919 1.1.1.5 christos {
1920 1.1.1.5 christos /* We modify the token array here, safe in the
1921 1.1.1.5 christos knowledge, that if this was the wrong
1922 1.1.1.5 christos choice then the original contents will be
1923 1.1.1.5 christos restored from BKTOK. */
1924 1.1.1.5 christos tok[tokidx].X_op = O_constant;
1925 1.1.1.5 christos tok[tokidx].X_add_number = auxr->address;
1926 1.1.1.5 christos ARC_SET_FLAG (tok[tokidx].X_add_symbol, ARC_FLAG_AUX);
1927 1.1.1.5 christos }
1928 1.1.1.7 christos free (tmpp);
1929 1.1.1.5 christos
1930 1.1.1.5 christos if (tok[tokidx].X_op != O_constant)
1931 1.1.1.5 christos goto de_fault;
1932 1.1.1.5 christos }
1933 1.1.1.6 christos /* Fall through. */
1934 1.1.1.5 christos case O_constant:
1935 1.1.1.5 christos /* Check the range. */
1936 1.1.1.5 christos if (operand->bits != 32
1937 1.1.1.5 christos && !(operand->flags & ARC_OPERAND_NCHK))
1938 1.1.1.5 christos {
1939 1.1.1.5 christos offsetT min, max, val;
1940 1.1.1.5 christos val = tok[tokidx].X_add_number;
1941 1.1.1.5 christos
1942 1.1.1.5 christos if (operand->flags & ARC_OPERAND_SIGNED)
1943 1.1.1.5 christos {
1944 1.1.1.5 christos max = (1 << (operand->bits - 1)) - 1;
1945 1.1.1.5 christos min = -(1 << (operand->bits - 1));
1946 1.1.1.5 christos }
1947 1.1.1.5 christos else
1948 1.1.1.5 christos {
1949 1.1.1.5 christos max = (1 << operand->bits) - 1;
1950 1.1.1.5 christos min = 0;
1951 1.1.1.5 christos }
1952 1.1.1.5 christos
1953 1.1.1.5 christos if (val < min || val > max)
1954 1.1.1.8 christos {
1955 1.1.1.8 christos tmpmsg = _("immediate is out of bounds");
1956 1.1.1.8 christos goto match_failed;
1957 1.1.1.8 christos }
1958 1.1.1.5 christos
1959 1.1.1.6 christos /* Check alignments. */
1960 1.1.1.5 christos if ((operand->flags & ARC_OPERAND_ALIGNED32)
1961 1.1.1.5 christos && (val & 0x03))
1962 1.1.1.8 christos {
1963 1.1.1.8 christos tmpmsg = _("immediate is not 32bit aligned");
1964 1.1.1.8 christos goto match_failed;
1965 1.1.1.8 christos }
1966 1.1.1.5 christos
1967 1.1.1.5 christos if ((operand->flags & ARC_OPERAND_ALIGNED16)
1968 1.1.1.5 christos && (val & 0x01))
1969 1.1.1.8 christos {
1970 1.1.1.8 christos tmpmsg = _("immediate is not 16bit aligned");
1971 1.1.1.8 christos goto match_failed;
1972 1.1.1.8 christos }
1973 1.1.1.5 christos }
1974 1.1.1.5 christos else if (operand->flags & ARC_OPERAND_NCHK)
1975 1.1.1.5 christos {
1976 1.1.1.5 christos if (operand->insert)
1977 1.1.1.5 christos {
1978 1.1.1.8 christos tmpmsg = NULL;
1979 1.1.1.5 christos (*operand->insert)(0,
1980 1.1.1.5 christos tok[tokidx].X_add_number,
1981 1.1.1.8 christos &tmpmsg);
1982 1.1.1.8 christos if (tmpmsg)
1983 1.1.1.5 christos goto match_failed;
1984 1.1.1.5 christos }
1985 1.1.1.5 christos else if (!(operand->flags & ARC_OPERAND_IGNORE))
1986 1.1.1.5 christos goto match_failed;
1987 1.1.1.5 christos }
1988 1.1.1.5 christos break;
1989 1.1.1.5 christos
1990 1.1.1.5 christos case O_subtract:
1991 1.1.1.5 christos /* Check if it is register range. */
1992 1.1.1.5 christos if ((tok[tokidx].X_add_number == 0)
1993 1.1.1.5 christos && contains_register (tok[tokidx].X_add_symbol)
1994 1.1.1.5 christos && contains_register (tok[tokidx].X_op_symbol))
1995 1.1.1.5 christos {
1996 1.1.1.5 christos int regs;
1997 1.1.1.5 christos
1998 1.1.1.5 christos regs = get_register (tok[tokidx].X_add_symbol);
1999 1.1.1.5 christos regs <<= 16;
2000 1.1.1.5 christos regs |= get_register (tok[tokidx].X_op_symbol);
2001 1.1.1.5 christos if (operand->insert)
2002 1.1.1.5 christos {
2003 1.1.1.8 christos tmpmsg = NULL;
2004 1.1.1.5 christos (*operand->insert)(0,
2005 1.1.1.5 christos regs,
2006 1.1.1.8 christos &tmpmsg);
2007 1.1.1.8 christos if (tmpmsg)
2008 1.1.1.5 christos goto match_failed;
2009 1.1.1.5 christos }
2010 1.1.1.5 christos else
2011 1.1.1.5 christos goto match_failed;
2012 1.1.1.5 christos break;
2013 1.1.1.5 christos }
2014 1.1.1.6 christos /* Fall through. */
2015 1.1.1.5 christos default:
2016 1.1.1.5 christos de_fault:
2017 1.1.1.5 christos if (operand->default_reloc == 0)
2018 1.1.1.5 christos goto match_failed; /* The operand needs relocation. */
2019 1.1.1.5 christos
2020 1.1.1.5 christos /* Relocs requiring long immediate. FIXME! make it
2021 1.1.1.5 christos generic and move it to a function. */
2022 1.1.1.5 christos switch (tok[tokidx].X_md)
2023 1.1.1.5 christos {
2024 1.1.1.5 christos case O_gotoff:
2025 1.1.1.5 christos case O_gotpc:
2026 1.1.1.5 christos case O_pcl:
2027 1.1.1.5 christos case O_tpoff:
2028 1.1.1.5 christos case O_dtpoff:
2029 1.1.1.5 christos case O_tlsgd:
2030 1.1.1.5 christos case O_tlsie:
2031 1.1.1.5 christos if (!(operand->flags & ARC_OPERAND_LIMM))
2032 1.1.1.5 christos goto match_failed;
2033 1.1.1.6 christos /* Fall through. */
2034 1.1.1.5 christos case O_absent:
2035 1.1.1.5 christos if (!generic_reloc_p (operand->default_reloc))
2036 1.1.1.5 christos goto match_failed;
2037 1.1.1.6 christos break;
2038 1.1.1.5 christos default:
2039 1.1.1.5 christos break;
2040 1.1.1.5 christos }
2041 1.1.1.5 christos break;
2042 1.1.1.5 christos }
2043 1.1.1.5 christos /* If expect duplicate, make sure it is duplicate. */
2044 1.1.1.5 christos if (operand->flags & ARC_OPERAND_DUPLICATE)
2045 1.1.1.5 christos {
2046 1.1.1.5 christos if (t->X_op == O_illegal
2047 1.1.1.5 christos || t->X_op == O_absent
2048 1.1.1.5 christos || t->X_op == O_register
2049 1.1.1.5 christos || (t->X_add_number != tok[tokidx].X_add_number))
2050 1.1.1.8 christos {
2051 1.1.1.8 christos tmpmsg = _("operand is not duplicate of the "
2052 1.1.1.8 christos "previous one");
2053 1.1.1.8 christos goto match_failed;
2054 1.1.1.8 christos }
2055 1.1.1.5 christos }
2056 1.1.1.5 christos t = &tok[tokidx];
2057 1.1.1.5 christos break;
2058 1.1.1.5 christos
2059 1.1.1.5 christos default:
2060 1.1.1.5 christos /* Everything else should have been fake. */
2061 1.1.1.5 christos abort ();
2062 1.1.1.5 christos }
2063 1.1.1.5 christos
2064 1.1.1.5 christos ++tokidx;
2065 1.1.1.3 christos }
2066 1.1.1.5 christos pr_debug ("opr ");
2067 1.1.1.5 christos
2068 1.1.1.5 christos /* Setup ready for flag parsing. */
2069 1.1.1.5 christos if (!parse_opcode_flags (opcode, nflgs, first_pflag))
2070 1.1.1.8 christos {
2071 1.1.1.8 christos tmpmsg = _("flag mismatch");
2072 1.1.1.8 christos goto match_failed;
2073 1.1.1.8 christos }
2074 1.1.1.5 christos
2075 1.1.1.5 christos pr_debug ("flg");
2076 1.1.1.5 christos /* Possible match -- did we use all of our input? */
2077 1.1.1.5 christos if (tokidx == ntok)
2078 1.1.1.3 christos {
2079 1.1.1.5 christos *pntok = ntok;
2080 1.1.1.5 christos pr_debug ("\n");
2081 1.1.1.5 christos return opcode;
2082 1.1.1.3 christos }
2083 1.1.1.8 christos tmpmsg = _("too many arguments");
2084 1.1.1.5 christos
2085 1.1.1.5 christos match_failed:;
2086 1.1.1.5 christos pr_debug ("\n");
2087 1.1.1.5 christos /* Restore the original parameters. */
2088 1.1.1.5 christos memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok));
2089 1.1.1.5 christos ntok = bkntok;
2090 1.1.1.8 christos if (tokidx >= maxerridx
2091 1.1.1.8 christos && tmpmsg)
2092 1.1.1.8 christos {
2093 1.1.1.8 christos maxerridx = tokidx;
2094 1.1.1.8 christos *errmsg = tmpmsg;
2095 1.1.1.8 christos }
2096 1.1 skrll }
2097 1.1 skrll
2098 1.1.1.5 christos if (*pcpumatch)
2099 1.1.1.5 christos *pcpumatch = got_cpu_match;
2100 1.1 skrll
2101 1.1.1.5 christos return NULL;
2102 1.1.1.5 christos }
2103 1.1.1.3 christos
2104 1.1.1.5 christos /* Swap operand tokens. */
2105 1.1 skrll
2106 1.1.1.5 christos static void
2107 1.1.1.5 christos swap_operand (expressionS *operand_array,
2108 1.1.1.5 christos unsigned source,
2109 1.1.1.5 christos unsigned destination)
2110 1.1.1.5 christos {
2111 1.1.1.5 christos expressionS cpy_operand;
2112 1.1.1.5 christos expressionS *src_operand;
2113 1.1.1.5 christos expressionS *dst_operand;
2114 1.1.1.5 christos size_t size;
2115 1.1.1.3 christos
2116 1.1.1.5 christos if (source == destination)
2117 1.1.1.5 christos return;
2118 1.1.1.3 christos
2119 1.1.1.5 christos src_operand = &operand_array[source];
2120 1.1.1.5 christos dst_operand = &operand_array[destination];
2121 1.1.1.5 christos size = sizeof (expressionS);
2122 1.1.1.5 christos
2123 1.1.1.5 christos /* Make copy of operand to swap with and swap. */
2124 1.1.1.5 christos memcpy (&cpy_operand, dst_operand, size);
2125 1.1.1.5 christos memcpy (dst_operand, src_operand, size);
2126 1.1.1.5 christos memcpy (src_operand, &cpy_operand, size);
2127 1.1.1.5 christos }
2128 1.1.1.5 christos
2129 1.1.1.5 christos /* Check if *op matches *tok type.
2130 1.1.1.5 christos Returns FALSE if they don't match, TRUE if they match. */
2131 1.1.1.5 christos
2132 1.1.1.8 christos static bool
2133 1.1.1.5 christos pseudo_operand_match (const expressionS *tok,
2134 1.1.1.5 christos const struct arc_operand_operation *op)
2135 1.1.1.5 christos {
2136 1.1.1.5 christos offsetT min, max, val;
2137 1.1.1.8 christos bool ret;
2138 1.1.1.5 christos const struct arc_operand *operand_real = &arc_operands[op->operand_idx];
2139 1.1.1.5 christos
2140 1.1.1.8 christos ret = false;
2141 1.1.1.5 christos switch (tok->X_op)
2142 1.1.1.3 christos {
2143 1.1.1.5 christos case O_constant:
2144 1.1.1.5 christos if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM))
2145 1.1.1.5 christos ret = 1;
2146 1.1.1.5 christos else if (!(operand_real->flags & ARC_OPERAND_IR))
2147 1.1.1.5 christos {
2148 1.1.1.5 christos val = tok->X_add_number + op->count;
2149 1.1.1.5 christos if (operand_real->flags & ARC_OPERAND_SIGNED)
2150 1.1.1.5 christos {
2151 1.1.1.5 christos max = (1 << (operand_real->bits - 1)) - 1;
2152 1.1.1.5 christos min = -(1 << (operand_real->bits - 1));
2153 1.1.1.5 christos }
2154 1.1.1.5 christos else
2155 1.1.1.5 christos {
2156 1.1.1.5 christos max = (1 << operand_real->bits) - 1;
2157 1.1.1.5 christos min = 0;
2158 1.1.1.5 christos }
2159 1.1.1.5 christos if (min <= val && val <= max)
2160 1.1.1.8 christos ret = true;
2161 1.1.1.5 christos }
2162 1.1.1.5 christos break;
2163 1.1.1.5 christos
2164 1.1.1.5 christos case O_symbol:
2165 1.1.1.5 christos /* Handle all symbols as long immediates or signed 9. */
2166 1.1.1.6 christos if (operand_real->flags & ARC_OPERAND_LIMM
2167 1.1.1.6 christos || ((operand_real->flags & ARC_OPERAND_SIGNED)
2168 1.1.1.6 christos && operand_real->bits == 9))
2169 1.1.1.8 christos ret = true;
2170 1.1.1.3 christos break;
2171 1.1 skrll
2172 1.1.1.5 christos case O_register:
2173 1.1.1.5 christos if (operand_real->flags & ARC_OPERAND_IR)
2174 1.1.1.8 christos ret = true;
2175 1.1.1.3 christos break;
2176 1.1.1.3 christos
2177 1.1.1.5 christos case O_bracket:
2178 1.1.1.5 christos if (operand_real->flags & ARC_OPERAND_BRAKET)
2179 1.1.1.8 christos ret = true;
2180 1.1.1.3 christos break;
2181 1.1 skrll
2182 1.1.1.3 christos default:
2183 1.1.1.5 christos /* Unknown. */
2184 1.1.1.3 christos break;
2185 1.1.1.3 christos }
2186 1.1.1.5 christos return ret;
2187 1.1.1.5 christos }
2188 1.1 skrll
2189 1.1.1.5 christos /* Find pseudo instruction in array. */
2190 1.1.1.5 christos
2191 1.1.1.5 christos static const struct arc_pseudo_insn *
2192 1.1.1.5 christos find_pseudo_insn (const char *opname,
2193 1.1.1.5 christos int ntok,
2194 1.1.1.5 christos const expressionS *tok)
2195 1.1.1.5 christos {
2196 1.1.1.5 christos const struct arc_pseudo_insn *pseudo_insn = NULL;
2197 1.1.1.5 christos const struct arc_operand_operation *op;
2198 1.1.1.5 christos unsigned int i;
2199 1.1.1.5 christos int j;
2200 1.1.1.5 christos
2201 1.1.1.5 christos for (i = 0; i < arc_num_pseudo_insn; ++i)
2202 1.1 skrll {
2203 1.1.1.5 christos pseudo_insn = &arc_pseudo_insns[i];
2204 1.1.1.5 christos if (strcmp (pseudo_insn->mnemonic_p, opname) == 0)
2205 1.1.1.5 christos {
2206 1.1.1.5 christos op = pseudo_insn->operand;
2207 1.1.1.5 christos for (j = 0; j < ntok; ++j)
2208 1.1.1.5 christos if (!pseudo_operand_match (&tok[j], &op[j]))
2209 1.1.1.5 christos break;
2210 1.1.1.5 christos
2211 1.1.1.5 christos /* Found the right instruction. */
2212 1.1.1.5 christos if (j == ntok)
2213 1.1.1.5 christos return pseudo_insn;
2214 1.1.1.5 christos }
2215 1.1 skrll }
2216 1.1.1.5 christos return NULL;
2217 1.1.1.5 christos }
2218 1.1 skrll
2219 1.1.1.5 christos /* Assumes the expressionS *tok is of sufficient size. */
2220 1.1 skrll
2221 1.1.1.5 christos static const struct arc_opcode_hash_entry *
2222 1.1.1.5 christos find_special_case_pseudo (const char *opname,
2223 1.1.1.5 christos int *ntok,
2224 1.1.1.5 christos expressionS *tok,
2225 1.1.1.5 christos int *nflgs,
2226 1.1.1.5 christos struct arc_flags *pflags)
2227 1.1.1.5 christos {
2228 1.1.1.5 christos const struct arc_pseudo_insn *pseudo_insn = NULL;
2229 1.1.1.5 christos const struct arc_operand_operation *operand_pseudo;
2230 1.1.1.5 christos const struct arc_operand *operand_real;
2231 1.1.1.5 christos unsigned i;
2232 1.1.1.5 christos char construct_operand[MAX_CONSTR_STR];
2233 1.1.1.3 christos
2234 1.1.1.5 christos /* Find whether opname is in pseudo instruction array. */
2235 1.1.1.5 christos pseudo_insn = find_pseudo_insn (opname, *ntok, tok);
2236 1.1 skrll
2237 1.1.1.5 christos if (pseudo_insn == NULL)
2238 1.1.1.5 christos return NULL;
2239 1.1 skrll
2240 1.1.1.5 christos /* Handle flag, Limited to one flag at the moment. */
2241 1.1.1.5 christos if (pseudo_insn->flag_r != NULL)
2242 1.1.1.5 christos *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs],
2243 1.1.1.5 christos MAX_INSN_FLGS - *nflgs);
2244 1.1 skrll
2245 1.1.1.5 christos /* Handle operand operations. */
2246 1.1.1.5 christos for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2247 1.1.1.5 christos {
2248 1.1.1.5 christos operand_pseudo = &pseudo_insn->operand[i];
2249 1.1.1.5 christos operand_real = &arc_operands[operand_pseudo->operand_idx];
2250 1.1.1.3 christos
2251 1.1.1.6 christos if (operand_real->flags & ARC_OPERAND_BRAKET
2252 1.1.1.6 christos && !operand_pseudo->needs_insert)
2253 1.1.1.5 christos continue;
2254 1.1.1.3 christos
2255 1.1.1.5 christos /* Has to be inserted (i.e. this token does not exist yet). */
2256 1.1.1.5 christos if (operand_pseudo->needs_insert)
2257 1.1.1.5 christos {
2258 1.1.1.5 christos if (operand_real->flags & ARC_OPERAND_BRAKET)
2259 1.1.1.5 christos {
2260 1.1.1.5 christos tok[i].X_op = O_bracket;
2261 1.1.1.5 christos ++(*ntok);
2262 1.1.1.5 christos continue;
2263 1.1.1.5 christos }
2264 1.1.1.3 christos
2265 1.1.1.5 christos /* Check if operand is a register or constant and handle it
2266 1.1.1.5 christos by type. */
2267 1.1.1.5 christos if (operand_real->flags & ARC_OPERAND_IR)
2268 1.1.1.5 christos snprintf (construct_operand, MAX_CONSTR_STR, "r%d",
2269 1.1.1.5 christos operand_pseudo->count);
2270 1.1.1.5 christos else
2271 1.1.1.5 christos snprintf (construct_operand, MAX_CONSTR_STR, "%d",
2272 1.1.1.5 christos operand_pseudo->count);
2273 1.1.1.3 christos
2274 1.1.1.5 christos tokenize_arguments (construct_operand, &tok[i], 1);
2275 1.1.1.5 christos ++(*ntok);
2276 1.1.1.5 christos }
2277 1.1 skrll
2278 1.1.1.5 christos else if (operand_pseudo->count)
2279 1.1.1.5 christos {
2280 1.1.1.5 christos /* Operand number has to be adjusted accordingly (by operand
2281 1.1.1.5 christos type). */
2282 1.1.1.5 christos switch (tok[i].X_op)
2283 1.1.1.5 christos {
2284 1.1.1.5 christos case O_constant:
2285 1.1.1.5 christos tok[i].X_add_number += operand_pseudo->count;
2286 1.1.1.5 christos break;
2287 1.1 skrll
2288 1.1.1.5 christos case O_symbol:
2289 1.1.1.5 christos break;
2290 1.1.1.3 christos
2291 1.1.1.5 christos default:
2292 1.1.1.5 christos /* Ignored. */
2293 1.1.1.5 christos break;
2294 1.1.1.5 christos }
2295 1.1.1.5 christos }
2296 1.1.1.3 christos }
2297 1.1.1.3 christos
2298 1.1.1.5 christos /* Swap operands if necessary. Only supports one swap at the
2299 1.1.1.5 christos moment. */
2300 1.1.1.5 christos for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2301 1.1.1.3 christos {
2302 1.1.1.5 christos operand_pseudo = &pseudo_insn->operand[i];
2303 1.1.1.5 christos
2304 1.1.1.5 christos if (operand_pseudo->swap_operand_idx == i)
2305 1.1.1.5 christos continue;
2306 1.1.1.5 christos
2307 1.1.1.5 christos swap_operand (tok, i, operand_pseudo->swap_operand_idx);
2308 1.1.1.5 christos
2309 1.1.1.5 christos /* Prevent a swap back later by breaking out. */
2310 1.1.1.5 christos break;
2311 1.1 skrll }
2312 1.1.1.5 christos
2313 1.1.1.5 christos return arc_find_opcode (pseudo_insn->mnemonic_r);
2314 1.1.1.5 christos }
2315 1.1.1.5 christos
2316 1.1.1.5 christos static const struct arc_opcode_hash_entry *
2317 1.1.1.5 christos find_special_case_flag (const char *opname,
2318 1.1.1.5 christos int *nflgs,
2319 1.1.1.5 christos struct arc_flags *pflags)
2320 1.1.1.5 christos {
2321 1.1.1.5 christos unsigned int i;
2322 1.1.1.5 christos const char *flagnm;
2323 1.1.1.5 christos unsigned flag_idx, flag_arr_idx;
2324 1.1.1.5 christos size_t flaglen, oplen;
2325 1.1.1.5 christos const struct arc_flag_special *arc_flag_special_opcode;
2326 1.1.1.5 christos const struct arc_opcode_hash_entry *entry;
2327 1.1.1.5 christos
2328 1.1.1.5 christos /* Search for special case instruction. */
2329 1.1.1.5 christos for (i = 0; i < arc_num_flag_special; i++)
2330 1.1 skrll {
2331 1.1.1.5 christos arc_flag_special_opcode = &arc_flag_special_cases[i];
2332 1.1.1.5 christos oplen = strlen (arc_flag_special_opcode->name);
2333 1.1.1.5 christos
2334 1.1.1.5 christos if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0)
2335 1.1.1.5 christos continue;
2336 1.1.1.5 christos
2337 1.1.1.5 christos /* Found a potential special case instruction, now test for
2338 1.1.1.5 christos flags. */
2339 1.1.1.5 christos for (flag_arr_idx = 0;; ++flag_arr_idx)
2340 1.1 skrll {
2341 1.1.1.5 christos flag_idx = arc_flag_special_opcode->flags[flag_arr_idx];
2342 1.1.1.5 christos if (flag_idx == 0)
2343 1.1.1.5 christos break; /* End of array, nothing found. */
2344 1.1.1.5 christos
2345 1.1.1.5 christos flagnm = arc_flag_operands[flag_idx].name;
2346 1.1.1.5 christos flaglen = strlen (flagnm);
2347 1.1.1.5 christos if (strcmp (opname + oplen, flagnm) == 0)
2348 1.1.1.5 christos {
2349 1.1.1.5 christos entry = arc_find_opcode (arc_flag_special_opcode->name);
2350 1.1.1.5 christos
2351 1.1.1.5 christos if (*nflgs + 1 > MAX_INSN_FLGS)
2352 1.1.1.5 christos break;
2353 1.1.1.5 christos memcpy (pflags[*nflgs].name, flagnm, flaglen);
2354 1.1.1.5 christos pflags[*nflgs].name[flaglen] = '\0';
2355 1.1.1.5 christos (*nflgs)++;
2356 1.1.1.5 christos return entry;
2357 1.1.1.5 christos }
2358 1.1 skrll }
2359 1.1 skrll }
2360 1.1.1.5 christos return NULL;
2361 1.1.1.5 christos }
2362 1.1 skrll
2363 1.1.1.5 christos /* Used to find special case opcode. */
2364 1.1 skrll
2365 1.1.1.5 christos static const struct arc_opcode_hash_entry *
2366 1.1.1.5 christos find_special_case (const char *opname,
2367 1.1.1.5 christos int *nflgs,
2368 1.1.1.5 christos struct arc_flags *pflags,
2369 1.1.1.5 christos expressionS *tok,
2370 1.1.1.5 christos int *ntok)
2371 1.1 skrll {
2372 1.1.1.5 christos const struct arc_opcode_hash_entry *entry;
2373 1.1 skrll
2374 1.1.1.5 christos entry = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
2375 1.1.1.3 christos
2376 1.1.1.5 christos if (entry == NULL)
2377 1.1.1.5 christos entry = find_special_case_flag (opname, nflgs, pflags);
2378 1.1.1.3 christos
2379 1.1.1.5 christos return entry;
2380 1.1.1.5 christos }
2381 1.1.1.3 christos
2382 1.1.1.6 christos /* Autodetect cpu attribute list. */
2383 1.1.1.6 christos
2384 1.1.1.6 christos static void
2385 1.1.1.6 christos autodetect_attributes (const struct arc_opcode *opcode,
2386 1.1.1.6 christos const expressionS *tok,
2387 1.1.1.6 christos int ntok)
2388 1.1.1.6 christos {
2389 1.1.1.6 christos unsigned i;
2390 1.1.1.6 christos struct mpy_type
2391 1.1.1.6 christos {
2392 1.1.1.6 christos unsigned feature;
2393 1.1.1.6 christos unsigned encoding;
2394 1.1.1.6 christos } mpy_list[] = {{ MPY1E, 1 }, { MPY6E, 6 }, { MPY7E, 7 }, { MPY8E, 8 },
2395 1.1.1.6 christos { MPY9E, 9 }};
2396 1.1.1.6 christos
2397 1.1.1.6 christos for (i = 0; i < ARRAY_SIZE (feature_list); i++)
2398 1.1.1.6 christos if (opcode->subclass == feature_list[i].feature)
2399 1.1.1.6 christos selected_cpu.features |= feature_list[i].feature;
2400 1.1.1.6 christos
2401 1.1.1.6 christos for (i = 0; i < ARRAY_SIZE (mpy_list); i++)
2402 1.1.1.6 christos if (opcode->subclass == mpy_list[i].feature)
2403 1.1.1.6 christos mpy_option = mpy_list[i].encoding;
2404 1.1.1.6 christos
2405 1.1.1.6 christos for (i = 0; i < (unsigned) ntok; i++)
2406 1.1.1.6 christos {
2407 1.1.1.6 christos switch (tok[i].X_md)
2408 1.1.1.6 christos {
2409 1.1.1.6 christos case O_gotoff:
2410 1.1.1.6 christos case O_gotpc:
2411 1.1.1.6 christos case O_plt:
2412 1.1.1.6 christos pic_option = 2;
2413 1.1.1.6 christos break;
2414 1.1.1.6 christos case O_sda:
2415 1.1.1.6 christos sda_option = 2;
2416 1.1.1.6 christos break;
2417 1.1.1.6 christos case O_tlsgd:
2418 1.1.1.6 christos case O_tlsie:
2419 1.1.1.6 christos case O_tpoff9:
2420 1.1.1.6 christos case O_tpoff:
2421 1.1.1.6 christos case O_dtpoff9:
2422 1.1.1.6 christos case O_dtpoff:
2423 1.1.1.6 christos tls_option = 1;
2424 1.1.1.6 christos break;
2425 1.1.1.6 christos default:
2426 1.1.1.6 christos break;
2427 1.1.1.6 christos }
2428 1.1.1.7 christos
2429 1.1.1.7 christos switch (tok[i].X_op)
2430 1.1.1.7 christos {
2431 1.1.1.7 christos case O_register:
2432 1.1.1.7 christos if ((tok[i].X_add_number >= 4 && tok[i].X_add_number <= 9)
2433 1.1.1.7 christos || (tok[i].X_add_number >= 16 && tok[i].X_add_number <= 25))
2434 1.1.1.8 christos rf16_only = false;
2435 1.1.1.7 christos break;
2436 1.1.1.7 christos default:
2437 1.1.1.7 christos break;
2438 1.1.1.7 christos }
2439 1.1.1.6 christos }
2440 1.1.1.6 christos }
2441 1.1.1.6 christos
2442 1.1.1.5 christos /* Given an opcode name, pre-tockenized set of argumenst and the
2443 1.1.1.5 christos opcode flags, take it all the way through emission. */
2444 1.1 skrll
2445 1.1.1.5 christos static void
2446 1.1.1.5 christos assemble_tokens (const char *opname,
2447 1.1.1.5 christos expressionS *tok,
2448 1.1.1.5 christos int ntok,
2449 1.1.1.5 christos struct arc_flags *pflags,
2450 1.1.1.5 christos int nflgs)
2451 1.1.1.5 christos {
2452 1.1.1.8 christos bool found_something = false;
2453 1.1.1.5 christos const struct arc_opcode_hash_entry *entry;
2454 1.1.1.5 christos int cpumatch = 1;
2455 1.1.1.6 christos const char *errmsg = NULL;
2456 1.1 skrll
2457 1.1.1.5 christos /* Search opcodes. */
2458 1.1.1.5 christos entry = arc_find_opcode (opname);
2459 1.1 skrll
2460 1.1.1.5 christos /* Couldn't find opcode conventional way, try special cases. */
2461 1.1.1.5 christos if (entry == NULL)
2462 1.1.1.5 christos entry = find_special_case (opname, &nflgs, pflags, tok, &ntok);
2463 1.1.1.5 christos
2464 1.1.1.5 christos if (entry != NULL)
2465 1.1.1.3 christos {
2466 1.1.1.5 christos const struct arc_opcode *opcode;
2467 1.1.1.5 christos
2468 1.1.1.5 christos pr_debug ("%s:%d: assemble_tokens: %s\n",
2469 1.1.1.5 christos frag_now->fr_file, frag_now->fr_line, opname);
2470 1.1.1.8 christos found_something = true;
2471 1.1.1.5 christos opcode = find_opcode_match (entry, tok, &ntok, pflags,
2472 1.1.1.6 christos nflgs, &cpumatch, &errmsg);
2473 1.1.1.5 christos if (opcode != NULL)
2474 1.1.1.3 christos {
2475 1.1.1.5 christos struct arc_insn insn;
2476 1.1.1.5 christos
2477 1.1.1.6 christos autodetect_attributes (opcode, tok, ntok);
2478 1.1.1.5 christos assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
2479 1.1.1.5 christos emit_insn (&insn);
2480 1.1.1.5 christos return;
2481 1.1.1.3 christos }
2482 1.1.1.3 christos }
2483 1.1 skrll
2484 1.1.1.5 christos if (found_something)
2485 1.1.1.5 christos {
2486 1.1.1.5 christos if (cpumatch)
2487 1.1.1.6 christos if (errmsg)
2488 1.1.1.6 christos as_bad (_("%s for instruction '%s'"), errmsg, opname);
2489 1.1.1.6 christos else
2490 1.1.1.6 christos as_bad (_("inappropriate arguments for opcode '%s'"), opname);
2491 1.1.1.5 christos else
2492 1.1.1.5 christos as_bad (_("opcode '%s' not supported for target %s"), opname,
2493 1.1.1.6 christos selected_cpu.name);
2494 1.1.1.5 christos }
2495 1.1.1.5 christos else
2496 1.1.1.5 christos as_bad (_("unknown opcode '%s'"), opname);
2497 1.1 skrll }
2498 1.1 skrll
2499 1.1.1.5 christos /* The public interface to the instruction assembler. */
2500 1.1.1.3 christos
2501 1.1.1.3 christos void
2502 1.1.1.5 christos md_assemble (char *str)
2503 1.1 skrll {
2504 1.1.1.5 christos char *opname;
2505 1.1.1.5 christos expressionS tok[MAX_INSN_ARGS];
2506 1.1.1.5 christos int ntok, nflg;
2507 1.1.1.5 christos size_t opnamelen;
2508 1.1.1.5 christos struct arc_flags flags[MAX_INSN_FLGS];
2509 1.1.1.3 christos
2510 1.1.1.5 christos /* Split off the opcode. */
2511 1.1.1.5 christos opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_0123468");
2512 1.1.1.5 christos opname = xmemdup0 (str, opnamelen);
2513 1.1.1.3 christos
2514 1.1.1.6 christos /* Signalize we are assembling the instructions. */
2515 1.1.1.8 christos assembling_insn = true;
2516 1.1.1.3 christos
2517 1.1.1.5 christos /* Tokenize the flags. */
2518 1.1.1.5 christos if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1)
2519 1.1.1.5 christos {
2520 1.1.1.5 christos as_bad (_("syntax error"));
2521 1.1.1.5 christos return;
2522 1.1.1.3 christos }
2523 1.1.1.3 christos
2524 1.1.1.5 christos /* Scan up to the end of the mnemonic which must end in space or end
2525 1.1.1.5 christos of string. */
2526 1.1.1.5 christos str += opnamelen;
2527 1.1.1.5 christos for (; *str != '\0'; str++)
2528 1.1.1.5 christos if (*str == ' ')
2529 1.1.1.5 christos break;
2530 1.1 skrll
2531 1.1.1.5 christos /* Tokenize the rest of the line. */
2532 1.1.1.5 christos if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0)
2533 1.1.1.3 christos {
2534 1.1.1.5 christos as_bad (_("syntax error"));
2535 1.1.1.5 christos return;
2536 1.1.1.3 christos }
2537 1.1.1.5 christos
2538 1.1.1.5 christos /* Finish it off. */
2539 1.1.1.5 christos assemble_tokens (opname, tok, ntok, flags, nflg);
2540 1.1.1.8 christos assembling_insn = false;
2541 1.1.1.3 christos }
2542 1.1 skrll
2543 1.1.1.5 christos /* Callback to insert a register into the hash table. */
2544 1.1.1.3 christos
2545 1.1.1.5 christos static void
2546 1.1.1.5 christos declare_register (const char *name, int number)
2547 1.1.1.3 christos {
2548 1.1.1.5 christos symbolS *regS = symbol_create (name, reg_section,
2549 1.1.1.8 christos &zero_address_frag, number);
2550 1.1.1.3 christos
2551 1.1.1.8 christos if (str_hash_insert (arc_reg_hash, S_GET_NAME (regS), regS, 0) != NULL)
2552 1.1.1.8 christos as_fatal (_("duplicate %s"), name);
2553 1.1.1.5 christos }
2554 1.1.1.3 christos
2555 1.1.1.5 christos /* Construct symbols for each of the general registers. */
2556 1.1.1.3 christos
2557 1.1.1.5 christos static void
2558 1.1.1.5 christos declare_register_set (void)
2559 1.1.1.5 christos {
2560 1.1.1.5 christos int i;
2561 1.1.1.5 christos for (i = 0; i < 64; ++i)
2562 1.1.1.3 christos {
2563 1.1.1.8 christos char name[32];
2564 1.1.1.5 christos
2565 1.1.1.5 christos sprintf (name, "r%d", i);
2566 1.1.1.5 christos declare_register (name, i);
2567 1.1.1.5 christos if ((i & 0x01) == 0)
2568 1.1.1.5 christos {
2569 1.1.1.5 christos sprintf (name, "r%dr%d", i, i+1);
2570 1.1.1.5 christos declare_register (name, i);
2571 1.1.1.5 christos }
2572 1.1.1.3 christos }
2573 1.1.1.3 christos }
2574 1.1.1.3 christos
2575 1.1.1.6 christos /* Construct a symbol for an address type. */
2576 1.1.1.6 christos
2577 1.1.1.6 christos static void
2578 1.1.1.6 christos declare_addrtype (const char *name, int number)
2579 1.1.1.6 christos {
2580 1.1.1.6 christos symbolS *addrtypeS = symbol_create (name, undefined_section,
2581 1.1.1.8 christos &zero_address_frag, number);
2582 1.1.1.6 christos
2583 1.1.1.8 christos if (str_hash_insert (arc_addrtype_hash, S_GET_NAME (addrtypeS), addrtypeS, 0))
2584 1.1.1.8 christos as_fatal (_("duplicate %s"), name);
2585 1.1.1.6 christos }
2586 1.1.1.6 christos
2587 1.1.1.5 christos /* Port-specific assembler initialization. This function is called
2588 1.1.1.5 christos once, at assembler startup time. */
2589 1.1.1.5 christos
2590 1.1.1.5 christos void
2591 1.1.1.5 christos md_begin (void)
2592 1.1.1.5 christos {
2593 1.1.1.5 christos const struct arc_opcode *opcode = arc_opcodes;
2594 1.1.1.5 christos
2595 1.1.1.6 christos if (mach_selection_mode == MACH_SELECTION_NONE)
2596 1.1.1.6 christos arc_select_cpu (TARGET_WITH_CPU, MACH_SELECTION_FROM_DEFAULT);
2597 1.1.1.3 christos
2598 1.1.1.5 christos /* The endianness can be chosen "at the factory". */
2599 1.1.1.5 christos target_big_endian = byte_order == BIG_ENDIAN;
2600 1.1.1.3 christos
2601 1.1.1.6 christos if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
2602 1.1.1.5 christos as_warn (_("could not set architecture and machine"));
2603 1.1.1.3 christos
2604 1.1.1.5 christos /* Set elf header flags. */
2605 1.1.1.6 christos bfd_set_private_flags (stdoutput, selected_cpu.eflags);
2606 1.1.1.3 christos
2607 1.1.1.5 christos /* Set up a hash table for the instructions. */
2608 1.1.1.8 christos arc_opcode_hash = str_htab_create ();
2609 1.1.1.3 christos
2610 1.1.1.5 christos /* Initialize the hash table with the insns. */
2611 1.1.1.5 christos do
2612 1.1.1.3 christos {
2613 1.1.1.5 christos const char *name = opcode->name;
2614 1.1.1.3 christos
2615 1.1.1.5 christos arc_insert_opcode (opcode);
2616 1.1.1.3 christos
2617 1.1.1.5 christos while (++opcode && opcode->name
2618 1.1.1.5 christos && (opcode->name == name
2619 1.1.1.5 christos || !strcmp (opcode->name, name)))
2620 1.1.1.5 christos continue;
2621 1.1.1.5 christos }while (opcode->name);
2622 1.1.1.3 christos
2623 1.1.1.5 christos /* Register declaration. */
2624 1.1.1.8 christos arc_reg_hash = str_htab_create ();
2625 1.1.1.3 christos
2626 1.1.1.5 christos declare_register_set ();
2627 1.1.1.5 christos declare_register ("gp", 26);
2628 1.1.1.5 christos declare_register ("fp", 27);
2629 1.1.1.5 christos declare_register ("sp", 28);
2630 1.1.1.5 christos declare_register ("ilink", 29);
2631 1.1.1.5 christos declare_register ("ilink1", 29);
2632 1.1.1.5 christos declare_register ("ilink2", 30);
2633 1.1.1.5 christos declare_register ("blink", 31);
2634 1.1 skrll
2635 1.1.1.5 christos /* XY memory registers. */
2636 1.1.1.5 christos declare_register ("x0_u0", 32);
2637 1.1.1.5 christos declare_register ("x0_u1", 33);
2638 1.1.1.5 christos declare_register ("x1_u0", 34);
2639 1.1.1.5 christos declare_register ("x1_u1", 35);
2640 1.1.1.5 christos declare_register ("x2_u0", 36);
2641 1.1.1.5 christos declare_register ("x2_u1", 37);
2642 1.1.1.5 christos declare_register ("x3_u0", 38);
2643 1.1.1.5 christos declare_register ("x3_u1", 39);
2644 1.1.1.5 christos declare_register ("y0_u0", 40);
2645 1.1.1.5 christos declare_register ("y0_u1", 41);
2646 1.1.1.5 christos declare_register ("y1_u0", 42);
2647 1.1.1.5 christos declare_register ("y1_u1", 43);
2648 1.1.1.5 christos declare_register ("y2_u0", 44);
2649 1.1.1.5 christos declare_register ("y2_u1", 45);
2650 1.1.1.5 christos declare_register ("y3_u0", 46);
2651 1.1.1.5 christos declare_register ("y3_u1", 47);
2652 1.1.1.5 christos declare_register ("x0_nu", 48);
2653 1.1.1.5 christos declare_register ("x1_nu", 49);
2654 1.1.1.5 christos declare_register ("x2_nu", 50);
2655 1.1.1.5 christos declare_register ("x3_nu", 51);
2656 1.1.1.5 christos declare_register ("y0_nu", 52);
2657 1.1.1.5 christos declare_register ("y1_nu", 53);
2658 1.1.1.5 christos declare_register ("y2_nu", 54);
2659 1.1.1.5 christos declare_register ("y3_nu", 55);
2660 1.1 skrll
2661 1.1.1.5 christos declare_register ("mlo", 57);
2662 1.1.1.5 christos declare_register ("mmid", 58);
2663 1.1.1.5 christos declare_register ("mhi", 59);
2664 1.1.1.3 christos
2665 1.1.1.5 christos declare_register ("acc1", 56);
2666 1.1.1.5 christos declare_register ("acc2", 57);
2667 1.1.1.3 christos
2668 1.1.1.5 christos declare_register ("lp_count", 60);
2669 1.1.1.5 christos declare_register ("pcl", 63);
2670 1.1 skrll
2671 1.1.1.5 christos /* Initialize the last instructions. */
2672 1.1.1.5 christos memset (&arc_last_insns[0], 0, sizeof (arc_last_insns));
2673 1.1 skrll
2674 1.1.1.5 christos /* Aux register declaration. */
2675 1.1.1.8 christos arc_aux_hash = str_htab_create ();
2676 1.1 skrll
2677 1.1.1.5 christos const struct arc_aux_reg *auxr = &arc_aux_regs[0];
2678 1.1.1.5 christos unsigned int i;
2679 1.1.1.5 christos for (i = 0; i < arc_num_aux_regs; i++, auxr++)
2680 1.1.1.5 christos {
2681 1.1.1.6 christos if (!(auxr->cpu & selected_cpu.flags))
2682 1.1.1.5 christos continue;
2683 1.1 skrll
2684 1.1.1.5 christos if ((auxr->subclass != NONE)
2685 1.1.1.5 christos && !check_cpu_feature (auxr->subclass))
2686 1.1.1.5 christos continue;
2687 1.1 skrll
2688 1.1.1.8 christos if (str_hash_insert (arc_aux_hash, auxr->name, auxr, 0) != 0)
2689 1.1.1.8 christos as_fatal (_("duplicate %s"), auxr->name);
2690 1.1.1.3 christos }
2691 1.1.1.6 christos
2692 1.1.1.6 christos /* Address type declaration. */
2693 1.1.1.8 christos arc_addrtype_hash = str_htab_create ();
2694 1.1.1.6 christos
2695 1.1.1.6 christos declare_addrtype ("bd", ARC_NPS400_ADDRTYPE_BD);
2696 1.1.1.6 christos declare_addrtype ("jid", ARC_NPS400_ADDRTYPE_JID);
2697 1.1.1.6 christos declare_addrtype ("lbd", ARC_NPS400_ADDRTYPE_LBD);
2698 1.1.1.6 christos declare_addrtype ("mbd", ARC_NPS400_ADDRTYPE_MBD);
2699 1.1.1.6 christos declare_addrtype ("sd", ARC_NPS400_ADDRTYPE_SD);
2700 1.1.1.6 christos declare_addrtype ("sm", ARC_NPS400_ADDRTYPE_SM);
2701 1.1.1.6 christos declare_addrtype ("xa", ARC_NPS400_ADDRTYPE_XA);
2702 1.1.1.6 christos declare_addrtype ("xd", ARC_NPS400_ADDRTYPE_XD);
2703 1.1.1.6 christos declare_addrtype ("cd", ARC_NPS400_ADDRTYPE_CD);
2704 1.1.1.6 christos declare_addrtype ("cbd", ARC_NPS400_ADDRTYPE_CBD);
2705 1.1.1.6 christos declare_addrtype ("cjid", ARC_NPS400_ADDRTYPE_CJID);
2706 1.1.1.6 christos declare_addrtype ("clbd", ARC_NPS400_ADDRTYPE_CLBD);
2707 1.1.1.6 christos declare_addrtype ("cm", ARC_NPS400_ADDRTYPE_CM);
2708 1.1.1.6 christos declare_addrtype ("csd", ARC_NPS400_ADDRTYPE_CSD);
2709 1.1.1.6 christos declare_addrtype ("cxa", ARC_NPS400_ADDRTYPE_CXA);
2710 1.1.1.6 christos declare_addrtype ("cxd", ARC_NPS400_ADDRTYPE_CXD);
2711 1.1.1.3 christos }
2712 1.1.1.3 christos
2713 1.1.1.5 christos /* Write a value out to the object file, using the appropriate
2714 1.1.1.5 christos endianness. */
2715 1.1.1.5 christos
2716 1.1.1.3 christos void
2717 1.1.1.5 christos md_number_to_chars (char *buf,
2718 1.1.1.5 christos valueT val,
2719 1.1.1.5 christos int n)
2720 1.1.1.3 christos {
2721 1.1.1.5 christos if (target_big_endian)
2722 1.1.1.5 christos number_to_chars_bigendian (buf, val, n);
2723 1.1.1.5 christos else
2724 1.1.1.5 christos number_to_chars_littleendian (buf, val, n);
2725 1.1.1.5 christos }
2726 1.1.1.3 christos
2727 1.1.1.5 christos /* Round up a section size to the appropriate boundary. */
2728 1.1.1.3 christos
2729 1.1.1.5 christos valueT
2730 1.1.1.5 christos md_section_align (segT segment,
2731 1.1.1.5 christos valueT size)
2732 1.1.1.5 christos {
2733 1.1.1.7 christos int align = bfd_section_alignment (segment);
2734 1.1.1.5 christos
2735 1.1.1.5 christos return ((size + (1 << align) - 1) & (-((valueT) 1 << align)));
2736 1.1.1.3 christos }
2737 1.1.1.3 christos
2738 1.1.1.5 christos /* The location from which a PC relative jump should be calculated,
2739 1.1.1.5 christos given a PC relative reloc. */
2740 1.1.1.5 christos
2741 1.1.1.5 christos long
2742 1.1.1.5 christos md_pcrel_from_section (fixS *fixP,
2743 1.1.1.5 christos segT sec)
2744 1.1.1.3 christos {
2745 1.1.1.5 christos offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
2746 1.1.1.5 christos
2747 1.1.1.5 christos pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP->fx_offset);
2748 1.1.1.5 christos
2749 1.1.1.5 christos if (fixP->fx_addsy != (symbolS *) NULL
2750 1.1.1.5 christos && (!S_IS_DEFINED (fixP->fx_addsy)
2751 1.1.1.5 christos || S_GET_SEGMENT (fixP->fx_addsy) != sec))
2752 1.1.1.5 christos {
2753 1.1.1.5 christos pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP->fx_addsy));
2754 1.1.1.5 christos
2755 1.1.1.5 christos /* The symbol is undefined (or is defined but not in this section).
2756 1.1.1.5 christos Let the linker figure it out. */
2757 1.1.1.5 christos return 0;
2758 1.1.1.5 christos }
2759 1.1.1.3 christos
2760 1.1.1.5 christos if ((int) fixP->fx_r_type < 0)
2761 1.1.1.5 christos {
2762 1.1.1.5 christos /* These are the "internal" relocations. Align them to
2763 1.1.1.5 christos 32 bit boundary (PCL), for the moment. */
2764 1.1.1.5 christos base &= ~3;
2765 1.1.1.5 christos }
2766 1.1.1.5 christos else
2767 1.1.1.3 christos {
2768 1.1.1.5 christos switch (fixP->fx_r_type)
2769 1.1.1.3 christos {
2770 1.1.1.5 christos case BFD_RELOC_ARC_PC32:
2771 1.1.1.5 christos /* The hardware calculates relative to the start of the
2772 1.1.1.5 christos insn, but this relocation is relative to location of the
2773 1.1.1.5 christos LIMM, compensate. The base always needs to be
2774 1.1.1.6 christos subtracted by 4 as we do not support this type of PCrel
2775 1.1.1.5 christos relocation for short instructions. */
2776 1.1.1.5 christos base -= 4;
2777 1.1.1.5 christos /* Fall through. */
2778 1.1.1.5 christos case BFD_RELOC_ARC_PLT32:
2779 1.1.1.5 christos case BFD_RELOC_ARC_S25H_PCREL_PLT:
2780 1.1.1.5 christos case BFD_RELOC_ARC_S21H_PCREL_PLT:
2781 1.1.1.5 christos case BFD_RELOC_ARC_S25W_PCREL_PLT:
2782 1.1.1.5 christos case BFD_RELOC_ARC_S21W_PCREL_PLT:
2783 1.1.1.3 christos
2784 1.1.1.5 christos case BFD_RELOC_ARC_S21H_PCREL:
2785 1.1.1.5 christos case BFD_RELOC_ARC_S25H_PCREL:
2786 1.1.1.5 christos case BFD_RELOC_ARC_S13_PCREL:
2787 1.1.1.5 christos case BFD_RELOC_ARC_S21W_PCREL:
2788 1.1.1.5 christos case BFD_RELOC_ARC_S25W_PCREL:
2789 1.1.1.5 christos base &= ~3;
2790 1.1.1.3 christos break;
2791 1.1.1.3 christos default:
2792 1.1.1.5 christos as_bad_where (fixP->fx_file, fixP->fx_line,
2793 1.1.1.5 christos _("unhandled reloc %s in md_pcrel_from_section"),
2794 1.1.1.5 christos bfd_get_reloc_code_name (fixP->fx_r_type));
2795 1.1.1.3 christos break;
2796 1.1 skrll }
2797 1.1.1.3 christos }
2798 1.1.1.5 christos
2799 1.1.1.5 christos pr_debug ("pcrel from %"BFD_VMA_FMT"x + %lx = %"BFD_VMA_FMT"x, "
2800 1.1.1.5 christos "symbol: %s (%"BFD_VMA_FMT"x)\n",
2801 1.1.1.5 christos fixP->fx_frag->fr_address, fixP->fx_where, base,
2802 1.1.1.5 christos fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "(null)",
2803 1.1.1.5 christos fixP->fx_addsy ? S_GET_VALUE (fixP->fx_addsy) : 0);
2804 1.1.1.5 christos
2805 1.1.1.5 christos return base;
2806 1.1.1.3 christos }
2807 1.1.1.3 christos
2808 1.1.1.6 christos /* Given a BFD relocation find the corresponding operand. */
2809 1.1.1.3 christos
2810 1.1.1.5 christos static const struct arc_operand *
2811 1.1.1.5 christos find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc)
2812 1.1.1.3 christos {
2813 1.1.1.5 christos unsigned i;
2814 1.1.1.3 christos
2815 1.1.1.5 christos for (i = 0; i < arc_num_operands; i++)
2816 1.1.1.5 christos if (arc_operands[i].default_reloc == reloc)
2817 1.1.1.5 christos return &arc_operands[i];
2818 1.1.1.5 christos return NULL;
2819 1.1.1.5 christos }
2820 1.1 skrll
2821 1.1.1.5 christos /* Insert an operand value into an instruction. */
2822 1.1.1.3 christos
2823 1.1.1.6 christos static unsigned long long
2824 1.1.1.6 christos insert_operand (unsigned long long insn,
2825 1.1.1.5 christos const struct arc_operand *operand,
2826 1.1.1.6 christos long long val,
2827 1.1.1.5 christos const char *file,
2828 1.1.1.5 christos unsigned line)
2829 1.1.1.5 christos {
2830 1.1.1.5 christos offsetT min = 0, max = 0;
2831 1.1.1.3 christos
2832 1.1.1.5 christos if (operand->bits != 32
2833 1.1.1.5 christos && !(operand->flags & ARC_OPERAND_NCHK)
2834 1.1.1.5 christos && !(operand->flags & ARC_OPERAND_FAKE))
2835 1.1.1.5 christos {
2836 1.1.1.5 christos if (operand->flags & ARC_OPERAND_SIGNED)
2837 1.1 skrll {
2838 1.1.1.5 christos max = (1 << (operand->bits - 1)) - 1;
2839 1.1.1.5 christos min = -(1 << (operand->bits - 1));
2840 1.1.1.3 christos }
2841 1.1.1.3 christos else
2842 1.1.1.5 christos {
2843 1.1.1.5 christos max = (1 << operand->bits) - 1;
2844 1.1.1.5 christos min = 0;
2845 1.1.1.5 christos }
2846 1.1.1.5 christos
2847 1.1.1.5 christos if (val < min || val > max)
2848 1.1.1.5 christos as_bad_value_out_of_range (_("operand"),
2849 1.1.1.5 christos val, min, max, file, line);
2850 1.1.1.3 christos }
2851 1.1 skrll
2852 1.1.1.6 christos pr_debug ("insert field: %ld <= %lld <= %ld in 0x%08llx\n",
2853 1.1.1.5 christos min, val, max, insn);
2854 1.1 skrll
2855 1.1.1.5 christos if ((operand->flags & ARC_OPERAND_ALIGNED32)
2856 1.1.1.5 christos && (val & 0x03))
2857 1.1.1.5 christos as_bad_where (file, line,
2858 1.1.1.5 christos _("Unaligned operand. Needs to be 32bit aligned"));
2859 1.1 skrll
2860 1.1.1.5 christos if ((operand->flags & ARC_OPERAND_ALIGNED16)
2861 1.1.1.5 christos && (val & 0x01))
2862 1.1.1.5 christos as_bad_where (file, line,
2863 1.1.1.5 christos _("Unaligned operand. Needs to be 16bit aligned"));
2864 1.1 skrll
2865 1.1.1.5 christos if (operand->insert)
2866 1.1.1.5 christos {
2867 1.1.1.5 christos const char *errmsg = NULL;
2868 1.1 skrll
2869 1.1.1.5 christos insn = (*operand->insert) (insn, val, &errmsg);
2870 1.1.1.5 christos if (errmsg)
2871 1.1.1.5 christos as_warn_where (file, line, "%s", errmsg);
2872 1.1.1.5 christos }
2873 1.1.1.5 christos else
2874 1.1.1.5 christos {
2875 1.1.1.5 christos if (operand->flags & ARC_OPERAND_TRUNCATE)
2876 1.1.1.5 christos {
2877 1.1.1.5 christos if (operand->flags & ARC_OPERAND_ALIGNED32)
2878 1.1.1.5 christos val >>= 2;
2879 1.1.1.5 christos if (operand->flags & ARC_OPERAND_ALIGNED16)
2880 1.1.1.5 christos val >>= 1;
2881 1.1.1.5 christos }
2882 1.1.1.5 christos insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2883 1.1.1.5 christos }
2884 1.1.1.5 christos return insn;
2885 1.1.1.3 christos }
2886 1.1 skrll
2887 1.1.1.5 christos /* Apply a fixup to the object code. At this point all symbol values
2888 1.1.1.5 christos should be fully resolved, and we attempt to completely resolve the
2889 1.1.1.5 christos reloc. If we can not do that, we determine the correct reloc code
2890 1.1.1.5 christos and put it back in the fixup. To indicate that a fixup has been
2891 1.1.1.5 christos eliminated, set fixP->fx_done. */
2892 1.1 skrll
2893 1.1.1.5 christos void
2894 1.1.1.5 christos md_apply_fix (fixS *fixP,
2895 1.1.1.5 christos valueT *valP,
2896 1.1.1.5 christos segT seg)
2897 1.1.1.3 christos {
2898 1.1.1.5 christos char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
2899 1.1.1.5 christos valueT value = *valP;
2900 1.1.1.5 christos unsigned insn = 0;
2901 1.1.1.5 christos symbolS *fx_addsy, *fx_subsy;
2902 1.1.1.5 christos offsetT fx_offset;
2903 1.1.1.5 christos segT add_symbol_segment = absolute_section;
2904 1.1.1.5 christos segT sub_symbol_segment = absolute_section;
2905 1.1.1.5 christos const struct arc_operand *operand = NULL;
2906 1.1.1.5 christos extended_bfd_reloc_code_real_type reloc;
2907 1.1 skrll
2908 1.1.1.5 christos pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2909 1.1.1.5 christos fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
2910 1.1.1.5 christos ((int) fixP->fx_r_type < 0) ? "Internal":
2911 1.1.1.5 christos bfd_get_reloc_code_name (fixP->fx_r_type), value,
2912 1.1.1.5 christos fixP->fx_offset);
2913 1.1.1.3 christos
2914 1.1.1.5 christos fx_addsy = fixP->fx_addsy;
2915 1.1.1.5 christos fx_subsy = fixP->fx_subsy;
2916 1.1.1.5 christos fx_offset = 0;
2917 1.1.1.3 christos
2918 1.1.1.5 christos if (fx_addsy)
2919 1.1.1.5 christos {
2920 1.1.1.5 christos add_symbol_segment = S_GET_SEGMENT (fx_addsy);
2921 1.1.1.5 christos }
2922 1.1 skrll
2923 1.1.1.5 christos if (fx_subsy
2924 1.1.1.5 christos && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF
2925 1.1.1.5 christos && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF_S9
2926 1.1.1.5 christos && fixP->fx_r_type != BFD_RELOC_ARC_TLS_GD_LD)
2927 1.1.1.5 christos {
2928 1.1.1.5 christos resolve_symbol_value (fx_subsy);
2929 1.1.1.5 christos sub_symbol_segment = S_GET_SEGMENT (fx_subsy);
2930 1.1.1.3 christos
2931 1.1.1.5 christos if (sub_symbol_segment == absolute_section)
2932 1.1.1.5 christos {
2933 1.1.1.5 christos /* The symbol is really a constant. */
2934 1.1.1.5 christos fx_offset -= S_GET_VALUE (fx_subsy);
2935 1.1.1.5 christos fx_subsy = NULL;
2936 1.1.1.5 christos }
2937 1.1.1.5 christos else
2938 1.1.1.5 christos {
2939 1.1.1.8 christos as_bad_subtract (fixP);
2940 1.1.1.5 christos return;
2941 1.1.1.5 christos }
2942 1.1.1.5 christos }
2943 1.1.1.3 christos
2944 1.1.1.5 christos if (fx_addsy
2945 1.1.1.5 christos && !S_IS_WEAK (fx_addsy))
2946 1.1.1.3 christos {
2947 1.1.1.5 christos if (add_symbol_segment == seg
2948 1.1.1.5 christos && fixP->fx_pcrel)
2949 1.1.1.3 christos {
2950 1.1.1.5 christos value += S_GET_VALUE (fx_addsy);
2951 1.1.1.5 christos value -= md_pcrel_from_section (fixP, seg);
2952 1.1.1.5 christos fx_addsy = NULL;
2953 1.1.1.8 christos fixP->fx_pcrel = false;
2954 1.1.1.3 christos }
2955 1.1.1.5 christos else if (add_symbol_segment == absolute_section)
2956 1.1.1.5 christos {
2957 1.1.1.5 christos value = fixP->fx_offset;
2958 1.1.1.5 christos fx_offset += S_GET_VALUE (fixP->fx_addsy);
2959 1.1.1.5 christos fx_addsy = NULL;
2960 1.1.1.8 christos fixP->fx_pcrel = false;
2961 1.1.1.5 christos }
2962 1.1.1.5 christos }
2963 1.1 skrll
2964 1.1.1.5 christos if (!fx_addsy)
2965 1.1.1.8 christos fixP->fx_done = true;
2966 1.1.1.3 christos
2967 1.1.1.5 christos if (fixP->fx_pcrel)
2968 1.1.1.5 christos {
2969 1.1.1.5 christos if (fx_addsy
2970 1.1.1.5 christos && ((S_IS_DEFINED (fx_addsy)
2971 1.1.1.5 christos && S_GET_SEGMENT (fx_addsy) != seg)
2972 1.1.1.5 christos || S_IS_WEAK (fx_addsy)))
2973 1.1.1.5 christos value += md_pcrel_from_section (fixP, seg);
2974 1.1.1.3 christos
2975 1.1.1.5 christos switch (fixP->fx_r_type)
2976 1.1.1.5 christos {
2977 1.1.1.5 christos case BFD_RELOC_ARC_32_ME:
2978 1.1.1.5 christos /* This is a pc-relative value in a LIMM. Adjust it to the
2979 1.1.1.5 christos address of the instruction not to the address of the
2980 1.1.1.6 christos LIMM. Note: it is not any longer valid this affirmation as
2981 1.1.1.5 christos the linker consider ARC_PC32 a fixup to entire 64 bit
2982 1.1.1.5 christos insn. */
2983 1.1.1.5 christos fixP->fx_offset += fixP->fx_frag->fr_address;
2984 1.1.1.5 christos /* Fall through. */
2985 1.1.1.5 christos case BFD_RELOC_32:
2986 1.1.1.5 christos fixP->fx_r_type = BFD_RELOC_ARC_PC32;
2987 1.1.1.5 christos /* Fall through. */
2988 1.1.1.5 christos case BFD_RELOC_ARC_PC32:
2989 1.1.1.5 christos /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
2990 1.1.1.5 christos break;
2991 1.1.1.5 christos default:
2992 1.1.1.5 christos if ((int) fixP->fx_r_type < 0)
2993 1.1.1.6 christos as_bad_where (fixP->fx_file, fixP->fx_line,
2994 1.1.1.6 christos _("PC relative relocation not allowed for (internal)"
2995 1.1.1.6 christos " type %d"),
2996 1.1.1.6 christos fixP->fx_r_type);
2997 1.1.1.5 christos break;
2998 1.1.1.5 christos }
2999 1.1.1.3 christos }
3000 1.1.1.3 christos
3001 1.1.1.5 christos pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
3002 1.1.1.5 christos fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
3003 1.1.1.5 christos ((int) fixP->fx_r_type < 0) ? "Internal":
3004 1.1.1.5 christos bfd_get_reloc_code_name (fixP->fx_r_type), value,
3005 1.1.1.5 christos fixP->fx_offset);
3006 1.1.1.3 christos
3007 1.1.1.3 christos
3008 1.1.1.5 christos /* Now check for TLS relocations. */
3009 1.1.1.5 christos reloc = fixP->fx_r_type;
3010 1.1.1.5 christos switch (reloc)
3011 1.1.1.3 christos {
3012 1.1.1.5 christos case BFD_RELOC_ARC_TLS_DTPOFF:
3013 1.1.1.5 christos case BFD_RELOC_ARC_TLS_LE_32:
3014 1.1.1.5 christos if (fixP->fx_done)
3015 1.1.1.5 christos break;
3016 1.1.1.5 christos /* Fall through. */
3017 1.1.1.5 christos case BFD_RELOC_ARC_TLS_GD_GOT:
3018 1.1.1.5 christos case BFD_RELOC_ARC_TLS_IE_GOT:
3019 1.1.1.5 christos S_SET_THREAD_LOCAL (fixP->fx_addsy);
3020 1.1.1.5 christos break;
3021 1.1.1.3 christos
3022 1.1.1.5 christos case BFD_RELOC_ARC_TLS_GD_LD:
3023 1.1.1.5 christos gas_assert (!fixP->fx_offset);
3024 1.1.1.5 christos if (fixP->fx_subsy)
3025 1.1.1.5 christos fixP->fx_offset
3026 1.1.1.5 christos = (S_GET_VALUE (fixP->fx_subsy)
3027 1.1.1.5 christos - fixP->fx_frag->fr_address- fixP->fx_where);
3028 1.1.1.5 christos fixP->fx_subsy = NULL;
3029 1.1.1.5 christos /* Fall through. */
3030 1.1.1.5 christos case BFD_RELOC_ARC_TLS_GD_CALL:
3031 1.1.1.5 christos /* These two relocs are there just to allow ld to change the tls
3032 1.1.1.5 christos model for this symbol, by patching the code. The offset -
3033 1.1.1.5 christos and scale, if any - will be installed by the linker. */
3034 1.1.1.5 christos S_SET_THREAD_LOCAL (fixP->fx_addsy);
3035 1.1.1.5 christos break;
3036 1.1 skrll
3037 1.1.1.5 christos case BFD_RELOC_ARC_TLS_LE_S9:
3038 1.1.1.5 christos case BFD_RELOC_ARC_TLS_DTPOFF_S9:
3039 1.1.1.5 christos as_bad (_("TLS_*_S9 relocs are not supported yet"));
3040 1.1.1.5 christos break;
3041 1.1.1.3 christos
3042 1.1.1.5 christos default:
3043 1.1.1.5 christos break;
3044 1.1.1.5 christos }
3045 1.1.1.3 christos
3046 1.1.1.5 christos if (!fixP->fx_done)
3047 1.1.1.5 christos {
3048 1.1.1.5 christos return;
3049 1.1.1.5 christos }
3050 1.1.1.3 christos
3051 1.1.1.6 christos /* Adjust the value if we have a constant. */
3052 1.1.1.5 christos value += fx_offset;
3053 1.1.1.3 christos
3054 1.1.1.5 christos /* For hosts with longs bigger than 32-bits make sure that the top
3055 1.1.1.5 christos bits of a 32-bit negative value read in by the parser are set,
3056 1.1.1.5 christos so that the correct comparisons are made. */
3057 1.1.1.5 christos if (value & 0x80000000)
3058 1.1.1.5 christos value |= (-1UL << 31);
3059 1.1.1.3 christos
3060 1.1.1.5 christos reloc = fixP->fx_r_type;
3061 1.1.1.5 christos switch (reloc)
3062 1.1.1.3 christos {
3063 1.1.1.5 christos case BFD_RELOC_8:
3064 1.1.1.5 christos case BFD_RELOC_16:
3065 1.1.1.5 christos case BFD_RELOC_24:
3066 1.1.1.5 christos case BFD_RELOC_32:
3067 1.1.1.5 christos case BFD_RELOC_64:
3068 1.1.1.5 christos case BFD_RELOC_ARC_32_PCREL:
3069 1.1.1.5 christos md_number_to_chars (fixpos, value, fixP->fx_size);
3070 1.1.1.5 christos return;
3071 1.1.1.3 christos
3072 1.1.1.5 christos case BFD_RELOC_ARC_GOTPC32:
3073 1.1.1.5 christos /* I cannot fix an GOTPC relocation because I need to relax it
3074 1.1.1.5 christos from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
3075 1.1.1.5 christos as_bad (_("Unsupported operation on reloc"));
3076 1.1.1.5 christos return;
3077 1.1.1.3 christos
3078 1.1.1.5 christos case BFD_RELOC_ARC_TLS_DTPOFF:
3079 1.1.1.5 christos case BFD_RELOC_ARC_TLS_LE_32:
3080 1.1.1.5 christos gas_assert (!fixP->fx_addsy);
3081 1.1.1.5 christos gas_assert (!fixP->fx_subsy);
3082 1.1.1.6 christos /* Fall through. */
3083 1.1.1.3 christos
3084 1.1.1.5 christos case BFD_RELOC_ARC_GOTOFF:
3085 1.1.1.5 christos case BFD_RELOC_ARC_32_ME:
3086 1.1.1.5 christos case BFD_RELOC_ARC_PC32:
3087 1.1.1.5 christos md_number_to_chars_midend (fixpos, value, fixP->fx_size);
3088 1.1.1.5 christos return;
3089 1.1.1.3 christos
3090 1.1.1.5 christos case BFD_RELOC_ARC_PLT32:
3091 1.1.1.5 christos md_number_to_chars_midend (fixpos, value, fixP->fx_size);
3092 1.1.1.5 christos return;
3093 1.1.1.3 christos
3094 1.1.1.5 christos case BFD_RELOC_ARC_S25H_PCREL_PLT:
3095 1.1.1.5 christos reloc = BFD_RELOC_ARC_S25W_PCREL;
3096 1.1.1.5 christos goto solve_plt;
3097 1.1.1.3 christos
3098 1.1.1.5 christos case BFD_RELOC_ARC_S21H_PCREL_PLT:
3099 1.1.1.5 christos reloc = BFD_RELOC_ARC_S21H_PCREL;
3100 1.1.1.5 christos goto solve_plt;
3101 1.1.1.3 christos
3102 1.1.1.5 christos case BFD_RELOC_ARC_S25W_PCREL_PLT:
3103 1.1.1.5 christos reloc = BFD_RELOC_ARC_S25W_PCREL;
3104 1.1.1.5 christos goto solve_plt;
3105 1.1.1.3 christos
3106 1.1.1.5 christos case BFD_RELOC_ARC_S21W_PCREL_PLT:
3107 1.1.1.5 christos reloc = BFD_RELOC_ARC_S21W_PCREL;
3108 1.1.1.6 christos /* Fall through. */
3109 1.1.1.3 christos
3110 1.1.1.5 christos case BFD_RELOC_ARC_S25W_PCREL:
3111 1.1.1.5 christos case BFD_RELOC_ARC_S21W_PCREL:
3112 1.1.1.5 christos case BFD_RELOC_ARC_S21H_PCREL:
3113 1.1.1.5 christos case BFD_RELOC_ARC_S25H_PCREL:
3114 1.1.1.5 christos case BFD_RELOC_ARC_S13_PCREL:
3115 1.1.1.5 christos solve_plt:
3116 1.1.1.5 christos operand = find_operand_for_reloc (reloc);
3117 1.1.1.5 christos gas_assert (operand);
3118 1.1.1.5 christos break;
3119 1.1.1.3 christos
3120 1.1.1.5 christos default:
3121 1.1.1.5 christos {
3122 1.1.1.5 christos if ((int) fixP->fx_r_type >= 0)
3123 1.1.1.5 christos as_fatal (_("unhandled relocation type %s"),
3124 1.1.1.5 christos bfd_get_reloc_code_name (fixP->fx_r_type));
3125 1.1.1.3 christos
3126 1.1.1.5 christos /* The rest of these fixups needs to be completely resolved as
3127 1.1.1.5 christos constants. */
3128 1.1.1.5 christos if (fixP->fx_addsy != 0
3129 1.1.1.5 christos && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
3130 1.1.1.5 christos as_bad_where (fixP->fx_file, fixP->fx_line,
3131 1.1.1.5 christos _("non-absolute expression in constant field"));
3132 1.1.1.5 christos
3133 1.1.1.5 christos gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands);
3134 1.1.1.5 christos operand = &arc_operands[-(int) fixP->fx_r_type];
3135 1.1.1.5 christos break;
3136 1.1.1.5 christos }
3137 1.1.1.3 christos }
3138 1.1.1.3 christos
3139 1.1.1.5 christos if (target_big_endian)
3140 1.1.1.5 christos {
3141 1.1.1.5 christos switch (fixP->fx_size)
3142 1.1.1.5 christos {
3143 1.1.1.5 christos case 4:
3144 1.1.1.5 christos insn = bfd_getb32 (fixpos);
3145 1.1.1.5 christos break;
3146 1.1.1.5 christos case 2:
3147 1.1.1.5 christos insn = bfd_getb16 (fixpos);
3148 1.1.1.5 christos break;
3149 1.1.1.5 christos default:
3150 1.1.1.5 christos as_bad_where (fixP->fx_file, fixP->fx_line,
3151 1.1.1.5 christos _("unknown fixup size"));
3152 1.1.1.5 christos }
3153 1.1.1.5 christos }
3154 1.1.1.5 christos else
3155 1.1.1.5 christos {
3156 1.1.1.5 christos insn = 0;
3157 1.1.1.5 christos switch (fixP->fx_size)
3158 1.1.1.5 christos {
3159 1.1.1.5 christos case 4:
3160 1.1.1.5 christos insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2);
3161 1.1.1.5 christos break;
3162 1.1.1.5 christos case 2:
3163 1.1.1.5 christos insn = bfd_getl16 (fixpos);
3164 1.1.1.5 christos break;
3165 1.1.1.5 christos default:
3166 1.1.1.5 christos as_bad_where (fixP->fx_file, fixP->fx_line,
3167 1.1.1.5 christos _("unknown fixup size"));
3168 1.1.1.5 christos }
3169 1.1.1.5 christos }
3170 1.1.1.3 christos
3171 1.1.1.5 christos insn = insert_operand (insn, operand, (offsetT) value,
3172 1.1.1.5 christos fixP->fx_file, fixP->fx_line);
3173 1.1.1.3 christos
3174 1.1.1.5 christos md_number_to_chars_midend (fixpos, insn, fixP->fx_size);
3175 1.1.1.5 christos }
3176 1.1.1.3 christos
3177 1.1.1.5 christos /* Prepare machine-dependent frags for relaxation.
3178 1.1.1.3 christos
3179 1.1.1.5 christos Called just before relaxation starts. Any symbol that is now undefined
3180 1.1.1.5 christos will not become defined.
3181 1.1.1.3 christos
3182 1.1.1.5 christos Return the correct fr_subtype in the frag.
3183 1.1.1.3 christos
3184 1.1.1.5 christos Return the initial "guess for fr_var" to caller. The guess for fr_var
3185 1.1.1.5 christos is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
3186 1.1.1.5 christos or fr_var contributes to our returned value.
3187 1.1.1.3 christos
3188 1.1.1.5 christos Although it may not be explicit in the frag, pretend
3189 1.1.1.5 christos fr_var starts with a value. */
3190 1.1.1.3 christos
3191 1.1.1.5 christos int
3192 1.1.1.5 christos md_estimate_size_before_relax (fragS *fragP,
3193 1.1.1.5 christos segT segment)
3194 1.1.1.3 christos {
3195 1.1.1.5 christos int growth;
3196 1.1.1.5 christos
3197 1.1.1.5 christos /* If the symbol is not located within the same section AND it's not
3198 1.1.1.5 christos an absolute section, use the maximum. OR if the symbol is a
3199 1.1.1.5 christos constant AND the insn is by nature not pc-rel, use the maximum.
3200 1.1.1.5 christos OR if the symbol is being equated against another symbol, use the
3201 1.1.1.5 christos maximum. OR if the symbol is weak use the maximum. */
3202 1.1.1.5 christos if ((S_GET_SEGMENT (fragP->fr_symbol) != segment
3203 1.1.1.5 christos && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
3204 1.1.1.5 christos || (symbol_constant_p (fragP->fr_symbol)
3205 1.1.1.5 christos && !fragP->tc_frag_data.pcrel)
3206 1.1.1.5 christos || symbol_equated_p (fragP->fr_symbol)
3207 1.1.1.5 christos || S_IS_WEAK (fragP->fr_symbol))
3208 1.1.1.5 christos {
3209 1.1.1.5 christos while (md_relax_table[fragP->fr_subtype].rlx_more != ARC_RLX_NONE)
3210 1.1.1.5 christos ++fragP->fr_subtype;
3211 1.1.1.5 christos }
3212 1.1.1.3 christos
3213 1.1.1.5 christos growth = md_relax_table[fragP->fr_subtype].rlx_length;
3214 1.1.1.5 christos fragP->fr_var = growth;
3215 1.1.1.3 christos
3216 1.1.1.5 christos pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
3217 1.1.1.5 christos fragP->fr_file, fragP->fr_line, growth);
3218 1.1.1.3 christos
3219 1.1.1.5 christos return growth;
3220 1.1.1.3 christos }
3221 1.1.1.3 christos
3222 1.1.1.5 christos /* Translate internal representation of relocation info to BFD target
3223 1.1.1.5 christos format. */
3224 1.1.1.3 christos
3225 1.1.1.5 christos arelent *
3226 1.1.1.5 christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
3227 1.1.1.5 christos fixS *fixP)
3228 1.1.1.3 christos {
3229 1.1.1.5 christos arelent *reloc;
3230 1.1.1.5 christos bfd_reloc_code_real_type code;
3231 1.1.1.3 christos
3232 1.1.1.5 christos reloc = XNEW (arelent);
3233 1.1.1.5 christos reloc->sym_ptr_ptr = XNEW (asymbol *);
3234 1.1.1.5 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
3235 1.1.1.5 christos reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
3236 1.1.1.3 christos
3237 1.1.1.5 christos /* Make sure none of our internal relocations make it this far.
3238 1.1.1.5 christos They'd better have been fully resolved by this point. */
3239 1.1.1.5 christos gas_assert ((int) fixP->fx_r_type > 0);
3240 1.1.1.3 christos
3241 1.1.1.5 christos code = fixP->fx_r_type;
3242 1.1.1.3 christos
3243 1.1.1.5 christos /* if we have something like add gp, pcl,
3244 1.1.1.5 christos _GLOBAL_OFFSET_TABLE_@gotpc. */
3245 1.1.1.5 christos if (code == BFD_RELOC_ARC_GOTPC32
3246 1.1.1.5 christos && GOT_symbol
3247 1.1.1.5 christos && fixP->fx_addsy == GOT_symbol)
3248 1.1.1.5 christos code = BFD_RELOC_ARC_GOTPC;
3249 1.1.1.3 christos
3250 1.1.1.5 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
3251 1.1.1.5 christos if (reloc->howto == NULL)
3252 1.1.1.5 christos {
3253 1.1.1.5 christos as_bad_where (fixP->fx_file, fixP->fx_line,
3254 1.1.1.5 christos _("cannot represent `%s' relocation in object file"),
3255 1.1.1.5 christos bfd_get_reloc_code_name (code));
3256 1.1.1.5 christos return NULL;
3257 1.1.1.5 christos }
3258 1.1.1.3 christos
3259 1.1.1.5 christos if (!fixP->fx_pcrel != !reloc->howto->pc_relative)
3260 1.1.1.5 christos as_fatal (_("internal error? cannot generate `%s' relocation"),
3261 1.1.1.5 christos bfd_get_reloc_code_name (code));
3262 1.1.1.5 christos
3263 1.1.1.5 christos gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
3264 1.1.1.5 christos
3265 1.1.1.6 christos reloc->addend = fixP->fx_offset;
3266 1.1.1.5 christos
3267 1.1.1.5 christos return reloc;
3268 1.1.1.3 christos }
3269 1.1.1.3 christos
3270 1.1.1.5 christos /* Perform post-processing of machine-dependent frags after relaxation.
3271 1.1.1.5 christos Called after relaxation is finished.
3272 1.1.1.5 christos In: Address of frag.
3273 1.1.1.5 christos fr_type == rs_machine_dependent.
3274 1.1.1.5 christos fr_subtype is what the address relaxed to.
3275 1.1.1.3 christos
3276 1.1.1.5 christos Out: Any fixS:s and constants are set up. */
3277 1.1.1.5 christos
3278 1.1.1.5 christos void
3279 1.1.1.5 christos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
3280 1.1.1.5 christos segT segment ATTRIBUTE_UNUSED,
3281 1.1.1.5 christos fragS *fragP)
3282 1.1.1.3 christos {
3283 1.1.1.5 christos const relax_typeS *table_entry;
3284 1.1.1.5 christos char *dest;
3285 1.1.1.5 christos const struct arc_opcode *opcode;
3286 1.1.1.5 christos struct arc_insn insn;
3287 1.1.1.5 christos int size, fix;
3288 1.1.1.5 christos struct arc_relax_type *relax_arg = &fragP->tc_frag_data;
3289 1.1.1.5 christos
3290 1.1.1.7 christos fix = fragP->fr_fix;
3291 1.1.1.5 christos dest = fragP->fr_literal + fix;
3292 1.1.1.5 christos table_entry = TC_GENERIC_RELAX_TABLE + fragP->fr_subtype;
3293 1.1.1.3 christos
3294 1.1.1.5 christos pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, "
3295 1.1.1.5 christos "var: %"BFD_VMA_FMT"d\n",
3296 1.1.1.5 christos fragP->fr_file, fragP->fr_line,
3297 1.1.1.5 christos fragP->fr_subtype, fix, fragP->fr_var);
3298 1.1.1.3 christos
3299 1.1.1.5 christos if (fragP->fr_subtype <= 0
3300 1.1.1.5 christos && fragP->fr_subtype >= arc_num_relax_opcodes)
3301 1.1.1.5 christos as_fatal (_("no relaxation found for this instruction."));
3302 1.1.1.3 christos
3303 1.1.1.5 christos opcode = &arc_relax_opcodes[fragP->fr_subtype];
3304 1.1.1.3 christos
3305 1.1.1.5 christos assemble_insn (opcode, relax_arg->tok, relax_arg->ntok, relax_arg->pflags,
3306 1.1.1.5 christos relax_arg->nflg, &insn);
3307 1.1.1.3 christos
3308 1.1.1.5 christos apply_fixups (&insn, fragP, fix);
3309 1.1.1.3 christos
3310 1.1.1.6 christos size = insn.len + (insn.has_limm ? 4 : 0);
3311 1.1.1.5 christos gas_assert (table_entry->rlx_length == size);
3312 1.1.1.8 christos emit_insn0 (&insn, dest, true);
3313 1.1.1.3 christos
3314 1.1.1.5 christos fragP->fr_fix += table_entry->rlx_length;
3315 1.1.1.5 christos fragP->fr_var = 0;
3316 1.1.1.5 christos }
3317 1.1.1.5 christos
3318 1.1.1.5 christos /* We have no need to default values of symbols. We could catch
3319 1.1.1.5 christos register names here, but that is handled by inserting them all in
3320 1.1.1.5 christos the symbol table to begin with. */
3321 1.1.1.5 christos
3322 1.1.1.5 christos symbolS *
3323 1.1.1.5 christos md_undefined_symbol (char *name)
3324 1.1.1.5 christos {
3325 1.1.1.5 christos /* The arc abi demands that a GOT[0] should be referencible as
3326 1.1.1.5 christos [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
3327 1.1.1.5 christos GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
3328 1.1.1.5 christos if (((*name == '_')
3329 1.1.1.5 christos && (*(name+1) == 'G')
3330 1.1.1.6 christos && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0)))
3331 1.1.1.5 christos {
3332 1.1.1.5 christos if (!GOT_symbol)
3333 1.1.1.3 christos {
3334 1.1.1.5 christos if (symbol_find (name))
3335 1.1.1.5 christos as_bad ("GOT already in symbol table");
3336 1.1.1.3 christos
3337 1.1.1.5 christos GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section,
3338 1.1.1.8 christos &zero_address_frag, 0);
3339 1.1.1.5 christos };
3340 1.1.1.5 christos return GOT_symbol;
3341 1.1.1.5 christos }
3342 1.1.1.5 christos return NULL;
3343 1.1.1.5 christos }
3344 1.1.1.3 christos
3345 1.1.1.5 christos /* Turn a string in input_line_pointer into a floating point constant
3346 1.1.1.5 christos of type type, and store the appropriate bytes in *litP. The number
3347 1.1.1.5 christos of LITTLENUMS emitted is stored in *sizeP. An error message is
3348 1.1.1.5 christos returned, or NULL on OK. */
3349 1.1.1.3 christos
3350 1.1.1.5 christos const char *
3351 1.1.1.5 christos md_atof (int type, char *litP, int *sizeP)
3352 1.1.1.5 christos {
3353 1.1.1.5 christos return ieee_md_atof (type, litP, sizeP, target_big_endian);
3354 1.1.1.5 christos }
3355 1.1.1.3 christos
3356 1.1.1.5 christos /* Called for any expression that can not be recognized. When the
3357 1.1.1.5 christos function is called, `input_line_pointer' will point to the start of
3358 1.1.1.7 christos the expression. We use it when we have complex operations like
3359 1.1.1.7 christos @label1 - @label2. */
3360 1.1.1.3 christos
3361 1.1.1.5 christos void
3362 1.1.1.7 christos md_operand (expressionS *expressionP)
3363 1.1.1.5 christos {
3364 1.1.1.5 christos char *p = input_line_pointer;
3365 1.1.1.5 christos if (*p == '@')
3366 1.1.1.5 christos {
3367 1.1.1.5 christos input_line_pointer++;
3368 1.1.1.5 christos expressionP->X_op = O_symbol;
3369 1.1.1.7 christos expressionP->X_md = O_absent;
3370 1.1.1.5 christos expression (expressionP);
3371 1.1.1.5 christos }
3372 1.1.1.5 christos }
3373 1.1.1.3 christos
3374 1.1.1.5 christos /* This function is called from the function 'expression', it attempts
3375 1.1.1.5 christos to parse special names (in our case register names). It fills in
3376 1.1.1.5 christos the expression with the identified register. It returns TRUE if
3377 1.1.1.5 christos it is a register and FALSE otherwise. */
3378 1.1.1.5 christos
3379 1.1.1.8 christos bool
3380 1.1.1.5 christos arc_parse_name (const char *name,
3381 1.1.1.5 christos struct expressionS *e)
3382 1.1.1.5 christos {
3383 1.1.1.5 christos struct symbol *sym;
3384 1.1.1.5 christos
3385 1.1.1.5 christos if (!assembling_insn)
3386 1.1.1.8 christos return false;
3387 1.1.1.3 christos
3388 1.1.1.7 christos if (e->X_op == O_symbol
3389 1.1.1.7 christos && e->X_md == O_absent)
3390 1.1.1.8 christos return false;
3391 1.1.1.3 christos
3392 1.1.1.8 christos sym = str_hash_find (arc_reg_hash, name);
3393 1.1.1.5 christos if (sym)
3394 1.1.1.5 christos {
3395 1.1.1.5 christos e->X_op = O_register;
3396 1.1.1.5 christos e->X_add_number = S_GET_VALUE (sym);
3397 1.1.1.8 christos return true;
3398 1.1.1.5 christos }
3399 1.1.1.6 christos
3400 1.1.1.8 christos sym = str_hash_find (arc_addrtype_hash, name);
3401 1.1.1.6 christos if (sym)
3402 1.1.1.6 christos {
3403 1.1.1.6 christos e->X_op = O_addrtype;
3404 1.1.1.6 christos e->X_add_number = S_GET_VALUE (sym);
3405 1.1.1.8 christos return true;
3406 1.1.1.6 christos }
3407 1.1.1.6 christos
3408 1.1.1.8 christos return false;
3409 1.1.1.5 christos }
3410 1.1.1.3 christos
3411 1.1.1.5 christos /* md_parse_option
3412 1.1.1.5 christos Invocation line includes a switch not recognized by the base assembler.
3413 1.1.1.5 christos See if it's a processor-specific option.
3414 1.1.1.3 christos
3415 1.1.1.5 christos New options (supported) are:
3416 1.1.1.3 christos
3417 1.1.1.5 christos -mcpu=<cpu name> Assemble for selected processor
3418 1.1.1.5 christos -EB/-mbig-endian Big-endian
3419 1.1.1.5 christos -EL/-mlittle-endian Little-endian
3420 1.1.1.5 christos -mrelax Enable relaxation
3421 1.1.1.3 christos
3422 1.1.1.5 christos The following CPU names are recognized:
3423 1.1.1.5 christos arc600, arc700, arcem, archs, nps400. */
3424 1.1.1.3 christos
3425 1.1.1.5 christos int
3426 1.1.1.5 christos md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
3427 1.1.1.5 christos {
3428 1.1.1.5 christos switch (c)
3429 1.1.1.5 christos {
3430 1.1.1.5 christos case OPTION_ARC600:
3431 1.1.1.5 christos case OPTION_ARC601:
3432 1.1.1.5 christos return md_parse_option (OPTION_MCPU, "arc600");
3433 1.1.1.3 christos
3434 1.1.1.5 christos case OPTION_ARC700:
3435 1.1.1.5 christos return md_parse_option (OPTION_MCPU, "arc700");
3436 1.1.1.3 christos
3437 1.1.1.5 christos case OPTION_ARCEM:
3438 1.1.1.5 christos return md_parse_option (OPTION_MCPU, "arcem");
3439 1.1.1.3 christos
3440 1.1.1.5 christos case OPTION_ARCHS:
3441 1.1.1.5 christos return md_parse_option (OPTION_MCPU, "archs");
3442 1.1.1.3 christos
3443 1.1.1.5 christos case OPTION_MCPU:
3444 1.1.1.5 christos {
3445 1.1.1.6 christos arc_select_cpu (arg, MACH_SELECTION_FROM_COMMAND_LINE);
3446 1.1.1.5 christos break;
3447 1.1.1.5 christos }
3448 1.1.1.3 christos
3449 1.1.1.5 christos case OPTION_EB:
3450 1.1.1.5 christos arc_target_format = "elf32-bigarc";
3451 1.1.1.5 christos byte_order = BIG_ENDIAN;
3452 1.1.1.5 christos break;
3453 1.1.1.3 christos
3454 1.1.1.5 christos case OPTION_EL:
3455 1.1.1.5 christos arc_target_format = "elf32-littlearc";
3456 1.1.1.5 christos byte_order = LITTLE_ENDIAN;
3457 1.1.1.5 christos break;
3458 1.1.1.3 christos
3459 1.1.1.5 christos case OPTION_CD:
3460 1.1.1.6 christos selected_cpu.features |= CD;
3461 1.1.1.6 christos cl_features |= CD;
3462 1.1.1.6 christos arc_check_feature ();
3463 1.1.1.5 christos break;
3464 1.1.1.3 christos
3465 1.1.1.5 christos case OPTION_RELAX:
3466 1.1.1.5 christos relaxation_state = 1;
3467 1.1.1.5 christos break;
3468 1.1.1.3 christos
3469 1.1.1.5 christos case OPTION_NPS400:
3470 1.1.1.6 christos selected_cpu.features |= NPS400;
3471 1.1.1.6 christos cl_features |= NPS400;
3472 1.1.1.6 christos arc_check_feature ();
3473 1.1.1.5 christos break;
3474 1.1.1.3 christos
3475 1.1.1.5 christos case OPTION_SPFP:
3476 1.1.1.6 christos selected_cpu.features |= SPX;
3477 1.1.1.6 christos cl_features |= SPX;
3478 1.1.1.6 christos arc_check_feature ();
3479 1.1.1.5 christos break;
3480 1.1.1.3 christos
3481 1.1.1.5 christos case OPTION_DPFP:
3482 1.1.1.6 christos selected_cpu.features |= DPX;
3483 1.1.1.6 christos cl_features |= DPX;
3484 1.1.1.6 christos arc_check_feature ();
3485 1.1.1.5 christos break;
3486 1.1.1.3 christos
3487 1.1.1.5 christos case OPTION_FPUDA:
3488 1.1.1.6 christos selected_cpu.features |= DPA;
3489 1.1.1.6 christos cl_features |= DPA;
3490 1.1.1.6 christos arc_check_feature ();
3491 1.1.1.5 christos break;
3492 1.1.1.3 christos
3493 1.1.1.5 christos /* Dummy options are accepted but have no effect. */
3494 1.1.1.5 christos case OPTION_USER_MODE:
3495 1.1.1.5 christos case OPTION_LD_EXT_MASK:
3496 1.1.1.5 christos case OPTION_SWAP:
3497 1.1.1.5 christos case OPTION_NORM:
3498 1.1.1.5 christos case OPTION_BARREL_SHIFT:
3499 1.1.1.5 christos case OPTION_MIN_MAX:
3500 1.1.1.5 christos case OPTION_NO_MPY:
3501 1.1.1.5 christos case OPTION_EA:
3502 1.1.1.5 christos case OPTION_MUL64:
3503 1.1.1.5 christos case OPTION_SIMD:
3504 1.1.1.5 christos case OPTION_XMAC_D16:
3505 1.1.1.5 christos case OPTION_XMAC_24:
3506 1.1.1.5 christos case OPTION_DSP_PACKA:
3507 1.1.1.5 christos case OPTION_CRC:
3508 1.1.1.5 christos case OPTION_DVBF:
3509 1.1.1.5 christos case OPTION_TELEPHONY:
3510 1.1.1.5 christos case OPTION_XYMEMORY:
3511 1.1.1.5 christos case OPTION_LOCK:
3512 1.1.1.5 christos case OPTION_SWAPE:
3513 1.1.1.5 christos case OPTION_RTSC:
3514 1.1.1.5 christos break;
3515 1.1.1.3 christos
3516 1.1.1.5 christos default:
3517 1.1.1.5 christos return 0;
3518 1.1.1.3 christos }
3519 1.1.1.3 christos
3520 1.1.1.5 christos return 1;
3521 1.1.1.5 christos }
3522 1.1.1.5 christos
3523 1.1.1.6 christos /* Display the list of cpu names for use in the help text. */
3524 1.1.1.6 christos
3525 1.1.1.6 christos static void
3526 1.1.1.6 christos arc_show_cpu_list (FILE *stream)
3527 1.1.1.6 christos {
3528 1.1.1.6 christos int i, offset;
3529 1.1.1.6 christos static const char *space_buf = " ";
3530 1.1.1.6 christos
3531 1.1.1.6 christos fprintf (stream, "%s", space_buf);
3532 1.1.1.6 christos offset = strlen (space_buf);
3533 1.1.1.6 christos for (i = 0; cpu_types[i].name != NULL; ++i)
3534 1.1.1.6 christos {
3535 1.1.1.8 christos bool last = (cpu_types[i + 1].name == NULL);
3536 1.1.1.6 christos
3537 1.1.1.6 christos /* If displaying the new cpu name string, and the ', ' (for all
3538 1.1.1.6 christos but the last one) will take us past a target width of 80
3539 1.1.1.6 christos characters, then it's time for a new line. */
3540 1.1.1.6 christos if (offset + strlen (cpu_types[i].name) + (last ? 0 : 2) > 80)
3541 1.1.1.6 christos {
3542 1.1.1.6 christos fprintf (stream, "\n%s", space_buf);
3543 1.1.1.6 christos offset = strlen (space_buf);
3544 1.1.1.6 christos }
3545 1.1.1.6 christos
3546 1.1.1.6 christos fprintf (stream, "%s%s", cpu_types[i].name, (last ? "\n" : ", "));
3547 1.1.1.6 christos offset += strlen (cpu_types [i].name) + (last ? 0 : 2);
3548 1.1.1.6 christos }
3549 1.1.1.6 christos }
3550 1.1.1.6 christos
3551 1.1.1.5 christos void
3552 1.1.1.5 christos md_show_usage (FILE *stream)
3553 1.1.1.5 christos {
3554 1.1.1.5 christos fprintf (stream, _("ARC-specific assembler options:\n"));
3555 1.1.1.5 christos
3556 1.1.1.6 christos fprintf (stream, " -mcpu=<cpu name>\t (default: %s), assemble for"
3557 1.1.1.6 christos " CPU <cpu name>, one of:\n", TARGET_WITH_CPU);
3558 1.1.1.6 christos arc_show_cpu_list (stream);
3559 1.1.1.6 christos fprintf (stream, "\n");
3560 1.1.1.5 christos fprintf (stream, " -mA6/-mARC600/-mARC601 same as -mcpu=arc600\n");
3561 1.1.1.5 christos fprintf (stream, " -mA7/-mARC700\t\t same as -mcpu=arc700\n");
3562 1.1.1.5 christos fprintf (stream, " -mEM\t\t\t same as -mcpu=arcem\n");
3563 1.1.1.5 christos fprintf (stream, " -mHS\t\t\t same as -mcpu=archs\n");
3564 1.1.1.5 christos
3565 1.1.1.5 christos fprintf (stream, " -mnps400\t\t enable NPS-400 extended instructions\n");
3566 1.1.1.6 christos fprintf (stream, " -mspfp\t\t enable single-precision floating point"
3567 1.1.1.6 christos " instructions\n");
3568 1.1.1.6 christos fprintf (stream, " -mdpfp\t\t enable double-precision floating point"
3569 1.1.1.6 christos " instructions\n");
3570 1.1.1.5 christos fprintf (stream, " -mfpuda\t\t enable double-precision assist floating "
3571 1.1.1.5 christos "point\n\t\t\t instructions for ARC EM\n");
3572 1.1.1.5 christos
3573 1.1.1.5 christos fprintf (stream,
3574 1.1.1.5 christos " -mcode-density\t enable code density option for ARC EM\n");
3575 1.1.1.5 christos
3576 1.1.1.5 christos fprintf (stream, _("\
3577 1.1.1.5 christos -EB assemble code for a big-endian cpu\n"));
3578 1.1.1.5 christos fprintf (stream, _("\
3579 1.1.1.5 christos -EL assemble code for a little-endian cpu\n"));
3580 1.1.1.5 christos fprintf (stream, _("\
3581 1.1.1.5 christos -mrelax enable relaxation\n"));
3582 1.1.1.5 christos
3583 1.1.1.5 christos fprintf (stream, _("The following ARC-specific assembler options are "
3584 1.1.1.5 christos "deprecated and are accepted\nfor compatibility only:\n"));
3585 1.1.1.3 christos
3586 1.1.1.5 christos fprintf (stream, _(" -mEA\n"
3587 1.1.1.5 christos " -mbarrel-shifter\n"
3588 1.1.1.5 christos " -mbarrel_shifter\n"
3589 1.1.1.5 christos " -mcrc\n"
3590 1.1.1.5 christos " -mdsp-packa\n"
3591 1.1.1.5 christos " -mdsp_packa\n"
3592 1.1.1.5 christos " -mdvbf\n"
3593 1.1.1.5 christos " -mld-extension-reg-mask\n"
3594 1.1.1.5 christos " -mlock\n"
3595 1.1.1.5 christos " -mmac-24\n"
3596 1.1.1.5 christos " -mmac-d16\n"
3597 1.1.1.5 christos " -mmac_24\n"
3598 1.1.1.5 christos " -mmac_d16\n"
3599 1.1.1.5 christos " -mmin-max\n"
3600 1.1.1.5 christos " -mmin_max\n"
3601 1.1.1.5 christos " -mmul64\n"
3602 1.1.1.5 christos " -mno-mpy\n"
3603 1.1.1.5 christos " -mnorm\n"
3604 1.1.1.5 christos " -mrtsc\n"
3605 1.1.1.5 christos " -msimd\n"
3606 1.1.1.5 christos " -mswap\n"
3607 1.1.1.5 christos " -mswape\n"
3608 1.1.1.5 christos " -mtelephony\n"
3609 1.1.1.5 christos " -muser-mode-only\n"
3610 1.1.1.5 christos " -mxy\n"));
3611 1.1.1.3 christos }
3612 1.1.1.3 christos
3613 1.1.1.3 christos /* Find the proper relocation for the given opcode. */
3614 1.1.1.3 christos
3615 1.1.1.3 christos static extended_bfd_reloc_code_real_type
3616 1.1.1.3 christos find_reloc (const char *name,
3617 1.1.1.3 christos const char *opcodename,
3618 1.1.1.3 christos const struct arc_flags *pflags,
3619 1.1.1.3 christos int nflg,
3620 1.1.1.3 christos extended_bfd_reloc_code_real_type reloc)
3621 1.1.1.3 christos {
3622 1.1.1.3 christos unsigned int i;
3623 1.1.1.3 christos int j;
3624 1.1.1.8 christos bool found_flag, tmp;
3625 1.1.1.3 christos extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED;
3626 1.1.1.3 christos
3627 1.1.1.3 christos for (i = 0; i < arc_num_equiv_tab; i++)
3628 1.1.1.3 christos {
3629 1.1.1.3 christos const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i];
3630 1.1.1.3 christos
3631 1.1.1.3 christos /* Find the entry. */
3632 1.1.1.3 christos if (strcmp (name, r->name))
3633 1.1.1.3 christos continue;
3634 1.1.1.3 christos if (r->mnemonic && (strcmp (r->mnemonic, opcodename)))
3635 1.1.1.3 christos continue;
3636 1.1.1.5 christos if (r->flags[0])
3637 1.1.1.3 christos {
3638 1.1.1.3 christos if (!nflg)
3639 1.1.1.3 christos continue;
3640 1.1.1.8 christos found_flag = false;
3641 1.1.1.5 christos unsigned * psflg = (unsigned *)r->flags;
3642 1.1.1.5 christos do
3643 1.1.1.5 christos {
3644 1.1.1.8 christos tmp = false;
3645 1.1.1.5 christos for (j = 0; j < nflg; j++)
3646 1.1.1.5 christos if (!strcmp (pflags[j].name,
3647 1.1.1.5 christos arc_flag_operands[*psflg].name))
3648 1.1.1.5 christos {
3649 1.1.1.8 christos tmp = true;
3650 1.1.1.5 christos break;
3651 1.1.1.5 christos }
3652 1.1.1.5 christos if (!tmp)
3653 1.1.1.5 christos {
3654 1.1.1.8 christos found_flag = false;
3655 1.1.1.5 christos break;
3656 1.1.1.5 christos }
3657 1.1.1.5 christos else
3658 1.1.1.5 christos {
3659 1.1.1.8 christos found_flag = true;
3660 1.1.1.5 christos }
3661 1.1.1.5 christos ++ psflg;
3662 1.1.1.5 christos } while (*psflg);
3663 1.1.1.5 christos
3664 1.1.1.3 christos if (!found_flag)
3665 1.1.1.3 christos continue;
3666 1.1.1.3 christos }
3667 1.1.1.3 christos
3668 1.1.1.3 christos if (reloc != r->oldreloc)
3669 1.1.1.3 christos continue;
3670 1.1.1.3 christos /* Found it. */
3671 1.1.1.3 christos ret = r->newreloc;
3672 1.1.1.3 christos break;
3673 1.1.1.3 christos }
3674 1.1.1.3 christos
3675 1.1.1.3 christos if (ret == BFD_RELOC_UNUSED)
3676 1.1.1.3 christos as_bad (_("Unable to find %s relocation for instruction %s"),
3677 1.1.1.3 christos name, opcodename);
3678 1.1.1.3 christos return ret;
3679 1.1.1.3 christos }
3680 1.1.1.3 christos
3681 1.1.1.5 christos /* All the symbol types that are allowed to be used for
3682 1.1.1.5 christos relaxation. */
3683 1.1.1.5 christos
3684 1.1.1.8 christos static bool
3685 1.1.1.5 christos may_relax_expr (expressionS tok)
3686 1.1.1.5 christos {
3687 1.1.1.5 christos /* Check if we have unrelaxable relocs. */
3688 1.1.1.5 christos switch (tok.X_md)
3689 1.1.1.5 christos {
3690 1.1.1.5 christos default:
3691 1.1.1.5 christos break;
3692 1.1.1.5 christos case O_plt:
3693 1.1.1.8 christos return false;
3694 1.1.1.5 christos }
3695 1.1.1.5 christos
3696 1.1.1.5 christos switch (tok.X_op)
3697 1.1.1.5 christos {
3698 1.1.1.5 christos case O_symbol:
3699 1.1.1.5 christos case O_multiply:
3700 1.1.1.5 christos case O_divide:
3701 1.1.1.5 christos case O_modulus:
3702 1.1.1.5 christos case O_add:
3703 1.1.1.5 christos case O_subtract:
3704 1.1.1.5 christos break;
3705 1.1.1.5 christos
3706 1.1.1.5 christos default:
3707 1.1.1.8 christos return false;
3708 1.1.1.5 christos }
3709 1.1.1.8 christos return true;
3710 1.1.1.5 christos }
3711 1.1.1.5 christos
3712 1.1.1.5 christos /* Checks if flags are in line with relaxable insn. */
3713 1.1.1.5 christos
3714 1.1.1.8 christos static bool
3715 1.1.1.5 christos relaxable_flag (const struct arc_relaxable_ins *ins,
3716 1.1.1.5 christos const struct arc_flags *pflags,
3717 1.1.1.5 christos int nflgs)
3718 1.1.1.5 christos {
3719 1.1.1.5 christos unsigned flag_class,
3720 1.1.1.5 christos flag,
3721 1.1.1.5 christos flag_class_idx = 0,
3722 1.1.1.5 christos flag_idx = 0;
3723 1.1.1.5 christos
3724 1.1.1.5 christos const struct arc_flag_operand *flag_opand;
3725 1.1.1.5 christos int i, counttrue = 0;
3726 1.1.1.5 christos
3727 1.1.1.5 christos /* Iterate through flags classes. */
3728 1.1.1.5 christos while ((flag_class = ins->flag_classes[flag_class_idx]) != 0)
3729 1.1.1.5 christos {
3730 1.1.1.5 christos /* Iterate through flags in flag class. */
3731 1.1.1.5 christos while ((flag = arc_flag_classes[flag_class].flags[flag_idx])
3732 1.1.1.5 christos != 0)
3733 1.1.1.5 christos {
3734 1.1.1.5 christos flag_opand = &arc_flag_operands[flag];
3735 1.1.1.5 christos /* Iterate through flags in ins to compare. */
3736 1.1.1.5 christos for (i = 0; i < nflgs; ++i)
3737 1.1.1.5 christos {
3738 1.1.1.5 christos if (strcmp (flag_opand->name, pflags[i].name) == 0)
3739 1.1.1.5 christos ++counttrue;
3740 1.1.1.5 christos }
3741 1.1.1.5 christos
3742 1.1.1.5 christos ++flag_idx;
3743 1.1.1.5 christos }
3744 1.1.1.5 christos
3745 1.1.1.5 christos ++flag_class_idx;
3746 1.1.1.5 christos flag_idx = 0;
3747 1.1.1.5 christos }
3748 1.1.1.5 christos
3749 1.1.1.5 christos /* If counttrue == nflgs, then all flags have been found. */
3750 1.1.1.8 christos return counttrue == nflgs;
3751 1.1.1.5 christos }
3752 1.1.1.5 christos
3753 1.1.1.5 christos /* Checks if operands are in line with relaxable insn. */
3754 1.1.1.5 christos
3755 1.1.1.8 christos static bool
3756 1.1.1.5 christos relaxable_operand (const struct arc_relaxable_ins *ins,
3757 1.1.1.5 christos const expressionS *tok,
3758 1.1.1.5 christos int ntok)
3759 1.1.1.5 christos {
3760 1.1.1.5 christos const enum rlx_operand_type *operand = &ins->operands[0];
3761 1.1.1.5 christos int i = 0;
3762 1.1.1.5 christos
3763 1.1.1.5 christos while (*operand != EMPTY)
3764 1.1.1.5 christos {
3765 1.1.1.5 christos const expressionS *epr = &tok[i];
3766 1.1.1.5 christos
3767 1.1.1.5 christos if (i != 0 && i >= ntok)
3768 1.1.1.8 christos return false;
3769 1.1.1.5 christos
3770 1.1.1.5 christos switch (*operand)
3771 1.1.1.5 christos {
3772 1.1.1.5 christos case IMMEDIATE:
3773 1.1.1.5 christos if (!(epr->X_op == O_multiply
3774 1.1.1.5 christos || epr->X_op == O_divide
3775 1.1.1.5 christos || epr->X_op == O_modulus
3776 1.1.1.5 christos || epr->X_op == O_add
3777 1.1.1.5 christos || epr->X_op == O_subtract
3778 1.1.1.5 christos || epr->X_op == O_symbol))
3779 1.1.1.8 christos return false;
3780 1.1.1.5 christos break;
3781 1.1.1.5 christos
3782 1.1.1.5 christos case REGISTER_DUP:
3783 1.1.1.5 christos if ((i <= 0)
3784 1.1.1.5 christos || (epr->X_add_number != tok[i - 1].X_add_number))
3785 1.1.1.8 christos return false;
3786 1.1.1.5 christos /* Fall through. */
3787 1.1.1.5 christos case REGISTER:
3788 1.1.1.5 christos if (epr->X_op != O_register)
3789 1.1.1.8 christos return false;
3790 1.1.1.5 christos break;
3791 1.1.1.5 christos
3792 1.1.1.5 christos case REGISTER_S:
3793 1.1.1.5 christos if (epr->X_op != O_register)
3794 1.1.1.8 christos return false;
3795 1.1.1.5 christos
3796 1.1.1.5 christos switch (epr->X_add_number)
3797 1.1.1.5 christos {
3798 1.1.1.5 christos case 0: case 1: case 2: case 3:
3799 1.1.1.5 christos case 12: case 13: case 14: case 15:
3800 1.1.1.5 christos break;
3801 1.1.1.5 christos default:
3802 1.1.1.8 christos return false;
3803 1.1.1.5 christos }
3804 1.1.1.5 christos break;
3805 1.1.1.5 christos
3806 1.1.1.5 christos case REGISTER_NO_GP:
3807 1.1.1.5 christos if ((epr->X_op != O_register)
3808 1.1.1.5 christos || (epr->X_add_number == 26)) /* 26 is the gp register. */
3809 1.1.1.8 christos return false;
3810 1.1.1.5 christos break;
3811 1.1.1.5 christos
3812 1.1.1.5 christos case BRACKET:
3813 1.1.1.5 christos if (epr->X_op != O_bracket)
3814 1.1.1.8 christos return false;
3815 1.1.1.5 christos break;
3816 1.1.1.5 christos
3817 1.1.1.5 christos default:
3818 1.1.1.5 christos /* Don't understand, bail out. */
3819 1.1.1.8 christos return false;
3820 1.1.1.5 christos break;
3821 1.1.1.5 christos }
3822 1.1.1.5 christos
3823 1.1.1.5 christos ++i;
3824 1.1.1.5 christos operand = &ins->operands[i];
3825 1.1.1.5 christos }
3826 1.1.1.5 christos
3827 1.1.1.8 christos return i == ntok;
3828 1.1.1.5 christos }
3829 1.1.1.5 christos
3830 1.1.1.5 christos /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3831 1.1.1.5 christos
3832 1.1.1.8 christos static bool
3833 1.1.1.5 christos relax_insn_p (const struct arc_opcode *opcode,
3834 1.1.1.5 christos const expressionS *tok,
3835 1.1.1.5 christos int ntok,
3836 1.1.1.5 christos const struct arc_flags *pflags,
3837 1.1.1.5 christos int nflg)
3838 1.1.1.5 christos {
3839 1.1.1.5 christos unsigned i;
3840 1.1.1.8 christos bool rv = false;
3841 1.1.1.5 christos
3842 1.1.1.5 christos /* Check the relaxation table. */
3843 1.1.1.5 christos for (i = 0; i < arc_num_relaxable_ins && relaxation_state; ++i)
3844 1.1.1.5 christos {
3845 1.1.1.5 christos const struct arc_relaxable_ins *arc_rlx_ins = &arc_relaxable_insns[i];
3846 1.1.1.5 christos
3847 1.1.1.5 christos if ((strcmp (opcode->name, arc_rlx_ins->mnemonic_r) == 0)
3848 1.1.1.5 christos && may_relax_expr (tok[arc_rlx_ins->opcheckidx])
3849 1.1.1.5 christos && relaxable_operand (arc_rlx_ins, tok, ntok)
3850 1.1.1.5 christos && relaxable_flag (arc_rlx_ins, pflags, nflg))
3851 1.1.1.5 christos {
3852 1.1.1.8 christos rv = true;
3853 1.1.1.5 christos frag_now->fr_subtype = arc_relaxable_insns[i].subtype;
3854 1.1.1.5 christos memcpy (&frag_now->tc_frag_data.tok, tok,
3855 1.1.1.5 christos sizeof (expressionS) * ntok);
3856 1.1.1.5 christos memcpy (&frag_now->tc_frag_data.pflags, pflags,
3857 1.1.1.5 christos sizeof (struct arc_flags) * nflg);
3858 1.1.1.5 christos frag_now->tc_frag_data.nflg = nflg;
3859 1.1.1.5 christos frag_now->tc_frag_data.ntok = ntok;
3860 1.1.1.5 christos break;
3861 1.1.1.5 christos }
3862 1.1.1.5 christos }
3863 1.1.1.5 christos
3864 1.1.1.5 christos return rv;
3865 1.1.1.5 christos }
3866 1.1.1.5 christos
3867 1.1.1.3 christos /* Turn an opcode description and a set of arguments into
3868 1.1.1.3 christos an instruction and a fixup. */
3869 1.1.1.3 christos
3870 1.1.1.3 christos static void
3871 1.1.1.3 christos assemble_insn (const struct arc_opcode *opcode,
3872 1.1.1.3 christos const expressionS *tok,
3873 1.1.1.3 christos int ntok,
3874 1.1.1.3 christos const struct arc_flags *pflags,
3875 1.1.1.3 christos int nflg,
3876 1.1.1.3 christos struct arc_insn *insn)
3877 1.1.1.3 christos {
3878 1.1.1.3 christos const expressionS *reloc_exp = NULL;
3879 1.1.1.6 christos unsigned long long image;
3880 1.1.1.3 christos const unsigned char *argidx;
3881 1.1.1.3 christos int i;
3882 1.1.1.3 christos int tokidx = 0;
3883 1.1.1.3 christos unsigned char pcrel = 0;
3884 1.1.1.8 christos bool needGOTSymbol;
3885 1.1.1.8 christos bool has_delay_slot = false;
3886 1.1.1.3 christos extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
3887 1.1.1.3 christos
3888 1.1.1.3 christos memset (insn, 0, sizeof (*insn));
3889 1.1.1.3 christos image = opcode->opcode;
3890 1.1.1.3 christos
3891 1.1.1.6 christos pr_debug ("%s:%d: assemble_insn: %s using opcode %llx\n",
3892 1.1.1.3 christos frag_now->fr_file, frag_now->fr_line, opcode->name,
3893 1.1.1.3 christos opcode->opcode);
3894 1.1.1.3 christos
3895 1.1.1.3 christos /* Handle operands. */
3896 1.1.1.3 christos for (argidx = opcode->operands; *argidx; ++argidx)
3897 1.1.1.3 christos {
3898 1.1.1.3 christos const struct arc_operand *operand = &arc_operands[*argidx];
3899 1.1.1.3 christos const expressionS *t = (const expressionS *) 0;
3900 1.1.1.3 christos
3901 1.1.1.6 christos if (ARC_OPERAND_IS_FAKE (operand))
3902 1.1.1.3 christos continue;
3903 1.1.1.3 christos
3904 1.1.1.3 christos if (operand->flags & ARC_OPERAND_DUPLICATE)
3905 1.1.1.3 christos {
3906 1.1.1.3 christos /* Duplicate operand, already inserted. */
3907 1.1.1.3 christos tokidx ++;
3908 1.1.1.3 christos continue;
3909 1.1.1.3 christos }
3910 1.1.1.3 christos
3911 1.1.1.3 christos if (tokidx >= ntok)
3912 1.1.1.3 christos {
3913 1.1.1.3 christos abort ();
3914 1.1.1.3 christos }
3915 1.1.1.3 christos else
3916 1.1.1.3 christos t = &tok[tokidx++];
3917 1.1.1.3 christos
3918 1.1.1.3 christos /* Regardless if we have a reloc or not mark the instruction
3919 1.1.1.3 christos limm if it is the case. */
3920 1.1.1.3 christos if (operand->flags & ARC_OPERAND_LIMM)
3921 1.1.1.8 christos insn->has_limm = true;
3922 1.1.1.3 christos
3923 1.1.1.3 christos switch (t->X_op)
3924 1.1.1.3 christos {
3925 1.1.1.3 christos case O_register:
3926 1.1.1.3 christos image = insert_operand (image, operand, regno (t->X_add_number),
3927 1.1.1.3 christos NULL, 0);
3928 1.1.1.3 christos break;
3929 1.1.1.3 christos
3930 1.1.1.3 christos case O_constant:
3931 1.1.1.3 christos image = insert_operand (image, operand, t->X_add_number, NULL, 0);
3932 1.1.1.3 christos reloc_exp = t;
3933 1.1.1.3 christos if (operand->flags & ARC_OPERAND_LIMM)
3934 1.1.1.3 christos insn->limm = t->X_add_number;
3935 1.1.1.3 christos break;
3936 1.1.1.3 christos
3937 1.1.1.3 christos case O_bracket:
3938 1.1.1.6 christos case O_colon:
3939 1.1.1.6 christos case O_addrtype:
3940 1.1.1.6 christos /* Ignore brackets, colons, and address types. */
3941 1.1.1.3 christos break;
3942 1.1.1.3 christos
3943 1.1.1.3 christos case O_absent:
3944 1.1.1.3 christos gas_assert (operand->flags & ARC_OPERAND_IGNORE);
3945 1.1.1.3 christos break;
3946 1.1.1.3 christos
3947 1.1.1.3 christos case O_subtract:
3948 1.1.1.3 christos /* Maybe register range. */
3949 1.1.1.3 christos if ((t->X_add_number == 0)
3950 1.1.1.3 christos && contains_register (t->X_add_symbol)
3951 1.1.1.3 christos && contains_register (t->X_op_symbol))
3952 1.1.1.3 christos {
3953 1.1.1.3 christos int regs;
3954 1.1.1.3 christos
3955 1.1.1.3 christos regs = get_register (t->X_add_symbol);
3956 1.1.1.3 christos regs <<= 16;
3957 1.1.1.3 christos regs |= get_register (t->X_op_symbol);
3958 1.1.1.3 christos image = insert_operand (image, operand, regs, NULL, 0);
3959 1.1.1.3 christos break;
3960 1.1.1.3 christos }
3961 1.1.1.6 christos /* Fall through. */
3962 1.1.1.3 christos
3963 1.1.1.3 christos default:
3964 1.1.1.3 christos /* This operand needs a relocation. */
3965 1.1.1.8 christos needGOTSymbol = false;
3966 1.1.1.3 christos
3967 1.1.1.3 christos switch (t->X_md)
3968 1.1.1.3 christos {
3969 1.1.1.3 christos case O_plt:
3970 1.1.1.5 christos if (opcode->insn_class == JUMP)
3971 1.1.1.6 christos as_bad (_("Unable to use @plt relocation for insn %s"),
3972 1.1.1.6 christos opcode->name);
3973 1.1.1.8 christos needGOTSymbol = true;
3974 1.1.1.3 christos reloc = find_reloc ("plt", opcode->name,
3975 1.1.1.3 christos pflags, nflg,
3976 1.1.1.3 christos operand->default_reloc);
3977 1.1.1.3 christos break;
3978 1.1.1.3 christos
3979 1.1.1.3 christos case O_gotoff:
3980 1.1.1.3 christos case O_gotpc:
3981 1.1.1.8 christos needGOTSymbol = true;
3982 1.1.1.3 christos reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3983 1.1.1.3 christos break;
3984 1.1.1.3 christos case O_pcl:
3985 1.1.1.6 christos if (operand->flags & ARC_OPERAND_LIMM)
3986 1.1.1.6 christos {
3987 1.1.1.6 christos reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3988 1.1.1.6 christos if (arc_opcode_len (opcode) == 2
3989 1.1.1.6 christos || opcode->insn_class == JUMP)
3990 1.1.1.6 christos as_bad (_("Unable to use @pcl relocation for insn %s"),
3991 1.1.1.6 christos opcode->name);
3992 1.1.1.6 christos }
3993 1.1.1.6 christos else
3994 1.1.1.6 christos {
3995 1.1.1.6 christos /* This is a relaxed operand which initially was
3996 1.1.1.6 christos limm, choose whatever we have defined in the
3997 1.1.1.6 christos opcode as reloc. */
3998 1.1.1.6 christos reloc = operand->default_reloc;
3999 1.1.1.6 christos }
4000 1.1.1.3 christos break;
4001 1.1.1.3 christos case O_sda:
4002 1.1.1.3 christos reloc = find_reloc ("sda", opcode->name,
4003 1.1.1.3 christos pflags, nflg,
4004 1.1.1.3 christos operand->default_reloc);
4005 1.1.1.3 christos break;
4006 1.1.1.3 christos case O_tlsgd:
4007 1.1.1.3 christos case O_tlsie:
4008 1.1.1.8 christos needGOTSymbol = true;
4009 1.1.1.3 christos /* Fall-through. */
4010 1.1.1.3 christos
4011 1.1.1.3 christos case O_tpoff:
4012 1.1.1.3 christos case O_dtpoff:
4013 1.1.1.3 christos reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
4014 1.1.1.3 christos break;
4015 1.1.1.3 christos
4016 1.1.1.3 christos case O_tpoff9: /*FIXME! Check for the conditionality of
4017 1.1.1.3 christos the insn. */
4018 1.1.1.3 christos case O_dtpoff9: /*FIXME! Check for the conditionality of
4019 1.1.1.3 christos the insn. */
4020 1.1.1.3 christos as_bad (_("TLS_*_S9 relocs are not supported yet"));
4021 1.1.1.3 christos break;
4022 1.1.1.3 christos
4023 1.1.1.3 christos default:
4024 1.1.1.3 christos /* Just consider the default relocation. */
4025 1.1.1.3 christos reloc = operand->default_reloc;
4026 1.1.1.3 christos break;
4027 1.1.1.3 christos }
4028 1.1.1.3 christos
4029 1.1.1.3 christos if (needGOTSymbol && (GOT_symbol == NULL))
4030 1.1.1.3 christos GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
4031 1.1.1.3 christos
4032 1.1.1.3 christos reloc_exp = t;
4033 1.1.1.3 christos
4034 1.1.1.3 christos #if 0
4035 1.1.1.3 christos if (reloc > 0)
4036 1.1.1.3 christos {
4037 1.1.1.3 christos /* sanity checks. */
4038 1.1.1.3 christos reloc_howto_type *reloc_howto
4039 1.1.1.3 christos = bfd_reloc_type_lookup (stdoutput,
4040 1.1.1.3 christos (bfd_reloc_code_real_type) reloc);
4041 1.1.1.3 christos unsigned reloc_bitsize = reloc_howto->bitsize;
4042 1.1.1.3 christos if (reloc_howto->rightshift)
4043 1.1.1.3 christos reloc_bitsize -= reloc_howto->rightshift;
4044 1.1.1.3 christos if (reloc_bitsize != operand->bits)
4045 1.1.1.3 christos {
4046 1.1.1.3 christos as_bad (_("invalid relocation %s for field"),
4047 1.1.1.3 christos bfd_get_reloc_code_name (reloc));
4048 1.1.1.3 christos return;
4049 1.1.1.3 christos }
4050 1.1.1.3 christos }
4051 1.1.1.3 christos #endif
4052 1.1.1.3 christos if (insn->nfixups >= MAX_INSN_FIXUPS)
4053 1.1.1.3 christos as_fatal (_("too many fixups"));
4054 1.1.1.3 christos
4055 1.1.1.3 christos struct arc_fixup *fixup;
4056 1.1.1.3 christos fixup = &insn->fixups[insn->nfixups++];
4057 1.1.1.3 christos fixup->exp = *t;
4058 1.1.1.3 christos fixup->reloc = reloc;
4059 1.1.1.6 christos if ((int) reloc < 0)
4060 1.1.1.6 christos pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
4061 1.1.1.6 christos else
4062 1.1.1.6 christos {
4063 1.1.1.6 christos reloc_howto_type *reloc_howto =
4064 1.1.1.6 christos bfd_reloc_type_lookup (stdoutput,
4065 1.1.1.6 christos (bfd_reloc_code_real_type) fixup->reloc);
4066 1.1.1.6 christos pcrel = reloc_howto->pc_relative;
4067 1.1.1.6 christos }
4068 1.1.1.3 christos fixup->pcrel = pcrel;
4069 1.1.1.8 christos fixup->islong = (operand->flags & ARC_OPERAND_LIMM) != 0;
4070 1.1.1.3 christos break;
4071 1.1.1.3 christos }
4072 1.1.1.3 christos }
4073 1.1.1.3 christos
4074 1.1.1.3 christos /* Handle flags. */
4075 1.1.1.3 christos for (i = 0; i < nflg; i++)
4076 1.1.1.3 christos {
4077 1.1.1.5 christos const struct arc_flag_operand *flg_operand = pflags[i].flgp;
4078 1.1.1.3 christos
4079 1.1.1.3 christos /* Check if the instruction has a delay slot. */
4080 1.1.1.3 christos if (!strcmp (flg_operand->name, "d"))
4081 1.1.1.8 christos has_delay_slot = true;
4082 1.1.1.3 christos
4083 1.1.1.6 christos /* There is an exceptional case when we cannot insert a flag just as
4084 1.1.1.6 christos it is. On ARCv2 the '.t' and '.nt' flags must be handled in
4085 1.1.1.6 christos relation with the relative address. Unfortunately, some of the
4086 1.1.1.6 christos ARC700 extensions (NPS400) also have a '.nt' flag that should be
4087 1.1.1.6 christos handled in the normal way.
4088 1.1.1.6 christos
4089 1.1.1.6 christos Flag operands don't have an architecture field, so we can't
4090 1.1.1.6 christos directly validate that FLAG_OPERAND is valid for the current
4091 1.1.1.6 christos architecture, what we do instead is just validate that we're
4092 1.1.1.6 christos assembling for an ARCv2 architecture. */
4093 1.1.1.6 christos if ((selected_cpu.flags & ARC_OPCODE_ARCV2)
4094 1.1.1.6 christos && (!strcmp (flg_operand->name, "t")
4095 1.1.1.6 christos || !strcmp (flg_operand->name, "nt")))
4096 1.1.1.3 christos {
4097 1.1.1.3 christos unsigned bitYoperand = 0;
4098 1.1.1.3 christos /* FIXME! move selection bbit/brcc in arc-opc.c. */
4099 1.1.1.3 christos if (!strcmp (flg_operand->name, "t"))
4100 1.1.1.3 christos if (!strcmp (opcode->name, "bbit0")
4101 1.1.1.3 christos || !strcmp (opcode->name, "bbit1"))
4102 1.1.1.3 christos bitYoperand = arc_NToperand;
4103 1.1.1.3 christos else
4104 1.1.1.3 christos bitYoperand = arc_Toperand;
4105 1.1.1.3 christos else
4106 1.1.1.3 christos if (!strcmp (opcode->name, "bbit0")
4107 1.1.1.3 christos || !strcmp (opcode->name, "bbit1"))
4108 1.1.1.3 christos bitYoperand = arc_Toperand;
4109 1.1.1.3 christos else
4110 1.1.1.3 christos bitYoperand = arc_NToperand;
4111 1.1.1.3 christos
4112 1.1.1.3 christos gas_assert (reloc_exp != NULL);
4113 1.1.1.3 christos if (reloc_exp->X_op == O_constant)
4114 1.1.1.3 christos {
4115 1.1.1.3 christos /* Check if we have a constant and solved it
4116 1.1.1.3 christos immediately. */
4117 1.1.1.3 christos offsetT val = reloc_exp->X_add_number;
4118 1.1.1.3 christos image |= insert_operand (image, &arc_operands[bitYoperand],
4119 1.1.1.3 christos val, NULL, 0);
4120 1.1.1.3 christos }
4121 1.1.1.3 christos else
4122 1.1.1.3 christos {
4123 1.1.1.3 christos struct arc_fixup *fixup;
4124 1.1.1.3 christos
4125 1.1.1.3 christos if (insn->nfixups >= MAX_INSN_FIXUPS)
4126 1.1.1.3 christos as_fatal (_("too many fixups"));
4127 1.1.1.3 christos
4128 1.1.1.3 christos fixup = &insn->fixups[insn->nfixups++];
4129 1.1.1.3 christos fixup->exp = *reloc_exp;
4130 1.1.1.3 christos fixup->reloc = -bitYoperand;
4131 1.1.1.3 christos fixup->pcrel = pcrel;
4132 1.1.1.8 christos fixup->islong = false;
4133 1.1.1.3 christos }
4134 1.1.1.3 christos }
4135 1.1.1.3 christos else
4136 1.1.1.3 christos image |= (flg_operand->code & ((1 << flg_operand->bits) - 1))
4137 1.1.1.3 christos << flg_operand->shift;
4138 1.1.1.3 christos }
4139 1.1.1.3 christos
4140 1.1.1.5 christos insn->relax = relax_insn_p (opcode, tok, ntok, pflags, nflg);
4141 1.1.1.5 christos
4142 1.1.1.6 christos /* Instruction length. */
4143 1.1.1.6 christos insn->len = arc_opcode_len (opcode);
4144 1.1.1.5 christos
4145 1.1.1.5 christos insn->insn = image;
4146 1.1.1.5 christos
4147 1.1.1.5 christos /* Update last insn status. */
4148 1.1.1.5 christos arc_last_insns[1] = arc_last_insns[0];
4149 1.1.1.5 christos arc_last_insns[0].opcode = opcode;
4150 1.1.1.5 christos arc_last_insns[0].has_limm = insn->has_limm;
4151 1.1.1.5 christos arc_last_insns[0].has_delay_slot = has_delay_slot;
4152 1.1.1.5 christos
4153 1.1.1.5 christos /* Check if the current instruction is legally used. */
4154 1.1.1.5 christos if (arc_last_insns[1].has_delay_slot
4155 1.1.1.5 christos && is_br_jmp_insn_p (arc_last_insns[0].opcode))
4156 1.1.1.6 christos as_bad (_("Insn %s has a jump/branch instruction %s in its delay slot."),
4157 1.1.1.6 christos arc_last_insns[1].opcode->name,
4158 1.1.1.6 christos arc_last_insns[0].opcode->name);
4159 1.1.1.6 christos if (arc_last_insns[1].has_delay_slot
4160 1.1.1.6 christos && arc_last_insns[0].has_limm)
4161 1.1.1.6 christos as_bad (_("Insn %s has an instruction %s with limm in its delay slot."),
4162 1.1.1.6 christos arc_last_insns[1].opcode->name,
4163 1.1.1.6 christos arc_last_insns[0].opcode->name);
4164 1.1.1.3 christos }
4165 1.1.1.3 christos
4166 1.1.1.3 christos void
4167 1.1.1.3 christos arc_handle_align (fragS* fragP)
4168 1.1.1.3 christos {
4169 1.1.1.3 christos if ((fragP)->fr_type == rs_align_code)
4170 1.1.1.3 christos {
4171 1.1.1.3 christos char *dest = (fragP)->fr_literal + (fragP)->fr_fix;
4172 1.1.1.3 christos valueT count = ((fragP)->fr_next->fr_address
4173 1.1.1.3 christos - (fragP)->fr_address - (fragP)->fr_fix);
4174 1.1.1.3 christos
4175 1.1.1.3 christos (fragP)->fr_var = 2;
4176 1.1.1.3 christos
4177 1.1.1.3 christos if (count & 1)/* Padding in the gap till the next 2-byte
4178 1.1.1.3 christos boundary with 0s. */
4179 1.1.1.3 christos {
4180 1.1.1.3 christos (fragP)->fr_fix++;
4181 1.1.1.3 christos *dest++ = 0;
4182 1.1.1.3 christos }
4183 1.1.1.3 christos /* Writing nop_s. */
4184 1.1.1.3 christos md_number_to_chars (dest, NOP_OPCODE_S, 2);
4185 1.1.1.3 christos }
4186 1.1.1.3 christos }
4187 1.1.1.3 christos
4188 1.1.1.3 christos /* Here we decide which fixups can be adjusted to make them relative
4189 1.1.1.3 christos to the beginning of the section instead of the symbol. Basically
4190 1.1.1.3 christos we need to make sure that the dynamic relocations are done
4191 1.1.1.3 christos correctly, so in some cases we force the original symbol to be
4192 1.1.1.3 christos used. */
4193 1.1.1.3 christos
4194 1.1.1.3 christos int
4195 1.1.1.3 christos tc_arc_fix_adjustable (fixS *fixP)
4196 1.1.1.3 christos {
4197 1.1.1.3 christos
4198 1.1.1.3 christos /* Prevent all adjustments to global symbols. */
4199 1.1.1.3 christos if (S_IS_EXTERNAL (fixP->fx_addsy))
4200 1.1.1.3 christos return 0;
4201 1.1.1.3 christos if (S_IS_WEAK (fixP->fx_addsy))
4202 1.1.1.3 christos return 0;
4203 1.1.1.3 christos
4204 1.1.1.3 christos /* Adjust_reloc_syms doesn't know about the GOT. */
4205 1.1.1.3 christos switch (fixP->fx_r_type)
4206 1.1.1.3 christos {
4207 1.1.1.3 christos case BFD_RELOC_ARC_GOTPC32:
4208 1.1.1.3 christos case BFD_RELOC_ARC_PLT32:
4209 1.1.1.3 christos case BFD_RELOC_ARC_S25H_PCREL_PLT:
4210 1.1.1.3 christos case BFD_RELOC_ARC_S21H_PCREL_PLT:
4211 1.1.1.3 christos case BFD_RELOC_ARC_S25W_PCREL_PLT:
4212 1.1.1.3 christos case BFD_RELOC_ARC_S21W_PCREL_PLT:
4213 1.1.1.3 christos return 0;
4214 1.1.1.3 christos
4215 1.1.1.3 christos default:
4216 1.1.1.3 christos break;
4217 1.1.1.3 christos }
4218 1.1.1.3 christos
4219 1.1.1.5 christos return 1;
4220 1.1.1.3 christos }
4221 1.1.1.3 christos
4222 1.1.1.3 christos /* Compute the reloc type of an expression EXP. */
4223 1.1.1.3 christos
4224 1.1.1.3 christos static void
4225 1.1.1.3 christos arc_check_reloc (expressionS *exp,
4226 1.1.1.3 christos bfd_reloc_code_real_type *r_type_p)
4227 1.1.1.3 christos {
4228 1.1.1.3 christos if (*r_type_p == BFD_RELOC_32
4229 1.1.1.3 christos && exp->X_op == O_subtract
4230 1.1.1.3 christos && exp->X_op_symbol != NULL
4231 1.1.1.7 christos && S_GET_SEGMENT (exp->X_op_symbol) == now_seg)
4232 1.1.1.3 christos *r_type_p = BFD_RELOC_ARC_32_PCREL;
4233 1.1.1.3 christos }
4234 1.1.1.3 christos
4235 1.1.1.3 christos
4236 1.1.1.3 christos /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
4237 1.1.1.3 christos
4238 1.1.1.3 christos void
4239 1.1.1.3 christos arc_cons_fix_new (fragS *frag,
4240 1.1.1.3 christos int off,
4241 1.1.1.3 christos int size,
4242 1.1.1.3 christos expressionS *exp,
4243 1.1.1.3 christos bfd_reloc_code_real_type r_type)
4244 1.1.1.3 christos {
4245 1.1.1.3 christos r_type = BFD_RELOC_UNUSED;
4246 1.1.1.3 christos
4247 1.1.1.3 christos switch (size)
4248 1.1.1.3 christos {
4249 1.1.1.3 christos case 1:
4250 1.1.1.3 christos r_type = BFD_RELOC_8;
4251 1.1.1.3 christos break;
4252 1.1.1.3 christos
4253 1.1.1.3 christos case 2:
4254 1.1.1.3 christos r_type = BFD_RELOC_16;
4255 1.1.1.3 christos break;
4256 1.1.1.3 christos
4257 1.1.1.3 christos case 3:
4258 1.1.1.3 christos r_type = BFD_RELOC_24;
4259 1.1.1.3 christos break;
4260 1.1.1.3 christos
4261 1.1.1.3 christos case 4:
4262 1.1.1.3 christos r_type = BFD_RELOC_32;
4263 1.1.1.3 christos arc_check_reloc (exp, &r_type);
4264 1.1.1.3 christos break;
4265 1.1.1.3 christos
4266 1.1.1.3 christos case 8:
4267 1.1.1.3 christos r_type = BFD_RELOC_64;
4268 1.1.1.3 christos break;
4269 1.1.1.3 christos
4270 1.1.1.3 christos default:
4271 1.1.1.3 christos as_bad (_("unsupported BFD relocation size %u"), size);
4272 1.1.1.3 christos r_type = BFD_RELOC_UNUSED;
4273 1.1.1.3 christos }
4274 1.1.1.3 christos
4275 1.1.1.3 christos fix_new_exp (frag, off, size, exp, 0, r_type);
4276 1.1.1.3 christos }
4277 1.1.1.3 christos
4278 1.1.1.3 christos /* The actual routine that checks the ZOL conditions. */
4279 1.1.1.3 christos
4280 1.1.1.3 christos static void
4281 1.1.1.3 christos check_zol (symbolS *s)
4282 1.1.1.3 christos {
4283 1.1.1.6 christos switch (selected_cpu.mach)
4284 1.1.1.3 christos {
4285 1.1.1.3 christos case bfd_mach_arc_arcv2:
4286 1.1.1.6 christos if (selected_cpu.flags & ARC_OPCODE_ARCv2EM)
4287 1.1.1.3 christos return;
4288 1.1.1.3 christos
4289 1.1.1.3 christos if (is_br_jmp_insn_p (arc_last_insns[0].opcode)
4290 1.1.1.3 christos || arc_last_insns[1].has_delay_slot)
4291 1.1.1.3 christos as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
4292 1.1.1.3 christos S_GET_NAME (s));
4293 1.1.1.3 christos
4294 1.1.1.3 christos break;
4295 1.1.1.3 christos case bfd_mach_arc_arc600:
4296 1.1.1.3 christos
4297 1.1.1.3 christos if (is_kernel_insn_p (arc_last_insns[0].opcode))
4298 1.1.1.3 christos as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
4299 1.1.1.3 christos S_GET_NAME (s));
4300 1.1.1.3 christos
4301 1.1.1.3 christos if (arc_last_insns[0].has_limm
4302 1.1.1.3 christos && is_br_jmp_insn_p (arc_last_insns[0].opcode))
4303 1.1.1.3 christos as_bad (_("A jump instruction with long immediate detected at the \
4304 1.1.1.3 christos end of the ZOL label @%s"), S_GET_NAME (s));
4305 1.1.1.3 christos
4306 1.1.1.3 christos /* Fall through. */
4307 1.1.1.3 christos case bfd_mach_arc_arc700:
4308 1.1.1.3 christos if (arc_last_insns[0].has_delay_slot)
4309 1.1.1.3 christos as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
4310 1.1.1.3 christos S_GET_NAME (s));
4311 1.1.1.3 christos
4312 1.1.1.3 christos break;
4313 1.1.1.3 christos default:
4314 1.1.1.3 christos break;
4315 1.1.1.3 christos }
4316 1.1.1.3 christos }
4317 1.1.1.3 christos
4318 1.1.1.3 christos /* If ZOL end check the last two instruction for illegals. */
4319 1.1.1.3 christos void
4320 1.1.1.3 christos arc_frob_label (symbolS * sym)
4321 1.1.1.3 christos {
4322 1.1.1.3 christos if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL)
4323 1.1.1.3 christos check_zol (sym);
4324 1.1.1.3 christos
4325 1.1.1.3 christos dwarf2_emit_label (sym);
4326 1.1 skrll }
4327 1.1.1.5 christos
4328 1.1.1.5 christos /* Used because generic relaxation assumes a pc-rel value whilst we
4329 1.1.1.5 christos also relax instructions that use an absolute value resolved out of
4330 1.1.1.5 christos relative values (if that makes any sense). An example: 'add r1,
4331 1.1.1.5 christos r2, @.L2 - .' The symbols . and @.L2 are relative to the section
4332 1.1.1.5 christos but if they're in the same section we can subtract the section
4333 1.1.1.5 christos offset relocation which ends up in a resolved value. So if @.L2 is
4334 1.1.1.5 christos .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
4335 1.1.1.5 christos .text + 0x40 = 0x10. */
4336 1.1.1.5 christos int
4337 1.1.1.5 christos arc_pcrel_adjust (fragS *fragP)
4338 1.1.1.5 christos {
4339 1.1.1.6 christos pr_debug ("arc_pcrel_adjust: address=%ld, fix=%ld, PCrel %s\n",
4340 1.1.1.6 christos fragP->fr_address, fragP->fr_fix,
4341 1.1.1.6 christos fragP->tc_frag_data.pcrel ? "Y" : "N");
4342 1.1.1.6 christos
4343 1.1.1.5 christos if (!fragP->tc_frag_data.pcrel)
4344 1.1.1.5 christos return fragP->fr_address + fragP->fr_fix;
4345 1.1.1.5 christos
4346 1.1.1.6 christos /* Take into account the PCL rounding. */
4347 1.1.1.6 christos return (fragP->fr_address + fragP->fr_fix) & 0x03;
4348 1.1.1.5 christos }
4349 1.1.1.5 christos
4350 1.1.1.5 christos /* Initialize the DWARF-2 unwind information for this procedure. */
4351 1.1.1.5 christos
4352 1.1.1.5 christos void
4353 1.1.1.5 christos tc_arc_frame_initial_instructions (void)
4354 1.1.1.5 christos {
4355 1.1.1.5 christos /* Stack pointer is register 28. */
4356 1.1.1.5 christos cfi_add_CFA_def_cfa (28, 0);
4357 1.1.1.5 christos }
4358 1.1.1.5 christos
4359 1.1.1.5 christos int
4360 1.1.1.5 christos tc_arc_regname_to_dw2regnum (char *regname)
4361 1.1.1.5 christos {
4362 1.1.1.5 christos struct symbol *sym;
4363 1.1.1.5 christos
4364 1.1.1.8 christos sym = str_hash_find (arc_reg_hash, regname);
4365 1.1.1.5 christos if (sym)
4366 1.1.1.5 christos return S_GET_VALUE (sym);
4367 1.1.1.5 christos
4368 1.1.1.5 christos return -1;
4369 1.1.1.5 christos }
4370 1.1.1.5 christos
4371 1.1.1.5 christos /* Adjust the symbol table. Delete found AUX register symbols. */
4372 1.1.1.5 christos
4373 1.1.1.5 christos void
4374 1.1.1.5 christos arc_adjust_symtab (void)
4375 1.1.1.5 christos {
4376 1.1.1.5 christos symbolS * sym;
4377 1.1.1.5 christos
4378 1.1.1.5 christos for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
4379 1.1.1.5 christos {
4380 1.1.1.5 christos /* I've created a symbol during parsing process. Now, remove
4381 1.1.1.5 christos the symbol as it is found to be an AUX register. */
4382 1.1.1.5 christos if (ARC_GET_FLAG (sym) & ARC_FLAG_AUX)
4383 1.1.1.5 christos symbol_remove (sym, &symbol_rootP, &symbol_lastP);
4384 1.1.1.5 christos }
4385 1.1.1.5 christos
4386 1.1.1.5 christos /* Now do generic ELF adjustments. */
4387 1.1.1.5 christos elf_adjust_symtab ();
4388 1.1.1.5 christos }
4389 1.1.1.5 christos
4390 1.1.1.5 christos static void
4391 1.1.1.5 christos tokenize_extinsn (extInstruction_t *einsn)
4392 1.1.1.5 christos {
4393 1.1.1.5 christos char *p, c;
4394 1.1.1.5 christos char *insn_name;
4395 1.1.1.5 christos unsigned char major_opcode;
4396 1.1.1.5 christos unsigned char sub_opcode;
4397 1.1.1.5 christos unsigned char syntax_class = 0;
4398 1.1.1.5 christos unsigned char syntax_class_modifiers = 0;
4399 1.1.1.5 christos unsigned char suffix_class = 0;
4400 1.1.1.5 christos unsigned int i;
4401 1.1.1.5 christos
4402 1.1.1.5 christos SKIP_WHITESPACE ();
4403 1.1.1.5 christos
4404 1.1.1.5 christos /* 1st: get instruction name. */
4405 1.1.1.5 christos p = input_line_pointer;
4406 1.1.1.5 christos c = get_symbol_name (&p);
4407 1.1.1.5 christos
4408 1.1.1.5 christos insn_name = xstrdup (p);
4409 1.1.1.5 christos restore_line_pointer (c);
4410 1.1.1.5 christos
4411 1.1.1.7 christos /* Convert to lower case. */
4412 1.1.1.7 christos for (p = insn_name; *p; ++p)
4413 1.1.1.7 christos *p = TOLOWER (*p);
4414 1.1.1.7 christos
4415 1.1.1.5 christos /* 2nd: get major opcode. */
4416 1.1.1.5 christos if (*input_line_pointer != ',')
4417 1.1.1.5 christos {
4418 1.1.1.5 christos as_bad (_("expected comma after instruction name"));
4419 1.1.1.5 christos ignore_rest_of_line ();
4420 1.1.1.5 christos return;
4421 1.1.1.5 christos }
4422 1.1.1.5 christos input_line_pointer++;
4423 1.1.1.5 christos major_opcode = get_absolute_expression ();
4424 1.1.1.5 christos
4425 1.1.1.5 christos /* 3rd: get sub-opcode. */
4426 1.1.1.5 christos SKIP_WHITESPACE ();
4427 1.1.1.5 christos
4428 1.1.1.5 christos if (*input_line_pointer != ',')
4429 1.1.1.5 christos {
4430 1.1.1.5 christos as_bad (_("expected comma after major opcode"));
4431 1.1.1.5 christos ignore_rest_of_line ();
4432 1.1.1.5 christos return;
4433 1.1.1.5 christos }
4434 1.1.1.5 christos input_line_pointer++;
4435 1.1.1.5 christos sub_opcode = get_absolute_expression ();
4436 1.1.1.5 christos
4437 1.1.1.5 christos /* 4th: get suffix class. */
4438 1.1.1.5 christos SKIP_WHITESPACE ();
4439 1.1.1.5 christos
4440 1.1.1.5 christos if (*input_line_pointer != ',')
4441 1.1.1.5 christos {
4442 1.1.1.5 christos as_bad ("expected comma after sub opcode");
4443 1.1.1.5 christos ignore_rest_of_line ();
4444 1.1.1.5 christos return;
4445 1.1.1.5 christos }
4446 1.1.1.5 christos input_line_pointer++;
4447 1.1.1.5 christos
4448 1.1.1.5 christos while (1)
4449 1.1.1.5 christos {
4450 1.1.1.5 christos SKIP_WHITESPACE ();
4451 1.1.1.5 christos
4452 1.1.1.5 christos for (i = 0; i < ARRAY_SIZE (suffixclass); i++)
4453 1.1.1.5 christos {
4454 1.1.1.5 christos if (!strncmp (suffixclass[i].name, input_line_pointer,
4455 1.1.1.5 christos suffixclass[i].len))
4456 1.1.1.5 christos {
4457 1.1.1.5 christos suffix_class |= suffixclass[i].attr_class;
4458 1.1.1.5 christos input_line_pointer += suffixclass[i].len;
4459 1.1.1.5 christos break;
4460 1.1.1.5 christos }
4461 1.1.1.5 christos }
4462 1.1.1.5 christos
4463 1.1.1.5 christos if (i == ARRAY_SIZE (suffixclass))
4464 1.1.1.5 christos {
4465 1.1.1.5 christos as_bad ("invalid suffix class");
4466 1.1.1.5 christos ignore_rest_of_line ();
4467 1.1.1.5 christos return;
4468 1.1.1.5 christos }
4469 1.1.1.5 christos
4470 1.1.1.5 christos SKIP_WHITESPACE ();
4471 1.1.1.5 christos
4472 1.1.1.5 christos if (*input_line_pointer == '|')
4473 1.1.1.5 christos input_line_pointer++;
4474 1.1.1.5 christos else
4475 1.1.1.5 christos break;
4476 1.1.1.5 christos }
4477 1.1.1.5 christos
4478 1.1.1.5 christos /* 5th: get syntax class and syntax class modifiers. */
4479 1.1.1.5 christos if (*input_line_pointer != ',')
4480 1.1.1.5 christos {
4481 1.1.1.5 christos as_bad ("expected comma after suffix class");
4482 1.1.1.5 christos ignore_rest_of_line ();
4483 1.1.1.5 christos return;
4484 1.1.1.5 christos }
4485 1.1.1.5 christos input_line_pointer++;
4486 1.1.1.5 christos
4487 1.1.1.5 christos while (1)
4488 1.1.1.5 christos {
4489 1.1.1.5 christos SKIP_WHITESPACE ();
4490 1.1.1.5 christos
4491 1.1.1.5 christos for (i = 0; i < ARRAY_SIZE (syntaxclassmod); i++)
4492 1.1.1.5 christos {
4493 1.1.1.5 christos if (!strncmp (syntaxclassmod[i].name,
4494 1.1.1.5 christos input_line_pointer,
4495 1.1.1.5 christos syntaxclassmod[i].len))
4496 1.1.1.5 christos {
4497 1.1.1.5 christos syntax_class_modifiers |= syntaxclassmod[i].attr_class;
4498 1.1.1.5 christos input_line_pointer += syntaxclassmod[i].len;
4499 1.1.1.5 christos break;
4500 1.1.1.5 christos }
4501 1.1.1.5 christos }
4502 1.1.1.5 christos
4503 1.1.1.5 christos if (i == ARRAY_SIZE (syntaxclassmod))
4504 1.1.1.5 christos {
4505 1.1.1.5 christos for (i = 0; i < ARRAY_SIZE (syntaxclass); i++)
4506 1.1.1.5 christos {
4507 1.1.1.5 christos if (!strncmp (syntaxclass[i].name,
4508 1.1.1.5 christos input_line_pointer,
4509 1.1.1.5 christos syntaxclass[i].len))
4510 1.1.1.5 christos {
4511 1.1.1.5 christos syntax_class |= syntaxclass[i].attr_class;
4512 1.1.1.5 christos input_line_pointer += syntaxclass[i].len;
4513 1.1.1.5 christos break;
4514 1.1.1.5 christos }
4515 1.1.1.5 christos }
4516 1.1.1.5 christos
4517 1.1.1.5 christos if (i == ARRAY_SIZE (syntaxclass))
4518 1.1.1.5 christos {
4519 1.1.1.5 christos as_bad ("missing syntax class");
4520 1.1.1.5 christos ignore_rest_of_line ();
4521 1.1.1.5 christos return;
4522 1.1.1.5 christos }
4523 1.1.1.5 christos }
4524 1.1.1.5 christos
4525 1.1.1.5 christos SKIP_WHITESPACE ();
4526 1.1.1.5 christos
4527 1.1.1.5 christos if (*input_line_pointer == '|')
4528 1.1.1.5 christos input_line_pointer++;
4529 1.1.1.5 christos else
4530 1.1.1.5 christos break;
4531 1.1.1.5 christos }
4532 1.1.1.5 christos
4533 1.1.1.5 christos demand_empty_rest_of_line ();
4534 1.1.1.5 christos
4535 1.1.1.5 christos einsn->name = insn_name;
4536 1.1.1.5 christos einsn->major = major_opcode;
4537 1.1.1.5 christos einsn->minor = sub_opcode;
4538 1.1.1.5 christos einsn->syntax = syntax_class;
4539 1.1.1.5 christos einsn->modsyn = syntax_class_modifiers;
4540 1.1.1.5 christos einsn->suffix = suffix_class;
4541 1.1.1.5 christos einsn->flags = syntax_class
4542 1.1.1.5 christos | (syntax_class_modifiers & ARC_OP1_IMM_IMPLIED ? 0x10 : 0);
4543 1.1.1.5 christos }
4544 1.1.1.5 christos
4545 1.1.1.5 christos /* Generate an extension section. */
4546 1.1.1.5 christos
4547 1.1.1.5 christos static int
4548 1.1.1.5 christos arc_set_ext_seg (void)
4549 1.1.1.5 christos {
4550 1.1.1.5 christos if (!arcext_section)
4551 1.1.1.5 christos {
4552 1.1.1.5 christos arcext_section = subseg_new (".arcextmap", 0);
4553 1.1.1.7 christos bfd_set_section_flags (arcext_section, SEC_READONLY | SEC_HAS_CONTENTS);
4554 1.1.1.5 christos }
4555 1.1.1.5 christos else
4556 1.1.1.5 christos subseg_set (arcext_section, 0);
4557 1.1.1.5 christos return 1;
4558 1.1.1.5 christos }
4559 1.1.1.5 christos
4560 1.1.1.5 christos /* Create an extension instruction description in the arc extension
4561 1.1.1.5 christos section of the output file.
4562 1.1.1.5 christos The structure for an instruction is like this:
4563 1.1.1.5 christos [0]: Length of the record.
4564 1.1.1.5 christos [1]: Type of the record.
4565 1.1.1.5 christos
4566 1.1.1.5 christos [2]: Major opcode.
4567 1.1.1.5 christos [3]: Sub-opcode.
4568 1.1.1.5 christos [4]: Syntax (flags).
4569 1.1.1.5 christos [5]+ Name instruction.
4570 1.1.1.5 christos
4571 1.1.1.5 christos The sequence is terminated by an empty entry. */
4572 1.1.1.5 christos
4573 1.1.1.5 christos static void
4574 1.1.1.5 christos create_extinst_section (extInstruction_t *einsn)
4575 1.1.1.5 christos {
4576 1.1.1.5 christos
4577 1.1.1.5 christos segT old_sec = now_seg;
4578 1.1.1.5 christos int old_subsec = now_subseg;
4579 1.1.1.5 christos char *p;
4580 1.1.1.5 christos int name_len = strlen (einsn->name);
4581 1.1.1.5 christos
4582 1.1.1.5 christos arc_set_ext_seg ();
4583 1.1.1.5 christos
4584 1.1.1.5 christos p = frag_more (1);
4585 1.1.1.5 christos *p = 5 + name_len + 1;
4586 1.1.1.5 christos p = frag_more (1);
4587 1.1.1.5 christos *p = EXT_INSTRUCTION;
4588 1.1.1.5 christos p = frag_more (1);
4589 1.1.1.5 christos *p = einsn->major;
4590 1.1.1.5 christos p = frag_more (1);
4591 1.1.1.5 christos *p = einsn->minor;
4592 1.1.1.5 christos p = frag_more (1);
4593 1.1.1.5 christos *p = einsn->flags;
4594 1.1.1.5 christos p = frag_more (name_len + 1);
4595 1.1.1.5 christos strcpy (p, einsn->name);
4596 1.1.1.5 christos
4597 1.1.1.5 christos subseg_set (old_sec, old_subsec);
4598 1.1.1.5 christos }
4599 1.1.1.5 christos
4600 1.1.1.5 christos /* Handler .extinstruction pseudo-op. */
4601 1.1.1.5 christos
4602 1.1.1.5 christos static void
4603 1.1.1.5 christos arc_extinsn (int ignore ATTRIBUTE_UNUSED)
4604 1.1.1.5 christos {
4605 1.1.1.5 christos extInstruction_t einsn;
4606 1.1.1.5 christos struct arc_opcode *arc_ext_opcodes;
4607 1.1.1.5 christos const char *errmsg = NULL;
4608 1.1.1.5 christos unsigned char moplow, mophigh;
4609 1.1.1.5 christos
4610 1.1.1.5 christos memset (&einsn, 0, sizeof (einsn));
4611 1.1.1.5 christos tokenize_extinsn (&einsn);
4612 1.1.1.5 christos
4613 1.1.1.5 christos /* Check if the name is already used. */
4614 1.1.1.5 christos if (arc_find_opcode (einsn.name))
4615 1.1.1.5 christos as_warn (_("Pseudocode already used %s"), einsn.name);
4616 1.1.1.5 christos
4617 1.1.1.5 christos /* Check the opcode ranges. */
4618 1.1.1.5 christos moplow = 0x05;
4619 1.1.1.6 christos mophigh = (selected_cpu.flags & (ARC_OPCODE_ARCv2EM
4620 1.1.1.6 christos | ARC_OPCODE_ARCv2HS)) ? 0x07 : 0x0a;
4621 1.1.1.5 christos
4622 1.1.1.5 christos if ((einsn.major > mophigh) || (einsn.major < moplow))
4623 1.1.1.5 christos as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow, mophigh);
4624 1.1.1.5 christos
4625 1.1.1.5 christos if ((einsn.minor > 0x3f) && (einsn.major != 0x0a)
4626 1.1.1.5 christos && (einsn.major != 5) && (einsn.major != 9))
4627 1.1.1.5 christos as_fatal (_("minor opcode not in range [0x00 - 0x3f]"));
4628 1.1.1.5 christos
4629 1.1.1.5 christos switch (einsn.syntax & ARC_SYNTAX_MASK)
4630 1.1.1.5 christos {
4631 1.1.1.5 christos case ARC_SYNTAX_3OP:
4632 1.1.1.5 christos if (einsn.modsyn & ARC_OP1_IMM_IMPLIED)
4633 1.1.1.5 christos as_fatal (_("Improper use of OP1_IMM_IMPLIED"));
4634 1.1.1.5 christos break;
4635 1.1.1.5 christos case ARC_SYNTAX_2OP:
4636 1.1.1.5 christos case ARC_SYNTAX_1OP:
4637 1.1.1.5 christos case ARC_SYNTAX_NOP:
4638 1.1.1.5 christos if (einsn.modsyn & ARC_OP1_MUST_BE_IMM)
4639 1.1.1.5 christos as_fatal (_("Improper use of OP1_MUST_BE_IMM"));
4640 1.1.1.5 christos break;
4641 1.1.1.5 christos default:
4642 1.1.1.5 christos break;
4643 1.1.1.5 christos }
4644 1.1.1.5 christos
4645 1.1.1.6 christos arc_ext_opcodes = arcExtMap_genOpcode (&einsn, selected_cpu.flags, &errmsg);
4646 1.1.1.5 christos if (arc_ext_opcodes == NULL)
4647 1.1.1.5 christos {
4648 1.1.1.5 christos if (errmsg)
4649 1.1.1.5 christos as_fatal ("%s", errmsg);
4650 1.1.1.5 christos else
4651 1.1.1.5 christos as_fatal (_("Couldn't generate extension instruction opcodes"));
4652 1.1.1.5 christos }
4653 1.1.1.5 christos else if (errmsg)
4654 1.1.1.5 christos as_warn ("%s", errmsg);
4655 1.1.1.5 christos
4656 1.1.1.5 christos /* Insert the extension instruction. */
4657 1.1.1.5 christos arc_insert_opcode ((const struct arc_opcode *) arc_ext_opcodes);
4658 1.1.1.5 christos
4659 1.1.1.5 christos create_extinst_section (&einsn);
4660 1.1.1.5 christos }
4661 1.1.1.5 christos
4662 1.1.1.8 christos static bool
4663 1.1.1.5 christos tokenize_extregister (extRegister_t *ereg, int opertype)
4664 1.1.1.5 christos {
4665 1.1.1.5 christos char *name;
4666 1.1.1.5 christos char *mode;
4667 1.1.1.5 christos char c;
4668 1.1.1.5 christos char *p;
4669 1.1.1.5 christos int number, imode = 0;
4670 1.1.1.8 christos bool isCore_p = opertype == EXT_CORE_REGISTER;
4671 1.1.1.8 christos bool isReg_p = opertype == EXT_CORE_REGISTER || opertype == EXT_AUX_REGISTER;
4672 1.1.1.5 christos
4673 1.1.1.5 christos /* 1st: get register name. */
4674 1.1.1.5 christos SKIP_WHITESPACE ();
4675 1.1.1.5 christos p = input_line_pointer;
4676 1.1.1.5 christos c = get_symbol_name (&p);
4677 1.1.1.5 christos
4678 1.1.1.5 christos name = xstrdup (p);
4679 1.1.1.5 christos restore_line_pointer (c);
4680 1.1.1.5 christos
4681 1.1.1.5 christos /* 2nd: get register number. */
4682 1.1.1.5 christos SKIP_WHITESPACE ();
4683 1.1.1.5 christos
4684 1.1.1.5 christos if (*input_line_pointer != ',')
4685 1.1.1.5 christos {
4686 1.1.1.6 christos as_bad (_("expected comma after name"));
4687 1.1.1.5 christos ignore_rest_of_line ();
4688 1.1.1.5 christos free (name);
4689 1.1.1.8 christos return false;
4690 1.1.1.5 christos }
4691 1.1.1.5 christos input_line_pointer++;
4692 1.1.1.5 christos number = get_absolute_expression ();
4693 1.1.1.5 christos
4694 1.1.1.6 christos if ((number < 0)
4695 1.1.1.6 christos && (opertype != EXT_AUX_REGISTER))
4696 1.1.1.5 christos {
4697 1.1.1.6 christos as_bad (_("%s second argument cannot be a negative number %d"),
4698 1.1.1.6 christos isCore_p ? "extCoreRegister's" : "extCondCode's",
4699 1.1.1.6 christos number);
4700 1.1.1.5 christos ignore_rest_of_line ();
4701 1.1.1.5 christos free (name);
4702 1.1.1.8 christos return false;
4703 1.1.1.5 christos }
4704 1.1.1.5 christos
4705 1.1.1.5 christos if (isReg_p)
4706 1.1.1.5 christos {
4707 1.1.1.5 christos /* 3rd: get register mode. */
4708 1.1.1.5 christos SKIP_WHITESPACE ();
4709 1.1.1.5 christos
4710 1.1.1.5 christos if (*input_line_pointer != ',')
4711 1.1.1.5 christos {
4712 1.1.1.5 christos as_bad (_("expected comma after register number"));
4713 1.1.1.5 christos ignore_rest_of_line ();
4714 1.1.1.5 christos free (name);
4715 1.1.1.8 christos return false;
4716 1.1.1.5 christos }
4717 1.1.1.5 christos
4718 1.1.1.5 christos input_line_pointer++;
4719 1.1.1.5 christos mode = input_line_pointer;
4720 1.1.1.5 christos
4721 1.1.1.8 christos if (startswith (mode, "r|w"))
4722 1.1.1.5 christos {
4723 1.1.1.5 christos imode = 0;
4724 1.1.1.5 christos input_line_pointer += 3;
4725 1.1.1.5 christos }
4726 1.1.1.8 christos else if (startswith (mode, "r"))
4727 1.1.1.5 christos {
4728 1.1.1.5 christos imode = ARC_REGISTER_READONLY;
4729 1.1.1.5 christos input_line_pointer += 1;
4730 1.1.1.5 christos }
4731 1.1.1.8 christos else if (!startswith (mode, "w"))
4732 1.1.1.5 christos {
4733 1.1.1.5 christos as_bad (_("invalid mode"));
4734 1.1.1.5 christos ignore_rest_of_line ();
4735 1.1.1.5 christos free (name);
4736 1.1.1.8 christos return false;
4737 1.1.1.5 christos }
4738 1.1.1.5 christos else
4739 1.1.1.5 christos {
4740 1.1.1.5 christos imode = ARC_REGISTER_WRITEONLY;
4741 1.1.1.5 christos input_line_pointer += 1;
4742 1.1.1.5 christos }
4743 1.1.1.5 christos }
4744 1.1.1.5 christos
4745 1.1.1.5 christos if (isCore_p)
4746 1.1.1.5 christos {
4747 1.1.1.5 christos /* 4th: get core register shortcut. */
4748 1.1.1.5 christos SKIP_WHITESPACE ();
4749 1.1.1.5 christos if (*input_line_pointer != ',')
4750 1.1.1.5 christos {
4751 1.1.1.5 christos as_bad (_("expected comma after register mode"));
4752 1.1.1.5 christos ignore_rest_of_line ();
4753 1.1.1.5 christos free (name);
4754 1.1.1.8 christos return false;
4755 1.1.1.5 christos }
4756 1.1.1.5 christos
4757 1.1.1.5 christos input_line_pointer++;
4758 1.1.1.5 christos
4759 1.1.1.8 christos if (startswith (input_line_pointer, "cannot_shortcut"))
4760 1.1.1.5 christos {
4761 1.1.1.5 christos imode |= ARC_REGISTER_NOSHORT_CUT;
4762 1.1.1.5 christos input_line_pointer += 15;
4763 1.1.1.5 christos }
4764 1.1.1.8 christos else if (!startswith (input_line_pointer, "can_shortcut"))
4765 1.1.1.5 christos {
4766 1.1.1.5 christos as_bad (_("shortcut designator invalid"));
4767 1.1.1.5 christos ignore_rest_of_line ();
4768 1.1.1.5 christos free (name);
4769 1.1.1.8 christos return false;
4770 1.1.1.5 christos }
4771 1.1.1.5 christos else
4772 1.1.1.5 christos {
4773 1.1.1.5 christos input_line_pointer += 12;
4774 1.1.1.5 christos }
4775 1.1.1.5 christos }
4776 1.1.1.5 christos demand_empty_rest_of_line ();
4777 1.1.1.5 christos
4778 1.1.1.5 christos ereg->name = name;
4779 1.1.1.5 christos ereg->number = number;
4780 1.1.1.5 christos ereg->imode = imode;
4781 1.1.1.8 christos return true;
4782 1.1.1.5 christos }
4783 1.1.1.5 christos
4784 1.1.1.5 christos /* Create an extension register/condition description in the arc
4785 1.1.1.5 christos extension section of the output file.
4786 1.1.1.5 christos
4787 1.1.1.5 christos The structure for an instruction is like this:
4788 1.1.1.5 christos [0]: Length of the record.
4789 1.1.1.5 christos [1]: Type of the record.
4790 1.1.1.5 christos
4791 1.1.1.5 christos For core regs and condition codes:
4792 1.1.1.5 christos [2]: Value.
4793 1.1.1.5 christos [3]+ Name.
4794 1.1.1.5 christos
4795 1.1.1.6 christos For auxiliary registers:
4796 1.1.1.5 christos [2..5]: Value.
4797 1.1.1.5 christos [6]+ Name
4798 1.1.1.5 christos
4799 1.1.1.5 christos The sequence is terminated by an empty entry. */
4800 1.1.1.5 christos
4801 1.1.1.5 christos static void
4802 1.1.1.5 christos create_extcore_section (extRegister_t *ereg, int opertype)
4803 1.1.1.5 christos {
4804 1.1.1.5 christos segT old_sec = now_seg;
4805 1.1.1.5 christos int old_subsec = now_subseg;
4806 1.1.1.5 christos char *p;
4807 1.1.1.5 christos int name_len = strlen (ereg->name);
4808 1.1.1.5 christos
4809 1.1.1.5 christos arc_set_ext_seg ();
4810 1.1.1.5 christos
4811 1.1.1.5 christos switch (opertype)
4812 1.1.1.5 christos {
4813 1.1.1.5 christos case EXT_COND_CODE:
4814 1.1.1.5 christos case EXT_CORE_REGISTER:
4815 1.1.1.5 christos p = frag_more (1);
4816 1.1.1.5 christos *p = 3 + name_len + 1;
4817 1.1.1.5 christos p = frag_more (1);
4818 1.1.1.5 christos *p = opertype;
4819 1.1.1.5 christos p = frag_more (1);
4820 1.1.1.5 christos *p = ereg->number;
4821 1.1.1.5 christos break;
4822 1.1.1.5 christos case EXT_AUX_REGISTER:
4823 1.1.1.5 christos p = frag_more (1);
4824 1.1.1.5 christos *p = 6 + name_len + 1;
4825 1.1.1.5 christos p = frag_more (1);
4826 1.1.1.5 christos *p = EXT_AUX_REGISTER;
4827 1.1.1.5 christos p = frag_more (1);
4828 1.1.1.5 christos *p = (ereg->number >> 24) & 0xff;
4829 1.1.1.5 christos p = frag_more (1);
4830 1.1.1.5 christos *p = (ereg->number >> 16) & 0xff;
4831 1.1.1.5 christos p = frag_more (1);
4832 1.1.1.5 christos *p = (ereg->number >> 8) & 0xff;
4833 1.1.1.5 christos p = frag_more (1);
4834 1.1.1.5 christos *p = (ereg->number) & 0xff;
4835 1.1.1.5 christos break;
4836 1.1.1.5 christos default:
4837 1.1.1.5 christos break;
4838 1.1.1.5 christos }
4839 1.1.1.5 christos
4840 1.1.1.5 christos p = frag_more (name_len + 1);
4841 1.1.1.5 christos strcpy (p, ereg->name);
4842 1.1.1.5 christos
4843 1.1.1.5 christos subseg_set (old_sec, old_subsec);
4844 1.1.1.5 christos }
4845 1.1.1.5 christos
4846 1.1.1.5 christos /* Handler .extCoreRegister pseudo-op. */
4847 1.1.1.5 christos
4848 1.1.1.5 christos static void
4849 1.1.1.5 christos arc_extcorereg (int opertype)
4850 1.1.1.5 christos {
4851 1.1.1.5 christos extRegister_t ereg;
4852 1.1.1.5 christos struct arc_aux_reg *auxr;
4853 1.1.1.5 christos struct arc_flag_operand *ccode;
4854 1.1.1.5 christos
4855 1.1.1.5 christos memset (&ereg, 0, sizeof (ereg));
4856 1.1.1.6 christos if (!tokenize_extregister (&ereg, opertype))
4857 1.1.1.6 christos return;
4858 1.1.1.5 christos
4859 1.1.1.5 christos switch (opertype)
4860 1.1.1.5 christos {
4861 1.1.1.5 christos case EXT_CORE_REGISTER:
4862 1.1.1.5 christos /* Core register. */
4863 1.1.1.5 christos if (ereg.number > 60)
4864 1.1.1.5 christos as_bad (_("core register %s value (%d) too large"), ereg.name,
4865 1.1.1.5 christos ereg.number);
4866 1.1.1.5 christos declare_register (ereg.name, ereg.number);
4867 1.1.1.5 christos break;
4868 1.1.1.5 christos case EXT_AUX_REGISTER:
4869 1.1.1.5 christos /* Auxiliary register. */
4870 1.1.1.5 christos auxr = XNEW (struct arc_aux_reg);
4871 1.1.1.5 christos auxr->name = ereg.name;
4872 1.1.1.6 christos auxr->cpu = selected_cpu.flags;
4873 1.1.1.5 christos auxr->subclass = NONE;
4874 1.1.1.5 christos auxr->address = ereg.number;
4875 1.1.1.8 christos if (str_hash_insert (arc_aux_hash, auxr->name, auxr, 0) != NULL)
4876 1.1.1.8 christos as_bad (_("duplicate aux register %s"), auxr->name);
4877 1.1.1.5 christos break;
4878 1.1.1.5 christos case EXT_COND_CODE:
4879 1.1.1.5 christos /* Condition code. */
4880 1.1.1.5 christos if (ereg.number > 31)
4881 1.1.1.5 christos as_bad (_("condition code %s value (%d) too large"), ereg.name,
4882 1.1.1.5 christos ereg.number);
4883 1.1.1.5 christos ext_condcode.size ++;
4884 1.1.1.5 christos ext_condcode.arc_ext_condcode =
4885 1.1.1.5 christos XRESIZEVEC (struct arc_flag_operand, ext_condcode.arc_ext_condcode,
4886 1.1.1.5 christos ext_condcode.size + 1);
4887 1.1.1.5 christos
4888 1.1.1.5 christos ccode = ext_condcode.arc_ext_condcode + ext_condcode.size - 1;
4889 1.1.1.5 christos ccode->name = ereg.name;
4890 1.1.1.5 christos ccode->code = ereg.number;
4891 1.1.1.5 christos ccode->bits = 5;
4892 1.1.1.5 christos ccode->shift = 0;
4893 1.1.1.5 christos ccode->favail = 0; /* not used. */
4894 1.1.1.5 christos ccode++;
4895 1.1.1.5 christos memset (ccode, 0, sizeof (struct arc_flag_operand));
4896 1.1.1.5 christos break;
4897 1.1.1.5 christos default:
4898 1.1.1.5 christos as_bad (_("Unknown extension"));
4899 1.1.1.5 christos break;
4900 1.1.1.5 christos }
4901 1.1.1.5 christos create_extcore_section (&ereg, opertype);
4902 1.1.1.5 christos }
4903 1.1.1.5 christos
4904 1.1.1.6 christos /* Parse a .arc_attribute directive. */
4905 1.1.1.6 christos
4906 1.1.1.6 christos static void
4907 1.1.1.6 christos arc_attribute (int ignored ATTRIBUTE_UNUSED)
4908 1.1.1.6 christos {
4909 1.1.1.6 christos int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
4910 1.1.1.6 christos
4911 1.1.1.6 christos if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
4912 1.1.1.8 christos attributes_set_explicitly[tag] = true;
4913 1.1.1.6 christos }
4914 1.1.1.6 christos
4915 1.1.1.6 christos /* Set an attribute if it has not already been set by the user. */
4916 1.1.1.6 christos
4917 1.1.1.6 christos static void
4918 1.1.1.6 christos arc_set_attribute_int (int tag, int value)
4919 1.1.1.6 christos {
4920 1.1.1.6 christos if (tag < 1
4921 1.1.1.6 christos || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
4922 1.1.1.6 christos || !attributes_set_explicitly[tag])
4923 1.1.1.6 christos bfd_elf_add_proc_attr_int (stdoutput, tag, value);
4924 1.1.1.6 christos }
4925 1.1.1.6 christos
4926 1.1.1.6 christos static void
4927 1.1.1.6 christos arc_set_attribute_string (int tag, const char *value)
4928 1.1.1.6 christos {
4929 1.1.1.6 christos if (tag < 1
4930 1.1.1.6 christos || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
4931 1.1.1.6 christos || !attributes_set_explicitly[tag])
4932 1.1.1.6 christos bfd_elf_add_proc_attr_string (stdoutput, tag, value);
4933 1.1.1.6 christos }
4934 1.1.1.6 christos
4935 1.1.1.6 christos /* Allocate and concatenate two strings. s1 can be NULL but not
4936 1.1.1.6 christos s2. s1 pointer is freed at end of this procedure. */
4937 1.1.1.6 christos
4938 1.1.1.6 christos static char *
4939 1.1.1.6 christos arc_stralloc (char * s1, const char * s2)
4940 1.1.1.6 christos {
4941 1.1.1.6 christos char * p;
4942 1.1.1.6 christos int len = 0;
4943 1.1.1.6 christos
4944 1.1.1.6 christos if (s1)
4945 1.1.1.6 christos len = strlen (s1) + 1;
4946 1.1.1.6 christos
4947 1.1.1.6 christos /* Only s1 can be null. */
4948 1.1.1.6 christos gas_assert (s2);
4949 1.1.1.6 christos len += strlen (s2) + 1;
4950 1.1.1.6 christos
4951 1.1.1.6 christos p = (char *) xmalloc (len);
4952 1.1.1.6 christos
4953 1.1.1.6 christos if (s1)
4954 1.1.1.6 christos {
4955 1.1.1.6 christos strcpy (p, s1);
4956 1.1.1.6 christos strcat (p, ",");
4957 1.1.1.6 christos strcat (p, s2);
4958 1.1.1.6 christos free (s1);
4959 1.1.1.6 christos }
4960 1.1.1.6 christos else
4961 1.1.1.6 christos strcpy (p, s2);
4962 1.1.1.6 christos
4963 1.1.1.6 christos return p;
4964 1.1.1.6 christos }
4965 1.1.1.6 christos
4966 1.1.1.6 christos /* Set the public ARC object attributes. */
4967 1.1.1.6 christos
4968 1.1.1.6 christos static void
4969 1.1.1.6 christos arc_set_public_attributes (void)
4970 1.1.1.6 christos {
4971 1.1.1.6 christos int base = 0;
4972 1.1.1.6 christos char *s = NULL;
4973 1.1.1.6 christos unsigned int i;
4974 1.1.1.6 christos
4975 1.1.1.6 christos /* Tag_ARC_CPU_name. */
4976 1.1.1.6 christos arc_set_attribute_string (Tag_ARC_CPU_name, selected_cpu.name);
4977 1.1.1.6 christos
4978 1.1.1.6 christos /* Tag_ARC_CPU_base. */
4979 1.1.1.6 christos switch (selected_cpu.eflags & EF_ARC_MACH_MSK)
4980 1.1.1.6 christos {
4981 1.1.1.6 christos case E_ARC_MACH_ARC600:
4982 1.1.1.6 christos case E_ARC_MACH_ARC601:
4983 1.1.1.6 christos base = TAG_CPU_ARC6xx;
4984 1.1.1.6 christos break;
4985 1.1.1.6 christos case E_ARC_MACH_ARC700:
4986 1.1.1.6 christos base = TAG_CPU_ARC7xx;
4987 1.1.1.6 christos break;
4988 1.1.1.6 christos case EF_ARC_CPU_ARCV2EM:
4989 1.1.1.6 christos base = TAG_CPU_ARCEM;
4990 1.1.1.6 christos break;
4991 1.1.1.6 christos case EF_ARC_CPU_ARCV2HS:
4992 1.1.1.6 christos base = TAG_CPU_ARCHS;
4993 1.1.1.6 christos break;
4994 1.1.1.6 christos default:
4995 1.1.1.6 christos base = 0;
4996 1.1.1.6 christos break;
4997 1.1.1.6 christos }
4998 1.1.1.6 christos if (attributes_set_explicitly[Tag_ARC_CPU_base]
4999 1.1.1.6 christos && (base != bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
5000 1.1.1.6 christos Tag_ARC_CPU_base)))
5001 1.1.1.6 christos as_warn (_("Overwrite explicitly set Tag_ARC_CPU_base"));
5002 1.1.1.6 christos bfd_elf_add_proc_attr_int (stdoutput, Tag_ARC_CPU_base, base);
5003 1.1.1.6 christos
5004 1.1.1.6 christos /* Tag_ARC_ABI_osver. */
5005 1.1.1.6 christos if (attributes_set_explicitly[Tag_ARC_ABI_osver])
5006 1.1.1.6 christos {
5007 1.1.1.6 christos int val = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
5008 1.1.1.6 christos Tag_ARC_ABI_osver);
5009 1.1.1.6 christos
5010 1.1.1.6 christos selected_cpu.eflags = ((selected_cpu.eflags & ~EF_ARC_OSABI_MSK)
5011 1.1.1.6 christos | (val & 0x0f << 8));
5012 1.1.1.6 christos }
5013 1.1.1.6 christos else
5014 1.1.1.6 christos {
5015 1.1.1.6 christos arc_set_attribute_int (Tag_ARC_ABI_osver, E_ARC_OSABI_CURRENT >> 8);
5016 1.1.1.6 christos }
5017 1.1.1.6 christos
5018 1.1.1.6 christos /* Tag_ARC_ISA_config. */
5019 1.1.1.6 christos arc_check_feature();
5020 1.1.1.6 christos
5021 1.1.1.6 christos for (i = 0; i < ARRAY_SIZE (feature_list); i++)
5022 1.1.1.6 christos if (selected_cpu.features & feature_list[i].feature)
5023 1.1.1.6 christos s = arc_stralloc (s, feature_list[i].attr);
5024 1.1.1.6 christos
5025 1.1.1.6 christos if (s)
5026 1.1.1.6 christos arc_set_attribute_string (Tag_ARC_ISA_config, s);
5027 1.1.1.6 christos
5028 1.1.1.6 christos /* Tag_ARC_ISA_mpy_option. */
5029 1.1.1.6 christos arc_set_attribute_int (Tag_ARC_ISA_mpy_option, mpy_option);
5030 1.1.1.6 christos
5031 1.1.1.6 christos /* Tag_ARC_ABI_pic. */
5032 1.1.1.6 christos arc_set_attribute_int (Tag_ARC_ABI_pic, pic_option);
5033 1.1.1.6 christos
5034 1.1.1.6 christos /* Tag_ARC_ABI_sda. */
5035 1.1.1.6 christos arc_set_attribute_int (Tag_ARC_ABI_sda, sda_option);
5036 1.1.1.6 christos
5037 1.1.1.6 christos /* Tag_ARC_ABI_tls. */
5038 1.1.1.6 christos arc_set_attribute_int (Tag_ARC_ABI_tls, tls_option);
5039 1.1.1.7 christos
5040 1.1.1.7 christos /* Tag_ARC_ATR_version. */
5041 1.1.1.7 christos arc_set_attribute_int (Tag_ARC_ATR_version, 1);
5042 1.1.1.7 christos
5043 1.1.1.7 christos /* Tag_ARC_ABI_rf16. */
5044 1.1.1.7 christos if (attributes_set_explicitly[Tag_ARC_ABI_rf16]
5045 1.1.1.7 christos && bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
5046 1.1.1.7 christos Tag_ARC_ABI_rf16)
5047 1.1.1.7 christos && !rf16_only)
5048 1.1.1.7 christos {
5049 1.1.1.7 christos as_warn (_("Overwrite explicitly set Tag_ARC_ABI_rf16 to full "
5050 1.1.1.7 christos "register file"));
5051 1.1.1.7 christos bfd_elf_add_proc_attr_int (stdoutput, Tag_ARC_ABI_rf16, 0);
5052 1.1.1.7 christos }
5053 1.1.1.6 christos }
5054 1.1.1.6 christos
5055 1.1.1.6 christos /* Add the default contents for the .ARC.attributes section. */
5056 1.1.1.6 christos
5057 1.1.1.6 christos void
5058 1.1.1.6 christos arc_md_end (void)
5059 1.1.1.6 christos {
5060 1.1.1.6 christos arc_set_public_attributes ();
5061 1.1.1.6 christos
5062 1.1.1.6 christos if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
5063 1.1.1.6 christos as_fatal (_("could not set architecture and machine"));
5064 1.1.1.6 christos
5065 1.1.1.6 christos bfd_set_private_flags (stdoutput, selected_cpu.eflags);
5066 1.1.1.6 christos }
5067 1.1.1.6 christos
5068 1.1.1.6 christos void arc_copy_symbol_attributes (symbolS *dest, symbolS *src)
5069 1.1.1.6 christos {
5070 1.1.1.6 christos ARC_GET_FLAG (dest) = ARC_GET_FLAG (src);
5071 1.1.1.6 christos }
5072 1.1.1.6 christos
5073 1.1.1.6 christos int arc_convert_symbolic_attribute (const char *name)
5074 1.1.1.6 christos {
5075 1.1.1.6 christos static const struct
5076 1.1.1.6 christos {
5077 1.1.1.6 christos const char * name;
5078 1.1.1.6 christos const int tag;
5079 1.1.1.6 christos }
5080 1.1.1.6 christos attribute_table[] =
5081 1.1.1.6 christos {
5082 1.1.1.6 christos #define T(tag) {#tag, tag}
5083 1.1.1.6 christos T (Tag_ARC_PCS_config),
5084 1.1.1.6 christos T (Tag_ARC_CPU_base),
5085 1.1.1.6 christos T (Tag_ARC_CPU_variation),
5086 1.1.1.6 christos T (Tag_ARC_CPU_name),
5087 1.1.1.6 christos T (Tag_ARC_ABI_rf16),
5088 1.1.1.6 christos T (Tag_ARC_ABI_osver),
5089 1.1.1.6 christos T (Tag_ARC_ABI_sda),
5090 1.1.1.6 christos T (Tag_ARC_ABI_pic),
5091 1.1.1.6 christos T (Tag_ARC_ABI_tls),
5092 1.1.1.6 christos T (Tag_ARC_ABI_enumsize),
5093 1.1.1.6 christos T (Tag_ARC_ABI_exceptions),
5094 1.1.1.6 christos T (Tag_ARC_ABI_double_size),
5095 1.1.1.6 christos T (Tag_ARC_ISA_config),
5096 1.1.1.6 christos T (Tag_ARC_ISA_apex),
5097 1.1.1.7 christos T (Tag_ARC_ISA_mpy_option),
5098 1.1.1.7 christos T (Tag_ARC_ATR_version)
5099 1.1.1.6 christos #undef T
5100 1.1.1.6 christos };
5101 1.1.1.6 christos unsigned int i;
5102 1.1.1.6 christos
5103 1.1.1.6 christos if (name == NULL)
5104 1.1.1.6 christos return -1;
5105 1.1.1.6 christos
5106 1.1.1.6 christos for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
5107 1.1.1.6 christos if (streq (name, attribute_table[i].name))
5108 1.1.1.6 christos return attribute_table[i].tag;
5109 1.1.1.6 christos
5110 1.1.1.6 christos return -1;
5111 1.1.1.6 christos }
5112 1.1.1.6 christos
5113 1.1.1.5 christos /* Local variables:
5114 1.1.1.5 christos eval: (c-set-style "gnu")
5115 1.1.1.5 christos indent-tabs-mode: t
5116 1.1.1.5 christos End: */
5117