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