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