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