]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-arc.c
Remove unneeded AUX register symbols.
[thirdparty/binutils-gdb.git] / gas / config / tc-arc.c
1 /* tc-arc.c -- Assembler for the ARC
2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
3
4 Contributor: Claudiu Zissulescu <claziss@synopsys.com>
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
22
23 #include "as.h"
24 #include "subsegs.h"
25 #include "struc-symbol.h"
26 #include "dwarf2dbg.h"
27 #include "dw2gencfi.h"
28 #include "safe-ctype.h"
29
30 #include "opcode/arc.h"
31 #include "elf/arc.h"
32
33 /* Defines section. */
34
35 #define MAX_INSN_FIXUPS 2
36 #define MAX_CONSTR_STR 20
37 #define FRAG_MAX_GROWTH 8
38
39 #ifdef DEBUG
40 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
41 #else
42 # define pr_debug(fmt, args...)
43 #endif
44
45 #define MAJOR_OPCODE(x) (((x) & 0xF8000000) >> 27)
46 #define SUB_OPCODE(x) (((x) & 0x003F0000) >> 16)
47 #define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) && \
48 (SUB_OPCODE (x) == 0x28))
49
50 /* Equal to MAX_PRECISION in atof-ieee.c. */
51 #define MAX_LITTLENUMS 6
52
53 /* Enum used to enumerate the relaxable ins operands. */
54 enum rlx_operand_type
55 {
56 EMPTY = 0,
57 REGISTER,
58 REGISTER_S, /* Register for short instruction(s). */
59 REGISTER_NO_GP, /* Is a register but not gp register specifically. */
60 REGISTER_DUP, /* Duplication of previous operand of type register. */
61 IMMEDIATE,
62 BRACKET
63 };
64
65 enum arc_rlx_types
66 {
67 ARC_RLX_NONE = 0,
68 ARC_RLX_BL_S,
69 ARC_RLX_BL,
70 ARC_RLX_B_S,
71 ARC_RLX_B,
72 ARC_RLX_ADD_U3,
73 ARC_RLX_ADD_U6,
74 ARC_RLX_ADD_LIMM,
75 ARC_RLX_LD_U7,
76 ARC_RLX_LD_S9,
77 ARC_RLX_LD_LIMM,
78 ARC_RLX_MOV_U8,
79 ARC_RLX_MOV_S12,
80 ARC_RLX_MOV_LIMM,
81 ARC_RLX_SUB_U3,
82 ARC_RLX_SUB_U6,
83 ARC_RLX_SUB_LIMM,
84 ARC_RLX_MPY_U6,
85 ARC_RLX_MPY_LIMM,
86 ARC_RLX_MOV_RU6,
87 ARC_RLX_MOV_RLIMM,
88 ARC_RLX_ADD_RRU6,
89 ARC_RLX_ADD_RRLIMM,
90 };
91
92 /* Macros section. */
93
94 #define regno(x) ((x) & 0x3F)
95 #define is_ir_num(x) (((x) & ~0x3F) == 0)
96 #define is_code_density_p(sc) (((sc) == CD1 || (sc) == CD2))
97 #define is_spfp_p(op) (((sc) == SPX))
98 #define is_dpfp_p(op) (((sc) == DPX))
99 #define is_fpuda_p(op) (((sc) == DPA))
100 #define is_br_jmp_insn_p(op) (((op)->class == BRANCH || (op)->class == JUMP))
101 #define is_kernel_insn_p(op) (((op)->class == KERNEL))
102
103 /* Generic assembler global variables which must be defined by all
104 targets. */
105
106 /* Characters which always start a comment. */
107 const char comment_chars[] = "#;";
108
109 /* Characters which start a comment at the beginning of a line. */
110 const char line_comment_chars[] = "#";
111
112 /* Characters which may be used to separate multiple commands on a
113 single line. */
114 const char line_separator_chars[] = "`";
115
116 /* Characters which are used to indicate an exponent in a floating
117 point number. */
118 const char EXP_CHARS[] = "eE";
119
120 /* Chars that mean this number is a floating point constant
121 As in 0f12.456 or 0d1.2345e12. */
122 const char FLT_CHARS[] = "rRsSfFdD";
123
124 /* Byte order. */
125 extern int target_big_endian;
126 const char *arc_target_format = DEFAULT_TARGET_FORMAT;
127 static int byte_order = DEFAULT_BYTE_ORDER;
128
129 /* By default relaxation is disabled. */
130 static int relaxation_state = 0;
131
132 extern int arc_get_mach (char *);
133
134 /* Forward declarations. */
135 static void arc_lcomm (int);
136 static void arc_option (int);
137 static void arc_extra_reloc (int);
138
139
140 const pseudo_typeS md_pseudo_table[] =
141 {
142 /* Make sure that .word is 32 bits. */
143 { "word", cons, 4 },
144
145 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */
146 { "lcomm", arc_lcomm, 0 },
147 { "lcommon", arc_lcomm, 0 },
148 { "cpu", arc_option, 0 },
149
150 { "tls_gd_ld", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD },
151 { "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL },
152
153 { NULL, NULL, 0 }
154 };
155
156 const char *md_shortopts = "";
157
158 enum options
159 {
160 OPTION_EB = OPTION_MD_BASE,
161 OPTION_EL,
162
163 OPTION_ARC600,
164 OPTION_ARC601,
165 OPTION_ARC700,
166 OPTION_ARCEM,
167 OPTION_ARCHS,
168
169 OPTION_MCPU,
170 OPTION_CD,
171 OPTION_RELAX,
172
173 /* The following options are deprecated and provided here only for
174 compatibility reasons. */
175 OPTION_USER_MODE,
176 OPTION_LD_EXT_MASK,
177 OPTION_SWAP,
178 OPTION_NORM,
179 OPTION_BARREL_SHIFT,
180 OPTION_MIN_MAX,
181 OPTION_NO_MPY,
182 OPTION_EA,
183 OPTION_MUL64,
184 OPTION_SIMD,
185 OPTION_SPFP,
186 OPTION_DPFP,
187 OPTION_XMAC_D16,
188 OPTION_XMAC_24,
189 OPTION_DSP_PACKA,
190 OPTION_CRC,
191 OPTION_DVBF,
192 OPTION_TELEPHONY,
193 OPTION_XYMEMORY,
194 OPTION_LOCK,
195 OPTION_SWAPE,
196 OPTION_RTSC,
197 OPTION_FPUDA
198 };
199
200 struct option md_longopts[] =
201 {
202 { "EB", no_argument, NULL, OPTION_EB },
203 { "EL", no_argument, NULL, OPTION_EL },
204 { "mcpu", required_argument, NULL, OPTION_MCPU },
205 { "mA6", no_argument, NULL, OPTION_ARC600 },
206 { "mARC600", no_argument, NULL, OPTION_ARC600 },
207 { "mARC601", no_argument, NULL, OPTION_ARC601 },
208 { "mARC700", no_argument, NULL, OPTION_ARC700 },
209 { "mA7", no_argument, NULL, OPTION_ARC700 },
210 { "mEM", no_argument, NULL, OPTION_ARCEM },
211 { "mHS", no_argument, NULL, OPTION_ARCHS },
212 { "mcode-density", no_argument, NULL, OPTION_CD },
213 { "mrelax", no_argument, NULL, OPTION_RELAX },
214
215 /* The following options are deprecated and provided here only for
216 compatibility reasons. */
217 { "mav2em", no_argument, NULL, OPTION_ARCEM },
218 { "mav2hs", no_argument, NULL, OPTION_ARCHS },
219 { "muser-mode-only", no_argument, NULL, OPTION_USER_MODE },
220 { "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK },
221 { "mswap", no_argument, NULL, OPTION_SWAP },
222 { "mnorm", no_argument, NULL, OPTION_NORM },
223 { "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
224 { "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
225 { "mmin-max", no_argument, NULL, OPTION_MIN_MAX },
226 { "mmin_max", no_argument, NULL, OPTION_MIN_MAX },
227 { "mno-mpy", no_argument, NULL, OPTION_NO_MPY },
228 { "mea", no_argument, NULL, OPTION_EA },
229 { "mEA", no_argument, NULL, OPTION_EA },
230 { "mmul64", no_argument, NULL, OPTION_MUL64 },
231 { "msimd", no_argument, NULL, OPTION_SIMD},
232 { "mspfp", no_argument, NULL, OPTION_SPFP},
233 { "mspfp-compact", no_argument, NULL, OPTION_SPFP},
234 { "mspfp_compact", no_argument, NULL, OPTION_SPFP},
235 { "mspfp-fast", no_argument, NULL, OPTION_SPFP},
236 { "mspfp_fast", no_argument, NULL, OPTION_SPFP},
237 { "mdpfp", no_argument, NULL, OPTION_DPFP},
238 { "mdpfp-compact", no_argument, NULL, OPTION_DPFP},
239 { "mdpfp_compact", no_argument, NULL, OPTION_DPFP},
240 { "mdpfp-fast", no_argument, NULL, OPTION_DPFP},
241 { "mdpfp_fast", no_argument, NULL, OPTION_DPFP},
242 { "mmac-d16", no_argument, NULL, OPTION_XMAC_D16},
243 { "mmac_d16", no_argument, NULL, OPTION_XMAC_D16},
244 { "mmac-24", no_argument, NULL, OPTION_XMAC_24},
245 { "mmac_24", no_argument, NULL, OPTION_XMAC_24},
246 { "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA},
247 { "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA},
248 { "mcrc", no_argument, NULL, OPTION_CRC},
249 { "mdvbf", no_argument, NULL, OPTION_DVBF},
250 { "mtelephony", no_argument, NULL, OPTION_TELEPHONY},
251 { "mxy", no_argument, NULL, OPTION_XYMEMORY},
252 { "mlock", no_argument, NULL, OPTION_LOCK},
253 { "mswape", no_argument, NULL, OPTION_SWAPE},
254 { "mrtsc", no_argument, NULL, OPTION_RTSC},
255 { "mfpuda", no_argument, NULL, OPTION_FPUDA},
256
257 { NULL, no_argument, NULL, 0 }
258 };
259
260 size_t md_longopts_size = sizeof (md_longopts);
261
262 /* Local data and data types. */
263
264 /* Used since new relocation types are introduced in this
265 file (DUMMY_RELOC_LITUSE_*). */
266 typedef int extended_bfd_reloc_code_real_type;
267
268 struct arc_fixup
269 {
270 expressionS exp;
271
272 extended_bfd_reloc_code_real_type reloc;
273
274 /* index into arc_operands. */
275 unsigned int opindex;
276
277 /* PC-relative, used by internals fixups. */
278 unsigned char pcrel;
279
280 /* TRUE if this fixup is for LIMM operand. */
281 bfd_boolean islong;
282 };
283
284 struct arc_insn
285 {
286 unsigned int insn;
287 int nfixups;
288 struct arc_fixup fixups[MAX_INSN_FIXUPS];
289 long limm;
290 bfd_boolean short_insn; /* Boolean value: TRUE if current insn is
291 short. */
292 bfd_boolean has_limm; /* Boolean value: TRUE if limm field is
293 valid. */
294 bfd_boolean relax; /* Boolean value: TRUE if needs
295 relaxation. */
296 };
297
298 /* Structure to hold any last two instructions. */
299 static struct arc_last_insn
300 {
301 /* Saved instruction opcode. */
302 const struct arc_opcode *opcode;
303
304 /* Boolean value: TRUE if current insn is short. */
305 bfd_boolean has_limm;
306
307 /* Boolean value: TRUE if current insn has delay slot. */
308 bfd_boolean has_delay_slot;
309 } arc_last_insns[2];
310
311 /* Structure to hold an entry in ARC_OPCODE_HASH. */
312 struct arc_opcode_hash_entry
313 {
314 /* The number of pointers in the OPCODE list. */
315 size_t count;
316
317 /* Points to a list of opcode pointers. */
318 const struct arc_opcode **opcode;
319 };
320
321 /* Structure used for iterating through an arc_opcode_hash_entry. */
322 struct arc_opcode_hash_entry_iterator
323 {
324 /* Index into the OPCODE element of the arc_opcode_hash_entry. */
325 size_t index;
326
327 /* The specific ARC_OPCODE from the ARC_OPCODES table that was last
328 returned by this iterator. */
329 const struct arc_opcode *opcode;
330 };
331
332 /* Forward declaration. */
333 static void assemble_insn
334 (const struct arc_opcode *, const expressionS *, int,
335 const struct arc_flags *, int, struct arc_insn *);
336
337 /* The cpu for which we are generating code. */
338 static unsigned arc_target;
339 static const char *arc_target_name;
340 static unsigned arc_features;
341
342 /* The default architecture. */
343 static int arc_mach_type;
344
345 /* Non-zero if the cpu type has been explicitly specified. */
346 static int mach_type_specified_p = 0;
347
348 /* The hash table of instruction opcodes. */
349 static struct hash_control *arc_opcode_hash;
350
351 /* The hash table of register symbols. */
352 static struct hash_control *arc_reg_hash;
353
354 /* A table of CPU names and opcode sets. */
355 static const struct cpu_type
356 {
357 const char *name;
358 unsigned flags;
359 int mach;
360 unsigned eflags;
361 unsigned features;
362 }
363 cpu_types[] =
364 {
365 { "arc600", ARC_OPCODE_ARC600, bfd_mach_arc_arc600,
366 E_ARC_MACH_ARC600, 0x00},
367 { "arc700", ARC_OPCODE_ARC700, bfd_mach_arc_arc700,
368 E_ARC_MACH_ARC700, 0x00},
369 { "nps400", ARC_OPCODE_ARC700 | ARC_OPCODE_NPS400, bfd_mach_arc_nps400,
370 E_ARC_MACH_NPS400, 0x00},
371 { "arcem", ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2,
372 EF_ARC_CPU_ARCV2EM, ARC_CD},
373 { "archs", ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2,
374 EF_ARC_CPU_ARCV2HS, ARC_CD},
375 { 0, 0, 0, 0, 0 }
376 };
377
378 /* Used by the arc_reloc_op table. Order is important. */
379 #define O_gotoff O_md1 /* @gotoff relocation. */
380 #define O_gotpc O_md2 /* @gotpc relocation. */
381 #define O_plt O_md3 /* @plt relocation. */
382 #define O_sda O_md4 /* @sda relocation. */
383 #define O_pcl O_md5 /* @pcl relocation. */
384 #define O_tlsgd O_md6 /* @tlsgd relocation. */
385 #define O_tlsie O_md7 /* @tlsie relocation. */
386 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
387 #define O_tpoff O_md9 /* @tpoff relocation. */
388 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
389 #define O_dtpoff O_md11 /* @dtpoff relocation. */
390 #define O_last O_dtpoff
391
392 /* Used to define a bracket as operand in tokens. */
393 #define O_bracket O_md32
394
395 /* Dummy relocation, to be sorted out. */
396 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
397
398 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
399
400 /* A table to map the spelling of a relocation operand into an appropriate
401 bfd_reloc_code_real_type type. The table is assumed to be ordered such
402 that op-O_literal indexes into it. */
403 #define ARC_RELOC_TABLE(op) \
404 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
405 ? (abort (), 0) \
406 : (int) (op) - (int) O_gotoff) ])
407
408 #define DEF(NAME, RELOC, REQ) \
409 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
410
411 static const struct arc_reloc_op_tag
412 {
413 /* String to lookup. */
414 const char *name;
415 /* Size of the string. */
416 size_t length;
417 /* Which operator to use. */
418 operatorT op;
419 extended_bfd_reloc_code_real_type reloc;
420 /* Allows complex relocation expression like identifier@reloc +
421 const. */
422 unsigned int complex_expr : 1;
423 }
424 arc_reloc_op[] =
425 {
426 DEF (gotoff, BFD_RELOC_ARC_GOTOFF, 1),
427 DEF (gotpc, BFD_RELOC_ARC_GOTPC32, 0),
428 DEF (plt, BFD_RELOC_ARC_PLT32, 0),
429 DEF (sda, DUMMY_RELOC_ARC_ENTRY, 1),
430 DEF (pcl, BFD_RELOC_ARC_PC32, 1),
431 DEF (tlsgd, BFD_RELOC_ARC_TLS_GD_GOT, 0),
432 DEF (tlsie, BFD_RELOC_ARC_TLS_IE_GOT, 0),
433 DEF (tpoff9, BFD_RELOC_ARC_TLS_LE_S9, 0),
434 DEF (tpoff, BFD_RELOC_ARC_TLS_LE_32, 1),
435 DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9, 0),
436 DEF (dtpoff, BFD_RELOC_ARC_TLS_DTPOFF, 0),
437 };
438
439 static const int arc_num_reloc_op
440 = sizeof (arc_reloc_op) / sizeof (*arc_reloc_op);
441
442 /* Structure for relaxable instruction that have to be swapped with a
443 smaller alternative instruction. */
444 struct arc_relaxable_ins
445 {
446 /* Mnemonic that should be checked. */
447 const char *mnemonic_r;
448
449 /* Operands that should be checked.
450 Indexes of operands from operand array. */
451 enum rlx_operand_type operands[6];
452
453 /* Flags that should be checked. */
454 unsigned flag_classes[5];
455
456 /* Mnemonic (smaller) alternative to be used later for relaxation. */
457 const char *mnemonic_alt;
458
459 /* Index of operand that generic relaxation has to check. */
460 unsigned opcheckidx;
461
462 /* Base subtype index used. */
463 enum arc_rlx_types subtype;
464 };
465
466 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \
467 { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \
468 (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \
469 (SIZE), \
470 (NEXT) } \
471
472 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \
473 { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \
474 (ISSIGNED) ? -(0x7FFFFFFF) : 0, \
475 (SIZE), \
476 (NEXT) } \
477
478
479 /* ARC relaxation table. */
480 const relax_typeS md_relax_table[] =
481 {
482 /* Fake entry. */
483 {0, 0, 0, 0},
484
485 /* BL_S s13 ->
486 BL s25. */
487 RELAX_TABLE_ENTRY(13, 1, 2, ARC_RLX_BL),
488 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE),
489
490 /* B_S s10 ->
491 B s25. */
492 RELAX_TABLE_ENTRY(10, 1, 2, ARC_RLX_B),
493 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE),
494
495 /* ADD_S c,b, u3 ->
496 ADD<.f> a,b,u6 ->
497 ADD<.f> a,b,limm. */
498 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_ADD_U6),
499 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_LIMM),
500 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
501
502 /* LD_S a, [b, u7] ->
503 LD<zz><.x><.aa><.di> a, [b, s9] ->
504 LD<zz><.x><.aa><.di> a, [b, limm] */
505 RELAX_TABLE_ENTRY(7, 0, 2, ARC_RLX_LD_S9),
506 RELAX_TABLE_ENTRY(9, 1, 4, ARC_RLX_LD_LIMM),
507 RELAX_TABLE_ENTRY_MAX(1, 8, ARC_RLX_NONE),
508
509 /* MOV_S b, u8 ->
510 MOV<.f> b, s12 ->
511 MOV<.f> b, limm. */
512 RELAX_TABLE_ENTRY(8, 0, 2, ARC_RLX_MOV_S12),
513 RELAX_TABLE_ENTRY(8, 0, 4, ARC_RLX_MOV_LIMM),
514 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
515
516 /* SUB_S c, b, u3 ->
517 SUB<.f> a, b, u6 ->
518 SUB<.f> a, b, limm. */
519 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_SUB_U6),
520 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_SUB_LIMM),
521 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
522
523 /* MPY<.f> a, b, u6 ->
524 MPY<.f> a, b, limm. */
525 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MPY_LIMM),
526 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
527
528 /* MOV<.f><.cc> b, u6 ->
529 MOV<.f><.cc> b, limm. */
530 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MOV_RLIMM),
531 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
532
533 /* ADD<.f><.cc> b, b, u6 ->
534 ADD<.f><.cc> b, b, limm. */
535 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_RRLIMM),
536 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
537 };
538
539 /* Order of this table's entries matters! */
540 const struct arc_relaxable_ins arc_relaxable_insns[] =
541 {
542 { "bl", { IMMEDIATE }, { 0 }, "bl_s", 0, ARC_RLX_BL_S },
543 { "b", { IMMEDIATE }, { 0 }, "b_s", 0, ARC_RLX_B_S },
544 { "add", { REGISTER, REGISTER_DUP, IMMEDIATE }, { 5, 1, 0 }, "add",
545 2, ARC_RLX_ADD_RRU6},
546 { "add", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "add_s", 2,
547 ARC_RLX_ADD_U3 },
548 { "add", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "add", 2,
549 ARC_RLX_ADD_U6 },
550 { "ld", { REGISTER_S, BRACKET, REGISTER_S, IMMEDIATE, BRACKET },
551 { 0 }, "ld_s", 3, ARC_RLX_LD_U7 },
552 { "ld", { REGISTER, BRACKET, REGISTER_NO_GP, IMMEDIATE, BRACKET },
553 { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9 },
554 { "mov", { REGISTER_S, IMMEDIATE }, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8 },
555 { "mov", { REGISTER, IMMEDIATE }, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12 },
556 { "mov", { REGISTER, IMMEDIATE }, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6 },
557 { "sub", { REGISTER_S, REGISTER_S, IMMEDIATE }, { 0 }, "sub_s", 2,
558 ARC_RLX_SUB_U3 },
559 { "sub", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "sub", 2,
560 ARC_RLX_SUB_U6 },
561 { "mpy", { REGISTER, REGISTER, IMMEDIATE }, { 5, 0 }, "mpy", 2,
562 ARC_RLX_MPY_U6 },
563 };
564
565 const unsigned arc_num_relaxable_ins = ARRAY_SIZE (arc_relaxable_insns);
566
567 /* Flags to set in the elf header. */
568 static flagword arc_eflag = 0x00;
569
570 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
571 symbolS * GOT_symbol = 0;
572
573 /* Set to TRUE when we assemble instructions. */
574 static bfd_boolean assembling_insn = FALSE;
575
576 /* Functions implementation. */
577
578 /* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all
579 ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if there
580 are no matching entries in ARC_OPCODE_HASH. */
581
582 static const struct arc_opcode_hash_entry *
583 arc_find_opcode (const char *name)
584 {
585 const struct arc_opcode_hash_entry *entry;
586
587 entry = hash_find (arc_opcode_hash, name);
588 return entry;
589 }
590
591 /* Initialise the iterator ITER. */
592
593 static void
594 arc_opcode_hash_entry_iterator_init (struct arc_opcode_hash_entry_iterator *iter)
595 {
596 iter->index = 0;
597 iter->opcode = NULL;
598 }
599
600 /* Return the next ARC_OPCODE from ENTRY, using ITER to hold state between
601 calls to this function. Return NULL when all ARC_OPCODE entries have
602 been returned. */
603
604 static const struct arc_opcode *
605 arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry *entry,
606 struct arc_opcode_hash_entry_iterator *iter)
607 {
608 if (iter->opcode == NULL && iter->index == 0)
609 {
610 gas_assert (entry->count > 0);
611 iter->opcode = entry->opcode[iter->index];
612 }
613 else if (iter->opcode != NULL)
614 {
615 const char *old_name = iter->opcode->name;
616
617 iter->opcode++;
618 if ((iter->opcode - arc_opcodes >= (int) arc_num_opcodes)
619 || (strcmp (old_name, iter->opcode->name) != 0))
620 {
621 iter->index++;
622 if (iter->index == entry->count)
623 iter->opcode = NULL;
624 else
625 iter->opcode = entry->opcode[iter->index];
626 }
627 }
628
629 return iter->opcode;
630 }
631
632 /* Like md_number_to_chars but used for limms. The 4-byte limm value,
633 is encoded as 'middle-endian' for a little-endian target. FIXME!
634 this function is used for regular 4 byte instructions as well. */
635
636 static void
637 md_number_to_chars_midend (char *buf, valueT val, int n)
638 {
639 if (n == 4)
640 {
641 md_number_to_chars (buf, (val & 0xffff0000) >> 16, 2);
642 md_number_to_chars (buf + 2, (val & 0xffff), 2);
643 }
644 else
645 {
646 md_number_to_chars (buf, val, n);
647 }
648 }
649
650 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
651 the relevant static global variables. */
652
653 static void
654 arc_select_cpu (const char *arg)
655 {
656 int cpu_flags = 0;
657 int i;
658
659 for (i = 0; cpu_types[i].name; ++i)
660 {
661 if (!strcasecmp (cpu_types[i].name, arg))
662 {
663 arc_target = cpu_types[i].flags;
664 arc_target_name = cpu_types[i].name;
665 arc_features = cpu_types[i].features;
666 arc_mach_type = cpu_types[i].mach;
667 cpu_flags = cpu_types[i].eflags;
668 break;
669 }
670 }
671
672 if (!cpu_types[i].name)
673 as_fatal (_("unknown architecture: %s\n"), arg);
674 gas_assert (cpu_flags != 0);
675 arc_eflag = (arc_eflag & ~EF_ARC_MACH_MSK) | cpu_flags;
676 }
677
678 /* Here ends all the ARCompact extension instruction assembling
679 stuff. */
680
681 static void
682 arc_extra_reloc (int r_type)
683 {
684 char *sym_name, c;
685 symbolS *sym, *lab = NULL;
686
687 if (*input_line_pointer == '@')
688 input_line_pointer++;
689 c = get_symbol_name (&sym_name);
690 sym = symbol_find_or_make (sym_name);
691 restore_line_pointer (c);
692 if (c == ',' && r_type == BFD_RELOC_ARC_TLS_GD_LD)
693 {
694 ++input_line_pointer;
695 char *lab_name;
696 c = get_symbol_name (&lab_name);
697 lab = symbol_find_or_make (lab_name);
698 restore_line_pointer (c);
699 }
700
701 /* These relocations exist as a mechanism for the compiler to tell the
702 linker how to patch the code if the tls model is optimised. However,
703 the relocation itself does not require any space within the assembler
704 fragment, and so we pass a size of 0.
705
706 The lines that generate these relocations look like this:
707
708 .tls_gd_ld @.tdata`bl __tls_get_addr@plt
709
710 The '.tls_gd_ld @.tdata' is processed first and generates the
711 additional relocation, while the 'bl __tls_get_addr@plt' is processed
712 second and generates the additional branch.
713
714 It is possible that the additional relocation generated by the
715 '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
716 while the 'bl __tls_get_addr@plt' will be generated as the first thing
717 in the next fragment. This will be fine; both relocations will still
718 appear to be at the same address in the generated object file.
719 However, this only works as the additional relocation is generated
720 with size of 0 bytes. */
721 fixS *fixP
722 = fix_new (frag_now, /* Which frag? */
723 frag_now_fix (), /* Where in that frag? */
724 0, /* size: 1, 2, or 4 usually. */
725 sym, /* X_add_symbol. */
726 0, /* X_add_number. */
727 FALSE, /* TRUE if PC-relative relocation. */
728 r_type /* Relocation type. */);
729 fixP->fx_subsy = lab;
730 }
731
732 static symbolS *
733 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED,
734 symbolS *symbolP, addressT size)
735 {
736 addressT align = 0;
737 SKIP_WHITESPACE ();
738
739 if (*input_line_pointer == ',')
740 {
741 align = parse_align (1);
742
743 if (align == (addressT) -1)
744 return NULL;
745 }
746 else
747 {
748 if (size >= 8)
749 align = 3;
750 else if (size >= 4)
751 align = 2;
752 else if (size >= 2)
753 align = 1;
754 else
755 align = 0;
756 }
757
758 bss_alloc (symbolP, size, align);
759 S_CLEAR_EXTERNAL (symbolP);
760
761 return symbolP;
762 }
763
764 static void
765 arc_lcomm (int ignore)
766 {
767 symbolS *symbolP = s_comm_internal (ignore, arc_lcomm_internal);
768
769 if (symbolP)
770 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
771 }
772
773 /* Select the cpu we're assembling for. */
774
775 static void
776 arc_option (int ignore ATTRIBUTE_UNUSED)
777 {
778 int mach = -1;
779 char c;
780 char *cpu;
781
782 c = get_symbol_name (&cpu);
783 mach = arc_get_mach (cpu);
784
785 if (mach == -1)
786 goto bad_cpu;
787
788 if (!mach_type_specified_p)
789 {
790 if ((!strcmp ("ARC600", cpu))
791 || (!strcmp ("ARC601", cpu))
792 || (!strcmp ("A6", cpu)))
793 {
794 md_parse_option (OPTION_MCPU, "arc600");
795 }
796 else if ((!strcmp ("ARC700", cpu))
797 || (!strcmp ("A7", cpu)))
798 {
799 md_parse_option (OPTION_MCPU, "arc700");
800 }
801 else if (!strcmp ("EM", cpu))
802 {
803 md_parse_option (OPTION_MCPU, "arcem");
804 }
805 else if (!strcmp ("HS", cpu))
806 {
807 md_parse_option (OPTION_MCPU, "archs");
808 }
809 else
810 as_fatal (_("could not find the architecture"));
811
812 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
813 as_fatal (_("could not set architecture and machine"));
814 }
815 else
816 if (arc_mach_type != mach)
817 as_warn (_("Command-line value overrides \".cpu\" directive"));
818
819 restore_line_pointer (c);
820 demand_empty_rest_of_line ();
821 return;
822
823 bad_cpu:
824 restore_line_pointer (c);
825 as_bad (_("invalid identifier for \".cpu\""));
826 ignore_rest_of_line ();
827 }
828
829 /* Smartly print an expression. */
830
831 static void
832 debug_exp (expressionS *t)
833 {
834 const char *name ATTRIBUTE_UNUSED;
835 const char *namemd ATTRIBUTE_UNUSED;
836
837 pr_debug ("debug_exp: ");
838
839 switch (t->X_op)
840 {
841 default: name = "unknown"; break;
842 case O_illegal: name = "O_illegal"; break;
843 case O_absent: name = "O_absent"; break;
844 case O_constant: name = "O_constant"; break;
845 case O_symbol: name = "O_symbol"; break;
846 case O_symbol_rva: name = "O_symbol_rva"; break;
847 case O_register: name = "O_register"; break;
848 case O_big: name = "O_big"; break;
849 case O_uminus: name = "O_uminus"; break;
850 case O_bit_not: name = "O_bit_not"; break;
851 case O_logical_not: name = "O_logical_not"; break;
852 case O_multiply: name = "O_multiply"; break;
853 case O_divide: name = "O_divide"; break;
854 case O_modulus: name = "O_modulus"; break;
855 case O_left_shift: name = "O_left_shift"; break;
856 case O_right_shift: name = "O_right_shift"; break;
857 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
858 case O_bit_or_not: name = "O_bit_or_not"; break;
859 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
860 case O_bit_and: name = "O_bit_and"; break;
861 case O_add: name = "O_add"; break;
862 case O_subtract: name = "O_subtract"; break;
863 case O_eq: name = "O_eq"; break;
864 case O_ne: name = "O_ne"; break;
865 case O_lt: name = "O_lt"; break;
866 case O_le: name = "O_le"; break;
867 case O_ge: name = "O_ge"; break;
868 case O_gt: name = "O_gt"; break;
869 case O_logical_and: name = "O_logical_and"; break;
870 case O_logical_or: name = "O_logical_or"; break;
871 case O_index: name = "O_index"; break;
872 case O_bracket: name = "O_bracket"; break;
873 }
874
875 switch (t->X_md)
876 {
877 default: namemd = "unknown"; break;
878 case O_gotoff: namemd = "O_gotoff"; break;
879 case O_gotpc: namemd = "O_gotpc"; break;
880 case O_plt: namemd = "O_plt"; break;
881 case O_sda: namemd = "O_sda"; break;
882 case O_pcl: namemd = "O_pcl"; break;
883 case O_tlsgd: namemd = "O_tlsgd"; break;
884 case O_tlsie: namemd = "O_tlsie"; break;
885 case O_tpoff9: namemd = "O_tpoff9"; break;
886 case O_tpoff: namemd = "O_tpoff"; break;
887 case O_dtpoff9: namemd = "O_dtpoff9"; break;
888 case O_dtpoff: namemd = "O_dtpoff"; break;
889 }
890
891 pr_debug ("%s (%s, %s, %d, %s)", name,
892 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
893 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
894 (int) t->X_add_number,
895 (t->X_md) ? namemd : "--");
896 pr_debug ("\n");
897 fflush (stderr);
898 }
899
900 /* Parse the arguments to an opcode. */
901
902 static int
903 tokenize_arguments (char *str,
904 expressionS *tok,
905 int ntok)
906 {
907 char *old_input_line_pointer;
908 bfd_boolean saw_comma = FALSE;
909 bfd_boolean saw_arg = FALSE;
910 int brk_lvl = 0;
911 int num_args = 0;
912 int i;
913 size_t len;
914 const struct arc_reloc_op_tag *r;
915 expressionS tmpE;
916 char *reloc_name, c;
917
918 memset (tok, 0, sizeof (*tok) * ntok);
919
920 /* Save and restore input_line_pointer around this function. */
921 old_input_line_pointer = input_line_pointer;
922 input_line_pointer = str;
923
924 while (*input_line_pointer)
925 {
926 SKIP_WHITESPACE ();
927 switch (*input_line_pointer)
928 {
929 case '\0':
930 goto fini;
931
932 case ',':
933 input_line_pointer++;
934 if (saw_comma || !saw_arg)
935 goto err;
936 saw_comma = TRUE;
937 break;
938
939 case '}':
940 case ']':
941 ++input_line_pointer;
942 --brk_lvl;
943 if (!saw_arg)
944 goto err;
945 tok->X_op = O_bracket;
946 ++tok;
947 ++num_args;
948 break;
949
950 case '{':
951 case '[':
952 input_line_pointer++;
953 if (brk_lvl)
954 goto err;
955 ++brk_lvl;
956 tok->X_op = O_bracket;
957 ++tok;
958 ++num_args;
959 break;
960
961 case '@':
962 /* We have labels, function names and relocations, all
963 starting with @ symbol. Sort them out. */
964 if (saw_arg && !saw_comma)
965 goto err;
966
967 /* Parse @label. */
968 tok->X_op = O_symbol;
969 tok->X_md = O_absent;
970 expression (tok);
971 if (*input_line_pointer != '@')
972 goto normalsymbol; /* This is not a relocation. */
973
974 relocationsym:
975
976 /* A relocation opernad has the following form
977 @identifier@relocation_type. The identifier is already
978 in tok! */
979 if (tok->X_op != O_symbol)
980 {
981 as_bad (_("No valid label relocation operand"));
982 goto err;
983 }
984
985 /* Parse @relocation_type. */
986 input_line_pointer++;
987 c = get_symbol_name (&reloc_name);
988 len = input_line_pointer - reloc_name;
989 if (len == 0)
990 {
991 as_bad (_("No relocation operand"));
992 goto err;
993 }
994
995 /* Go through known relocation and try to find a match. */
996 r = &arc_reloc_op[0];
997 for (i = arc_num_reloc_op - 1; i >= 0; i--, r++)
998 if (len == r->length
999 && memcmp (reloc_name, r->name, len) == 0)
1000 break;
1001 if (i < 0)
1002 {
1003 as_bad (_("Unknown relocation operand: @%s"), reloc_name);
1004 goto err;
1005 }
1006
1007 *input_line_pointer = c;
1008 SKIP_WHITESPACE_AFTER_NAME ();
1009 /* Extra check for TLS: base. */
1010 if (*input_line_pointer == '@')
1011 {
1012 symbolS *base;
1013 if (tok->X_op_symbol != NULL
1014 || tok->X_op != O_symbol)
1015 {
1016 as_bad (_("Unable to parse TLS base: %s"),
1017 input_line_pointer);
1018 goto err;
1019 }
1020 input_line_pointer++;
1021 char *sym_name;
1022 c = get_symbol_name (&sym_name);
1023 base = symbol_find_or_make (sym_name);
1024 tok->X_op = O_subtract;
1025 tok->X_op_symbol = base;
1026 restore_line_pointer (c);
1027 tmpE.X_add_number = 0;
1028 }
1029 else if ((*input_line_pointer != '+')
1030 && (*input_line_pointer != '-'))
1031 {
1032 tmpE.X_add_number = 0;
1033 }
1034 else
1035 {
1036 /* Parse the constant of a complex relocation expression
1037 like @identifier@reloc +/- const. */
1038 if (! r->complex_expr)
1039 {
1040 as_bad (_("@%s is not a complex relocation."), r->name);
1041 goto err;
1042 }
1043 expression (&tmpE);
1044 if (tmpE.X_op != O_constant)
1045 {
1046 as_bad (_("Bad expression: @%s + %s."),
1047 r->name, input_line_pointer);
1048 goto err;
1049 }
1050 }
1051
1052 tok->X_md = r->op;
1053 tok->X_add_number = tmpE.X_add_number;
1054
1055 debug_exp (tok);
1056
1057 saw_comma = FALSE;
1058 saw_arg = TRUE;
1059 tok++;
1060 num_args++;
1061 break;
1062
1063 case '%':
1064 /* Can be a register. */
1065 ++input_line_pointer;
1066 /* Fall through. */
1067 default:
1068
1069 if (saw_arg && !saw_comma)
1070 goto err;
1071
1072 tok->X_op = O_absent;
1073 tok->X_md = O_absent;
1074 expression (tok);
1075
1076 /* Legacy: There are cases when we have
1077 identifier@relocation_type, if it is the case parse the
1078 relocation type as well. */
1079 if (*input_line_pointer == '@')
1080 goto relocationsym;
1081
1082 normalsymbol:
1083 debug_exp (tok);
1084
1085 if (tok->X_op == O_illegal || tok->X_op == O_absent)
1086 goto err;
1087
1088 saw_comma = FALSE;
1089 saw_arg = TRUE;
1090 tok++;
1091 num_args++;
1092 break;
1093 }
1094 }
1095
1096 fini:
1097 if (saw_comma || brk_lvl)
1098 goto err;
1099 input_line_pointer = old_input_line_pointer;
1100
1101 return num_args;
1102
1103 err:
1104 if (brk_lvl)
1105 as_bad (_("Brackets in operand field incorrect"));
1106 else if (saw_comma)
1107 as_bad (_("extra comma"));
1108 else if (!saw_arg)
1109 as_bad (_("missing argument"));
1110 else
1111 as_bad (_("missing comma or colon"));
1112 input_line_pointer = old_input_line_pointer;
1113 return -1;
1114 }
1115
1116 /* Parse the flags to a structure. */
1117
1118 static int
1119 tokenize_flags (const char *str,
1120 struct arc_flags flags[],
1121 int nflg)
1122 {
1123 char *old_input_line_pointer;
1124 bfd_boolean saw_flg = FALSE;
1125 bfd_boolean saw_dot = FALSE;
1126 int num_flags = 0;
1127 size_t flgnamelen;
1128
1129 memset (flags, 0, sizeof (*flags) * nflg);
1130
1131 /* Save and restore input_line_pointer around this function. */
1132 old_input_line_pointer = input_line_pointer;
1133 input_line_pointer = (char *) str;
1134
1135 while (*input_line_pointer)
1136 {
1137 switch (*input_line_pointer)
1138 {
1139 case ' ':
1140 case '\0':
1141 goto fini;
1142
1143 case '.':
1144 input_line_pointer++;
1145 if (saw_dot)
1146 goto err;
1147 saw_dot = TRUE;
1148 saw_flg = FALSE;
1149 break;
1150
1151 default:
1152 if (saw_flg && !saw_dot)
1153 goto err;
1154
1155 if (num_flags >= nflg)
1156 goto err;
1157
1158 flgnamelen = strspn (input_line_pointer,
1159 "abcdefghijklmnopqrstuvwxyz0123456789");
1160 if (flgnamelen > MAX_FLAG_NAME_LENGTH)
1161 goto err;
1162
1163 memcpy (flags->name, input_line_pointer, flgnamelen);
1164
1165 input_line_pointer += flgnamelen;
1166 flags++;
1167 saw_dot = FALSE;
1168 saw_flg = TRUE;
1169 num_flags++;
1170 break;
1171 }
1172 }
1173
1174 fini:
1175 input_line_pointer = old_input_line_pointer;
1176 return num_flags;
1177
1178 err:
1179 if (saw_dot)
1180 as_bad (_("extra dot"));
1181 else if (!saw_flg)
1182 as_bad (_("unrecognized flag"));
1183 else
1184 as_bad (_("failed to parse flags"));
1185 input_line_pointer = old_input_line_pointer;
1186 return -1;
1187 }
1188
1189 /* Apply the fixups in order. */
1190
1191 static void
1192 apply_fixups (struct arc_insn *insn, fragS *fragP, int fix)
1193 {
1194 int i;
1195
1196 for (i = 0; i < insn->nfixups; i++)
1197 {
1198 struct arc_fixup *fixup = &insn->fixups[i];
1199 int size, pcrel, offset = 0;
1200
1201 /* FIXME! the reloc size is wrong in the BFD file.
1202 When it is fixed please delete me. */
1203 size = (insn->short_insn && !fixup->islong) ? 2 : 4;
1204
1205 if (fixup->islong)
1206 offset = (insn->short_insn) ? 2 : 4;
1207
1208 /* Some fixups are only used internally, thus no howto. */
1209 if ((int) fixup->reloc == 0)
1210 as_fatal (_("Unhandled reloc type"));
1211
1212 if ((int) fixup->reloc < 0)
1213 {
1214 /* FIXME! the reloc size is wrong in the BFD file.
1215 When it is fixed please enable me.
1216 size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
1217 pcrel = fixup->pcrel;
1218 }
1219 else
1220 {
1221 reloc_howto_type *reloc_howto =
1222 bfd_reloc_type_lookup (stdoutput,
1223 (bfd_reloc_code_real_type) fixup->reloc);
1224 gas_assert (reloc_howto);
1225
1226 /* FIXME! the reloc size is wrong in the BFD file.
1227 When it is fixed please enable me.
1228 size = bfd_get_reloc_size (reloc_howto); */
1229 pcrel = reloc_howto->pc_relative;
1230 }
1231
1232 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1233 offset %d + %d\n",
1234 fragP->fr_file, fragP->fr_line,
1235 (fixup->reloc < 0) ? "Internal" :
1236 bfd_get_reloc_code_name (fixup->reloc),
1237 pcrel ? "Y" : "N",
1238 size, fix, offset);
1239 fix_new_exp (fragP, fix + offset,
1240 size, &fixup->exp, pcrel, fixup->reloc);
1241
1242 /* Check for ZOLs, and update symbol info if any. */
1243 if (LP_INSN (insn->insn))
1244 {
1245 gas_assert (fixup->exp.X_add_symbol);
1246 ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL);
1247 }
1248 }
1249 }
1250
1251 /* Actually output an instruction with its fixup. */
1252
1253 static void
1254 emit_insn0 (struct arc_insn *insn, char *where, bfd_boolean relax)
1255 {
1256 char *f = where;
1257
1258 pr_debug ("Emit insn : 0x%x\n", insn->insn);
1259 pr_debug ("\tShort : 0x%d\n", insn->short_insn);
1260 pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
1261
1262 /* Write out the instruction. */
1263 if (insn->short_insn)
1264 {
1265 if (insn->has_limm)
1266 {
1267 if (!relax)
1268 f = frag_more (6);
1269 md_number_to_chars (f, insn->insn, 2);
1270 md_number_to_chars_midend (f + 2, insn->limm, 4);
1271 dwarf2_emit_insn (6);
1272 }
1273 else
1274 {
1275 if (!relax)
1276 f = frag_more (2);
1277 md_number_to_chars (f, insn->insn, 2);
1278 dwarf2_emit_insn (2);
1279 }
1280 }
1281 else
1282 {
1283 if (insn->has_limm)
1284 {
1285 if (!relax)
1286 f = frag_more (8);
1287 md_number_to_chars_midend (f, insn->insn, 4);
1288 md_number_to_chars_midend (f + 4, insn->limm, 4);
1289 dwarf2_emit_insn (8);
1290 }
1291 else
1292 {
1293 if (!relax)
1294 f = frag_more (4);
1295 md_number_to_chars_midend (f, insn->insn, 4);
1296 dwarf2_emit_insn (4);
1297 }
1298 }
1299
1300 if (!relax)
1301 apply_fixups (insn, frag_now, (f - frag_now->fr_literal));
1302 }
1303
1304 static void
1305 emit_insn1 (struct arc_insn *insn)
1306 {
1307 /* How frag_var's args are currently configured:
1308 - rs_machine_dependent, to dictate it's a relaxation frag.
1309 - FRAG_MAX_GROWTH, maximum size of instruction
1310 - 0, variable size that might grow...unused by generic relaxation.
1311 - frag_now->fr_subtype, fr_subtype starting value, set previously.
1312 - s, opand expression.
1313 - 0, offset but it's unused.
1314 - 0, opcode but it's unused. */
1315 symbolS *s = make_expr_symbol (&insn->fixups[0].exp);
1316 frag_now->tc_frag_data.pcrel = insn->fixups[0].pcrel;
1317
1318 if (frag_room () < FRAG_MAX_GROWTH)
1319 {
1320 /* Handle differently when frag literal memory is exhausted.
1321 This is used because when there's not enough memory left in
1322 the current frag, a new frag is created and the information
1323 we put into frag_now->tc_frag_data is disregarded. */
1324
1325 struct arc_relax_type relax_info_copy;
1326 relax_substateT subtype = frag_now->fr_subtype;
1327
1328 memcpy (&relax_info_copy, &frag_now->tc_frag_data,
1329 sizeof (struct arc_relax_type));
1330
1331 frag_wane (frag_now);
1332 frag_grow (FRAG_MAX_GROWTH);
1333
1334 memcpy (&frag_now->tc_frag_data, &relax_info_copy,
1335 sizeof (struct arc_relax_type));
1336
1337 frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1338 subtype, s, 0, 0);
1339 }
1340 else
1341 frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1342 frag_now->fr_subtype, s, 0, 0);
1343 }
1344
1345 static void
1346 emit_insn (struct arc_insn *insn)
1347 {
1348 if (insn->relax)
1349 emit_insn1 (insn);
1350 else
1351 emit_insn0 (insn, NULL, FALSE);
1352 }
1353
1354 /* Check whether a symbol involves a register. */
1355
1356 static bfd_boolean
1357 contains_register (symbolS *sym)
1358 {
1359 if (sym)
1360 {
1361 expressionS *ex = symbol_get_value_expression (sym);
1362
1363 return ((O_register == ex->X_op)
1364 && !contains_register (ex->X_add_symbol)
1365 && !contains_register (ex->X_op_symbol));
1366 }
1367
1368 return FALSE;
1369 }
1370
1371 /* Returns the register number within a symbol. */
1372
1373 static int
1374 get_register (symbolS *sym)
1375 {
1376 if (!contains_register (sym))
1377 return -1;
1378
1379 expressionS *ex = symbol_get_value_expression (sym);
1380 return regno (ex->X_add_number);
1381 }
1382
1383 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1384 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1385
1386 static bfd_boolean
1387 generic_reloc_p (extended_bfd_reloc_code_real_type reloc)
1388 {
1389 if (!reloc)
1390 return FALSE;
1391
1392 switch (reloc)
1393 {
1394 case BFD_RELOC_ARC_SDA_LDST:
1395 case BFD_RELOC_ARC_SDA_LDST1:
1396 case BFD_RELOC_ARC_SDA_LDST2:
1397 case BFD_RELOC_ARC_SDA16_LD:
1398 case BFD_RELOC_ARC_SDA16_LD1:
1399 case BFD_RELOC_ARC_SDA16_LD2:
1400 case BFD_RELOC_ARC_SDA16_ST2:
1401 case BFD_RELOC_ARC_SDA32_ME:
1402 return FALSE;
1403 default:
1404 return TRUE;
1405 }
1406 }
1407
1408 /* Allocates a tok entry. */
1409
1410 static int
1411 allocate_tok (expressionS *tok, int ntok, int cidx)
1412 {
1413 if (ntok > MAX_INSN_ARGS - 2)
1414 return 0; /* No space left. */
1415
1416 if (cidx > ntok)
1417 return 0; /* Incorect args. */
1418
1419 memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok));
1420
1421 if (cidx == ntok)
1422 return 1; /* Success. */
1423 return allocate_tok (tok, ntok - 1, cidx);
1424 }
1425
1426 /* Check if an particular ARC feature is enabled. */
1427
1428 static bfd_boolean
1429 check_cpu_feature (insn_subclass_t sc)
1430 {
1431 if (!(arc_features & ARC_CD)
1432 && is_code_density_p (sc))
1433 return FALSE;
1434
1435 if (!(arc_features & ARC_SPFP)
1436 && is_spfp_p (sc))
1437 return FALSE;
1438
1439 if (!(arc_features & ARC_DPFP)
1440 && is_dpfp_p (sc))
1441 return FALSE;
1442
1443 if (!(arc_features & ARC_FPUDA)
1444 && is_fpuda_p (sc))
1445 return FALSE;
1446
1447 return TRUE;
1448 }
1449
1450 /* Search forward through all variants of an opcode looking for a
1451 syntax match. */
1452
1453 static const struct arc_opcode *
1454 find_opcode_match (const struct arc_opcode_hash_entry *entry,
1455 expressionS *tok,
1456 int *pntok,
1457 struct arc_flags *first_pflag,
1458 int nflgs,
1459 int *pcpumatch)
1460 {
1461 const struct arc_opcode *opcode;
1462 struct arc_opcode_hash_entry_iterator iter;
1463 int ntok = *pntok;
1464 int got_cpu_match = 0;
1465 expressionS bktok[MAX_INSN_ARGS];
1466 int bkntok;
1467 expressionS emptyE;
1468
1469 arc_opcode_hash_entry_iterator_init (&iter);
1470 memset (&emptyE, 0, sizeof (emptyE));
1471 memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
1472 bkntok = ntok;
1473
1474 for (opcode = arc_opcode_hash_entry_iterator_next (entry, &iter);
1475 opcode != NULL;
1476 opcode = arc_opcode_hash_entry_iterator_next (entry, &iter))
1477 {
1478 const unsigned char *opidx;
1479 const unsigned char *flgidx;
1480 int tokidx = 0, lnflg, i;
1481 const expressionS *t = &emptyE;
1482
1483 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
1484 frag_now->fr_file, frag_now->fr_line, opcode->opcode);
1485
1486 /* Don't match opcodes that don't exist on this
1487 architecture. */
1488 if (!(opcode->cpu & arc_target))
1489 goto match_failed;
1490
1491 if (!check_cpu_feature (opcode->subclass))
1492 goto match_failed;
1493
1494 got_cpu_match = 1;
1495 pr_debug ("cpu ");
1496
1497 /* Check the operands. */
1498 for (opidx = opcode->operands; *opidx; ++opidx)
1499 {
1500 const struct arc_operand *operand = &arc_operands[*opidx];
1501
1502 /* Only take input from real operands. */
1503 if ((operand->flags & ARC_OPERAND_FAKE)
1504 && !(operand->flags & ARC_OPERAND_BRAKET))
1505 continue;
1506
1507 /* When we expect input, make sure we have it. */
1508 if (tokidx >= ntok)
1509 goto match_failed;
1510
1511 /* Match operand type with expression type. */
1512 switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
1513 {
1514 case ARC_OPERAND_IR:
1515 /* Check to be a register. */
1516 if ((tok[tokidx].X_op != O_register
1517 || !is_ir_num (tok[tokidx].X_add_number))
1518 && !(operand->flags & ARC_OPERAND_IGNORE))
1519 goto match_failed;
1520
1521 /* If expect duplicate, make sure it is duplicate. */
1522 if (operand->flags & ARC_OPERAND_DUPLICATE)
1523 {
1524 /* Check for duplicate. */
1525 if (t->X_op != O_register
1526 || !is_ir_num (t->X_add_number)
1527 || (regno (t->X_add_number) !=
1528 regno (tok[tokidx].X_add_number)))
1529 goto match_failed;
1530 }
1531
1532 /* Special handling? */
1533 if (operand->insert)
1534 {
1535 const char *errmsg = NULL;
1536 (*operand->insert)(0,
1537 regno (tok[tokidx].X_add_number),
1538 &errmsg);
1539 if (errmsg)
1540 {
1541 if (operand->flags & ARC_OPERAND_IGNORE)
1542 {
1543 /* Missing argument, create one. */
1544 if (!allocate_tok (tok, ntok - 1, tokidx))
1545 goto match_failed;
1546
1547 tok[tokidx].X_op = O_absent;
1548 ++ntok;
1549 }
1550 else
1551 goto match_failed;
1552 }
1553 }
1554
1555 t = &tok[tokidx];
1556 break;
1557
1558 case ARC_OPERAND_BRAKET:
1559 /* Check if bracket is also in opcode table as
1560 operand. */
1561 if (tok[tokidx].X_op != O_bracket)
1562 goto match_failed;
1563 break;
1564
1565 case ARC_OPERAND_LIMM:
1566 case ARC_OPERAND_SIGNED:
1567 case ARC_OPERAND_UNSIGNED:
1568 switch (tok[tokidx].X_op)
1569 {
1570 case O_illegal:
1571 case O_absent:
1572 case O_register:
1573 goto match_failed;
1574
1575 case O_bracket:
1576 /* Got an (too) early bracket, check if it is an
1577 ignored operand. N.B. This procedure works only
1578 when bracket is the last operand! */
1579 if (!(operand->flags & ARC_OPERAND_IGNORE))
1580 goto match_failed;
1581 /* Insert the missing operand. */
1582 if (!allocate_tok (tok, ntok - 1, tokidx))
1583 goto match_failed;
1584
1585 tok[tokidx].X_op = O_absent;
1586 ++ntok;
1587 break;
1588
1589 case O_symbol:
1590 {
1591 const char *p;
1592 size_t len;
1593 const struct arc_aux_reg *auxr;
1594 unsigned j;
1595
1596 if (opcode->class != AUXREG)
1597 goto de_fault;
1598 p = S_GET_NAME (tok[tokidx].X_add_symbol);
1599 len = strlen (p);
1600
1601 auxr = &arc_aux_regs[0];
1602 for (j = 0; j < arc_num_aux_regs; j++, auxr++)
1603 if (len == auxr->length
1604 && strcasecmp (auxr->name, p) == 0
1605 && ((auxr->subclass == NONE)
1606 || check_cpu_feature (auxr->subclass)))
1607 {
1608 /* We modify the token array here, safe in the
1609 knowledge, that if this was the wrong choice
1610 then the original contents will be restored
1611 from BKTOK. */
1612 tok[tokidx].X_op = O_constant;
1613 tok[tokidx].X_add_number = auxr->address;
1614 ARC_SET_FLAG (tok[i].X_add_symbol, ARC_FLAG_AUX);
1615 break;
1616 }
1617
1618 if (tok[tokidx].X_op != O_constant)
1619 goto de_fault;
1620 }
1621 /* Fall-through */
1622 case O_constant:
1623 /* Check the range. */
1624 if (operand->bits != 32
1625 && !(operand->flags & ARC_OPERAND_NCHK))
1626 {
1627 offsetT min, max, val;
1628 val = tok[tokidx].X_add_number;
1629
1630 if (operand->flags & ARC_OPERAND_SIGNED)
1631 {
1632 max = (1 << (operand->bits - 1)) - 1;
1633 min = -(1 << (operand->bits - 1));
1634 }
1635 else
1636 {
1637 max = (1 << operand->bits) - 1;
1638 min = 0;
1639 }
1640
1641 if (val < min || val > max)
1642 goto match_failed;
1643
1644 /* Check alignmets. */
1645 if ((operand->flags & ARC_OPERAND_ALIGNED32)
1646 && (val & 0x03))
1647 goto match_failed;
1648
1649 if ((operand->flags & ARC_OPERAND_ALIGNED16)
1650 && (val & 0x01))
1651 goto match_failed;
1652 }
1653 else if (operand->flags & ARC_OPERAND_NCHK)
1654 {
1655 if (operand->insert)
1656 {
1657 const char *errmsg = NULL;
1658 (*operand->insert)(0,
1659 tok[tokidx].X_add_number,
1660 &errmsg);
1661 if (errmsg)
1662 goto match_failed;
1663 }
1664 else
1665 goto match_failed;
1666 }
1667 break;
1668
1669 case O_subtract:
1670 /* Check if it is register range. */
1671 if ((tok[tokidx].X_add_number == 0)
1672 && contains_register (tok[tokidx].X_add_symbol)
1673 && contains_register (tok[tokidx].X_op_symbol))
1674 {
1675 int regs;
1676
1677 regs = get_register (tok[tokidx].X_add_symbol);
1678 regs <<= 16;
1679 regs |= get_register (tok[tokidx].X_op_symbol);
1680 if (operand->insert)
1681 {
1682 const char *errmsg = NULL;
1683 (*operand->insert)(0,
1684 regs,
1685 &errmsg);
1686 if (errmsg)
1687 goto match_failed;
1688 }
1689 else
1690 goto match_failed;
1691 break;
1692 }
1693 default:
1694 de_fault:
1695 if (operand->default_reloc == 0)
1696 goto match_failed; /* The operand needs relocation. */
1697
1698 /* Relocs requiring long immediate. FIXME! make it
1699 generic and move it to a function. */
1700 switch (tok[tokidx].X_md)
1701 {
1702 case O_gotoff:
1703 case O_gotpc:
1704 case O_pcl:
1705 case O_tpoff:
1706 case O_dtpoff:
1707 case O_tlsgd:
1708 case O_tlsie:
1709 if (!(operand->flags & ARC_OPERAND_LIMM))
1710 goto match_failed;
1711 case O_absent:
1712 if (!generic_reloc_p (operand->default_reloc))
1713 goto match_failed;
1714 default:
1715 break;
1716 }
1717 break;
1718 }
1719 /* If expect duplicate, make sure it is duplicate. */
1720 if (operand->flags & ARC_OPERAND_DUPLICATE)
1721 {
1722 if (t->X_op == O_illegal
1723 || t->X_op == O_absent
1724 || t->X_op == O_register
1725 || (t->X_add_number != tok[tokidx].X_add_number))
1726 goto match_failed;
1727 }
1728 t = &tok[tokidx];
1729 break;
1730
1731 default:
1732 /* Everything else should have been fake. */
1733 abort ();
1734 }
1735
1736 ++tokidx;
1737 }
1738 pr_debug ("opr ");
1739
1740 /* Setup ready for flag parsing. */
1741 lnflg = nflgs;
1742 for (i = 0; i < nflgs; i++)
1743 first_pflag [i].code = 0;
1744
1745 /* Check the flags. Iterate over the valid flag classes. */
1746 for (flgidx = opcode->flags; *flgidx; ++flgidx)
1747 {
1748 /* Get a valid flag class. */
1749 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
1750 const unsigned *flgopridx;
1751 int cl_matches = 0;
1752
1753 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
1754 {
1755 const struct arc_flag_operand *flg_operand;
1756 struct arc_flags *pflag = first_pflag;
1757
1758 flg_operand = &arc_flag_operands[*flgopridx];
1759 for (i = 0; i < nflgs; i++, pflag++)
1760 {
1761 /* Match against the parsed flags. */
1762 if (!strcmp (flg_operand->name, pflag->name))
1763 {
1764 if (pflag->code != 0)
1765 goto match_failed;
1766 cl_matches++;
1767 pflag->code = *flgopridx;
1768 lnflg--;
1769 break; /* goto next flag class and parsed flag. */
1770 }
1771 }
1772 }
1773
1774 if (cl_flags->class == F_CLASS_REQUIRED && cl_matches == 0)
1775 goto match_failed;
1776 if (cl_flags->class == F_CLASS_OPTIONAL && cl_matches > 1)
1777 goto match_failed;
1778 }
1779 /* Did I check all the parsed flags? */
1780 if (lnflg)
1781 goto match_failed;
1782
1783 pr_debug ("flg");
1784 /* Possible match -- did we use all of our input? */
1785 if (tokidx == ntok)
1786 {
1787 *pntok = ntok;
1788 pr_debug ("\n");
1789 return opcode;
1790 }
1791
1792 match_failed:;
1793 pr_debug ("\n");
1794 /* Restore the original parameters. */
1795 memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok));
1796 ntok = bkntok;
1797 }
1798
1799 if (*pcpumatch)
1800 *pcpumatch = got_cpu_match;
1801
1802 return NULL;
1803 }
1804
1805 /* Swap operand tokens. */
1806
1807 static void
1808 swap_operand (expressionS *operand_array,
1809 unsigned source,
1810 unsigned destination)
1811 {
1812 expressionS cpy_operand;
1813 expressionS *src_operand;
1814 expressionS *dst_operand;
1815 size_t size;
1816
1817 if (source == destination)
1818 return;
1819
1820 src_operand = &operand_array[source];
1821 dst_operand = &operand_array[destination];
1822 size = sizeof (expressionS);
1823
1824 /* Make copy of operand to swap with and swap. */
1825 memcpy (&cpy_operand, dst_operand, size);
1826 memcpy (dst_operand, src_operand, size);
1827 memcpy (src_operand, &cpy_operand, size);
1828 }
1829
1830 /* Check if *op matches *tok type.
1831 Returns FALSE if they don't match, TRUE if they match. */
1832
1833 static bfd_boolean
1834 pseudo_operand_match (const expressionS *tok,
1835 const struct arc_operand_operation *op)
1836 {
1837 offsetT min, max, val;
1838 bfd_boolean ret;
1839 const struct arc_operand *operand_real = &arc_operands[op->operand_idx];
1840
1841 ret = FALSE;
1842 switch (tok->X_op)
1843 {
1844 case O_constant:
1845 if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM))
1846 ret = 1;
1847 else if (!(operand_real->flags & ARC_OPERAND_IR))
1848 {
1849 val = tok->X_add_number + op->count;
1850 if (operand_real->flags & ARC_OPERAND_SIGNED)
1851 {
1852 max = (1 << (operand_real->bits - 1)) - 1;
1853 min = -(1 << (operand_real->bits - 1));
1854 }
1855 else
1856 {
1857 max = (1 << operand_real->bits) - 1;
1858 min = 0;
1859 }
1860 if (min <= val && val <= max)
1861 ret = TRUE;
1862 }
1863 break;
1864
1865 case O_symbol:
1866 /* Handle all symbols as long immediates or signed 9. */
1867 if (operand_real->flags & ARC_OPERAND_LIMM ||
1868 ((operand_real->flags & ARC_OPERAND_SIGNED) && operand_real->bits == 9))
1869 ret = TRUE;
1870 break;
1871
1872 case O_register:
1873 if (operand_real->flags & ARC_OPERAND_IR)
1874 ret = TRUE;
1875 break;
1876
1877 case O_bracket:
1878 if (operand_real->flags & ARC_OPERAND_BRAKET)
1879 ret = TRUE;
1880 break;
1881
1882 default:
1883 /* Unknown. */
1884 break;
1885 }
1886 return ret;
1887 }
1888
1889 /* Find pseudo instruction in array. */
1890
1891 static const struct arc_pseudo_insn *
1892 find_pseudo_insn (const char *opname,
1893 int ntok,
1894 const expressionS *tok)
1895 {
1896 const struct arc_pseudo_insn *pseudo_insn = NULL;
1897 const struct arc_operand_operation *op;
1898 unsigned int i;
1899 int j;
1900
1901 for (i = 0; i < arc_num_pseudo_insn; ++i)
1902 {
1903 pseudo_insn = &arc_pseudo_insns[i];
1904 if (strcmp (pseudo_insn->mnemonic_p, opname) == 0)
1905 {
1906 op = pseudo_insn->operand;
1907 for (j = 0; j < ntok; ++j)
1908 if (!pseudo_operand_match (&tok[j], &op[j]))
1909 break;
1910
1911 /* Found the right instruction. */
1912 if (j == ntok)
1913 return pseudo_insn;
1914 }
1915 }
1916 return NULL;
1917 }
1918
1919 /* Assumes the expressionS *tok is of sufficient size. */
1920
1921 static const struct arc_opcode_hash_entry *
1922 find_special_case_pseudo (const char *opname,
1923 int *ntok,
1924 expressionS *tok,
1925 int *nflgs,
1926 struct arc_flags *pflags)
1927 {
1928 const struct arc_pseudo_insn *pseudo_insn = NULL;
1929 const struct arc_operand_operation *operand_pseudo;
1930 const struct arc_operand *operand_real;
1931 unsigned i;
1932 char construct_operand[MAX_CONSTR_STR];
1933
1934 /* Find whether opname is in pseudo instruction array. */
1935 pseudo_insn = find_pseudo_insn (opname, *ntok, tok);
1936
1937 if (pseudo_insn == NULL)
1938 return NULL;
1939
1940 /* Handle flag, Limited to one flag at the moment. */
1941 if (pseudo_insn->flag_r != NULL)
1942 *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs],
1943 MAX_INSN_FLGS - *nflgs);
1944
1945 /* Handle operand operations. */
1946 for (i = 0; i < pseudo_insn->operand_cnt; ++i)
1947 {
1948 operand_pseudo = &pseudo_insn->operand[i];
1949 operand_real = &arc_operands[operand_pseudo->operand_idx];
1950
1951 if (operand_real->flags & ARC_OPERAND_BRAKET &&
1952 !operand_pseudo->needs_insert)
1953 continue;
1954
1955 /* Has to be inserted (i.e. this token does not exist yet). */
1956 if (operand_pseudo->needs_insert)
1957 {
1958 if (operand_real->flags & ARC_OPERAND_BRAKET)
1959 {
1960 tok[i].X_op = O_bracket;
1961 ++(*ntok);
1962 continue;
1963 }
1964
1965 /* Check if operand is a register or constant and handle it
1966 by type. */
1967 if (operand_real->flags & ARC_OPERAND_IR)
1968 snprintf (construct_operand, MAX_CONSTR_STR, "r%d",
1969 operand_pseudo->count);
1970 else
1971 snprintf (construct_operand, MAX_CONSTR_STR, "%d",
1972 operand_pseudo->count);
1973
1974 tokenize_arguments (construct_operand, &tok[i], 1);
1975 ++(*ntok);
1976 }
1977
1978 else if (operand_pseudo->count)
1979 {
1980 /* Operand number has to be adjusted accordingly (by operand
1981 type). */
1982 switch (tok[i].X_op)
1983 {
1984 case O_constant:
1985 tok[i].X_add_number += operand_pseudo->count;
1986 break;
1987
1988 case O_symbol:
1989 break;
1990
1991 default:
1992 /* Ignored. */
1993 break;
1994 }
1995 }
1996 }
1997
1998 /* Swap operands if necessary. Only supports one swap at the
1999 moment. */
2000 for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2001 {
2002 operand_pseudo = &pseudo_insn->operand[i];
2003
2004 if (operand_pseudo->swap_operand_idx == i)
2005 continue;
2006
2007 swap_operand (tok, i, operand_pseudo->swap_operand_idx);
2008
2009 /* Prevent a swap back later by breaking out. */
2010 break;
2011 }
2012
2013 return arc_find_opcode (pseudo_insn->mnemonic_r);
2014 }
2015
2016 static const struct arc_opcode_hash_entry *
2017 find_special_case_flag (const char *opname,
2018 int *nflgs,
2019 struct arc_flags *pflags)
2020 {
2021 unsigned int i;
2022 const char *flagnm;
2023 unsigned flag_idx, flag_arr_idx;
2024 size_t flaglen, oplen;
2025 const struct arc_flag_special *arc_flag_special_opcode;
2026 const struct arc_opcode_hash_entry *entry;
2027
2028 /* Search for special case instruction. */
2029 for (i = 0; i < arc_num_flag_special; i++)
2030 {
2031 arc_flag_special_opcode = &arc_flag_special_cases[i];
2032 oplen = strlen (arc_flag_special_opcode->name);
2033
2034 if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0)
2035 continue;
2036
2037 /* Found a potential special case instruction, now test for
2038 flags. */
2039 for (flag_arr_idx = 0;; ++flag_arr_idx)
2040 {
2041 flag_idx = arc_flag_special_opcode->flags[flag_arr_idx];
2042 if (flag_idx == 0)
2043 break; /* End of array, nothing found. */
2044
2045 flagnm = arc_flag_operands[flag_idx].name;
2046 flaglen = strlen (flagnm);
2047 if (strcmp (opname + oplen, flagnm) == 0)
2048 {
2049 entry = arc_find_opcode (arc_flag_special_opcode->name);
2050
2051 if (*nflgs + 1 > MAX_INSN_FLGS)
2052 break;
2053 memcpy (pflags[*nflgs].name, flagnm, flaglen);
2054 pflags[*nflgs].name[flaglen] = '\0';
2055 (*nflgs)++;
2056 return entry;
2057 }
2058 }
2059 }
2060 return NULL;
2061 }
2062
2063 /* Used to find special case opcode. */
2064
2065 static const struct arc_opcode_hash_entry *
2066 find_special_case (const char *opname,
2067 int *nflgs,
2068 struct arc_flags *pflags,
2069 expressionS *tok,
2070 int *ntok)
2071 {
2072 const struct arc_opcode_hash_entry *entry;
2073
2074 entry = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
2075
2076 if (entry == NULL)
2077 entry = find_special_case_flag (opname, nflgs, pflags);
2078
2079 return entry;
2080 }
2081
2082 /* Given an opcode name, pre-tockenized set of argumenst and the
2083 opcode flags, take it all the way through emission. */
2084
2085 static void
2086 assemble_tokens (const char *opname,
2087 expressionS *tok,
2088 int ntok,
2089 struct arc_flags *pflags,
2090 int nflgs)
2091 {
2092 bfd_boolean found_something = FALSE;
2093 const struct arc_opcode_hash_entry *entry;
2094 int cpumatch = 1;
2095
2096 /* Search opcodes. */
2097 entry = arc_find_opcode (opname);
2098
2099 /* Couldn't find opcode conventional way, try special cases. */
2100 if (entry == NULL)
2101 entry = find_special_case (opname, &nflgs, pflags, tok, &ntok);
2102
2103 if (entry != NULL)
2104 {
2105 const struct arc_opcode *opcode;
2106
2107 pr_debug ("%s:%d: assemble_tokens: %s\n",
2108 frag_now->fr_file, frag_now->fr_line, opname);
2109 found_something = TRUE;
2110 opcode = find_opcode_match (entry, tok, &ntok, pflags,
2111 nflgs, &cpumatch);
2112 if (opcode != NULL)
2113 {
2114 struct arc_insn insn;
2115
2116 assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
2117 emit_insn (&insn);
2118 return;
2119 }
2120 }
2121
2122 if (found_something)
2123 {
2124 if (cpumatch)
2125 as_bad (_("inappropriate arguments for opcode '%s'"), opname);
2126 else
2127 as_bad (_("opcode '%s' not supported for target %s"), opname,
2128 arc_target_name);
2129 }
2130 else
2131 as_bad (_("unknown opcode '%s'"), opname);
2132 }
2133
2134 /* The public interface to the instruction assembler. */
2135
2136 void
2137 md_assemble (char *str)
2138 {
2139 char *opname;
2140 expressionS tok[MAX_INSN_ARGS];
2141 int ntok, nflg;
2142 size_t opnamelen;
2143 struct arc_flags flags[MAX_INSN_FLGS];
2144
2145 /* Split off the opcode. */
2146 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_0123468");
2147 opname = xmalloc (opnamelen + 1);
2148 memcpy (opname, str, opnamelen);
2149 opname[opnamelen] = '\0';
2150
2151 /* Signalize we are assmbling the instructions. */
2152 assembling_insn = TRUE;
2153
2154 /* Tokenize the flags. */
2155 if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1)
2156 {
2157 as_bad (_("syntax error"));
2158 return;
2159 }
2160
2161 /* Scan up to the end of the mnemonic which must end in space or end
2162 of string. */
2163 str += opnamelen;
2164 for (; *str != '\0'; str++)
2165 if (*str == ' ')
2166 break;
2167
2168 /* Tokenize the rest of the line. */
2169 if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0)
2170 {
2171 as_bad (_("syntax error"));
2172 return;
2173 }
2174
2175 /* Finish it off. */
2176 assemble_tokens (opname, tok, ntok, flags, nflg);
2177 assembling_insn = FALSE;
2178 }
2179
2180 /* Callback to insert a register into the hash table. */
2181
2182 static void
2183 declare_register (const char *name, int number)
2184 {
2185 const char *err;
2186 symbolS *regS = symbol_create (name, reg_section,
2187 number, &zero_address_frag);
2188
2189 err = hash_insert (arc_reg_hash, S_GET_NAME (regS), (void *) regS);
2190 if (err)
2191 as_fatal (_("Inserting \"%s\" into register table failed: %s"),
2192 name, err);
2193 }
2194
2195 /* Construct symbols for each of the general registers. */
2196
2197 static void
2198 declare_register_set (void)
2199 {
2200 int i;
2201 for (i = 0; i < 64; ++i)
2202 {
2203 char name[7];
2204
2205 sprintf (name, "r%d", i);
2206 declare_register (name, i);
2207 if ((i & 0x01) == 0)
2208 {
2209 sprintf (name, "r%dr%d", i, i+1);
2210 declare_register (name, i);
2211 }
2212 }
2213 }
2214
2215 /* Port-specific assembler initialization. This function is called
2216 once, at assembler startup time. */
2217
2218 void
2219 md_begin (void)
2220 {
2221 unsigned int i;
2222
2223 if (!mach_type_specified_p)
2224 arc_select_cpu ("arc700");
2225
2226 /* The endianness can be chosen "at the factory". */
2227 target_big_endian = byte_order == BIG_ENDIAN;
2228
2229 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
2230 as_warn (_("could not set architecture and machine"));
2231
2232 /* Set elf header flags. */
2233 bfd_set_private_flags (stdoutput, arc_eflag);
2234
2235 /* Set up a hash table for the instructions. */
2236 arc_opcode_hash = hash_new ();
2237 if (arc_opcode_hash == NULL)
2238 as_fatal (_("Virtual memory exhausted"));
2239
2240 /* Initialize the hash table with the insns. */
2241 for (i = 0; i < arc_num_opcodes;)
2242 {
2243 const char *name, *retval;
2244 struct arc_opcode_hash_entry *entry;
2245
2246 name = arc_opcodes[i].name;
2247
2248 entry = hash_find (arc_opcode_hash, name);
2249 if (entry == NULL)
2250 {
2251 entry = xmalloc (sizeof (*entry));
2252 entry->count = 0;
2253 entry->opcode = NULL;
2254
2255 retval = hash_insert (arc_opcode_hash, name, (void *) entry);
2256 if (retval)
2257 as_fatal (_("internal error: can't hash opcode '%s': %s"),
2258 name, retval);
2259 }
2260
2261 entry->opcode = xrealloc (entry->opcode,
2262 sizeof (const struct arc_opcode *)
2263 * entry->count + 1);
2264 entry->opcode [entry->count] = &arc_opcodes[i];
2265 entry->count++;
2266
2267 while (++i < arc_num_opcodes
2268 && (arc_opcodes[i].name == name
2269 || !strcmp (arc_opcodes[i].name, name)))
2270 continue;
2271 }
2272
2273 /* Register declaration. */
2274 arc_reg_hash = hash_new ();
2275 if (arc_reg_hash == NULL)
2276 as_fatal (_("Virtual memory exhausted"));
2277
2278 declare_register_set ();
2279 declare_register ("gp", 26);
2280 declare_register ("fp", 27);
2281 declare_register ("sp", 28);
2282 declare_register ("ilink", 29);
2283 declare_register ("ilink1", 29);
2284 declare_register ("ilink2", 30);
2285 declare_register ("blink", 31);
2286
2287 declare_register ("mlo", 57);
2288 declare_register ("mmid", 58);
2289 declare_register ("mhi", 59);
2290
2291 declare_register ("acc1", 56);
2292 declare_register ("acc2", 57);
2293
2294 declare_register ("lp_count", 60);
2295 declare_register ("pcl", 63);
2296
2297 /* Initialize the last instructions. */
2298 memset (&arc_last_insns[0], 0, sizeof (arc_last_insns));
2299 }
2300
2301 /* Write a value out to the object file, using the appropriate
2302 endianness. */
2303
2304 void
2305 md_number_to_chars (char *buf,
2306 valueT val,
2307 int n)
2308 {
2309 if (target_big_endian)
2310 number_to_chars_bigendian (buf, val, n);
2311 else
2312 number_to_chars_littleendian (buf, val, n);
2313 }
2314
2315 /* Round up a section size to the appropriate boundary. */
2316
2317 valueT
2318 md_section_align (segT segment,
2319 valueT size)
2320 {
2321 int align = bfd_get_section_alignment (stdoutput, segment);
2322
2323 return ((size + (1 << align) - 1) & (-((valueT) 1 << align)));
2324 }
2325
2326 /* The location from which a PC relative jump should be calculated,
2327 given a PC relative reloc. */
2328
2329 long
2330 md_pcrel_from_section (fixS *fixP,
2331 segT sec)
2332 {
2333 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
2334
2335 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP->fx_offset);
2336
2337 if (fixP->fx_addsy != (symbolS *) NULL
2338 && (!S_IS_DEFINED (fixP->fx_addsy)
2339 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
2340 {
2341 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP->fx_addsy));
2342
2343 /* The symbol is undefined (or is defined but not in this section).
2344 Let the linker figure it out. */
2345 return 0;
2346 }
2347
2348 if ((int) fixP->fx_r_type < 0)
2349 {
2350 /* These are the "internal" relocations. Align them to
2351 32 bit boundary (PCL), for the moment. */
2352 base &= ~3;
2353 }
2354 else
2355 {
2356 switch (fixP->fx_r_type)
2357 {
2358 case BFD_RELOC_ARC_PC32:
2359 /* The hardware calculates relative to the start of the
2360 insn, but this relocation is relative to location of the
2361 LIMM, compensate. The base always needs to be
2362 substracted by 4 as we do not support this type of PCrel
2363 relocation for short instructions. */
2364 base -= 4;
2365 /* Fall through. */
2366 case BFD_RELOC_ARC_PLT32:
2367 case BFD_RELOC_ARC_S25H_PCREL_PLT:
2368 case BFD_RELOC_ARC_S21H_PCREL_PLT:
2369 case BFD_RELOC_ARC_S25W_PCREL_PLT:
2370 case BFD_RELOC_ARC_S21W_PCREL_PLT:
2371
2372 case BFD_RELOC_ARC_S21H_PCREL:
2373 case BFD_RELOC_ARC_S25H_PCREL:
2374 case BFD_RELOC_ARC_S13_PCREL:
2375 case BFD_RELOC_ARC_S21W_PCREL:
2376 case BFD_RELOC_ARC_S25W_PCREL:
2377 base &= ~3;
2378 break;
2379 default:
2380 as_bad_where (fixP->fx_file, fixP->fx_line,
2381 _("unhandled reloc %s in md_pcrel_from_section"),
2382 bfd_get_reloc_code_name (fixP->fx_r_type));
2383 break;
2384 }
2385 }
2386
2387 pr_debug ("pcrel from %x + %lx = %x, symbol: %s (%x)\n",
2388 fixP->fx_frag->fr_address, fixP->fx_where, base,
2389 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "(null)",
2390 fixP->fx_addsy ? S_GET_VALUE (fixP->fx_addsy) : 0);
2391
2392 return base;
2393 }
2394
2395 /* Given a BFD relocation find the coresponding operand. */
2396
2397 static const struct arc_operand *
2398 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc)
2399 {
2400 unsigned i;
2401
2402 for (i = 0; i < arc_num_operands; i++)
2403 if (arc_operands[i].default_reloc == reloc)
2404 return &arc_operands[i];
2405 return NULL;
2406 }
2407
2408 /* Insert an operand value into an instruction. */
2409
2410 static unsigned
2411 insert_operand (unsigned insn,
2412 const struct arc_operand *operand,
2413 offsetT val,
2414 const char *file,
2415 unsigned line)
2416 {
2417 offsetT min = 0, max = 0;
2418
2419 if (operand->bits != 32
2420 && !(operand->flags & ARC_OPERAND_NCHK)
2421 && !(operand->flags & ARC_OPERAND_FAKE))
2422 {
2423 if (operand->flags & ARC_OPERAND_SIGNED)
2424 {
2425 max = (1 << (operand->bits - 1)) - 1;
2426 min = -(1 << (operand->bits - 1));
2427 }
2428 else
2429 {
2430 max = (1 << operand->bits) - 1;
2431 min = 0;
2432 }
2433
2434 if (val < min || val > max)
2435 as_bad_value_out_of_range (_("operand"),
2436 val, min, max, file, line);
2437 }
2438
2439 pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
2440 min, val, max, insn);
2441
2442 if ((operand->flags & ARC_OPERAND_ALIGNED32)
2443 && (val & 0x03))
2444 as_bad_where (file, line,
2445 _("Unaligned operand. Needs to be 32bit aligned"));
2446
2447 if ((operand->flags & ARC_OPERAND_ALIGNED16)
2448 && (val & 0x01))
2449 as_bad_where (file, line,
2450 _("Unaligned operand. Needs to be 16bit aligned"));
2451
2452 if (operand->insert)
2453 {
2454 const char *errmsg = NULL;
2455
2456 insn = (*operand->insert) (insn, val, &errmsg);
2457 if (errmsg)
2458 as_warn_where (file, line, "%s", errmsg);
2459 }
2460 else
2461 {
2462 if (operand->flags & ARC_OPERAND_TRUNCATE)
2463 {
2464 if (operand->flags & ARC_OPERAND_ALIGNED32)
2465 val >>= 2;
2466 if (operand->flags & ARC_OPERAND_ALIGNED16)
2467 val >>= 1;
2468 }
2469 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2470 }
2471 return insn;
2472 }
2473
2474 /* Apply a fixup to the object code. At this point all symbol values
2475 should be fully resolved, and we attempt to completely resolve the
2476 reloc. If we can not do that, we determine the correct reloc code
2477 and put it back in the fixup. To indicate that a fixup has been
2478 eliminated, set fixP->fx_done. */
2479
2480 void
2481 md_apply_fix (fixS *fixP,
2482 valueT *valP,
2483 segT seg)
2484 {
2485 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
2486 valueT value = *valP;
2487 unsigned insn = 0;
2488 symbolS *fx_addsy, *fx_subsy;
2489 offsetT fx_offset;
2490 segT add_symbol_segment = absolute_section;
2491 segT sub_symbol_segment = absolute_section;
2492 const struct arc_operand *operand = NULL;
2493 extended_bfd_reloc_code_real_type reloc;
2494
2495 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2496 fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
2497 ((int) fixP->fx_r_type < 0) ? "Internal":
2498 bfd_get_reloc_code_name (fixP->fx_r_type), value,
2499 fixP->fx_offset);
2500
2501 fx_addsy = fixP->fx_addsy;
2502 fx_subsy = fixP->fx_subsy;
2503 fx_offset = 0;
2504
2505 if (fx_addsy)
2506 {
2507 add_symbol_segment = S_GET_SEGMENT (fx_addsy);
2508 }
2509
2510 if (fx_subsy
2511 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF
2512 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF_S9
2513 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_GD_LD)
2514 {
2515 resolve_symbol_value (fx_subsy);
2516 sub_symbol_segment = S_GET_SEGMENT (fx_subsy);
2517
2518 if (sub_symbol_segment == absolute_section)
2519 {
2520 /* The symbol is really a constant. */
2521 fx_offset -= S_GET_VALUE (fx_subsy);
2522 fx_subsy = NULL;
2523 }
2524 else
2525 {
2526 as_bad_where (fixP->fx_file, fixP->fx_line,
2527 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
2528 fx_addsy ? S_GET_NAME (fx_addsy) : "0",
2529 segment_name (add_symbol_segment),
2530 S_GET_NAME (fx_subsy),
2531 segment_name (sub_symbol_segment));
2532 return;
2533 }
2534 }
2535
2536 if (fx_addsy
2537 && !S_IS_WEAK (fx_addsy))
2538 {
2539 if (add_symbol_segment == seg
2540 && fixP->fx_pcrel)
2541 {
2542 value += S_GET_VALUE (fx_addsy);
2543 value -= md_pcrel_from_section (fixP, seg);
2544 fx_addsy = NULL;
2545 fixP->fx_pcrel = FALSE;
2546 }
2547 else if (add_symbol_segment == absolute_section)
2548 {
2549 value = fixP->fx_offset;
2550 fx_offset += S_GET_VALUE (fixP->fx_addsy);
2551 fx_addsy = NULL;
2552 fixP->fx_pcrel = FALSE;
2553 }
2554 }
2555
2556 if (!fx_addsy)
2557 fixP->fx_done = TRUE;
2558
2559 if (fixP->fx_pcrel)
2560 {
2561 if (fx_addsy
2562 && ((S_IS_DEFINED (fx_addsy)
2563 && S_GET_SEGMENT (fx_addsy) != seg)
2564 || S_IS_WEAK (fx_addsy)))
2565 value += md_pcrel_from_section (fixP, seg);
2566
2567 switch (fixP->fx_r_type)
2568 {
2569 case BFD_RELOC_ARC_32_ME:
2570 /* This is a pc-relative value in a LIMM. Adjust it to the
2571 address of the instruction not to the address of the
2572 LIMM. Note: it is not anylonger valid this afirmation as
2573 the linker consider ARC_PC32 a fixup to entire 64 bit
2574 insn. */
2575 fixP->fx_offset += fixP->fx_frag->fr_address;
2576 /* Fall through. */
2577 case BFD_RELOC_32:
2578 fixP->fx_r_type = BFD_RELOC_ARC_PC32;
2579 /* Fall through. */
2580 case BFD_RELOC_ARC_PC32:
2581 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
2582 break;
2583 default:
2584 if ((int) fixP->fx_r_type < 0)
2585 as_fatal (_("PC relative relocation not allowed for (internal) type %d"),
2586 fixP->fx_r_type);
2587 break;
2588 }
2589 }
2590
2591 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2592 fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
2593 ((int) fixP->fx_r_type < 0) ? "Internal":
2594 bfd_get_reloc_code_name (fixP->fx_r_type), value,
2595 fixP->fx_offset);
2596
2597
2598 /* Now check for TLS relocations. */
2599 reloc = fixP->fx_r_type;
2600 switch (reloc)
2601 {
2602 case BFD_RELOC_ARC_TLS_DTPOFF:
2603 case BFD_RELOC_ARC_TLS_LE_32:
2604 if (fixP->fx_done)
2605 break;
2606 /* Fall through. */
2607 case BFD_RELOC_ARC_TLS_GD_GOT:
2608 case BFD_RELOC_ARC_TLS_IE_GOT:
2609 S_SET_THREAD_LOCAL (fixP->fx_addsy);
2610 break;
2611
2612 case BFD_RELOC_ARC_TLS_GD_LD:
2613 gas_assert (!fixP->fx_offset);
2614 if (fixP->fx_subsy)
2615 fixP->fx_offset
2616 = (S_GET_VALUE (fixP->fx_subsy)
2617 - fixP->fx_frag->fr_address- fixP->fx_where);
2618 fixP->fx_subsy = NULL;
2619 /* Fall through. */
2620 case BFD_RELOC_ARC_TLS_GD_CALL:
2621 /* These two relocs are there just to allow ld to change the tls
2622 model for this symbol, by patching the code. The offset -
2623 and scale, if any - will be installed by the linker. */
2624 S_SET_THREAD_LOCAL (fixP->fx_addsy);
2625 break;
2626
2627 case BFD_RELOC_ARC_TLS_LE_S9:
2628 case BFD_RELOC_ARC_TLS_DTPOFF_S9:
2629 as_bad (_("TLS_*_S9 relocs are not supported yet"));
2630 break;
2631
2632 default:
2633 break;
2634 }
2635
2636 if (!fixP->fx_done)
2637 {
2638 return;
2639 }
2640
2641 /* Addjust the value if we have a constant. */
2642 value += fx_offset;
2643
2644 /* For hosts with longs bigger than 32-bits make sure that the top
2645 bits of a 32-bit negative value read in by the parser are set,
2646 so that the correct comparisons are made. */
2647 if (value & 0x80000000)
2648 value |= (-1L << 31);
2649
2650 reloc = fixP->fx_r_type;
2651 switch (reloc)
2652 {
2653 case BFD_RELOC_8:
2654 case BFD_RELOC_16:
2655 case BFD_RELOC_24:
2656 case BFD_RELOC_32:
2657 case BFD_RELOC_64:
2658 case BFD_RELOC_ARC_32_PCREL:
2659 md_number_to_chars (fixpos, value, fixP->fx_size);
2660 return;
2661
2662 case BFD_RELOC_ARC_GOTPC32:
2663 /* I cannot fix an GOTPC relocation because I need to relax it
2664 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
2665 as_bad (_("Unsupported operation on reloc"));
2666 return;
2667
2668 case BFD_RELOC_ARC_TLS_DTPOFF:
2669 case BFD_RELOC_ARC_TLS_LE_32:
2670 gas_assert (!fixP->fx_addsy);
2671 gas_assert (!fixP->fx_subsy);
2672
2673 case BFD_RELOC_ARC_GOTOFF:
2674 case BFD_RELOC_ARC_32_ME:
2675 case BFD_RELOC_ARC_PC32:
2676 md_number_to_chars_midend (fixpos, value, fixP->fx_size);
2677 return;
2678
2679 case BFD_RELOC_ARC_PLT32:
2680 md_number_to_chars_midend (fixpos, value, fixP->fx_size);
2681 return;
2682
2683 case BFD_RELOC_ARC_S25H_PCREL_PLT:
2684 reloc = BFD_RELOC_ARC_S25W_PCREL;
2685 goto solve_plt;
2686
2687 case BFD_RELOC_ARC_S21H_PCREL_PLT:
2688 reloc = BFD_RELOC_ARC_S21H_PCREL;
2689 goto solve_plt;
2690
2691 case BFD_RELOC_ARC_S25W_PCREL_PLT:
2692 reloc = BFD_RELOC_ARC_S25W_PCREL;
2693 goto solve_plt;
2694
2695 case BFD_RELOC_ARC_S21W_PCREL_PLT:
2696 reloc = BFD_RELOC_ARC_S21W_PCREL;
2697
2698 case BFD_RELOC_ARC_S25W_PCREL:
2699 case BFD_RELOC_ARC_S21W_PCREL:
2700 case BFD_RELOC_ARC_S21H_PCREL:
2701 case BFD_RELOC_ARC_S25H_PCREL:
2702 case BFD_RELOC_ARC_S13_PCREL:
2703 solve_plt:
2704 operand = find_operand_for_reloc (reloc);
2705 gas_assert (operand);
2706 break;
2707
2708 default:
2709 {
2710 if ((int) fixP->fx_r_type >= 0)
2711 as_fatal (_("unhandled relocation type %s"),
2712 bfd_get_reloc_code_name (fixP->fx_r_type));
2713
2714 /* The rest of these fixups needs to be completely resolved as
2715 constants. */
2716 if (fixP->fx_addsy != 0
2717 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
2718 as_bad_where (fixP->fx_file, fixP->fx_line,
2719 _("non-absolute expression in constant field"));
2720
2721 gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands);
2722 operand = &arc_operands[-(int) fixP->fx_r_type];
2723 break;
2724 }
2725 }
2726
2727 if (target_big_endian)
2728 {
2729 switch (fixP->fx_size)
2730 {
2731 case 4:
2732 insn = bfd_getb32 (fixpos);
2733 break;
2734 case 2:
2735 insn = bfd_getb16 (fixpos);
2736 break;
2737 default:
2738 as_bad_where (fixP->fx_file, fixP->fx_line,
2739 _("unknown fixup size"));
2740 }
2741 }
2742 else
2743 {
2744 insn = 0;
2745 switch (fixP->fx_size)
2746 {
2747 case 4:
2748 insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2);
2749 break;
2750 case 2:
2751 insn = bfd_getl16 (fixpos);
2752 break;
2753 default:
2754 as_bad_where (fixP->fx_file, fixP->fx_line,
2755 _("unknown fixup size"));
2756 }
2757 }
2758
2759 insn = insert_operand (insn, operand, (offsetT) value,
2760 fixP->fx_file, fixP->fx_line);
2761
2762 md_number_to_chars_midend (fixpos, insn, fixP->fx_size);
2763 }
2764
2765 /* Prepare machine-dependent frags for relaxation.
2766
2767 Called just before relaxation starts. Any symbol that is now undefined
2768 will not become defined.
2769
2770 Return the correct fr_subtype in the frag.
2771
2772 Return the initial "guess for fr_var" to caller. The guess for fr_var
2773 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
2774 or fr_var contributes to our returned value.
2775
2776 Although it may not be explicit in the frag, pretend
2777 fr_var starts with a value. */
2778
2779 int
2780 md_estimate_size_before_relax (fragS *fragP,
2781 segT segment)
2782 {
2783 int growth;
2784
2785 /* If the symbol is not located within the same section AND it's not
2786 an absolute section, use the maximum. OR if the symbol is a
2787 constant AND the insn is by nature not pc-rel, use the maximum.
2788 OR if the symbol is being equated against another symbol, use the
2789 maximum. OR if the symbol is weak use the maximum. */
2790 if ((S_GET_SEGMENT (fragP->fr_symbol) != segment
2791 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2792 || (symbol_constant_p (fragP->fr_symbol)
2793 && !fragP->tc_frag_data.pcrel)
2794 || symbol_equated_p (fragP->fr_symbol)
2795 || S_IS_WEAK (fragP->fr_symbol))
2796 {
2797 while (md_relax_table[fragP->fr_subtype].rlx_more != ARC_RLX_NONE)
2798 ++fragP->fr_subtype;
2799 }
2800
2801 growth = md_relax_table[fragP->fr_subtype].rlx_length;
2802 fragP->fr_var = growth;
2803
2804 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
2805 fragP->fr_file, fragP->fr_line, growth);
2806
2807 return growth;
2808 }
2809
2810 /* Translate internal representation of relocation info to BFD target
2811 format. */
2812
2813 arelent *
2814 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
2815 fixS *fixP)
2816 {
2817 arelent *reloc;
2818 bfd_reloc_code_real_type code;
2819
2820 reloc = (arelent *) xmalloc (sizeof (* reloc));
2821 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2822 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
2823 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
2824
2825 /* Make sure none of our internal relocations make it this far.
2826 They'd better have been fully resolved by this point. */
2827 gas_assert ((int) fixP->fx_r_type > 0);
2828
2829 code = fixP->fx_r_type;
2830
2831 /* if we have something like add gp, pcl,
2832 _GLOBAL_OFFSET_TABLE_@gotpc. */
2833 if (code == BFD_RELOC_ARC_GOTPC32
2834 && GOT_symbol
2835 && fixP->fx_addsy == GOT_symbol)
2836 code = BFD_RELOC_ARC_GOTPC;
2837
2838 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
2839 if (reloc->howto == NULL)
2840 {
2841 as_bad_where (fixP->fx_file, fixP->fx_line,
2842 _("cannot represent `%s' relocation in object file"),
2843 bfd_get_reloc_code_name (code));
2844 return NULL;
2845 }
2846
2847 if (!fixP->fx_pcrel != !reloc->howto->pc_relative)
2848 as_fatal (_("internal error? cannot generate `%s' relocation"),
2849 bfd_get_reloc_code_name (code));
2850
2851 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
2852
2853 if (code == BFD_RELOC_ARC_TLS_DTPOFF
2854 || code == BFD_RELOC_ARC_TLS_DTPOFF_S9)
2855 {
2856 asymbol *sym
2857 = fixP->fx_subsy ? symbol_get_bfdsym (fixP->fx_subsy) : NULL;
2858 /* We just want to store a 24 bit index, but we have to wait
2859 till after write_contents has been called via
2860 bfd_map_over_sections before we can get the index from
2861 _bfd_elf_symbol_from_bfd_symbol. Thus, the write_relocs
2862 function is elf32-arc.c has to pick up the slack.
2863 Unfortunately, this leads to problems with hosts that have
2864 pointers wider than long (bfd_vma). There would be various
2865 ways to handle this, all error-prone :-( */
2866 reloc->addend = (bfd_vma) sym;
2867 if ((asymbol *) reloc->addend != sym)
2868 {
2869 as_bad ("Can't store pointer\n");
2870 return NULL;
2871 }
2872 }
2873 else
2874 reloc->addend = fixP->fx_offset;
2875
2876 return reloc;
2877 }
2878
2879 /* Perform post-processing of machine-dependent frags after relaxation.
2880 Called after relaxation is finished.
2881 In: Address of frag.
2882 fr_type == rs_machine_dependent.
2883 fr_subtype is what the address relaxed to.
2884
2885 Out: Any fixS:s and constants are set up. */
2886
2887 void
2888 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
2889 segT segment ATTRIBUTE_UNUSED,
2890 fragS *fragP)
2891 {
2892 const relax_typeS *table_entry;
2893 char *dest;
2894 const struct arc_opcode *opcode;
2895 struct arc_insn insn;
2896 int size, fix;
2897 struct arc_relax_type *relax_arg = &fragP->tc_frag_data;
2898
2899 fix = (fragP->fr_fix < 0 ? 0 : fragP->fr_fix);
2900 dest = fragP->fr_literal + fix;
2901 table_entry = TC_GENERIC_RELAX_TABLE + fragP->fr_subtype;
2902
2903 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, var: %d\n",
2904 fragP->fr_file, fragP->fr_line,
2905 fragP->fr_subtype, fix, fragP->fr_var);
2906
2907 if (fragP->fr_subtype <= 0
2908 && fragP->fr_subtype >= arc_num_relax_opcodes)
2909 as_fatal (_("no relaxation found for this instruction."));
2910
2911 opcode = &arc_relax_opcodes[fragP->fr_subtype];
2912
2913 assemble_insn (opcode, relax_arg->tok, relax_arg->ntok, relax_arg->pflags,
2914 relax_arg->nflg, &insn);
2915
2916 apply_fixups (&insn, fragP, fix);
2917
2918 size = insn.short_insn ? (insn.has_limm ? 6 : 2) : (insn.has_limm ? 8 : 4);
2919 gas_assert (table_entry->rlx_length == size);
2920 emit_insn0 (&insn, dest, TRUE);
2921
2922 fragP->fr_fix += table_entry->rlx_length;
2923 fragP->fr_var = 0;
2924 }
2925
2926 /* We have no need to default values of symbols. We could catch
2927 register names here, but that is handled by inserting them all in
2928 the symbol table to begin with. */
2929
2930 symbolS *
2931 md_undefined_symbol (char *name)
2932 {
2933 /* The arc abi demands that a GOT[0] should be referencible as
2934 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
2935 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
2936 if (((*name == '_')
2937 && (*(name+1) == 'G')
2938 && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0))
2939 || ((*name == '_')
2940 && (*(name+1) == 'D')
2941 && (strcmp (name, DYNAMIC_STRUCT_NAME) == 0)))
2942 {
2943 if (!GOT_symbol)
2944 {
2945 if (symbol_find (name))
2946 as_bad ("GOT already in symbol table");
2947
2948 GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section,
2949 (valueT) 0, &zero_address_frag);
2950 };
2951 return GOT_symbol;
2952 }
2953 return NULL;
2954 }
2955
2956 /* Turn a string in input_line_pointer into a floating point constant
2957 of type type, and store the appropriate bytes in *litP. The number
2958 of LITTLENUMS emitted is stored in *sizeP. An error message is
2959 returned, or NULL on OK. */
2960
2961 const char *
2962 md_atof (int type, char *litP, int *sizeP)
2963 {
2964 return ieee_md_atof (type, litP, sizeP, target_big_endian);
2965 }
2966
2967 /* Called for any expression that can not be recognized. When the
2968 function is called, `input_line_pointer' will point to the start of
2969 the expression. */
2970
2971 void
2972 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
2973 {
2974 char *p = input_line_pointer;
2975 if (*p == '@')
2976 {
2977 input_line_pointer++;
2978 expressionP->X_op = O_symbol;
2979 expression (expressionP);
2980 }
2981 }
2982
2983 /* This function is called from the function 'expression', it attempts
2984 to parse special names (in our case register names). It fills in
2985 the expression with the identified register. It returns TRUE if
2986 it is a register and FALSE otherwise. */
2987
2988 bfd_boolean
2989 arc_parse_name (const char *name,
2990 struct expressionS *e)
2991 {
2992 struct symbol *sym;
2993
2994 if (!assembling_insn)
2995 return FALSE;
2996
2997 /* Handle only registers. */
2998 if (e->X_op != O_absent)
2999 return FALSE;
3000
3001 sym = hash_find (arc_reg_hash, name);
3002 if (sym)
3003 {
3004 e->X_op = O_register;
3005 e->X_add_number = S_GET_VALUE (sym);
3006 return TRUE;
3007 }
3008 return FALSE;
3009 }
3010
3011 /* md_parse_option
3012 Invocation line includes a switch not recognized by the base assembler.
3013 See if it's a processor-specific option.
3014
3015 New options (supported) are:
3016
3017 -mcpu=<cpu name> Assemble for selected processor
3018 -EB/-mbig-endian Big-endian
3019 -EL/-mlittle-endian Little-endian
3020 -mrelax Enable relaxation
3021
3022 The following CPU names are recognized:
3023 arc700, av2em, av2hs. */
3024
3025 int
3026 md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
3027 {
3028 switch (c)
3029 {
3030 case OPTION_ARC600:
3031 case OPTION_ARC601:
3032 return md_parse_option (OPTION_MCPU, "arc600");
3033
3034 case OPTION_ARC700:
3035 return md_parse_option (OPTION_MCPU, "arc700");
3036
3037 case OPTION_ARCEM:
3038 return md_parse_option (OPTION_MCPU, "arcem");
3039
3040 case OPTION_ARCHS:
3041 return md_parse_option (OPTION_MCPU, "archs");
3042
3043 case OPTION_MCPU:
3044 {
3045 arc_select_cpu (arg);
3046 mach_type_specified_p = 1;
3047 break;
3048 }
3049
3050 case OPTION_EB:
3051 arc_target_format = "elf32-bigarc";
3052 byte_order = BIG_ENDIAN;
3053 break;
3054
3055 case OPTION_EL:
3056 arc_target_format = "elf32-littlearc";
3057 byte_order = LITTLE_ENDIAN;
3058 break;
3059
3060 case OPTION_CD:
3061 /* This option has an effect only on ARC EM. */
3062 if (arc_target & ARC_OPCODE_ARCv2EM)
3063 arc_features |= ARC_CD;
3064 else
3065 as_warn (_("Code density option invalid for selected CPU"));
3066 break;
3067
3068 case OPTION_RELAX:
3069 relaxation_state = 1;
3070 break;
3071
3072 case OPTION_USER_MODE:
3073 case OPTION_LD_EXT_MASK:
3074 case OPTION_SWAP:
3075 case OPTION_NORM:
3076 case OPTION_BARREL_SHIFT:
3077 case OPTION_MIN_MAX:
3078 case OPTION_NO_MPY:
3079 case OPTION_EA:
3080 case OPTION_MUL64:
3081 case OPTION_SIMD:
3082 /* Dummy options are accepted but have no effect. */
3083 break;
3084
3085 case OPTION_SPFP:
3086 arc_features |= ARC_SPFP;
3087 break;
3088
3089 case OPTION_DPFP:
3090 arc_features |= ARC_DPFP;
3091 break;
3092
3093 case OPTION_XMAC_D16:
3094 case OPTION_XMAC_24:
3095 case OPTION_DSP_PACKA:
3096 case OPTION_CRC:
3097 case OPTION_DVBF:
3098 case OPTION_TELEPHONY:
3099 case OPTION_XYMEMORY:
3100 case OPTION_LOCK:
3101 case OPTION_SWAPE:
3102 case OPTION_RTSC:
3103 /* Dummy options are accepted but have no effect. */
3104 break;
3105
3106 case OPTION_FPUDA:
3107 /* This option has an effect only on ARC EM. */
3108 if (arc_target & ARC_OPCODE_ARCv2EM)
3109 arc_features |= ARC_FPUDA;
3110 else
3111 as_warn (_("FPUDA invalid for selected CPU"));
3112 break;
3113
3114 default:
3115 return 0;
3116 }
3117
3118 return 1;
3119 }
3120
3121 void
3122 md_show_usage (FILE *stream)
3123 {
3124 fprintf (stream, _("ARC-specific assembler options:\n"));
3125
3126 fprintf (stream, " -mcpu=<cpu name>\t assemble for CPU <cpu name>\n");
3127 fprintf (stream,
3128 " -mcode-density\t enable code density option for ARC EM\n");
3129
3130 fprintf (stream, _("\
3131 -EB assemble code for a big-endian cpu\n"));
3132 fprintf (stream, _("\
3133 -EL assemble code for a little-endian cpu\n"));
3134 fprintf (stream, _("\
3135 -mrelax Enable relaxation\n"));
3136
3137 }
3138
3139 /* Find the proper relocation for the given opcode. */
3140
3141 static extended_bfd_reloc_code_real_type
3142 find_reloc (const char *name,
3143 const char *opcodename,
3144 const struct arc_flags *pflags,
3145 int nflg,
3146 extended_bfd_reloc_code_real_type reloc)
3147 {
3148 unsigned int i;
3149 int j;
3150 bfd_boolean found_flag, tmp;
3151 extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED;
3152
3153 for (i = 0; i < arc_num_equiv_tab; i++)
3154 {
3155 const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i];
3156
3157 /* Find the entry. */
3158 if (strcmp (name, r->name))
3159 continue;
3160 if (r->mnemonic && (strcmp (r->mnemonic, opcodename)))
3161 continue;
3162 if (r->flags[0])
3163 {
3164 if (!nflg)
3165 continue;
3166 found_flag = FALSE;
3167 unsigned * psflg = (unsigned *)r->flags;
3168 do
3169 {
3170 tmp = FALSE;
3171 for (j = 0; j < nflg; j++)
3172 if (!strcmp (pflags[j].name,
3173 arc_flag_operands[*psflg].name))
3174 {
3175 tmp = TRUE;
3176 break;
3177 }
3178 if (!tmp)
3179 {
3180 found_flag = FALSE;
3181 break;
3182 }
3183 else
3184 {
3185 found_flag = TRUE;
3186 }
3187 ++ psflg;
3188 } while (*psflg);
3189
3190 if (!found_flag)
3191 continue;
3192 }
3193
3194 if (reloc != r->oldreloc)
3195 continue;
3196 /* Found it. */
3197 ret = r->newreloc;
3198 break;
3199 }
3200
3201 if (ret == BFD_RELOC_UNUSED)
3202 as_bad (_("Unable to find %s relocation for instruction %s"),
3203 name, opcodename);
3204 return ret;
3205 }
3206
3207 /* All the symbol types that are allowed to be used for
3208 relaxation. */
3209
3210 static bfd_boolean
3211 may_relax_expr (expressionS tok)
3212 {
3213 /* Check if we have unrelaxable relocs. */
3214 switch (tok.X_md)
3215 {
3216 default:
3217 break;
3218 case O_plt:
3219 return FALSE;
3220 }
3221
3222 switch (tok.X_op)
3223 {
3224 case O_symbol:
3225 case O_multiply:
3226 case O_divide:
3227 case O_modulus:
3228 case O_add:
3229 case O_subtract:
3230 break;
3231
3232 default:
3233 return FALSE;
3234 }
3235 return TRUE;
3236 }
3237
3238 /* Checks if flags are in line with relaxable insn. */
3239
3240 static bfd_boolean
3241 relaxable_flag (const struct arc_relaxable_ins *ins,
3242 const struct arc_flags *pflags,
3243 int nflgs)
3244 {
3245 unsigned flag_class,
3246 flag,
3247 flag_class_idx = 0,
3248 flag_idx = 0;
3249
3250 const struct arc_flag_operand *flag_opand;
3251 int i, counttrue = 0;
3252
3253 /* Iterate through flags classes. */
3254 while ((flag_class = ins->flag_classes[flag_class_idx]) != 0)
3255 {
3256 /* Iterate through flags in flag class. */
3257 while ((flag = arc_flag_classes[flag_class].flags[flag_idx])
3258 != 0)
3259 {
3260 flag_opand = &arc_flag_operands[flag];
3261 /* Iterate through flags in ins to compare. */
3262 for (i = 0; i < nflgs; ++i)
3263 {
3264 if (strcmp (flag_opand->name, pflags[i].name) == 0)
3265 ++counttrue;
3266 }
3267
3268 ++flag_idx;
3269 }
3270
3271 ++flag_class_idx;
3272 flag_idx = 0;
3273 }
3274
3275 /* If counttrue == nflgs, then all flags have been found. */
3276 return (counttrue == nflgs ? TRUE : FALSE);
3277 }
3278
3279 /* Checks if operands are in line with relaxable insn. */
3280
3281 static bfd_boolean
3282 relaxable_operand (const struct arc_relaxable_ins *ins,
3283 const expressionS *tok,
3284 int ntok)
3285 {
3286 const enum rlx_operand_type *operand = &ins->operands[0];
3287 int i = 0;
3288
3289 while (*operand != EMPTY)
3290 {
3291 const expressionS *epr = &tok[i];
3292
3293 if (i != 0 && i >= ntok)
3294 return FALSE;
3295
3296 switch (*operand)
3297 {
3298 case IMMEDIATE:
3299 if (!(epr->X_op == O_multiply
3300 || epr->X_op == O_divide
3301 || epr->X_op == O_modulus
3302 || epr->X_op == O_add
3303 || epr->X_op == O_subtract
3304 || epr->X_op == O_symbol))
3305 return FALSE;
3306 break;
3307
3308 case REGISTER_DUP:
3309 if ((i <= 0)
3310 || (epr->X_add_number != tok[i - 1].X_add_number))
3311 return FALSE;
3312 /* Fall through. */
3313 case REGISTER:
3314 if (epr->X_op != O_register)
3315 return FALSE;
3316 break;
3317
3318 case REGISTER_S:
3319 if (epr->X_op != O_register)
3320 return FALSE;
3321
3322 switch (epr->X_add_number)
3323 {
3324 case 0: case 1: case 2: case 3:
3325 case 12: case 13: case 14: case 15:
3326 break;
3327 default:
3328 return FALSE;
3329 }
3330 break;
3331
3332 case REGISTER_NO_GP:
3333 if ((epr->X_op != O_register)
3334 || (epr->X_add_number == 26)) /* 26 is the gp register. */
3335 return FALSE;
3336 break;
3337
3338 case BRACKET:
3339 if (epr->X_op != O_bracket)
3340 return FALSE;
3341 break;
3342
3343 default:
3344 /* Don't understand, bail out. */
3345 return FALSE;
3346 break;
3347 }
3348
3349 ++i;
3350 operand = &ins->operands[i];
3351 }
3352
3353 return (i == ntok ? TRUE : FALSE);
3354 }
3355
3356 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3357
3358 static bfd_boolean
3359 relax_insn_p (const struct arc_opcode *opcode,
3360 const expressionS *tok,
3361 int ntok,
3362 const struct arc_flags *pflags,
3363 int nflg)
3364 {
3365 unsigned i;
3366 bfd_boolean rv = FALSE;
3367
3368 /* Check the relaxation table. */
3369 for (i = 0; i < arc_num_relaxable_ins && relaxation_state; ++i)
3370 {
3371 const struct arc_relaxable_ins *arc_rlx_ins = &arc_relaxable_insns[i];
3372
3373 if ((strcmp (opcode->name, arc_rlx_ins->mnemonic_r) == 0)
3374 && may_relax_expr (tok[arc_rlx_ins->opcheckidx])
3375 && relaxable_operand (arc_rlx_ins, tok, ntok)
3376 && relaxable_flag (arc_rlx_ins, pflags, nflg))
3377 {
3378 rv = TRUE;
3379 frag_now->fr_subtype = arc_relaxable_insns[i].subtype;
3380 memcpy (&frag_now->tc_frag_data.tok, tok,
3381 sizeof (expressionS) * ntok);
3382 memcpy (&frag_now->tc_frag_data.pflags, pflags,
3383 sizeof (struct arc_flags) * nflg);
3384 frag_now->tc_frag_data.nflg = nflg;
3385 frag_now->tc_frag_data.ntok = ntok;
3386 break;
3387 }
3388 }
3389
3390 return rv;
3391 }
3392
3393 /* Turn an opcode description and a set of arguments into
3394 an instruction and a fixup. */
3395
3396 static void
3397 assemble_insn (const struct arc_opcode *opcode,
3398 const expressionS *tok,
3399 int ntok,
3400 const struct arc_flags *pflags,
3401 int nflg,
3402 struct arc_insn *insn)
3403 {
3404 const expressionS *reloc_exp = NULL;
3405 unsigned image;
3406 const unsigned char *argidx;
3407 int i;
3408 int tokidx = 0;
3409 unsigned char pcrel = 0;
3410 bfd_boolean needGOTSymbol;
3411 bfd_boolean has_delay_slot = FALSE;
3412 extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
3413
3414 memset (insn, 0, sizeof (*insn));
3415 image = opcode->opcode;
3416
3417 pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
3418 frag_now->fr_file, frag_now->fr_line, opcode->name,
3419 opcode->opcode);
3420
3421 /* Handle operands. */
3422 for (argidx = opcode->operands; *argidx; ++argidx)
3423 {
3424 const struct arc_operand *operand = &arc_operands[*argidx];
3425 const expressionS *t = (const expressionS *) 0;
3426
3427 if ((operand->flags & ARC_OPERAND_FAKE)
3428 && !(operand->flags & ARC_OPERAND_BRAKET))
3429 continue;
3430
3431 if (operand->flags & ARC_OPERAND_DUPLICATE)
3432 {
3433 /* Duplicate operand, already inserted. */
3434 tokidx ++;
3435 continue;
3436 }
3437
3438 if (tokidx >= ntok)
3439 {
3440 abort ();
3441 }
3442 else
3443 t = &tok[tokidx++];
3444
3445 /* Regardless if we have a reloc or not mark the instruction
3446 limm if it is the case. */
3447 if (operand->flags & ARC_OPERAND_LIMM)
3448 insn->has_limm = TRUE;
3449
3450 switch (t->X_op)
3451 {
3452 case O_register:
3453 image = insert_operand (image, operand, regno (t->X_add_number),
3454 NULL, 0);
3455 break;
3456
3457 case O_constant:
3458 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
3459 reloc_exp = t;
3460 if (operand->flags & ARC_OPERAND_LIMM)
3461 insn->limm = t->X_add_number;
3462 break;
3463
3464 case O_bracket:
3465 /* Ignore brackets. */
3466 break;
3467
3468 case O_absent:
3469 gas_assert (operand->flags & ARC_OPERAND_IGNORE);
3470 break;
3471
3472 case O_subtract:
3473 /* Maybe register range. */
3474 if ((t->X_add_number == 0)
3475 && contains_register (t->X_add_symbol)
3476 && contains_register (t->X_op_symbol))
3477 {
3478 int regs;
3479
3480 regs = get_register (t->X_add_symbol);
3481 regs <<= 16;
3482 regs |= get_register (t->X_op_symbol);
3483 image = insert_operand (image, operand, regs, NULL, 0);
3484 break;
3485 }
3486
3487 default:
3488 /* This operand needs a relocation. */
3489 needGOTSymbol = FALSE;
3490
3491 switch (t->X_md)
3492 {
3493 case O_plt:
3494 if (opcode->class == JUMP)
3495 as_bad_where (frag_now->fr_file, frag_now->fr_line,
3496 _("Unable to use @plt relocatio for insn %s"),
3497 opcode->name);
3498 needGOTSymbol = TRUE;
3499 reloc = find_reloc ("plt", opcode->name,
3500 pflags, nflg,
3501 operand->default_reloc);
3502 break;
3503
3504 case O_gotoff:
3505 case O_gotpc:
3506 needGOTSymbol = TRUE;
3507 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3508 break;
3509 case O_pcl:
3510 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3511 if (ARC_SHORT (opcode->mask) || opcode->class == JUMP)
3512 as_bad_where (frag_now->fr_file, frag_now->fr_line,
3513 _("Unable to use @pcl relocation for insn %s"),
3514 opcode->name);
3515 break;
3516 case O_sda:
3517 reloc = find_reloc ("sda", opcode->name,
3518 pflags, nflg,
3519 operand->default_reloc);
3520 break;
3521 case O_tlsgd:
3522 case O_tlsie:
3523 needGOTSymbol = TRUE;
3524 /* Fall-through. */
3525
3526 case O_tpoff:
3527 case O_dtpoff:
3528 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3529 break;
3530
3531 case O_tpoff9: /*FIXME! Check for the conditionality of
3532 the insn. */
3533 case O_dtpoff9: /*FIXME! Check for the conditionality of
3534 the insn. */
3535 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3536 break;
3537
3538 default:
3539 /* Just consider the default relocation. */
3540 reloc = operand->default_reloc;
3541 break;
3542 }
3543
3544 if (needGOTSymbol && (GOT_symbol == NULL))
3545 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
3546
3547 reloc_exp = t;
3548
3549 #if 0
3550 if (reloc > 0)
3551 {
3552 /* sanity checks. */
3553 reloc_howto_type *reloc_howto
3554 = bfd_reloc_type_lookup (stdoutput,
3555 (bfd_reloc_code_real_type) reloc);
3556 unsigned reloc_bitsize = reloc_howto->bitsize;
3557 if (reloc_howto->rightshift)
3558 reloc_bitsize -= reloc_howto->rightshift;
3559 if (reloc_bitsize != operand->bits)
3560 {
3561 as_bad (_("invalid relocation %s for field"),
3562 bfd_get_reloc_code_name (reloc));
3563 return;
3564 }
3565 }
3566 #endif
3567 if (insn->nfixups >= MAX_INSN_FIXUPS)
3568 as_fatal (_("too many fixups"));
3569
3570 struct arc_fixup *fixup;
3571 fixup = &insn->fixups[insn->nfixups++];
3572 fixup->exp = *t;
3573 fixup->reloc = reloc;
3574 pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
3575 fixup->pcrel = pcrel;
3576 fixup->islong = (operand->flags & ARC_OPERAND_LIMM) ?
3577 TRUE : FALSE;
3578 break;
3579 }
3580 }
3581
3582 /* Handle flags. */
3583 for (i = 0; i < nflg; i++)
3584 {
3585 const struct arc_flag_operand *flg_operand =
3586 &arc_flag_operands[pflags[i].code];
3587
3588 /* Check if the instruction has a delay slot. */
3589 if (!strcmp (flg_operand->name, "d"))
3590 has_delay_slot = TRUE;
3591
3592 /* There is an exceptional case when we cannot insert a flag
3593 just as it is. The .T flag must be handled in relation with
3594 the relative address. */
3595 if (!strcmp (flg_operand->name, "t")
3596 || !strcmp (flg_operand->name, "nt"))
3597 {
3598 unsigned bitYoperand = 0;
3599 /* FIXME! move selection bbit/brcc in arc-opc.c. */
3600 if (!strcmp (flg_operand->name, "t"))
3601 if (!strcmp (opcode->name, "bbit0")
3602 || !strcmp (opcode->name, "bbit1"))
3603 bitYoperand = arc_NToperand;
3604 else
3605 bitYoperand = arc_Toperand;
3606 else
3607 if (!strcmp (opcode->name, "bbit0")
3608 || !strcmp (opcode->name, "bbit1"))
3609 bitYoperand = arc_Toperand;
3610 else
3611 bitYoperand = arc_NToperand;
3612
3613 gas_assert (reloc_exp != NULL);
3614 if (reloc_exp->X_op == O_constant)
3615 {
3616 /* Check if we have a constant and solved it
3617 immediately. */
3618 offsetT val = reloc_exp->X_add_number;
3619 image |= insert_operand (image, &arc_operands[bitYoperand],
3620 val, NULL, 0);
3621 }
3622 else
3623 {
3624 struct arc_fixup *fixup;
3625
3626 if (insn->nfixups >= MAX_INSN_FIXUPS)
3627 as_fatal (_("too many fixups"));
3628
3629 fixup = &insn->fixups[insn->nfixups++];
3630 fixup->exp = *reloc_exp;
3631 fixup->reloc = -bitYoperand;
3632 fixup->pcrel = pcrel;
3633 fixup->islong = FALSE;
3634 }
3635 }
3636 else
3637 image |= (flg_operand->code & ((1 << flg_operand->bits) - 1))
3638 << flg_operand->shift;
3639 }
3640
3641 insn->relax = relax_insn_p (opcode, tok, ntok, pflags, nflg);
3642
3643 /* Short instruction? */
3644 insn->short_insn = ARC_SHORT (opcode->mask) ? TRUE : FALSE;
3645
3646 insn->insn = image;
3647
3648 /* Update last insn status. */
3649 arc_last_insns[1] = arc_last_insns[0];
3650 arc_last_insns[0].opcode = opcode;
3651 arc_last_insns[0].has_limm = insn->has_limm;
3652 arc_last_insns[0].has_delay_slot = has_delay_slot;
3653
3654 /* Check if the current instruction is legally used. */
3655 if (arc_last_insns[1].has_delay_slot
3656 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
3657 as_bad_where (frag_now->fr_file, frag_now->fr_line,
3658 _("A jump/branch instruction in delay slot."));
3659 }
3660
3661 void
3662 arc_handle_align (fragS* fragP)
3663 {
3664 if ((fragP)->fr_type == rs_align_code)
3665 {
3666 char *dest = (fragP)->fr_literal + (fragP)->fr_fix;
3667 valueT count = ((fragP)->fr_next->fr_address
3668 - (fragP)->fr_address - (fragP)->fr_fix);
3669
3670 (fragP)->fr_var = 2;
3671
3672 if (count & 1)/* Padding in the gap till the next 2-byte
3673 boundary with 0s. */
3674 {
3675 (fragP)->fr_fix++;
3676 *dest++ = 0;
3677 }
3678 /* Writing nop_s. */
3679 md_number_to_chars (dest, NOP_OPCODE_S, 2);
3680 }
3681 }
3682
3683 /* Here we decide which fixups can be adjusted to make them relative
3684 to the beginning of the section instead of the symbol. Basically
3685 we need to make sure that the dynamic relocations are done
3686 correctly, so in some cases we force the original symbol to be
3687 used. */
3688
3689 int
3690 tc_arc_fix_adjustable (fixS *fixP)
3691 {
3692
3693 /* Prevent all adjustments to global symbols. */
3694 if (S_IS_EXTERNAL (fixP->fx_addsy))
3695 return 0;
3696 if (S_IS_WEAK (fixP->fx_addsy))
3697 return 0;
3698
3699 /* Adjust_reloc_syms doesn't know about the GOT. */
3700 switch (fixP->fx_r_type)
3701 {
3702 case BFD_RELOC_ARC_GOTPC32:
3703 case BFD_RELOC_ARC_PLT32:
3704 case BFD_RELOC_ARC_S25H_PCREL_PLT:
3705 case BFD_RELOC_ARC_S21H_PCREL_PLT:
3706 case BFD_RELOC_ARC_S25W_PCREL_PLT:
3707 case BFD_RELOC_ARC_S21W_PCREL_PLT:
3708 return 0;
3709
3710 default:
3711 break;
3712 }
3713
3714 return 1;
3715 }
3716
3717 /* Compute the reloc type of an expression EXP. */
3718
3719 static void
3720 arc_check_reloc (expressionS *exp,
3721 bfd_reloc_code_real_type *r_type_p)
3722 {
3723 if (*r_type_p == BFD_RELOC_32
3724 && exp->X_op == O_subtract
3725 && exp->X_op_symbol != NULL
3726 && exp->X_op_symbol->bsym->section == now_seg)
3727 *r_type_p = BFD_RELOC_ARC_32_PCREL;
3728 }
3729
3730
3731 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
3732
3733 void
3734 arc_cons_fix_new (fragS *frag,
3735 int off,
3736 int size,
3737 expressionS *exp,
3738 bfd_reloc_code_real_type r_type)
3739 {
3740 r_type = BFD_RELOC_UNUSED;
3741
3742 switch (size)
3743 {
3744 case 1:
3745 r_type = BFD_RELOC_8;
3746 break;
3747
3748 case 2:
3749 r_type = BFD_RELOC_16;
3750 break;
3751
3752 case 3:
3753 r_type = BFD_RELOC_24;
3754 break;
3755
3756 case 4:
3757 r_type = BFD_RELOC_32;
3758 arc_check_reloc (exp, &r_type);
3759 break;
3760
3761 case 8:
3762 r_type = BFD_RELOC_64;
3763 break;
3764
3765 default:
3766 as_bad (_("unsupported BFD relocation size %u"), size);
3767 r_type = BFD_RELOC_UNUSED;
3768 }
3769
3770 fix_new_exp (frag, off, size, exp, 0, r_type);
3771 }
3772
3773 /* The actual routine that checks the ZOL conditions. */
3774
3775 static void
3776 check_zol (symbolS *s)
3777 {
3778 switch (arc_mach_type)
3779 {
3780 case bfd_mach_arc_arcv2:
3781 if (arc_target & ARC_OPCODE_ARCv2EM)
3782 return;
3783
3784 if (is_br_jmp_insn_p (arc_last_insns[0].opcode)
3785 || arc_last_insns[1].has_delay_slot)
3786 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
3787 S_GET_NAME (s));
3788
3789 break;
3790 case bfd_mach_arc_arc600:
3791
3792 if (is_kernel_insn_p (arc_last_insns[0].opcode))
3793 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
3794 S_GET_NAME (s));
3795
3796 if (arc_last_insns[0].has_limm
3797 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
3798 as_bad (_("A jump instruction with long immediate detected at the \
3799 end of the ZOL label @%s"), S_GET_NAME (s));
3800
3801 /* Fall through. */
3802 case bfd_mach_arc_nps400:
3803 case bfd_mach_arc_arc700:
3804 if (arc_last_insns[0].has_delay_slot)
3805 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
3806 S_GET_NAME (s));
3807
3808 break;
3809 default:
3810 break;
3811 }
3812 }
3813
3814 /* If ZOL end check the last two instruction for illegals. */
3815 void
3816 arc_frob_label (symbolS * sym)
3817 {
3818 if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL)
3819 check_zol (sym);
3820
3821 dwarf2_emit_label (sym);
3822 }
3823
3824 /* Used because generic relaxation assumes a pc-rel value whilst we
3825 also relax instructions that use an absolute value resolved out of
3826 relative values (if that makes any sense). An example: 'add r1,
3827 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
3828 but if they're in the same section we can subtract the section
3829 offset relocation which ends up in a resolved value. So if @.L2 is
3830 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
3831 .text + 0x40 = 0x10. */
3832 int
3833 arc_pcrel_adjust (fragS *fragP)
3834 {
3835 if (!fragP->tc_frag_data.pcrel)
3836 return fragP->fr_address + fragP->fr_fix;
3837
3838 return 0;
3839 }
3840
3841 /* Initialize the DWARF-2 unwind information for this procedure. */
3842
3843 void
3844 tc_arc_frame_initial_instructions (void)
3845 {
3846 /* Stack pointer is register 28. */
3847 cfi_add_CFA_def_cfa_register (28);
3848 }
3849
3850 int
3851 tc_arc_regname_to_dw2regnum (char *regname)
3852 {
3853 struct symbol *sym;
3854
3855 sym = hash_find (arc_reg_hash, regname);
3856 if (sym)
3857 return S_GET_VALUE (sym);
3858
3859 return -1;
3860 }
3861
3862 /* Adjust the symbol table. Delete found AUX register symbols. */
3863
3864 void
3865 arc_adjust_symtab (void)
3866 {
3867 symbolS * sym;
3868
3869 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
3870 {
3871 /* I've created a symbol during parsing process. Now, remove
3872 the symbol as it is found to be an AUX register. */
3873 if (ARC_GET_FLAG (sym) & ARC_FLAG_AUX)
3874 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
3875 }
3876
3877 /* Now do generic ELF adjustments. */
3878 elf_adjust_symtab ();
3879 }