]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-arc.c
arc: Put DBNZ instruction to a separate class
[thirdparty/binutils-gdb.git] / gas / config / tc-arc.c
1 /* tc-arc.c -- Assembler for the ARC
2 Copyright (C) 1994-2024 Free Software Foundation, Inc.
3
4 Contributor: Claudiu Zissulescu <claziss@synopsys.com>
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
22
23 #include "as.h"
24 #include "subsegs.h"
25 #include "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 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 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 : (int) (op) - (int) 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_ARC_PLT32, 0),
548 DEF (sda, DUMMY_RELOC_ARC_ENTRY, 1),
549 DEF (pcl, BFD_RELOC_ARC_PC32, 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 when we assemble 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 = (string_tuple_t *) 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 *input_line_pointer = c;
1156 SKIP_WHITESPACE_AFTER_NAME ();
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 tok->X_op = O_symbol;
1279 tok->X_md = O_absent;
1280 expression (tok);
1281
1282 if (*input_line_pointer == '@')
1283 parse_reloc_symbol (tok);
1284
1285 debug_exp (tok);
1286
1287 if (tok->X_op == O_illegal
1288 || tok->X_op == O_absent
1289 || num_args == ntok)
1290 goto err;
1291
1292 saw_comma = false;
1293 saw_arg = true;
1294 tok++;
1295 num_args++;
1296 break;
1297
1298 case '%':
1299 /* Can be a register. */
1300 ++input_line_pointer;
1301 /* Fall through. */
1302 default:
1303
1304 if ((saw_arg && !saw_comma) || num_args == ntok)
1305 goto err;
1306
1307 tok->X_op = O_absent;
1308 tok->X_md = O_absent;
1309 expression (tok);
1310
1311 /* Legacy: There are cases when we have
1312 identifier@relocation_type, if it is the case parse the
1313 relocation type as well. */
1314 if (*input_line_pointer == '@')
1315 parse_reloc_symbol (tok);
1316 else
1317 resolve_register (tok);
1318
1319 debug_exp (tok);
1320
1321 if (tok->X_op == O_illegal
1322 || tok->X_op == O_absent
1323 || num_args == ntok)
1324 goto err;
1325
1326 saw_comma = false;
1327 saw_arg = true;
1328 tok++;
1329 num_args++;
1330 break;
1331 }
1332 }
1333
1334 fini:
1335 if (saw_comma || brk_lvl)
1336 goto err;
1337 input_line_pointer = old_input_line_pointer;
1338
1339 return num_args;
1340
1341 err:
1342 if (brk_lvl)
1343 as_bad (_("Brackets in operand field incorrect"));
1344 else if (saw_comma)
1345 as_bad (_("extra comma"));
1346 else if (!saw_arg)
1347 as_bad (_("missing argument"));
1348 else
1349 as_bad (_("missing comma or colon"));
1350 input_line_pointer = old_input_line_pointer;
1351 return -1;
1352 }
1353
1354 /* Parse the flags to a structure. */
1355
1356 static int
1357 tokenize_flags (const char *str,
1358 struct arc_flags flags[],
1359 int nflg)
1360 {
1361 char *old_input_line_pointer;
1362 bool saw_flg = false;
1363 bool saw_dot = false;
1364 int num_flags = 0;
1365 size_t flgnamelen;
1366
1367 memset (flags, 0, sizeof (*flags) * nflg);
1368
1369 /* Save and restore input_line_pointer around this function. */
1370 old_input_line_pointer = input_line_pointer;
1371 input_line_pointer = (char *) str;
1372
1373 while (*input_line_pointer)
1374 {
1375 switch (*input_line_pointer)
1376 {
1377 case ' ':
1378 case '\0':
1379 goto fini;
1380
1381 case '.':
1382 input_line_pointer++;
1383 if (saw_dot)
1384 goto err;
1385 saw_dot = true;
1386 saw_flg = false;
1387 break;
1388
1389 default:
1390 if (saw_flg && !saw_dot)
1391 goto err;
1392
1393 if (num_flags >= nflg)
1394 goto err;
1395
1396 flgnamelen = strspn (input_line_pointer,
1397 "abcdefghijklmnopqrstuvwxyz0123456789");
1398 if (flgnamelen > MAX_FLAG_NAME_LENGTH)
1399 goto err;
1400
1401 memcpy (flags->name, input_line_pointer, flgnamelen);
1402
1403 input_line_pointer += flgnamelen;
1404 flags++;
1405 saw_dot = false;
1406 saw_flg = true;
1407 num_flags++;
1408 break;
1409 }
1410 }
1411
1412 fini:
1413 input_line_pointer = old_input_line_pointer;
1414 return num_flags;
1415
1416 err:
1417 if (saw_dot)
1418 as_bad (_("extra dot"));
1419 else if (!saw_flg)
1420 as_bad (_("unrecognized flag"));
1421 else
1422 as_bad (_("failed to parse flags"));
1423 input_line_pointer = old_input_line_pointer;
1424 return -1;
1425 }
1426
1427 /* Apply the fixups in order. */
1428
1429 static void
1430 apply_fixups (struct arc_insn *insn, fragS *fragP, int fix)
1431 {
1432 int i;
1433
1434 for (i = 0; i < insn->nfixups; i++)
1435 {
1436 struct arc_fixup *fixup = &insn->fixups[i];
1437 int size, pcrel, offset = 0;
1438
1439 /* FIXME! the reloc size is wrong in the BFD file.
1440 When it is fixed please delete me. */
1441 size = ((insn->len == 2) && !fixup->islong) ? 2 : 4;
1442
1443 if (fixup->islong)
1444 offset = insn->len;
1445
1446 /* Some fixups are only used internally, thus no howto. */
1447 if ((int) fixup->reloc == 0)
1448 as_fatal (_("Unhandled reloc type"));
1449
1450 if ((int) fixup->reloc < 0)
1451 {
1452 /* FIXME! the reloc size is wrong in the BFD file.
1453 When it is fixed please enable me.
1454 size = ((insn->len == 2 && !fixup->islong) ? 2 : 4; */
1455 pcrel = fixup->pcrel;
1456 }
1457 else
1458 {
1459 reloc_howto_type *reloc_howto =
1460 bfd_reloc_type_lookup (stdoutput,
1461 (bfd_reloc_code_real_type) 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_ARC_PC32. */
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 /* Signalize we are assembling the instructions. */
2527 assembling_insn = true;
2528
2529 /* Tokenize the flags. */
2530 if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1)
2531 {
2532 as_bad (_("syntax error"));
2533 return;
2534 }
2535
2536 /* Scan up to the end of the mnemonic which must end in space or end
2537 of string. */
2538 str += opnamelen;
2539 for (; *str != '\0'; str++)
2540 if (*str == ' ')
2541 break;
2542
2543 /* Tokenize the rest of the line. */
2544 if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0)
2545 {
2546 as_bad (_("syntax error"));
2547 return;
2548 }
2549
2550 /* Finish it off. */
2551 assemble_tokens (opname, tok, ntok, flags, nflg);
2552 assembling_insn = false;
2553 }
2554
2555 /* Callback to insert a register into the hash table. */
2556
2557 static void
2558 declare_register (const char *name, int number)
2559 {
2560 symbolS *regS = symbol_create (name, reg_section,
2561 &zero_address_frag, number);
2562
2563 if (str_hash_insert (arc_reg_hash, S_GET_NAME (regS), regS, 0) != NULL)
2564 as_fatal (_("duplicate %s"), name);
2565 }
2566
2567 /* Construct symbols for each of the general registers. */
2568
2569 static void
2570 declare_register_set (void)
2571 {
2572 int i;
2573 for (i = 0; i < 64; ++i)
2574 {
2575 char name[32];
2576
2577 sprintf (name, "r%d", i);
2578 declare_register (name, i);
2579 if ((i & 0x01) == 0)
2580 {
2581 sprintf (name, "r%dr%d", i, i+1);
2582 declare_register (name, i);
2583 }
2584 }
2585 }
2586
2587 /* Construct a symbol for an address type. */
2588
2589 static void
2590 declare_addrtype (const char *name, int number)
2591 {
2592 symbolS *addrtypeS = symbol_create (name, undefined_section,
2593 &zero_address_frag, number);
2594
2595 if (str_hash_insert (arc_addrtype_hash, S_GET_NAME (addrtypeS), addrtypeS, 0))
2596 as_fatal (_("duplicate %s"), name);
2597 }
2598
2599 /* Port-specific assembler initialization. This function is called
2600 once, at assembler startup time. */
2601
2602 void
2603 md_begin (void)
2604 {
2605 const struct arc_opcode *opcode = arc_opcodes;
2606
2607 if (mach_selection_mode == MACH_SELECTION_NONE)
2608 arc_select_cpu (TARGET_WITH_CPU, MACH_SELECTION_FROM_DEFAULT);
2609
2610 /* The endianness can be chosen "at the factory". */
2611 target_big_endian = byte_order == BIG_ENDIAN;
2612
2613 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
2614 as_warn (_("could not set architecture and machine"));
2615
2616 /* Set elf header flags. */
2617 bfd_set_private_flags (stdoutput, selected_cpu.eflags);
2618
2619 /* Set up a hash table for the instructions. */
2620 arc_opcode_hash = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
2621 arc_opcode_free, xcalloc, free);
2622
2623 /* Initialize the hash table with the insns. */
2624 do
2625 {
2626 const char *name = opcode->name;
2627
2628 arc_insert_opcode (opcode);
2629
2630 while (++opcode && opcode->name
2631 && (opcode->name == name
2632 || !strcmp (opcode->name, name)))
2633 continue;
2634 }while (opcode->name);
2635
2636 /* Register declaration. */
2637 arc_reg_hash = str_htab_create ();
2638
2639 declare_register_set ();
2640 declare_register ("gp", 26);
2641 declare_register ("fp", 27);
2642 declare_register ("sp", 28);
2643 declare_register ("ilink", 29);
2644 declare_register ("ilink1", 29);
2645 declare_register ("ilink2", 30);
2646 declare_register ("blink", 31);
2647
2648 /* XY memory registers. */
2649 declare_register ("x0_u0", 32);
2650 declare_register ("x0_u1", 33);
2651 declare_register ("x1_u0", 34);
2652 declare_register ("x1_u1", 35);
2653 declare_register ("x2_u0", 36);
2654 declare_register ("x2_u1", 37);
2655 declare_register ("x3_u0", 38);
2656 declare_register ("x3_u1", 39);
2657 declare_register ("y0_u0", 40);
2658 declare_register ("y0_u1", 41);
2659 declare_register ("y1_u0", 42);
2660 declare_register ("y1_u1", 43);
2661 declare_register ("y2_u0", 44);
2662 declare_register ("y2_u1", 45);
2663 declare_register ("y3_u0", 46);
2664 declare_register ("y3_u1", 47);
2665 declare_register ("x0_nu", 48);
2666 declare_register ("x1_nu", 49);
2667 declare_register ("x2_nu", 50);
2668 declare_register ("x3_nu", 51);
2669 declare_register ("y0_nu", 52);
2670 declare_register ("y1_nu", 53);
2671 declare_register ("y2_nu", 54);
2672 declare_register ("y3_nu", 55);
2673
2674 declare_register ("mlo", 57);
2675 declare_register ("mmid", 58);
2676 declare_register ("mhi", 59);
2677
2678 declare_register ("acc1", 56);
2679 declare_register ("acc2", 57);
2680
2681 declare_register ("lp_count", 60);
2682 declare_register ("pcl", 63);
2683
2684 /* Initialize the last instructions. */
2685 memset (&arc_last_insns[0], 0, sizeof (arc_last_insns));
2686
2687 /* Aux register declaration. */
2688 arc_aux_hash = str_htab_create ();
2689
2690 const struct arc_aux_reg *auxr = &arc_aux_regs[0];
2691 unsigned int i;
2692 for (i = 0; i < arc_num_aux_regs; i++, auxr++)
2693 {
2694 if (!(auxr->cpu & selected_cpu.flags))
2695 continue;
2696
2697 if ((auxr->subclass != NONE)
2698 && !check_cpu_feature (auxr->subclass))
2699 continue;
2700
2701 if (str_hash_insert (arc_aux_hash, auxr->name, auxr, 0) != 0)
2702 as_fatal (_("duplicate %s"), auxr->name);
2703 }
2704
2705 /* Address type declaration. */
2706 arc_addrtype_hash = str_htab_create ();
2707
2708 declare_addrtype ("bd", ARC_NPS400_ADDRTYPE_BD);
2709 declare_addrtype ("jid", ARC_NPS400_ADDRTYPE_JID);
2710 declare_addrtype ("lbd", ARC_NPS400_ADDRTYPE_LBD);
2711 declare_addrtype ("mbd", ARC_NPS400_ADDRTYPE_MBD);
2712 declare_addrtype ("sd", ARC_NPS400_ADDRTYPE_SD);
2713 declare_addrtype ("sm", ARC_NPS400_ADDRTYPE_SM);
2714 declare_addrtype ("xa", ARC_NPS400_ADDRTYPE_XA);
2715 declare_addrtype ("xd", ARC_NPS400_ADDRTYPE_XD);
2716 declare_addrtype ("cd", ARC_NPS400_ADDRTYPE_CD);
2717 declare_addrtype ("cbd", ARC_NPS400_ADDRTYPE_CBD);
2718 declare_addrtype ("cjid", ARC_NPS400_ADDRTYPE_CJID);
2719 declare_addrtype ("clbd", ARC_NPS400_ADDRTYPE_CLBD);
2720 declare_addrtype ("cm", ARC_NPS400_ADDRTYPE_CM);
2721 declare_addrtype ("csd", ARC_NPS400_ADDRTYPE_CSD);
2722 declare_addrtype ("cxa", ARC_NPS400_ADDRTYPE_CXA);
2723 declare_addrtype ("cxd", ARC_NPS400_ADDRTYPE_CXD);
2724 }
2725
2726 void
2727 arc_md_end (void)
2728 {
2729 htab_delete (arc_opcode_hash);
2730 htab_delete (arc_reg_hash);
2731 htab_delete (arc_aux_hash);
2732 htab_delete (arc_addrtype_hash);
2733 }
2734
2735 /* Write a value out to the object file, using the appropriate
2736 endianness. */
2737
2738 void
2739 md_number_to_chars (char *buf,
2740 valueT val,
2741 int n)
2742 {
2743 if (target_big_endian)
2744 number_to_chars_bigendian (buf, val, n);
2745 else
2746 number_to_chars_littleendian (buf, val, n);
2747 }
2748
2749 /* Round up a section size to the appropriate boundary. */
2750
2751 valueT
2752 md_section_align (segT segment,
2753 valueT size)
2754 {
2755 int align = bfd_section_alignment (segment);
2756
2757 return ((size + (1 << align) - 1) & (-((valueT) 1 << align)));
2758 }
2759
2760 /* The location from which a PC relative jump should be calculated,
2761 given a PC relative reloc. */
2762
2763 long
2764 md_pcrel_from_section (fixS *fixP,
2765 segT sec)
2766 {
2767 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
2768
2769 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP->fx_offset);
2770
2771 if (fixP->fx_addsy != (symbolS *) NULL
2772 && (!S_IS_DEFINED (fixP->fx_addsy)
2773 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
2774 {
2775 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP->fx_addsy));
2776
2777 /* The symbol is undefined (or is defined but not in this section).
2778 Let the linker figure it out. */
2779 return 0;
2780 }
2781
2782 if ((int) fixP->fx_r_type < 0)
2783 {
2784 /* These are the "internal" relocations. Align them to
2785 32 bit boundary (PCL), for the moment. */
2786 base &= ~3;
2787 }
2788 else
2789 {
2790 switch (fixP->fx_r_type)
2791 {
2792 case BFD_RELOC_ARC_PC32:
2793 /* The hardware calculates relative to the start of the
2794 insn, but this relocation is relative to location of the
2795 LIMM, compensate. The base always needs to be
2796 subtracted by 4 as we do not support this type of PCrel
2797 relocation for short instructions. */
2798 base -= 4;
2799 /* Fall through. */
2800 case BFD_RELOC_ARC_PLT32:
2801 case BFD_RELOC_ARC_S25H_PCREL_PLT:
2802 case BFD_RELOC_ARC_S21H_PCREL_PLT:
2803 case BFD_RELOC_ARC_S25W_PCREL_PLT:
2804 case BFD_RELOC_ARC_S21W_PCREL_PLT:
2805
2806 case BFD_RELOC_ARC_S21H_PCREL:
2807 case BFD_RELOC_ARC_S25H_PCREL:
2808 case BFD_RELOC_ARC_S13_PCREL:
2809 case BFD_RELOC_ARC_S21W_PCREL:
2810 case BFD_RELOC_ARC_S25W_PCREL:
2811 base &= ~3;
2812 break;
2813 default:
2814 as_bad_where (fixP->fx_file, fixP->fx_line,
2815 _("unhandled reloc %s in md_pcrel_from_section"),
2816 bfd_get_reloc_code_name (fixP->fx_r_type));
2817 break;
2818 }
2819 }
2820
2821 pr_debug ("pcrel from %" PRIx64 " + %lx = %" PRIx64 ", "
2822 "symbol: %s (%" PRIx64 ")\n",
2823 (uint64_t) fixP->fx_frag->fr_address, fixP->fx_where, (uint64_t) base,
2824 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "(null)",
2825 fixP->fx_addsy ? (uint64_t) S_GET_VALUE (fixP->fx_addsy) : (uint64_t) 0);
2826
2827 return base;
2828 }
2829
2830 /* Given a BFD relocation find the corresponding operand. */
2831
2832 static const struct arc_operand *
2833 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc)
2834 {
2835 unsigned i;
2836
2837 for (i = 0; i < arc_num_operands; i++)
2838 if (arc_operands[i].default_reloc == reloc)
2839 return &arc_operands[i];
2840 return NULL;
2841 }
2842
2843 /* Insert an operand value into an instruction. */
2844
2845 static unsigned long long
2846 insert_operand (unsigned long long insn,
2847 const struct arc_operand *operand,
2848 long long val,
2849 const char *file,
2850 unsigned line)
2851 {
2852 offsetT min = 0, max = 0;
2853
2854 if (operand->bits != 32
2855 && !(operand->flags & ARC_OPERAND_NCHK)
2856 && !(operand->flags & ARC_OPERAND_FAKE))
2857 {
2858 if (operand->flags & ARC_OPERAND_SIGNED)
2859 {
2860 max = (1 << (operand->bits - 1)) - 1;
2861 min = -(1 << (operand->bits - 1));
2862 }
2863 else
2864 {
2865 max = (1 << operand->bits) - 1;
2866 min = 0;
2867 }
2868
2869 if (val < min || val > max)
2870 as_bad_value_out_of_range (_("operand"),
2871 val, min, max, file, line);
2872 }
2873
2874 pr_debug ("insert field: %ld <= %lld <= %ld in 0x%08llx\n",
2875 min, val, max, insn);
2876
2877 if ((operand->flags & ARC_OPERAND_ALIGNED32)
2878 && (val & 0x03))
2879 as_bad_where (file, line,
2880 _("Unaligned operand. Needs to be 32bit aligned"));
2881
2882 if ((operand->flags & ARC_OPERAND_ALIGNED16)
2883 && (val & 0x01))
2884 as_bad_where (file, line,
2885 _("Unaligned operand. Needs to be 16bit aligned"));
2886
2887 if (operand->insert)
2888 {
2889 const char *errmsg = NULL;
2890
2891 insn = (*operand->insert) (insn, val, &errmsg);
2892 if (errmsg)
2893 as_warn_where (file, line, "%s", errmsg);
2894 }
2895 else
2896 {
2897 if (operand->flags & ARC_OPERAND_TRUNCATE)
2898 {
2899 if (operand->flags & ARC_OPERAND_ALIGNED32)
2900 val >>= 2;
2901 if (operand->flags & ARC_OPERAND_ALIGNED16)
2902 val >>= 1;
2903 }
2904 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2905 }
2906 return insn;
2907 }
2908
2909 /* Apply a fixup to the object code. At this point all symbol values
2910 should be fully resolved, and we attempt to completely resolve the
2911 reloc. If we can not do that, we determine the correct reloc code
2912 and put it back in the fixup. To indicate that a fixup has been
2913 eliminated, set fixP->fx_done. */
2914
2915 void
2916 md_apply_fix (fixS *fixP,
2917 valueT *valP,
2918 segT seg)
2919 {
2920 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
2921 valueT value = *valP;
2922 unsigned insn = 0;
2923 symbolS *fx_addsy, *fx_subsy;
2924 offsetT fx_offset;
2925 segT add_symbol_segment = absolute_section;
2926 segT sub_symbol_segment = absolute_section;
2927 const struct arc_operand *operand = NULL;
2928 extended_bfd_reloc_code_real_type reloc;
2929
2930 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2931 fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
2932 ((int) fixP->fx_r_type < 0) ? "Internal":
2933 bfd_get_reloc_code_name (fixP->fx_r_type), value,
2934 fixP->fx_offset);
2935
2936 fx_addsy = fixP->fx_addsy;
2937 fx_subsy = fixP->fx_subsy;
2938 fx_offset = 0;
2939
2940 if (fx_addsy)
2941 {
2942 add_symbol_segment = S_GET_SEGMENT (fx_addsy);
2943 }
2944
2945 if (fx_subsy
2946 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF
2947 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF_S9
2948 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_GD_LD)
2949 {
2950 resolve_symbol_value (fx_subsy);
2951 sub_symbol_segment = S_GET_SEGMENT (fx_subsy);
2952
2953 if (sub_symbol_segment == absolute_section)
2954 {
2955 /* The symbol is really a constant. */
2956 fx_offset -= S_GET_VALUE (fx_subsy);
2957 fx_subsy = NULL;
2958 }
2959 else
2960 {
2961 as_bad_subtract (fixP);
2962 return;
2963 }
2964 }
2965
2966 if (fx_addsy
2967 && !S_IS_WEAK (fx_addsy))
2968 {
2969 if (add_symbol_segment == seg
2970 && fixP->fx_pcrel)
2971 {
2972 value += S_GET_VALUE (fx_addsy);
2973 value -= md_pcrel_from_section (fixP, seg);
2974 fx_addsy = NULL;
2975 fixP->fx_pcrel = false;
2976 }
2977 else if (add_symbol_segment == absolute_section)
2978 {
2979 value = fixP->fx_offset;
2980 fx_offset += S_GET_VALUE (fixP->fx_addsy);
2981 fx_addsy = NULL;
2982 fixP->fx_pcrel = false;
2983 }
2984 }
2985
2986 if (!fx_addsy)
2987 fixP->fx_done = true;
2988
2989 if (fixP->fx_pcrel)
2990 {
2991 if (fx_addsy
2992 && ((S_IS_DEFINED (fx_addsy)
2993 && S_GET_SEGMENT (fx_addsy) != seg)
2994 || S_IS_WEAK (fx_addsy)))
2995 value += md_pcrel_from_section (fixP, seg);
2996
2997 switch (fixP->fx_r_type)
2998 {
2999 case BFD_RELOC_ARC_32_ME:
3000 /* This is a pc-relative value in a LIMM. Adjust it to the
3001 address of the instruction not to the address of the
3002 LIMM. Note: it is not any longer valid this affirmation as
3003 the linker consider ARC_PC32 a fixup to entire 64 bit
3004 insn. */
3005 fixP->fx_offset += fixP->fx_frag->fr_address;
3006 /* Fall through. */
3007 case BFD_RELOC_32:
3008 fixP->fx_r_type = BFD_RELOC_ARC_PC32;
3009 /* Fall through. */
3010 case BFD_RELOC_ARC_PC32:
3011 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
3012 break;
3013 default:
3014 if ((int) fixP->fx_r_type < 0)
3015 as_bad_where (fixP->fx_file, fixP->fx_line,
3016 _("PC relative relocation not allowed for (internal)"
3017 " type %d"),
3018 fixP->fx_r_type);
3019 break;
3020 }
3021 }
3022
3023 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
3024 fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
3025 ((int) fixP->fx_r_type < 0) ? "Internal":
3026 bfd_get_reloc_code_name (fixP->fx_r_type), value,
3027 fixP->fx_offset);
3028
3029
3030 /* Now check for TLS relocations. */
3031 reloc = fixP->fx_r_type;
3032 switch (reloc)
3033 {
3034 case BFD_RELOC_ARC_TLS_DTPOFF:
3035 case BFD_RELOC_ARC_TLS_LE_32:
3036 if (fixP->fx_done)
3037 break;
3038 /* Fall through. */
3039 case BFD_RELOC_ARC_TLS_GD_GOT:
3040 case BFD_RELOC_ARC_TLS_IE_GOT:
3041 S_SET_THREAD_LOCAL (fixP->fx_addsy);
3042 break;
3043
3044 case BFD_RELOC_ARC_TLS_GD_LD:
3045 gas_assert (!fixP->fx_offset);
3046 if (fixP->fx_subsy)
3047 fixP->fx_offset
3048 = (S_GET_VALUE (fixP->fx_subsy)
3049 - fixP->fx_frag->fr_address- fixP->fx_where);
3050 fixP->fx_subsy = NULL;
3051 /* Fall through. */
3052 case BFD_RELOC_ARC_TLS_GD_CALL:
3053 /* These two relocs are there just to allow ld to change the tls
3054 model for this symbol, by patching the code. The offset -
3055 and scale, if any - will be installed by the linker. */
3056 S_SET_THREAD_LOCAL (fixP->fx_addsy);
3057 break;
3058
3059 case BFD_RELOC_ARC_TLS_LE_S9:
3060 case BFD_RELOC_ARC_TLS_DTPOFF_S9:
3061 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3062 break;
3063
3064 default:
3065 break;
3066 }
3067
3068 if (!fixP->fx_done)
3069 {
3070 return;
3071 }
3072
3073 /* Adjust the value if we have a constant. */
3074 value += fx_offset;
3075
3076 /* For hosts with longs bigger than 32-bits make sure that the top
3077 bits of a 32-bit negative value read in by the parser are set,
3078 so that the correct comparisons are made. */
3079 if (value & 0x80000000)
3080 value |= (-1UL << 31);
3081
3082 reloc = fixP->fx_r_type;
3083 switch (reloc)
3084 {
3085 case BFD_RELOC_8:
3086 case BFD_RELOC_16:
3087 case BFD_RELOC_24:
3088 case BFD_RELOC_32:
3089 case BFD_RELOC_64:
3090 case BFD_RELOC_ARC_32_PCREL:
3091 md_number_to_chars (fixpos, value, fixP->fx_size);
3092 return;
3093
3094 case BFD_RELOC_ARC_GOTPC32:
3095 /* I cannot fix an GOTPC relocation because I need to relax it
3096 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
3097 as_bad (_("Unsupported operation on reloc"));
3098 return;
3099
3100 case BFD_RELOC_ARC_TLS_DTPOFF:
3101 case BFD_RELOC_ARC_TLS_LE_32:
3102 gas_assert (!fixP->fx_addsy);
3103 gas_assert (!fixP->fx_subsy);
3104 /* Fall through. */
3105
3106 case BFD_RELOC_ARC_GOTOFF:
3107 case BFD_RELOC_ARC_32_ME:
3108 case BFD_RELOC_ARC_PC32:
3109 md_number_to_chars_midend (fixpos, value, fixP->fx_size);
3110 return;
3111
3112 case BFD_RELOC_ARC_PLT32:
3113 md_number_to_chars_midend (fixpos, value, fixP->fx_size);
3114 return;
3115
3116 case BFD_RELOC_ARC_S25H_PCREL_PLT:
3117 reloc = BFD_RELOC_ARC_S25W_PCREL;
3118 goto solve_plt;
3119
3120 case BFD_RELOC_ARC_S21H_PCREL_PLT:
3121 reloc = BFD_RELOC_ARC_S21H_PCREL;
3122 goto solve_plt;
3123
3124 case BFD_RELOC_ARC_S25W_PCREL_PLT:
3125 reloc = BFD_RELOC_ARC_S25W_PCREL;
3126 goto solve_plt;
3127
3128 case BFD_RELOC_ARC_S21W_PCREL_PLT:
3129 reloc = BFD_RELOC_ARC_S21W_PCREL;
3130 /* Fall through. */
3131
3132 case BFD_RELOC_ARC_S25W_PCREL:
3133 case BFD_RELOC_ARC_S21W_PCREL:
3134 case BFD_RELOC_ARC_S21H_PCREL:
3135 case BFD_RELOC_ARC_S25H_PCREL:
3136 case BFD_RELOC_ARC_S13_PCREL:
3137 solve_plt:
3138 operand = find_operand_for_reloc (reloc);
3139 gas_assert (operand);
3140 break;
3141
3142 default:
3143 {
3144 if ((int) fixP->fx_r_type >= 0)
3145 as_fatal (_("unhandled relocation type %s"),
3146 bfd_get_reloc_code_name (fixP->fx_r_type));
3147
3148 /* The rest of these fixups needs to be completely resolved as
3149 constants. */
3150 if (fixP->fx_addsy != 0
3151 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
3152 as_bad_where (fixP->fx_file, fixP->fx_line,
3153 _("non-absolute expression in constant field"));
3154
3155 gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands);
3156 operand = &arc_operands[-(int) fixP->fx_r_type];
3157 break;
3158 }
3159 }
3160
3161 if (target_big_endian)
3162 {
3163 switch (fixP->fx_size)
3164 {
3165 case 4:
3166 insn = bfd_getb32 (fixpos);
3167 break;
3168 case 2:
3169 insn = bfd_getb16 (fixpos);
3170 break;
3171 default:
3172 as_bad_where (fixP->fx_file, fixP->fx_line,
3173 _("unknown fixup size"));
3174 }
3175 }
3176 else
3177 {
3178 insn = 0;
3179 switch (fixP->fx_size)
3180 {
3181 case 4:
3182 insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2);
3183 break;
3184 case 2:
3185 insn = bfd_getl16 (fixpos);
3186 break;
3187 default:
3188 as_bad_where (fixP->fx_file, fixP->fx_line,
3189 _("unknown fixup size"));
3190 }
3191 }
3192
3193 insn = insert_operand (insn, operand, (offsetT) value,
3194 fixP->fx_file, fixP->fx_line);
3195
3196 md_number_to_chars_midend (fixpos, insn, fixP->fx_size);
3197 }
3198
3199 /* Prepare machine-dependent frags for relaxation.
3200
3201 Called just before relaxation starts. Any symbol that is now undefined
3202 will not become defined.
3203
3204 Return the correct fr_subtype in the frag.
3205
3206 Return the initial "guess for fr_var" to caller. The guess for fr_var
3207 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
3208 or fr_var contributes to our returned value.
3209
3210 Although it may not be explicit in the frag, pretend
3211 fr_var starts with a value. */
3212
3213 int
3214 md_estimate_size_before_relax (fragS *fragP,
3215 segT segment)
3216 {
3217 int growth;
3218
3219 /* If the symbol is not located within the same section AND it's not
3220 an absolute section, use the maximum. OR if the symbol is a
3221 constant AND the insn is by nature not pc-rel, use the maximum.
3222 OR if the symbol is being equated against another symbol, use the
3223 maximum. OR if the symbol is weak use the maximum. */
3224 if ((S_GET_SEGMENT (fragP->fr_symbol) != segment
3225 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
3226 || (symbol_constant_p (fragP->fr_symbol)
3227 && !fragP->tc_frag_data.pcrel)
3228 || symbol_equated_p (fragP->fr_symbol)
3229 || S_IS_WEAK (fragP->fr_symbol))
3230 {
3231 while (md_relax_table[fragP->fr_subtype].rlx_more != ARC_RLX_NONE)
3232 ++fragP->fr_subtype;
3233 }
3234
3235 growth = md_relax_table[fragP->fr_subtype].rlx_length;
3236 fragP->fr_var = growth;
3237
3238 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
3239 fragP->fr_file, fragP->fr_line, growth);
3240
3241 return growth;
3242 }
3243
3244 /* Translate internal representation of relocation info to BFD target
3245 format. */
3246
3247 arelent *
3248 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
3249 fixS *fixP)
3250 {
3251 arelent *reloc;
3252 bfd_reloc_code_real_type code;
3253
3254 reloc = XNEW (arelent);
3255 reloc->sym_ptr_ptr = XNEW (asymbol *);
3256 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
3257 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
3258
3259 /* Make sure none of our internal relocations make it this far.
3260 They'd better have been fully resolved by this point. */
3261 gas_assert ((int) fixP->fx_r_type > 0);
3262
3263 code = fixP->fx_r_type;
3264
3265 /* if we have something like add gp, pcl,
3266 _GLOBAL_OFFSET_TABLE_@gotpc. */
3267 if (code == BFD_RELOC_ARC_GOTPC32
3268 && GOT_symbol
3269 && fixP->fx_addsy == GOT_symbol)
3270 code = BFD_RELOC_ARC_GOTPC;
3271
3272 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
3273 if (reloc->howto == NULL)
3274 {
3275 as_bad_where (fixP->fx_file, fixP->fx_line,
3276 _("cannot represent `%s' relocation in object file"),
3277 bfd_get_reloc_code_name (code));
3278 return NULL;
3279 }
3280
3281 if (!fixP->fx_pcrel != !reloc->howto->pc_relative)
3282 as_fatal (_("internal error? cannot generate `%s' relocation"),
3283 bfd_get_reloc_code_name (code));
3284
3285 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
3286
3287 reloc->addend = fixP->fx_offset;
3288
3289 return reloc;
3290 }
3291
3292 /* Perform post-processing of machine-dependent frags after relaxation.
3293 Called after relaxation is finished.
3294 In: Address of frag.
3295 fr_type == rs_machine_dependent.
3296 fr_subtype is what the address relaxed to.
3297
3298 Out: Any fixS:s and constants are set up. */
3299
3300 void
3301 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
3302 segT segment ATTRIBUTE_UNUSED,
3303 fragS *fragP)
3304 {
3305 const relax_typeS *table_entry;
3306 char *dest;
3307 const struct arc_opcode *opcode;
3308 struct arc_insn insn;
3309 int size, fix;
3310 struct arc_relax_type *relax_arg = &fragP->tc_frag_data;
3311
3312 fix = fragP->fr_fix;
3313 dest = fragP->fr_literal + fix;
3314 table_entry = TC_GENERIC_RELAX_TABLE + fragP->fr_subtype;
3315
3316 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, "
3317 "var: %" PRId64 "\n",
3318 fragP->fr_file, fragP->fr_line,
3319 fragP->fr_subtype, fix, (int64_t) fragP->fr_var);
3320
3321 if (fragP->fr_subtype <= 0
3322 && fragP->fr_subtype >= arc_num_relax_opcodes)
3323 as_fatal (_("no relaxation found for this instruction."));
3324
3325 opcode = &arc_relax_opcodes[fragP->fr_subtype];
3326
3327 assemble_insn (opcode, relax_arg->tok, relax_arg->ntok, relax_arg->pflags,
3328 relax_arg->nflg, &insn);
3329
3330 apply_fixups (&insn, fragP, fix);
3331
3332 size = insn.len + (insn.has_limm ? 4 : 0);
3333 gas_assert (table_entry->rlx_length == size);
3334 emit_insn0 (&insn, dest, true);
3335
3336 fragP->fr_fix += table_entry->rlx_length;
3337 fragP->fr_var = 0;
3338 }
3339
3340 /* We have no need to default values of symbols. We could catch
3341 register names here, but that is handled by inserting them all in
3342 the symbol table to begin with. */
3343
3344 symbolS *
3345 md_undefined_symbol (char *name)
3346 {
3347 /* The arc abi demands that a GOT[0] should be referencible as
3348 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
3349 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
3350 if (((*name == '_')
3351 && (*(name+1) == 'G')
3352 && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0)))
3353 {
3354 if (!GOT_symbol)
3355 {
3356 if (symbol_find (name))
3357 as_bad ("GOT already in symbol table");
3358
3359 GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section,
3360 &zero_address_frag, 0);
3361 };
3362 return GOT_symbol;
3363 }
3364 return NULL;
3365 }
3366
3367 /* Turn a string in input_line_pointer into a floating point constant
3368 of type type, and store the appropriate bytes in *litP. The number
3369 of LITTLENUMS emitted is stored in *sizeP. An error message is
3370 returned, or NULL on OK. */
3371
3372 const char *
3373 md_atof (int type, char *litP, int *sizeP)
3374 {
3375 return ieee_md_atof (type, litP, sizeP, target_big_endian);
3376 }
3377
3378 /* Called for any expression that can not be recognized. When the
3379 function is called, `input_line_pointer' will point to the start of
3380 the expression. We use it when we have complex operations like
3381 @label1 - @label2. */
3382
3383 void
3384 md_operand (expressionS *expressionP)
3385 {
3386 char *p = input_line_pointer;
3387 if (*p == '@')
3388 {
3389 input_line_pointer++;
3390 expressionP->X_op = O_symbol;
3391 expressionP->X_md = O_absent;
3392 expression (expressionP);
3393 }
3394 }
3395
3396 /* This function is called from the function 'expression', it attempts
3397 to parse special names (in our case register names). It fills in
3398 the expression with the identified register. It returns TRUE if
3399 it is a register and FALSE otherwise. */
3400
3401 bool
3402 arc_parse_name (const char *name,
3403 struct expressionS *e)
3404 {
3405 struct symbol *sym;
3406
3407 if (!assembling_insn)
3408 return false;
3409
3410 if (e->X_op == O_symbol
3411 && e->X_md == O_absent)
3412 return false;
3413
3414 sym = str_hash_find (arc_reg_hash, name);
3415 if (sym)
3416 {
3417 e->X_op = O_register;
3418 e->X_add_number = S_GET_VALUE (sym);
3419 return true;
3420 }
3421
3422 sym = str_hash_find (arc_addrtype_hash, name);
3423 if (sym)
3424 {
3425 e->X_op = O_addrtype;
3426 e->X_add_number = S_GET_VALUE (sym);
3427 return true;
3428 }
3429
3430 return false;
3431 }
3432
3433 /* md_parse_option
3434 Invocation line includes a switch not recognized by the base assembler.
3435 See if it's a processor-specific option.
3436
3437 New options (supported) are:
3438
3439 -mcpu=<cpu name> Assemble for selected processor
3440 -EB/-mbig-endian Big-endian
3441 -EL/-mlittle-endian Little-endian
3442 -mrelax Enable relaxation
3443
3444 The following CPU names are recognized:
3445 arc600, arc700, arcem, archs, nps400. */
3446
3447 int
3448 md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
3449 {
3450 switch (c)
3451 {
3452 case OPTION_ARC600:
3453 case OPTION_ARC601:
3454 return md_parse_option (OPTION_MCPU, "arc600");
3455
3456 case OPTION_ARC700:
3457 return md_parse_option (OPTION_MCPU, "arc700");
3458
3459 case OPTION_ARCEM:
3460 return md_parse_option (OPTION_MCPU, "arcem");
3461
3462 case OPTION_ARCHS:
3463 return md_parse_option (OPTION_MCPU, "archs");
3464
3465 case OPTION_MCPU:
3466 {
3467 arc_select_cpu (arg, MACH_SELECTION_FROM_COMMAND_LINE);
3468 break;
3469 }
3470
3471 case OPTION_EB:
3472 arc_target_format = "elf32-bigarc";
3473 byte_order = BIG_ENDIAN;
3474 break;
3475
3476 case OPTION_EL:
3477 arc_target_format = "elf32-littlearc";
3478 byte_order = LITTLE_ENDIAN;
3479 break;
3480
3481 case OPTION_CD:
3482 selected_cpu.features |= CD;
3483 cl_features |= CD;
3484 arc_check_feature ();
3485 break;
3486
3487 case OPTION_RELAX:
3488 relaxation_state = 1;
3489 break;
3490
3491 case OPTION_NPS400:
3492 selected_cpu.features |= NPS400;
3493 cl_features |= NPS400;
3494 arc_check_feature ();
3495 break;
3496
3497 case OPTION_SPFP:
3498 selected_cpu.features |= SPX;
3499 cl_features |= SPX;
3500 arc_check_feature ();
3501 break;
3502
3503 case OPTION_DPFP:
3504 selected_cpu.features |= DPX;
3505 cl_features |= DPX;
3506 arc_check_feature ();
3507 break;
3508
3509 case OPTION_FPUDA:
3510 selected_cpu.features |= DPA;
3511 cl_features |= DPA;
3512 arc_check_feature ();
3513 break;
3514
3515 /* Dummy options are accepted but have no effect. */
3516 case OPTION_USER_MODE:
3517 case OPTION_LD_EXT_MASK:
3518 case OPTION_SWAP:
3519 case OPTION_NORM:
3520 case OPTION_BARREL_SHIFT:
3521 case OPTION_MIN_MAX:
3522 case OPTION_NO_MPY:
3523 case OPTION_EA:
3524 case OPTION_MUL64:
3525 case OPTION_SIMD:
3526 case OPTION_XMAC_D16:
3527 case OPTION_XMAC_24:
3528 case OPTION_DSP_PACKA:
3529 case OPTION_CRC:
3530 case OPTION_DVBF:
3531 case OPTION_TELEPHONY:
3532 case OPTION_XYMEMORY:
3533 case OPTION_LOCK:
3534 case OPTION_SWAPE:
3535 case OPTION_RTSC:
3536 break;
3537
3538 default:
3539 return 0;
3540 }
3541
3542 return 1;
3543 }
3544
3545 /* Display the list of cpu names for use in the help text. */
3546
3547 static void
3548 arc_show_cpu_list (FILE *stream)
3549 {
3550 int i, offset;
3551 static const char *space_buf = " ";
3552
3553 fprintf (stream, "%s", space_buf);
3554 offset = strlen (space_buf);
3555 for (i = 0; cpu_types[i].name != NULL; ++i)
3556 {
3557 bool last = (cpu_types[i + 1].name == NULL);
3558
3559 /* If displaying the new cpu name string, and the ', ' (for all
3560 but the last one) will take us past a target width of 80
3561 characters, then it's time for a new line. */
3562 if (offset + strlen (cpu_types[i].name) + (last ? 0 : 2) > 80)
3563 {
3564 fprintf (stream, "\n%s", space_buf);
3565 offset = strlen (space_buf);
3566 }
3567
3568 fprintf (stream, "%s%s", cpu_types[i].name, (last ? "\n" : ", "));
3569 offset += strlen (cpu_types [i].name) + (last ? 0 : 2);
3570 }
3571 }
3572
3573 void
3574 md_show_usage (FILE *stream)
3575 {
3576 fprintf (stream, _("ARC-specific assembler options:\n"));
3577
3578 fprintf (stream, " -mcpu=<cpu name>\t (default: %s), assemble for"
3579 " CPU <cpu name>, one of:\n", TARGET_WITH_CPU);
3580 arc_show_cpu_list (stream);
3581 fprintf (stream, "\n");
3582 fprintf (stream, " -mA6/-mARC600/-mARC601 same as -mcpu=arc600\n");
3583 fprintf (stream, " -mA7/-mARC700\t\t same as -mcpu=arc700\n");
3584 fprintf (stream, " -mEM\t\t\t same as -mcpu=arcem\n");
3585 fprintf (stream, " -mHS\t\t\t same as -mcpu=archs\n");
3586
3587 fprintf (stream, " -mnps400\t\t enable NPS-400 extended instructions\n");
3588 fprintf (stream, " -mspfp\t\t enable single-precision floating point"
3589 " instructions\n");
3590 fprintf (stream, " -mdpfp\t\t enable double-precision floating point"
3591 " instructions\n");
3592 fprintf (stream, " -mfpuda\t\t enable double-precision assist floating "
3593 "point\n\t\t\t instructions for ARC EM\n");
3594
3595 fprintf (stream,
3596 " -mcode-density\t enable code density option for ARC EM\n");
3597
3598 fprintf (stream, _("\
3599 -EB assemble code for a big-endian cpu\n"));
3600 fprintf (stream, _("\
3601 -EL assemble code for a little-endian cpu\n"));
3602 fprintf (stream, _("\
3603 -mrelax enable relaxation\n"));
3604
3605 fprintf (stream, _("The following ARC-specific assembler options are "
3606 "deprecated and are accepted\nfor compatibility only:\n"));
3607
3608 fprintf (stream, _(" -mEA\n"
3609 " -mbarrel-shifter\n"
3610 " -mbarrel_shifter\n"
3611 " -mcrc\n"
3612 " -mdsp-packa\n"
3613 " -mdsp_packa\n"
3614 " -mdvbf\n"
3615 " -mld-extension-reg-mask\n"
3616 " -mlock\n"
3617 " -mmac-24\n"
3618 " -mmac-d16\n"
3619 " -mmac_24\n"
3620 " -mmac_d16\n"
3621 " -mmin-max\n"
3622 " -mmin_max\n"
3623 " -mmul64\n"
3624 " -mno-mpy\n"
3625 " -mnorm\n"
3626 " -mrtsc\n"
3627 " -msimd\n"
3628 " -mswap\n"
3629 " -mswape\n"
3630 " -mtelephony\n"
3631 " -muser-mode-only\n"
3632 " -mxy\n"));
3633 }
3634
3635 /* Find the proper relocation for the given opcode. */
3636
3637 static extended_bfd_reloc_code_real_type
3638 find_reloc (const char *name,
3639 const char *opcodename,
3640 const struct arc_flags *pflags,
3641 int nflg,
3642 extended_bfd_reloc_code_real_type reloc)
3643 {
3644 unsigned int i;
3645 int j;
3646 bool found_flag, tmp;
3647 extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED;
3648
3649 for (i = 0; i < arc_num_equiv_tab; i++)
3650 {
3651 const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i];
3652
3653 /* Find the entry. */
3654 if (strcmp (name, r->name))
3655 continue;
3656 if (r->mnemonic && (strcmp (r->mnemonic, opcodename)))
3657 continue;
3658 if (r->flags[0])
3659 {
3660 if (!nflg)
3661 continue;
3662 found_flag = false;
3663 unsigned * psflg = (unsigned *)r->flags;
3664 do
3665 {
3666 tmp = false;
3667 for (j = 0; j < nflg; j++)
3668 if (!strcmp (pflags[j].name,
3669 arc_flag_operands[*psflg].name))
3670 {
3671 tmp = true;
3672 break;
3673 }
3674 if (!tmp)
3675 {
3676 found_flag = false;
3677 break;
3678 }
3679 else
3680 {
3681 found_flag = true;
3682 }
3683 ++ psflg;
3684 } while (*psflg);
3685
3686 if (!found_flag)
3687 continue;
3688 }
3689
3690 if (reloc != r->oldreloc)
3691 continue;
3692 /* Found it. */
3693 ret = r->newreloc;
3694 break;
3695 }
3696
3697 if (ret == BFD_RELOC_UNUSED)
3698 as_bad (_("Unable to find %s relocation for instruction %s"),
3699 name, opcodename);
3700 return ret;
3701 }
3702
3703 /* All the symbol types that are allowed to be used for
3704 relaxation. */
3705
3706 static bool
3707 may_relax_expr (expressionS tok)
3708 {
3709 /* Check if we have unrelaxable relocs. */
3710 switch (tok.X_md)
3711 {
3712 default:
3713 break;
3714 case O_plt:
3715 return false;
3716 }
3717
3718 switch (tok.X_op)
3719 {
3720 case O_symbol:
3721 case O_multiply:
3722 case O_divide:
3723 case O_modulus:
3724 case O_add:
3725 case O_subtract:
3726 break;
3727
3728 default:
3729 return false;
3730 }
3731 return true;
3732 }
3733
3734 /* Checks if flags are in line with relaxable insn. */
3735
3736 static bool
3737 relaxable_flag (const struct arc_relaxable_ins *ins,
3738 const struct arc_flags *pflags,
3739 int nflgs)
3740 {
3741 unsigned flag_class,
3742 flag,
3743 flag_class_idx = 0,
3744 flag_idx = 0;
3745
3746 const struct arc_flag_operand *flag_opand;
3747 int i, counttrue = 0;
3748
3749 /* Iterate through flags classes. */
3750 while ((flag_class = ins->flag_classes[flag_class_idx]) != 0)
3751 {
3752 /* Iterate through flags in flag class. */
3753 while ((flag = arc_flag_classes[flag_class].flags[flag_idx])
3754 != 0)
3755 {
3756 flag_opand = &arc_flag_operands[flag];
3757 /* Iterate through flags in ins to compare. */
3758 for (i = 0; i < nflgs; ++i)
3759 {
3760 if (strcmp (flag_opand->name, pflags[i].name) == 0)
3761 ++counttrue;
3762 }
3763
3764 ++flag_idx;
3765 }
3766
3767 ++flag_class_idx;
3768 flag_idx = 0;
3769 }
3770
3771 /* If counttrue == nflgs, then all flags have been found. */
3772 return counttrue == nflgs;
3773 }
3774
3775 /* Checks if operands are in line with relaxable insn. */
3776
3777 static bool
3778 relaxable_operand (const struct arc_relaxable_ins *ins,
3779 const expressionS *tok,
3780 int ntok)
3781 {
3782 const enum rlx_operand_type *operand = &ins->operands[0];
3783 int i = 0;
3784
3785 while (*operand != EMPTY)
3786 {
3787 const expressionS *epr = &tok[i];
3788
3789 if (i != 0 && i >= ntok)
3790 return false;
3791
3792 switch (*operand)
3793 {
3794 case IMMEDIATE:
3795 if (!(epr->X_op == O_multiply
3796 || epr->X_op == O_divide
3797 || epr->X_op == O_modulus
3798 || epr->X_op == O_add
3799 || epr->X_op == O_subtract
3800 || epr->X_op == O_symbol))
3801 return false;
3802 break;
3803
3804 case REGISTER_DUP:
3805 if ((i <= 0)
3806 || (epr->X_add_number != tok[i - 1].X_add_number))
3807 return false;
3808 /* Fall through. */
3809 case REGISTER:
3810 if (epr->X_op != O_register)
3811 return false;
3812 break;
3813
3814 case REGISTER_S:
3815 if (epr->X_op != O_register)
3816 return false;
3817
3818 switch (epr->X_add_number)
3819 {
3820 case 0: case 1: case 2: case 3:
3821 case 12: case 13: case 14: case 15:
3822 break;
3823 default:
3824 return false;
3825 }
3826 break;
3827
3828 case REGISTER_NO_GP:
3829 if ((epr->X_op != O_register)
3830 || (epr->X_add_number == 26)) /* 26 is the gp register. */
3831 return false;
3832 break;
3833
3834 case BRACKET:
3835 if (epr->X_op != O_bracket)
3836 return false;
3837 break;
3838
3839 default:
3840 /* Don't understand, bail out. */
3841 return false;
3842 break;
3843 }
3844
3845 ++i;
3846 operand = &ins->operands[i];
3847 }
3848
3849 return i == ntok;
3850 }
3851
3852 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3853
3854 static bool
3855 relax_insn_p (const struct arc_opcode *opcode,
3856 const expressionS *tok,
3857 int ntok,
3858 const struct arc_flags *pflags,
3859 int nflg)
3860 {
3861 unsigned i;
3862 bool rv = false;
3863
3864 /* Check the relaxation table. */
3865 for (i = 0; i < arc_num_relaxable_ins && relaxation_state; ++i)
3866 {
3867 const struct arc_relaxable_ins *arc_rlx_ins = &arc_relaxable_insns[i];
3868
3869 if ((strcmp (opcode->name, arc_rlx_ins->mnemonic_r) == 0)
3870 && may_relax_expr (tok[arc_rlx_ins->opcheckidx])
3871 && relaxable_operand (arc_rlx_ins, tok, ntok)
3872 && relaxable_flag (arc_rlx_ins, pflags, nflg))
3873 {
3874 rv = true;
3875 frag_now->fr_subtype = arc_relaxable_insns[i].subtype;
3876 memcpy (&frag_now->tc_frag_data.tok, tok,
3877 sizeof (expressionS) * ntok);
3878 memcpy (&frag_now->tc_frag_data.pflags, pflags,
3879 sizeof (struct arc_flags) * nflg);
3880 frag_now->tc_frag_data.nflg = nflg;
3881 frag_now->tc_frag_data.ntok = ntok;
3882 break;
3883 }
3884 }
3885
3886 return rv;
3887 }
3888
3889 /* Turn an opcode description and a set of arguments into
3890 an instruction and a fixup. */
3891
3892 static void
3893 assemble_insn (const struct arc_opcode *opcode,
3894 const expressionS *tok,
3895 int ntok,
3896 const struct arc_flags *pflags,
3897 int nflg,
3898 struct arc_insn *insn)
3899 {
3900 const expressionS *reloc_exp = NULL;
3901 unsigned long long image;
3902 const unsigned char *argidx;
3903 int i;
3904 int tokidx = 0;
3905 unsigned char pcrel = 0;
3906 bool needGOTSymbol;
3907 bool has_delay_slot = false;
3908 extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
3909
3910 memset (insn, 0, sizeof (*insn));
3911 image = opcode->opcode;
3912
3913 pr_debug ("%s:%d: assemble_insn: %s using opcode %llx\n",
3914 frag_now->fr_file, frag_now->fr_line, opcode->name,
3915 opcode->opcode);
3916
3917 /* Handle operands. */
3918 for (argidx = opcode->operands; *argidx; ++argidx)
3919 {
3920 const struct arc_operand *operand = &arc_operands[*argidx];
3921 const expressionS *t = (const expressionS *) 0;
3922
3923 if (ARC_OPERAND_IS_FAKE (operand))
3924 continue;
3925
3926 if (operand->flags & ARC_OPERAND_DUPLICATE)
3927 {
3928 /* Duplicate operand, already inserted. */
3929 tokidx ++;
3930 continue;
3931 }
3932
3933 if (tokidx >= ntok)
3934 {
3935 abort ();
3936 }
3937 else
3938 t = &tok[tokidx++];
3939
3940 /* Regardless if we have a reloc or not mark the instruction
3941 limm if it is the case. */
3942 if (operand->flags & ARC_OPERAND_LIMM)
3943 insn->has_limm = true;
3944
3945 switch (t->X_op)
3946 {
3947 case O_register:
3948 image = insert_operand (image, operand, regno (t->X_add_number),
3949 NULL, 0);
3950 break;
3951
3952 case O_constant:
3953 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
3954 reloc_exp = t;
3955 if (operand->flags & ARC_OPERAND_LIMM)
3956 insn->limm = t->X_add_number;
3957 break;
3958
3959 case O_bracket:
3960 case O_colon:
3961 case O_addrtype:
3962 /* Ignore brackets, colons, and address types. */
3963 break;
3964
3965 case O_absent:
3966 gas_assert (operand->flags & ARC_OPERAND_IGNORE);
3967 break;
3968
3969 case O_subtract:
3970 /* Maybe register range. */
3971 if ((t->X_add_number == 0)
3972 && contains_register (t->X_add_symbol)
3973 && contains_register (t->X_op_symbol))
3974 {
3975 int regs;
3976
3977 regs = get_register (t->X_add_symbol);
3978 regs <<= 16;
3979 regs |= get_register (t->X_op_symbol);
3980 image = insert_operand (image, operand, regs, NULL, 0);
3981 break;
3982 }
3983 /* Fall through. */
3984
3985 default:
3986 /* This operand needs a relocation. */
3987 needGOTSymbol = false;
3988
3989 switch (t->X_md)
3990 {
3991 case O_plt:
3992 if (opcode->insn_class == JUMP)
3993 as_bad (_("Unable to use @plt relocation for insn %s"),
3994 opcode->name);
3995 needGOTSymbol = true;
3996 reloc = find_reloc ("plt", opcode->name,
3997 pflags, nflg,
3998 operand->default_reloc);
3999 break;
4000
4001 case O_gotoff:
4002 case O_gotpc:
4003 needGOTSymbol = true;
4004 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
4005 break;
4006 case O_pcl:
4007 if (operand->flags & ARC_OPERAND_LIMM)
4008 {
4009 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
4010 if (arc_opcode_len (opcode) == 2
4011 || opcode->insn_class == JUMP)
4012 as_bad (_("Unable to use @pcl relocation for insn %s"),
4013 opcode->name);
4014 }
4015 else
4016 {
4017 /* This is a relaxed operand which initially was
4018 limm, choose whatever we have defined in the
4019 opcode as reloc. */
4020 reloc = operand->default_reloc;
4021 }
4022 break;
4023 case O_sda:
4024 reloc = find_reloc ("sda", opcode->name,
4025 pflags, nflg,
4026 operand->default_reloc);
4027 break;
4028 case O_tlsgd:
4029 case O_tlsie:
4030 needGOTSymbol = true;
4031 /* Fall-through. */
4032
4033 case O_tpoff:
4034 case O_dtpoff:
4035 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
4036 break;
4037
4038 case O_tpoff9: /*FIXME! Check for the conditionality of
4039 the insn. */
4040 case O_dtpoff9: /*FIXME! Check for the conditionality of
4041 the insn. */
4042 as_bad (_("TLS_*_S9 relocs are not supported yet"));
4043 break;
4044
4045 default:
4046 /* Just consider the default relocation. */
4047 reloc = operand->default_reloc;
4048 break;
4049 }
4050
4051 if (needGOTSymbol && (GOT_symbol == NULL))
4052 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
4053
4054 reloc_exp = t;
4055
4056 #if 0
4057 if (reloc > 0)
4058 {
4059 /* sanity checks. */
4060 reloc_howto_type *reloc_howto
4061 = bfd_reloc_type_lookup (stdoutput,
4062 (bfd_reloc_code_real_type) reloc);
4063 unsigned reloc_bitsize = reloc_howto->bitsize;
4064 if (reloc_howto->rightshift)
4065 reloc_bitsize -= reloc_howto->rightshift;
4066 if (reloc_bitsize != operand->bits)
4067 {
4068 as_bad (_("invalid relocation %s for field"),
4069 bfd_get_reloc_code_name (reloc));
4070 return;
4071 }
4072 }
4073 #endif
4074 if (insn->nfixups >= MAX_INSN_FIXUPS)
4075 as_fatal (_("too many fixups"));
4076
4077 struct arc_fixup *fixup;
4078 fixup = &insn->fixups[insn->nfixups++];
4079 fixup->exp = *t;
4080 fixup->reloc = reloc;
4081 if ((int) reloc < 0)
4082 pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
4083 else
4084 {
4085 reloc_howto_type *reloc_howto =
4086 bfd_reloc_type_lookup (stdoutput,
4087 (bfd_reloc_code_real_type) fixup->reloc);
4088 pcrel = reloc_howto->pc_relative;
4089 }
4090 fixup->pcrel = pcrel;
4091 fixup->islong = (operand->flags & ARC_OPERAND_LIMM) != 0;
4092 break;
4093 }
4094 }
4095
4096 /* Handle flags. */
4097 for (i = 0; i < nflg; i++)
4098 {
4099 const struct arc_flag_operand *flg_operand = pflags[i].flgp;
4100
4101 /* Check if the instruction has a delay slot. */
4102 if (!strcmp (flg_operand->name, "d"))
4103 has_delay_slot = true;
4104
4105 /* There is an exceptional case when we cannot insert a flag just as
4106 it is. On ARCv2 the '.t' and '.nt' flags must be handled in
4107 relation with the relative address. Unfortunately, some of the
4108 ARC700 extensions (NPS400) also have a '.nt' flag that should be
4109 handled in the normal way.
4110
4111 Flag operands don't have an architecture field, so we can't
4112 directly validate that FLAG_OPERAND is valid for the current
4113 architecture, what we do instead is just validate that we're
4114 assembling for an ARCv2 architecture. */
4115 if ((selected_cpu.flags & ARC_OPCODE_ARCV2)
4116 && (!strcmp (flg_operand->name, "t")
4117 || !strcmp (flg_operand->name, "nt")))
4118 {
4119 unsigned bitYoperand = 0;
4120 /* FIXME! move selection bbit/brcc in arc-opc.c. */
4121 if (!strcmp (flg_operand->name, "t"))
4122 if (!strcmp (opcode->name, "bbit0")
4123 || !strcmp (opcode->name, "bbit1"))
4124 bitYoperand = arc_NToperand;
4125 else
4126 bitYoperand = arc_Toperand;
4127 else
4128 if (!strcmp (opcode->name, "bbit0")
4129 || !strcmp (opcode->name, "bbit1"))
4130 bitYoperand = arc_Toperand;
4131 else
4132 bitYoperand = arc_NToperand;
4133
4134 gas_assert (reloc_exp != NULL);
4135 if (reloc_exp->X_op == O_constant)
4136 {
4137 /* Check if we have a constant and solved it
4138 immediately. */
4139 offsetT val = reloc_exp->X_add_number;
4140 image |= insert_operand (image, &arc_operands[bitYoperand],
4141 val, NULL, 0);
4142 }
4143 else
4144 {
4145 struct arc_fixup *fixup;
4146
4147 if (insn->nfixups >= MAX_INSN_FIXUPS)
4148 as_fatal (_("too many fixups"));
4149
4150 fixup = &insn->fixups[insn->nfixups++];
4151 fixup->exp = *reloc_exp;
4152 fixup->reloc = -bitYoperand;
4153 fixup->pcrel = pcrel;
4154 fixup->islong = false;
4155 }
4156 }
4157 else
4158 image |= (flg_operand->code & ((1 << flg_operand->bits) - 1))
4159 << flg_operand->shift;
4160 }
4161
4162 insn->relax = relax_insn_p (opcode, tok, ntok, pflags, nflg);
4163
4164 /* Instruction length. */
4165 insn->len = arc_opcode_len (opcode);
4166
4167 insn->insn = image;
4168
4169 /* Update last insn status. */
4170 arc_last_insns[1] = arc_last_insns[0];
4171 arc_last_insns[0].opcode = opcode;
4172 arc_last_insns[0].has_limm = insn->has_limm;
4173 arc_last_insns[0].has_delay_slot = has_delay_slot;
4174
4175 /* Check if the current instruction is legally used. */
4176 if (arc_last_insns[1].has_delay_slot
4177 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
4178 as_bad (_("Insn %s has a jump/branch instruction %s in its delay slot."),
4179 arc_last_insns[1].opcode->name,
4180 arc_last_insns[0].opcode->name);
4181 if (arc_last_insns[1].has_delay_slot
4182 && arc_last_insns[0].has_limm)
4183 as_bad (_("Insn %s has an instruction %s with limm in its delay slot."),
4184 arc_last_insns[1].opcode->name,
4185 arc_last_insns[0].opcode->name);
4186 }
4187
4188 void
4189 arc_handle_align (fragS* fragP)
4190 {
4191 if ((fragP)->fr_type == rs_align_code)
4192 {
4193 char *dest = (fragP)->fr_literal + (fragP)->fr_fix;
4194 valueT count = ((fragP)->fr_next->fr_address
4195 - (fragP)->fr_address - (fragP)->fr_fix);
4196
4197 (fragP)->fr_var = 2;
4198
4199 if (count & 1)/* Padding in the gap till the next 2-byte
4200 boundary with 0s. */
4201 {
4202 (fragP)->fr_fix++;
4203 *dest++ = 0;
4204 }
4205 /* Writing nop_s. */
4206 md_number_to_chars (dest, NOP_OPCODE_S, 2);
4207 }
4208 }
4209
4210 /* Here we decide which fixups can be adjusted to make them relative
4211 to the beginning of the section instead of the symbol. Basically
4212 we need to make sure that the dynamic relocations are done
4213 correctly, so in some cases we force the original symbol to be
4214 used. */
4215
4216 int
4217 tc_arc_fix_adjustable (fixS *fixP)
4218 {
4219
4220 /* Prevent all adjustments to global symbols. */
4221 if (S_IS_EXTERNAL (fixP->fx_addsy))
4222 return 0;
4223 if (S_IS_WEAK (fixP->fx_addsy))
4224 return 0;
4225
4226 /* Adjust_reloc_syms doesn't know about the GOT. */
4227 switch (fixP->fx_r_type)
4228 {
4229 case BFD_RELOC_ARC_GOTPC32:
4230 case BFD_RELOC_ARC_PLT32:
4231 case BFD_RELOC_ARC_S25H_PCREL_PLT:
4232 case BFD_RELOC_ARC_S21H_PCREL_PLT:
4233 case BFD_RELOC_ARC_S25W_PCREL_PLT:
4234 case BFD_RELOC_ARC_S21W_PCREL_PLT:
4235 return 0;
4236
4237 default:
4238 break;
4239 }
4240
4241 return 1;
4242 }
4243
4244 /* Compute the reloc type of an expression EXP. */
4245
4246 static void
4247 arc_check_reloc (expressionS *exp,
4248 bfd_reloc_code_real_type *r_type_p)
4249 {
4250 if (*r_type_p == BFD_RELOC_32
4251 && exp->X_op == O_subtract
4252 && exp->X_op_symbol != NULL
4253 && S_GET_SEGMENT (exp->X_op_symbol) == now_seg)
4254 *r_type_p = BFD_RELOC_ARC_32_PCREL;
4255 }
4256
4257
4258 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
4259
4260 void
4261 arc_cons_fix_new (fragS *frag,
4262 int off,
4263 int size,
4264 expressionS *exp,
4265 bfd_reloc_code_real_type r_type)
4266 {
4267 r_type = BFD_RELOC_UNUSED;
4268
4269 switch (size)
4270 {
4271 case 1:
4272 r_type = BFD_RELOC_8;
4273 break;
4274
4275 case 2:
4276 r_type = BFD_RELOC_16;
4277 break;
4278
4279 case 3:
4280 r_type = BFD_RELOC_24;
4281 break;
4282
4283 case 4:
4284 r_type = BFD_RELOC_32;
4285 arc_check_reloc (exp, &r_type);
4286 break;
4287
4288 case 8:
4289 r_type = BFD_RELOC_64;
4290 break;
4291
4292 default:
4293 as_bad (_("unsupported BFD relocation size %u"), size);
4294 r_type = BFD_RELOC_UNUSED;
4295 }
4296
4297 fix_new_exp (frag, off, size, exp, 0, r_type);
4298 }
4299
4300 /* The actual routine that checks the ZOL conditions. */
4301
4302 static void
4303 check_zol (symbolS *s)
4304 {
4305 switch (selected_cpu.mach)
4306 {
4307 case bfd_mach_arc_arcv2:
4308 if (selected_cpu.flags & ARC_OPCODE_ARCv2EM)
4309 return;
4310
4311 if (is_br_jmp_insn_p (arc_last_insns[0].opcode)
4312 || arc_last_insns[1].has_delay_slot)
4313 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
4314 S_GET_NAME (s));
4315
4316 break;
4317 case bfd_mach_arc_arc600:
4318
4319 if (is_kernel_insn_p (arc_last_insns[0].opcode))
4320 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
4321 S_GET_NAME (s));
4322
4323 if (arc_last_insns[0].has_limm
4324 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
4325 as_bad (_("A jump instruction with long immediate detected at the \
4326 end of the ZOL label @%s"), S_GET_NAME (s));
4327
4328 /* Fall through. */
4329 case bfd_mach_arc_arc700:
4330 if (arc_last_insns[0].has_delay_slot)
4331 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
4332 S_GET_NAME (s));
4333
4334 break;
4335 default:
4336 break;
4337 }
4338 }
4339
4340 /* If ZOL end check the last two instruction for illegals. */
4341 void
4342 arc_frob_label (symbolS * sym)
4343 {
4344 if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL)
4345 check_zol (sym);
4346
4347 dwarf2_emit_label (sym);
4348 }
4349
4350 /* Used because generic relaxation assumes a pc-rel value whilst we
4351 also relax instructions that use an absolute value resolved out of
4352 relative values (if that makes any sense). An example: 'add r1,
4353 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
4354 but if they're in the same section we can subtract the section
4355 offset relocation which ends up in a resolved value. So if @.L2 is
4356 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
4357 .text + 0x40 = 0x10. */
4358 int
4359 arc_pcrel_adjust (fragS *fragP)
4360 {
4361 pr_debug ("arc_pcrel_adjust: address=%ld, fix=%ld, PCrel %s\n",
4362 fragP->fr_address, fragP->fr_fix,
4363 fragP->tc_frag_data.pcrel ? "Y" : "N");
4364
4365 if (!fragP->tc_frag_data.pcrel)
4366 return fragP->fr_address + fragP->fr_fix;
4367
4368 /* Take into account the PCL rounding. */
4369 return (fragP->fr_address + fragP->fr_fix) & 0x03;
4370 }
4371
4372 /* Initialize the DWARF-2 unwind information for this procedure. */
4373
4374 void
4375 tc_arc_frame_initial_instructions (void)
4376 {
4377 /* Stack pointer is register 28. */
4378 cfi_add_CFA_def_cfa (28, 0);
4379 }
4380
4381 int
4382 tc_arc_regname_to_dw2regnum (char *regname)
4383 {
4384 struct symbol *sym;
4385
4386 sym = str_hash_find (arc_reg_hash, regname);
4387 if (sym)
4388 return S_GET_VALUE (sym);
4389
4390 return -1;
4391 }
4392
4393 /* Adjust the symbol table. Delete found AUX register symbols. */
4394
4395 void
4396 arc_adjust_symtab (void)
4397 {
4398 symbolS * sym;
4399
4400 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
4401 {
4402 /* I've created a symbol during parsing process. Now, remove
4403 the symbol as it is found to be an AUX register. */
4404 if (ARC_GET_FLAG (sym) & ARC_FLAG_AUX)
4405 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
4406 }
4407
4408 /* Now do generic ELF adjustments. */
4409 elf_adjust_symtab ();
4410 }
4411
4412 static void
4413 tokenize_extinsn (extInstruction_t *einsn)
4414 {
4415 char *p, c;
4416 char *insn_name;
4417 unsigned char major_opcode;
4418 unsigned char sub_opcode;
4419 unsigned char syntax_class = 0;
4420 unsigned char syntax_class_modifiers = 0;
4421 unsigned char suffix_class = 0;
4422 unsigned int i;
4423
4424 SKIP_WHITESPACE ();
4425
4426 /* 1st: get instruction name. */
4427 p = input_line_pointer;
4428 c = get_symbol_name (&p);
4429
4430 insn_name = xstrdup (p);
4431 restore_line_pointer (c);
4432
4433 /* Convert to lower case. */
4434 for (p = insn_name; *p; ++p)
4435 *p = TOLOWER (*p);
4436
4437 /* 2nd: get major opcode. */
4438 if (*input_line_pointer != ',')
4439 {
4440 as_bad (_("expected comma after instruction name"));
4441 ignore_rest_of_line ();
4442 return;
4443 }
4444 input_line_pointer++;
4445 major_opcode = get_absolute_expression ();
4446
4447 /* 3rd: get sub-opcode. */
4448 SKIP_WHITESPACE ();
4449
4450 if (*input_line_pointer != ',')
4451 {
4452 as_bad (_("expected comma after major opcode"));
4453 ignore_rest_of_line ();
4454 return;
4455 }
4456 input_line_pointer++;
4457 sub_opcode = get_absolute_expression ();
4458
4459 /* 4th: get suffix class. */
4460 SKIP_WHITESPACE ();
4461
4462 if (*input_line_pointer != ',')
4463 {
4464 as_bad ("expected comma after sub opcode");
4465 ignore_rest_of_line ();
4466 return;
4467 }
4468 input_line_pointer++;
4469
4470 while (1)
4471 {
4472 SKIP_WHITESPACE ();
4473
4474 for (i = 0; i < ARRAY_SIZE (suffixclass); i++)
4475 {
4476 if (!strncmp (suffixclass[i].name, input_line_pointer,
4477 suffixclass[i].len))
4478 {
4479 suffix_class |= suffixclass[i].attr_class;
4480 input_line_pointer += suffixclass[i].len;
4481 break;
4482 }
4483 }
4484
4485 if (i == ARRAY_SIZE (suffixclass))
4486 {
4487 as_bad ("invalid suffix class");
4488 ignore_rest_of_line ();
4489 return;
4490 }
4491
4492 SKIP_WHITESPACE ();
4493
4494 if (*input_line_pointer == '|')
4495 input_line_pointer++;
4496 else
4497 break;
4498 }
4499
4500 /* 5th: get syntax class and syntax class modifiers. */
4501 if (*input_line_pointer != ',')
4502 {
4503 as_bad ("expected comma after suffix class");
4504 ignore_rest_of_line ();
4505 return;
4506 }
4507 input_line_pointer++;
4508
4509 while (1)
4510 {
4511 SKIP_WHITESPACE ();
4512
4513 for (i = 0; i < ARRAY_SIZE (syntaxclassmod); i++)
4514 {
4515 if (!strncmp (syntaxclassmod[i].name,
4516 input_line_pointer,
4517 syntaxclassmod[i].len))
4518 {
4519 syntax_class_modifiers |= syntaxclassmod[i].attr_class;
4520 input_line_pointer += syntaxclassmod[i].len;
4521 break;
4522 }
4523 }
4524
4525 if (i == ARRAY_SIZE (syntaxclassmod))
4526 {
4527 for (i = 0; i < ARRAY_SIZE (syntaxclass); i++)
4528 {
4529 if (!strncmp (syntaxclass[i].name,
4530 input_line_pointer,
4531 syntaxclass[i].len))
4532 {
4533 syntax_class |= syntaxclass[i].attr_class;
4534 input_line_pointer += syntaxclass[i].len;
4535 break;
4536 }
4537 }
4538
4539 if (i == ARRAY_SIZE (syntaxclass))
4540 {
4541 as_bad ("missing syntax class");
4542 ignore_rest_of_line ();
4543 return;
4544 }
4545 }
4546
4547 SKIP_WHITESPACE ();
4548
4549 if (*input_line_pointer == '|')
4550 input_line_pointer++;
4551 else
4552 break;
4553 }
4554
4555 demand_empty_rest_of_line ();
4556
4557 einsn->name = insn_name;
4558 einsn->major = major_opcode;
4559 einsn->minor = sub_opcode;
4560 einsn->syntax = syntax_class;
4561 einsn->modsyn = syntax_class_modifiers;
4562 einsn->suffix = suffix_class;
4563 einsn->flags = syntax_class
4564 | (syntax_class_modifiers & ARC_OP1_IMM_IMPLIED ? 0x10 : 0);
4565 }
4566
4567 /* Generate an extension section. */
4568
4569 static int
4570 arc_set_ext_seg (void)
4571 {
4572 if (!arcext_section)
4573 {
4574 arcext_section = subseg_new (".arcextmap", 0);
4575 bfd_set_section_flags (arcext_section, SEC_READONLY | SEC_HAS_CONTENTS);
4576 }
4577 else
4578 subseg_set (arcext_section, 0);
4579 return 1;
4580 }
4581
4582 /* Create an extension instruction description in the arc extension
4583 section of the output file.
4584 The structure for an instruction is like this:
4585 [0]: Length of the record.
4586 [1]: Type of the record.
4587
4588 [2]: Major opcode.
4589 [3]: Sub-opcode.
4590 [4]: Syntax (flags).
4591 [5]+ Name instruction.
4592
4593 The sequence is terminated by an empty entry. */
4594
4595 static void
4596 create_extinst_section (extInstruction_t *einsn)
4597 {
4598
4599 segT old_sec = now_seg;
4600 int old_subsec = now_subseg;
4601 char *p;
4602 int name_len = strlen (einsn->name);
4603
4604 arc_set_ext_seg ();
4605
4606 p = frag_more (1);
4607 *p = 5 + name_len + 1;
4608 p = frag_more (1);
4609 *p = EXT_INSTRUCTION;
4610 p = frag_more (1);
4611 *p = einsn->major;
4612 p = frag_more (1);
4613 *p = einsn->minor;
4614 p = frag_more (1);
4615 *p = einsn->flags;
4616 p = frag_more (name_len + 1);
4617 strcpy (p, einsn->name);
4618
4619 subseg_set (old_sec, old_subsec);
4620 }
4621
4622 /* Handler .extinstruction pseudo-op. */
4623
4624 static void
4625 arc_extinsn (int ignore ATTRIBUTE_UNUSED)
4626 {
4627 extInstruction_t einsn;
4628 struct arc_opcode *arc_ext_opcodes;
4629 const char *errmsg = NULL;
4630 unsigned char moplow, mophigh;
4631
4632 memset (&einsn, 0, sizeof (einsn));
4633 tokenize_extinsn (&einsn);
4634
4635 /* Check if the name is already used. */
4636 if (arc_find_opcode (einsn.name))
4637 as_warn (_("Pseudocode already used %s"), einsn.name);
4638
4639 /* Check the opcode ranges. */
4640 moplow = 0x05;
4641 mophigh = (selected_cpu.flags & (ARC_OPCODE_ARCv2EM
4642 | ARC_OPCODE_ARCv2HS)) ? 0x07 : 0x0a;
4643
4644 if ((einsn.major > mophigh) || (einsn.major < moplow))
4645 as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow, mophigh);
4646
4647 if ((einsn.minor > 0x3f) && (einsn.major != 0x0a)
4648 && (einsn.major != 5) && (einsn.major != 9))
4649 as_fatal (_("minor opcode not in range [0x00 - 0x3f]"));
4650
4651 switch (einsn.syntax & ARC_SYNTAX_MASK)
4652 {
4653 case ARC_SYNTAX_3OP:
4654 if (einsn.modsyn & ARC_OP1_IMM_IMPLIED)
4655 as_fatal (_("Improper use of OP1_IMM_IMPLIED"));
4656 break;
4657 case ARC_SYNTAX_2OP:
4658 case ARC_SYNTAX_1OP:
4659 case ARC_SYNTAX_NOP:
4660 if (einsn.modsyn & ARC_OP1_MUST_BE_IMM)
4661 as_fatal (_("Improper use of OP1_MUST_BE_IMM"));
4662 break;
4663 default:
4664 break;
4665 }
4666
4667 arc_ext_opcodes = arcExtMap_genOpcode (&einsn, selected_cpu.flags, &errmsg);
4668 if (arc_ext_opcodes == NULL)
4669 {
4670 if (errmsg)
4671 as_fatal ("%s", errmsg);
4672 else
4673 as_fatal (_("Couldn't generate extension instruction opcodes"));
4674 }
4675 else if (errmsg)
4676 as_warn ("%s", errmsg);
4677
4678 /* Insert the extension instruction. */
4679 arc_insert_opcode ((const struct arc_opcode *) arc_ext_opcodes);
4680
4681 create_extinst_section (&einsn);
4682 }
4683
4684 static bool
4685 tokenize_extregister (extRegister_t *ereg, int opertype)
4686 {
4687 char *name;
4688 char *mode;
4689 char c;
4690 char *p;
4691 int number, imode = 0;
4692 bool isCore_p = opertype == EXT_CORE_REGISTER;
4693 bool isReg_p = opertype == EXT_CORE_REGISTER || opertype == EXT_AUX_REGISTER;
4694
4695 /* 1st: get register name. */
4696 SKIP_WHITESPACE ();
4697 p = input_line_pointer;
4698 c = get_symbol_name (&p);
4699
4700 name = xstrdup (p);
4701 restore_line_pointer (c);
4702
4703 /* 2nd: get register number. */
4704 SKIP_WHITESPACE ();
4705
4706 if (*input_line_pointer != ',')
4707 {
4708 as_bad (_("expected comma after name"));
4709 ignore_rest_of_line ();
4710 free (name);
4711 return false;
4712 }
4713 input_line_pointer++;
4714 number = get_absolute_expression ();
4715
4716 if ((number < 0)
4717 && (opertype != EXT_AUX_REGISTER))
4718 {
4719 as_bad (_("%s second argument cannot be a negative number %d"),
4720 isCore_p ? "extCoreRegister's" : "extCondCode's",
4721 number);
4722 ignore_rest_of_line ();
4723 free (name);
4724 return false;
4725 }
4726
4727 if (isReg_p)
4728 {
4729 /* 3rd: get register mode. */
4730 SKIP_WHITESPACE ();
4731
4732 if (*input_line_pointer != ',')
4733 {
4734 as_bad (_("expected comma after register number"));
4735 ignore_rest_of_line ();
4736 free (name);
4737 return false;
4738 }
4739
4740 input_line_pointer++;
4741 mode = input_line_pointer;
4742
4743 if (startswith (mode, "r|w"))
4744 {
4745 imode = 0;
4746 input_line_pointer += 3;
4747 }
4748 else if (startswith (mode, "r"))
4749 {
4750 imode = ARC_REGISTER_READONLY;
4751 input_line_pointer += 1;
4752 }
4753 else if (!startswith (mode, "w"))
4754 {
4755 as_bad (_("invalid mode"));
4756 ignore_rest_of_line ();
4757 free (name);
4758 return false;
4759 }
4760 else
4761 {
4762 imode = ARC_REGISTER_WRITEONLY;
4763 input_line_pointer += 1;
4764 }
4765 }
4766
4767 if (isCore_p)
4768 {
4769 /* 4th: get core register shortcut. */
4770 SKIP_WHITESPACE ();
4771 if (*input_line_pointer != ',')
4772 {
4773 as_bad (_("expected comma after register mode"));
4774 ignore_rest_of_line ();
4775 free (name);
4776 return false;
4777 }
4778
4779 input_line_pointer++;
4780
4781 if (startswith (input_line_pointer, "cannot_shortcut"))
4782 {
4783 imode |= ARC_REGISTER_NOSHORT_CUT;
4784 input_line_pointer += 15;
4785 }
4786 else if (!startswith (input_line_pointer, "can_shortcut"))
4787 {
4788 as_bad (_("shortcut designator invalid"));
4789 ignore_rest_of_line ();
4790 free (name);
4791 return false;
4792 }
4793 else
4794 {
4795 input_line_pointer += 12;
4796 }
4797 }
4798 demand_empty_rest_of_line ();
4799
4800 ereg->name = name;
4801 ereg->number = number;
4802 ereg->imode = imode;
4803 return true;
4804 }
4805
4806 /* Create an extension register/condition description in the arc
4807 extension section of the output file.
4808
4809 The structure for an instruction is like this:
4810 [0]: Length of the record.
4811 [1]: Type of the record.
4812
4813 For core regs and condition codes:
4814 [2]: Value.
4815 [3]+ Name.
4816
4817 For auxiliary registers:
4818 [2..5]: Value.
4819 [6]+ Name
4820
4821 The sequence is terminated by an empty entry. */
4822
4823 static void
4824 create_extcore_section (extRegister_t *ereg, int opertype)
4825 {
4826 segT old_sec = now_seg;
4827 int old_subsec = now_subseg;
4828 char *p;
4829 int name_len = strlen (ereg->name);
4830
4831 arc_set_ext_seg ();
4832
4833 switch (opertype)
4834 {
4835 case EXT_COND_CODE:
4836 case EXT_CORE_REGISTER:
4837 p = frag_more (1);
4838 *p = 3 + name_len + 1;
4839 p = frag_more (1);
4840 *p = opertype;
4841 p = frag_more (1);
4842 *p = ereg->number;
4843 break;
4844 case EXT_AUX_REGISTER:
4845 p = frag_more (1);
4846 *p = 6 + name_len + 1;
4847 p = frag_more (1);
4848 *p = EXT_AUX_REGISTER;
4849 p = frag_more (1);
4850 *p = (ereg->number >> 24) & 0xff;
4851 p = frag_more (1);
4852 *p = (ereg->number >> 16) & 0xff;
4853 p = frag_more (1);
4854 *p = (ereg->number >> 8) & 0xff;
4855 p = frag_more (1);
4856 *p = (ereg->number) & 0xff;
4857 break;
4858 default:
4859 break;
4860 }
4861
4862 p = frag_more (name_len + 1);
4863 strcpy (p, ereg->name);
4864
4865 subseg_set (old_sec, old_subsec);
4866 }
4867
4868 /* Handler .extCoreRegister pseudo-op. */
4869
4870 static void
4871 arc_extcorereg (int opertype)
4872 {
4873 extRegister_t ereg;
4874 struct arc_aux_reg *auxr;
4875 struct arc_flag_operand *ccode;
4876
4877 memset (&ereg, 0, sizeof (ereg));
4878 if (!tokenize_extregister (&ereg, opertype))
4879 return;
4880
4881 switch (opertype)
4882 {
4883 case EXT_CORE_REGISTER:
4884 /* Core register. */
4885 if (ereg.number > 60)
4886 as_bad (_("core register %s value (%d) too large"), ereg.name,
4887 ereg.number);
4888 declare_register (ereg.name, ereg.number);
4889 break;
4890 case EXT_AUX_REGISTER:
4891 /* Auxiliary register. */
4892 auxr = XNEW (struct arc_aux_reg);
4893 auxr->name = ereg.name;
4894 auxr->cpu = selected_cpu.flags;
4895 auxr->subclass = NONE;
4896 auxr->address = ereg.number;
4897 if (str_hash_insert (arc_aux_hash, auxr->name, auxr, 0) != NULL)
4898 as_bad (_("duplicate aux register %s"), auxr->name);
4899 break;
4900 case EXT_COND_CODE:
4901 /* Condition code. */
4902 if (ereg.number > 31)
4903 as_bad (_("condition code %s value (%d) too large"), ereg.name,
4904 ereg.number);
4905 ext_condcode.size ++;
4906 ext_condcode.arc_ext_condcode =
4907 XRESIZEVEC (struct arc_flag_operand, ext_condcode.arc_ext_condcode,
4908 ext_condcode.size + 1);
4909
4910 ccode = ext_condcode.arc_ext_condcode + ext_condcode.size - 1;
4911 ccode->name = ereg.name;
4912 ccode->code = ereg.number;
4913 ccode->bits = 5;
4914 ccode->shift = 0;
4915 ccode->favail = 0; /* not used. */
4916 ccode++;
4917 memset (ccode, 0, sizeof (struct arc_flag_operand));
4918 break;
4919 default:
4920 as_bad (_("Unknown extension"));
4921 break;
4922 }
4923 create_extcore_section (&ereg, opertype);
4924 }
4925
4926 /* Parse a .arc_attribute directive. */
4927
4928 static void
4929 arc_attribute (int ignored ATTRIBUTE_UNUSED)
4930 {
4931 int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
4932
4933 if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
4934 attributes_set_explicitly[tag] = true;
4935 }
4936
4937 /* Set an attribute if it has not already been set by the user. */
4938
4939 static void
4940 arc_set_attribute_int (int tag, int value)
4941 {
4942 if (tag < 1
4943 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
4944 || !attributes_set_explicitly[tag])
4945 if (!bfd_elf_add_proc_attr_int (stdoutput, tag, value))
4946 as_fatal (_("error adding attribute: %s"),
4947 bfd_errmsg (bfd_get_error ()));
4948 }
4949
4950 static void
4951 arc_set_attribute_string (int tag, const char *value)
4952 {
4953 if (tag < 1
4954 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
4955 || !attributes_set_explicitly[tag])
4956 if (!bfd_elf_add_proc_attr_string (stdoutput, tag, value))
4957 as_fatal (_("error adding attribute: %s"),
4958 bfd_errmsg (bfd_get_error ()));
4959 }
4960
4961 /* Allocate and concatenate two strings. s1 can be NULL but not
4962 s2. s1 pointer is freed at end of this procedure. */
4963
4964 static char *
4965 arc_stralloc (char * s1, const char * s2)
4966 {
4967 char * p;
4968 int len = 0;
4969
4970 if (s1)
4971 len = strlen (s1) + 1;
4972
4973 /* Only s1 can be null. */
4974 gas_assert (s2);
4975 len += strlen (s2) + 1;
4976
4977 p = (char *) xmalloc (len);
4978
4979 if (s1)
4980 {
4981 strcpy (p, s1);
4982 strcat (p, ",");
4983 strcat (p, s2);
4984 free (s1);
4985 }
4986 else
4987 strcpy (p, s2);
4988
4989 return p;
4990 }
4991
4992 /* Set the public ARC object attributes. */
4993
4994 static void
4995 arc_set_public_attributes (void)
4996 {
4997 int base = 0;
4998 char *s = NULL;
4999 unsigned int i;
5000
5001 /* Tag_ARC_CPU_name. */
5002 arc_set_attribute_string (Tag_ARC_CPU_name, selected_cpu.name);
5003
5004 /* Tag_ARC_CPU_base. */
5005 switch (selected_cpu.eflags & EF_ARC_MACH_MSK)
5006 {
5007 case E_ARC_MACH_ARC600:
5008 case E_ARC_MACH_ARC601:
5009 base = TAG_CPU_ARC6xx;
5010 break;
5011 case E_ARC_MACH_ARC700:
5012 base = TAG_CPU_ARC7xx;
5013 break;
5014 case EF_ARC_CPU_ARCV2EM:
5015 base = TAG_CPU_ARCEM;
5016 break;
5017 case EF_ARC_CPU_ARCV2HS:
5018 base = TAG_CPU_ARCHS;
5019 break;
5020 default:
5021 base = 0;
5022 break;
5023 }
5024 if (attributes_set_explicitly[Tag_ARC_CPU_base]
5025 && (base != bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
5026 Tag_ARC_CPU_base)))
5027 as_warn (_("Overwrite explicitly set Tag_ARC_CPU_base"));
5028 if (!bfd_elf_add_proc_attr_int (stdoutput, Tag_ARC_CPU_base, base))
5029 as_fatal (_("error adding attribute: %s"),
5030 bfd_errmsg (bfd_get_error ()));
5031
5032 /* Tag_ARC_ABI_osver. */
5033 if (attributes_set_explicitly[Tag_ARC_ABI_osver])
5034 {
5035 int val = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
5036 Tag_ARC_ABI_osver);
5037
5038 selected_cpu.eflags = ((selected_cpu.eflags & ~EF_ARC_OSABI_MSK)
5039 | (val & 0x0f << 8));
5040 }
5041 else
5042 {
5043 arc_set_attribute_int (Tag_ARC_ABI_osver, E_ARC_OSABI_CURRENT >> 8);
5044 }
5045
5046 /* Tag_ARC_ISA_config. */
5047 arc_check_feature();
5048
5049 for (i = 0; i < ARRAY_SIZE (feature_list); i++)
5050 if (selected_cpu.features & feature_list[i].feature)
5051 s = arc_stralloc (s, feature_list[i].attr);
5052
5053 if (s)
5054 arc_set_attribute_string (Tag_ARC_ISA_config, s);
5055
5056 /* Tag_ARC_ISA_mpy_option. */
5057 arc_set_attribute_int (Tag_ARC_ISA_mpy_option, mpy_option);
5058
5059 /* Tag_ARC_ABI_pic. */
5060 arc_set_attribute_int (Tag_ARC_ABI_pic, pic_option);
5061
5062 /* Tag_ARC_ABI_sda. */
5063 arc_set_attribute_int (Tag_ARC_ABI_sda, sda_option);
5064
5065 /* Tag_ARC_ABI_tls. */
5066 arc_set_attribute_int (Tag_ARC_ABI_tls, tls_option);
5067
5068 /* Tag_ARC_ATR_version. */
5069 arc_set_attribute_int (Tag_ARC_ATR_version, 1);
5070
5071 /* Tag_ARC_ABI_rf16. */
5072 if (attributes_set_explicitly[Tag_ARC_ABI_rf16]
5073 && bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
5074 Tag_ARC_ABI_rf16)
5075 && !rf16_only)
5076 {
5077 as_warn (_("Overwrite explicitly set Tag_ARC_ABI_rf16 to full "
5078 "register file"));
5079 if (!bfd_elf_add_proc_attr_int (stdoutput, Tag_ARC_ABI_rf16, 0))
5080 as_fatal (_("error adding attribute: %s"),
5081 bfd_errmsg (bfd_get_error ()));
5082 }
5083 }
5084
5085 /* Add the default contents for the .ARC.attributes section. */
5086
5087 void
5088 arc_md_finish (void)
5089 {
5090 arc_set_public_attributes ();
5091
5092 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, selected_cpu.mach))
5093 as_fatal (_("could not set architecture and machine"));
5094
5095 bfd_set_private_flags (stdoutput, selected_cpu.eflags);
5096 }
5097
5098 void arc_copy_symbol_attributes (symbolS *dest, symbolS *src)
5099 {
5100 ARC_GET_FLAG (dest) = ARC_GET_FLAG (src);
5101 }
5102
5103 int arc_convert_symbolic_attribute (const char *name)
5104 {
5105 static const struct
5106 {
5107 const char * name;
5108 const int tag;
5109 }
5110 attribute_table[] =
5111 {
5112 #define T(tag) {#tag, tag}
5113 T (Tag_ARC_PCS_config),
5114 T (Tag_ARC_CPU_base),
5115 T (Tag_ARC_CPU_variation),
5116 T (Tag_ARC_CPU_name),
5117 T (Tag_ARC_ABI_rf16),
5118 T (Tag_ARC_ABI_osver),
5119 T (Tag_ARC_ABI_sda),
5120 T (Tag_ARC_ABI_pic),
5121 T (Tag_ARC_ABI_tls),
5122 T (Tag_ARC_ABI_enumsize),
5123 T (Tag_ARC_ABI_exceptions),
5124 T (Tag_ARC_ABI_double_size),
5125 T (Tag_ARC_ISA_config),
5126 T (Tag_ARC_ISA_apex),
5127 T (Tag_ARC_ISA_mpy_option),
5128 T (Tag_ARC_ATR_version)
5129 #undef T
5130 };
5131 unsigned int i;
5132
5133 if (name == NULL)
5134 return -1;
5135
5136 for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
5137 if (streq (name, attribute_table[i].name))
5138 return attribute_table[i].tag;
5139
5140 return -1;
5141 }
5142
5143 /* Local variables:
5144 eval: (c-set-style "gnu")
5145 indent-tabs-mode: t
5146 End: */