1 /* tc-arc.c -- Assembler for the ARC
2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
4 Contributor: Claudiu Zissulescu <claziss@synopsys.com>
6 This file is part of GAS, the GNU Assembler.
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)
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.
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
25 #include "struc-symbol.h"
26 #include "dwarf2dbg.h"
27 #include "dw2gencfi.h"
28 #include "safe-ctype.h"
30 #include "opcode/arc.h"
33 /* Defines section. */
35 #define MAX_INSN_FIXUPS 2
36 #define MAX_CONSTR_STR 20
37 #define FRAG_MAX_GROWTH 8
40 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
42 # define pr_debug(fmt, args...)
45 #define MAJOR_OPCODE(x) (((x) & 0xF8000000) >> 27)
46 #define SUB_OPCODE(x) (((x) & 0x003F0000) >> 16)
47 #define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) && \
48 (SUB_OPCODE (x) == 0x28))
50 /* Equal to MAX_PRECISION in atof-ieee.c. */
51 #define MAX_LITTLENUMS 6
53 /* Enum used to enumerate the relaxable ins operands. */
58 REGISTER_S
, /* Register for short instruction(s). */
59 REGISTER_NO_GP
, /* Is a register but not gp register specifically. */
60 REGISTER_DUP
, /* Duplication of previous operand of type register. */
94 #define regno(x) ((x) & 0x3F)
95 #define is_ir_num(x) (((x) & ~0x3F) == 0)
96 #define is_code_density_p(op) (((op)->subclass == CD1 || (op)->subclass == CD2))
97 #define is_br_jmp_insn_p(op) (((op)->class == BRANCH || (op)->class == JUMP))
98 #define is_kernel_insn_p(op) (((op)->class == KERNEL))
100 /* Generic assembler global variables which must be defined by all
103 /* Characters which always start a comment. */
104 const char comment_chars
[] = "#;";
106 /* Characters which start a comment at the beginning of a line. */
107 const char line_comment_chars
[] = "#";
109 /* Characters which may be used to separate multiple commands on a
111 const char line_separator_chars
[] = "`";
113 /* Characters which are used to indicate an exponent in a floating
115 const char EXP_CHARS
[] = "eE";
117 /* Chars that mean this number is a floating point constant
118 As in 0f12.456 or 0d1.2345e12. */
119 const char FLT_CHARS
[] = "rRsSfFdD";
122 extern int target_big_endian
;
123 const char *arc_target_format
= DEFAULT_TARGET_FORMAT
;
124 static int byte_order
= DEFAULT_BYTE_ORDER
;
126 /* By default relaxation is disabled. */
127 static int relaxation_state
= 0;
129 extern int arc_get_mach (char *);
131 /* Forward declarations. */
132 static void arc_lcomm (int);
133 static void arc_option (int);
134 static void arc_extra_reloc (int);
137 const pseudo_typeS md_pseudo_table
[] =
139 /* Make sure that .word is 32 bits. */
142 { "align", s_align_bytes
, 0 }, /* Defaulting is invalid (0). */
143 { "lcomm", arc_lcomm
, 0 },
144 { "lcommon", arc_lcomm
, 0 },
145 { "cpu", arc_option
, 0 },
147 { "tls_gd_ld", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_LD
},
148 { "tls_gd_call", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_CALL
},
153 const char *md_shortopts
= "";
157 OPTION_EB
= OPTION_MD_BASE
,
170 /* The following options are deprecated and provided here only for
171 compatibility reasons. */
197 struct option md_longopts
[] =
199 { "EB", no_argument
, NULL
, OPTION_EB
},
200 { "EL", no_argument
, NULL
, OPTION_EL
},
201 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
202 { "mA6", no_argument
, NULL
, OPTION_ARC600
},
203 { "mARC600", no_argument
, NULL
, OPTION_ARC600
},
204 { "mARC601", no_argument
, NULL
, OPTION_ARC601
},
205 { "mARC700", no_argument
, NULL
, OPTION_ARC700
},
206 { "mA7", no_argument
, NULL
, OPTION_ARC700
},
207 { "mEM", no_argument
, NULL
, OPTION_ARCEM
},
208 { "mHS", no_argument
, NULL
, OPTION_ARCHS
},
209 { "mcode-density", no_argument
, NULL
, OPTION_CD
},
210 { "mrelax", no_argument
, NULL
, OPTION_RELAX
},
212 /* The following options are deprecated and provided here only for
213 compatibility reasons. */
214 { "mav2em", no_argument
, NULL
, OPTION_ARCEM
},
215 { "mav2hs", no_argument
, NULL
, OPTION_ARCHS
},
216 { "muser-mode-only", no_argument
, NULL
, OPTION_USER_MODE
},
217 { "mld-extension-reg-mask", required_argument
, NULL
, OPTION_LD_EXT_MASK
},
218 { "mswap", no_argument
, NULL
, OPTION_SWAP
},
219 { "mnorm", no_argument
, NULL
, OPTION_NORM
},
220 { "mbarrel-shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
221 { "mbarrel_shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
222 { "mmin-max", no_argument
, NULL
, OPTION_MIN_MAX
},
223 { "mmin_max", no_argument
, NULL
, OPTION_MIN_MAX
},
224 { "mno-mpy", no_argument
, NULL
, OPTION_NO_MPY
},
225 { "mea", no_argument
, NULL
, OPTION_EA
},
226 { "mEA", no_argument
, NULL
, OPTION_EA
},
227 { "mmul64", no_argument
, NULL
, OPTION_MUL64
},
228 { "msimd", no_argument
, NULL
, OPTION_SIMD
},
229 { "mspfp", no_argument
, NULL
, OPTION_SPFP
},
230 { "mspfp-compact", no_argument
, NULL
, OPTION_SPFP
},
231 { "mspfp_compact", no_argument
, NULL
, OPTION_SPFP
},
232 { "mspfp-fast", no_argument
, NULL
, OPTION_SPFP
},
233 { "mspfp_fast", no_argument
, NULL
, OPTION_SPFP
},
234 { "mdpfp", no_argument
, NULL
, OPTION_DPFP
},
235 { "mdpfp-compact", no_argument
, NULL
, OPTION_DPFP
},
236 { "mdpfp_compact", no_argument
, NULL
, OPTION_DPFP
},
237 { "mdpfp-fast", no_argument
, NULL
, OPTION_DPFP
},
238 { "mdpfp_fast", no_argument
, NULL
, OPTION_DPFP
},
239 { "mmac-d16", no_argument
, NULL
, OPTION_XMAC_D16
},
240 { "mmac_d16", no_argument
, NULL
, OPTION_XMAC_D16
},
241 { "mmac-24", no_argument
, NULL
, OPTION_XMAC_24
},
242 { "mmac_24", no_argument
, NULL
, OPTION_XMAC_24
},
243 { "mdsp-packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
244 { "mdsp_packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
245 { "mcrc", no_argument
, NULL
, OPTION_CRC
},
246 { "mdvbf", no_argument
, NULL
, OPTION_DVBF
},
247 { "mtelephony", no_argument
, NULL
, OPTION_TELEPHONY
},
248 { "mxy", no_argument
, NULL
, OPTION_XYMEMORY
},
249 { "mlock", no_argument
, NULL
, OPTION_LOCK
},
250 { "mswape", no_argument
, NULL
, OPTION_SWAPE
},
251 { "mrtsc", no_argument
, NULL
, OPTION_RTSC
},
252 { "mfpuda", no_argument
, NULL
, OPTION_FPUDA
},
254 { NULL
, no_argument
, NULL
, 0 }
257 size_t md_longopts_size
= sizeof (md_longopts
);
259 /* Local data and data types. */
261 /* Used since new relocation types are introduced in this
262 file (DUMMY_RELOC_LITUSE_*). */
263 typedef int extended_bfd_reloc_code_real_type
;
269 extended_bfd_reloc_code_real_type reloc
;
271 /* index into arc_operands. */
272 unsigned int opindex
;
274 /* PC-relative, used by internals fixups. */
277 /* TRUE if this fixup is for LIMM operand. */
285 struct arc_fixup fixups
[MAX_INSN_FIXUPS
];
287 bfd_boolean short_insn
; /* Boolean value: TRUE if current insn is
289 bfd_boolean has_limm
; /* Boolean value: TRUE if limm field is
291 bfd_boolean relax
; /* Boolean value: TRUE if needs
295 /* Structure to hold any last two instructions. */
296 static struct arc_last_insn
298 /* Saved instruction opcode. */
299 const struct arc_opcode
*opcode
;
301 /* Boolean value: TRUE if current insn is short. */
302 bfd_boolean has_limm
;
304 /* Boolean value: TRUE if current insn has delay slot. */
305 bfd_boolean has_delay_slot
;
308 /* Forward declaration. */
309 static void assemble_insn
310 (const struct arc_opcode
*, const expressionS
*, int,
311 const struct arc_flags
*, int, struct arc_insn
*);
313 /* The cpu for which we are generating code. */
314 static unsigned arc_target
;
315 static const char *arc_target_name
;
316 static unsigned arc_features
;
318 /* The default architecture. */
319 static int arc_mach_type
;
321 /* Non-zero if the cpu type has been explicitly specified. */
322 static int mach_type_specified_p
= 0;
324 /* The hash table of instruction opcodes. */
325 static struct hash_control
*arc_opcode_hash
;
327 /* The hash table of register symbols. */
328 static struct hash_control
*arc_reg_hash
;
330 /* A table of CPU names and opcode sets. */
331 static const struct cpu_type
341 { "arc600", ARC_OPCODE_ARC600
, bfd_mach_arc_arc600
,
342 E_ARC_MACH_ARC600
, 0x00},
343 { "arc700", ARC_OPCODE_ARC700
, bfd_mach_arc_arc700
,
344 E_ARC_MACH_ARC700
, 0x00},
345 { "arcem", ARC_OPCODE_ARCv2EM
, bfd_mach_arc_arcv2
,
346 EF_ARC_CPU_ARCV2EM
, ARC_CD
},
347 { "archs", ARC_OPCODE_ARCv2HS
, bfd_mach_arc_arcv2
,
348 EF_ARC_CPU_ARCV2HS
, ARC_CD
},
352 /* Used by the arc_reloc_op table. Order is important. */
353 #define O_gotoff O_md1 /* @gotoff relocation. */
354 #define O_gotpc O_md2 /* @gotpc relocation. */
355 #define O_plt O_md3 /* @plt relocation. */
356 #define O_sda O_md4 /* @sda relocation. */
357 #define O_pcl O_md5 /* @pcl relocation. */
358 #define O_tlsgd O_md6 /* @tlsgd relocation. */
359 #define O_tlsie O_md7 /* @tlsie relocation. */
360 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
361 #define O_tpoff O_md9 /* @tpoff relocation. */
362 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
363 #define O_dtpoff O_md11 /* @dtpoff relocation. */
364 #define O_last O_dtpoff
366 /* Used to define a bracket as operand in tokens. */
367 #define O_bracket O_md32
369 /* Dummy relocation, to be sorted out. */
370 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
372 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
374 /* A table to map the spelling of a relocation operand into an appropriate
375 bfd_reloc_code_real_type type. The table is assumed to be ordered such
376 that op-O_literal indexes into it. */
377 #define ARC_RELOC_TABLE(op) \
378 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
380 : (int) (op) - (int) O_gotoff) ])
382 #define DEF(NAME, RELOC, REQ) \
383 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
385 static const struct arc_reloc_op_tag
387 /* String to lookup. */
389 /* Size of the string. */
391 /* Which operator to use. */
393 extended_bfd_reloc_code_real_type reloc
;
394 /* Allows complex relocation expression like identifier@reloc +
396 unsigned int complex_expr
: 1;
400 DEF (gotoff
, BFD_RELOC_ARC_GOTOFF
, 1),
401 DEF (gotpc
, BFD_RELOC_ARC_GOTPC32
, 0),
402 DEF (plt
, BFD_RELOC_ARC_PLT32
, 0),
403 DEF (sda
, DUMMY_RELOC_ARC_ENTRY
, 1),
404 DEF (pcl
, BFD_RELOC_ARC_PC32
, 1),
405 DEF (tlsgd
, BFD_RELOC_ARC_TLS_GD_GOT
, 0),
406 DEF (tlsie
, BFD_RELOC_ARC_TLS_IE_GOT
, 0),
407 DEF (tpoff9
, BFD_RELOC_ARC_TLS_LE_S9
, 0),
408 DEF (tpoff
, BFD_RELOC_ARC_TLS_LE_32
, 1),
409 DEF (dtpoff9
, BFD_RELOC_ARC_TLS_DTPOFF_S9
, 0),
410 DEF (dtpoff
, BFD_RELOC_ARC_TLS_DTPOFF
, 0),
413 static const int arc_num_reloc_op
414 = sizeof (arc_reloc_op
) / sizeof (*arc_reloc_op
);
416 /* Structure for relaxable instruction that have to be swapped with a
417 smaller alternative instruction. */
418 struct arc_relaxable_ins
420 /* Mnemonic that should be checked. */
421 const char *mnemonic_r
;
423 /* Operands that should be checked.
424 Indexes of operands from operand array. */
425 enum rlx_operand_type operands
[6];
427 /* Flags that should be checked. */
428 unsigned flag_classes
[5];
430 /* Mnemonic (smaller) alternative to be used later for relaxation. */
431 const char *mnemonic_alt
;
433 /* Index of operand that generic relaxation has to check. */
436 /* Base subtype index used. */
437 enum arc_rlx_types subtype
;
440 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \
441 { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \
442 (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \
446 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \
447 { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \
448 (ISSIGNED) ? -(0x7FFFFFFF) : 0, \
453 /* ARC relaxation table. */
454 const relax_typeS md_relax_table
[] =
461 RELAX_TABLE_ENTRY(13, 1, 2, ARC_RLX_BL
),
462 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE
),
466 RELAX_TABLE_ENTRY(10, 1, 2, ARC_RLX_B
),
467 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE
),
472 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_ADD_U6
),
473 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_LIMM
),
474 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
476 /* LD_S a, [b, u7] ->
477 LD<zz><.x><.aa><.di> a, [b, s9] ->
478 LD<zz><.x><.aa><.di> a, [b, limm] */
479 RELAX_TABLE_ENTRY(7, 0, 2, ARC_RLX_LD_S9
),
480 RELAX_TABLE_ENTRY(9, 1, 4, ARC_RLX_LD_LIMM
),
481 RELAX_TABLE_ENTRY_MAX(1, 8, ARC_RLX_NONE
),
486 RELAX_TABLE_ENTRY(8, 0, 2, ARC_RLX_MOV_S12
),
487 RELAX_TABLE_ENTRY(8, 0, 4, ARC_RLX_MOV_LIMM
),
488 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
492 SUB<.f> a, b, limm. */
493 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_SUB_U6
),
494 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_SUB_LIMM
),
495 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
497 /* MPY<.f> a, b, u6 ->
498 MPY<.f> a, b, limm. */
499 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MPY_LIMM
),
500 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
502 /* MOV<.f><.cc> b, u6 ->
503 MOV<.f><.cc> b, limm. */
504 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MOV_RLIMM
),
505 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
507 /* ADD<.f><.cc> b, b, u6 ->
508 ADD<.f><.cc> b, b, limm. */
509 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_RRLIMM
),
510 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
513 /* Order of this table's entries matters! */
514 const struct arc_relaxable_ins arc_relaxable_insns
[] =
516 { "bl", { IMMEDIATE
}, { 0 }, "bl_s", 0, ARC_RLX_BL_S
},
517 { "b", { IMMEDIATE
}, { 0 }, "b_s", 0, ARC_RLX_B_S
},
518 { "add", { REGISTER
, REGISTER_DUP
, IMMEDIATE
}, { 5, 1, 0 }, "add",
519 2, ARC_RLX_ADD_RRU6
},
520 { "add", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "add_s", 2,
522 { "add", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "add", 2,
524 { "ld", { REGISTER_S
, BRACKET
, REGISTER_S
, IMMEDIATE
, BRACKET
},
525 { 0 }, "ld_s", 3, ARC_RLX_LD_U7
},
526 { "ld", { REGISTER
, BRACKET
, REGISTER_NO_GP
, IMMEDIATE
, BRACKET
},
527 { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9
},
528 { "mov", { REGISTER_S
, IMMEDIATE
}, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8
},
529 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12
},
530 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6
},
531 { "sub", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "sub_s", 2,
533 { "sub", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "sub", 2,
535 { "mpy", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "mpy", 2,
539 const unsigned arc_num_relaxable_ins
= ARRAY_SIZE (arc_relaxable_insns
);
541 /* Flags to set in the elf header. */
542 static flagword arc_eflag
= 0x00;
544 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
545 symbolS
* GOT_symbol
= 0;
547 /* Set to TRUE when we assemble instructions. */
548 static bfd_boolean assembling_insn
= FALSE
;
550 /* Functions implementation. */
552 /* Like md_number_to_chars but used for limms. The 4-byte limm value,
553 is encoded as 'middle-endian' for a little-endian target. FIXME!
554 this function is used for regular 4 byte instructions as well. */
557 md_number_to_chars_midend (char *buf
, valueT val
, int n
)
561 md_number_to_chars (buf
, (val
& 0xffff0000) >> 16, 2);
562 md_number_to_chars (buf
+ 2, (val
& 0xffff), 2);
566 md_number_to_chars (buf
, val
, n
);
570 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
571 the relevant static global variables. */
574 arc_select_cpu (const char *arg
)
579 for (i
= 0; cpu_types
[i
].name
; ++i
)
581 if (!strcasecmp (cpu_types
[i
].name
, arg
))
583 arc_target
= cpu_types
[i
].flags
;
584 arc_target_name
= cpu_types
[i
].name
;
585 arc_features
= cpu_types
[i
].features
;
586 arc_mach_type
= cpu_types
[i
].mach
;
587 cpu_flags
= cpu_types
[i
].eflags
;
592 if (!cpu_types
[i
].name
)
593 as_fatal (_("unknown architecture: %s\n"), arg
);
594 gas_assert (cpu_flags
!= 0);
595 arc_eflag
= (arc_eflag
& ~EF_ARC_MACH_MSK
) | cpu_flags
;
598 /* Here ends all the ARCompact extension instruction assembling
602 arc_extra_reloc (int r_type
)
605 symbolS
*sym
, *lab
= NULL
;
607 if (*input_line_pointer
== '@')
608 input_line_pointer
++;
609 c
= get_symbol_name (&sym_name
);
610 sym
= symbol_find_or_make (sym_name
);
611 restore_line_pointer (c
);
612 if (c
== ',' && r_type
== BFD_RELOC_ARC_TLS_GD_LD
)
614 ++input_line_pointer
;
616 c
= get_symbol_name (&lab_name
);
617 lab
= symbol_find_or_make (lab_name
);
618 restore_line_pointer (c
);
621 /* These relocations exist as a mechanism for the compiler to tell the
622 linker how to patch the code if the tls model is optimised. However,
623 the relocation itself does not require any space within the assembler
624 fragment, and so we pass a size of 0.
626 The lines that generate these relocations look like this:
628 .tls_gd_ld @.tdata`bl __tls_get_addr@plt
630 The '.tls_gd_ld @.tdata' is processed first and generates the
631 additional relocation, while the 'bl __tls_get_addr@plt' is processed
632 second and generates the additional branch.
634 It is possible that the additional relocation generated by the
635 '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
636 while the 'bl __tls_get_addr@plt' will be generated as the first thing
637 in the next fragment. This will be fine; both relocations will still
638 appear to be at the same address in the generated object file.
639 However, this only works as the additional relocation is generated
640 with size of 0 bytes. */
642 = fix_new (frag_now
, /* Which frag? */
643 frag_now_fix (), /* Where in that frag? */
644 0, /* size: 1, 2, or 4 usually. */
645 sym
, /* X_add_symbol. */
646 0, /* X_add_number. */
647 FALSE
, /* TRUE if PC-relative relocation. */
648 r_type
/* Relocation type. */);
649 fixP
->fx_subsy
= lab
;
653 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED
,
654 symbolS
*symbolP
, addressT size
)
659 if (*input_line_pointer
== ',')
661 align
= parse_align (1);
663 if (align
== (addressT
) -1)
678 bss_alloc (symbolP
, size
, align
);
679 S_CLEAR_EXTERNAL (symbolP
);
685 arc_lcomm (int ignore
)
687 symbolS
*symbolP
= s_comm_internal (ignore
, arc_lcomm_internal
);
690 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
693 /* Select the cpu we're assembling for. */
696 arc_option (int ignore ATTRIBUTE_UNUSED
)
702 c
= get_symbol_name (&cpu
);
703 mach
= arc_get_mach (cpu
);
708 if (!mach_type_specified_p
)
710 if ((!strcmp ("ARC600", cpu
))
711 || (!strcmp ("ARC601", cpu
))
712 || (!strcmp ("A6", cpu
)))
714 md_parse_option (OPTION_MCPU
, "arc600");
716 else if ((!strcmp ("ARC700", cpu
))
717 || (!strcmp ("A7", cpu
)))
719 md_parse_option (OPTION_MCPU
, "arc700");
721 else if (!strcmp ("EM", cpu
))
723 md_parse_option (OPTION_MCPU
, "arcem");
725 else if (!strcmp ("HS", cpu
))
727 md_parse_option (OPTION_MCPU
, "archs");
730 as_fatal ("could not find the architecture");
732 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, mach
))
733 as_fatal ("could not set architecture and machine");
736 if (arc_mach_type
!= mach
)
737 as_warn ("Command-line value overrides \".cpu\" directive");
739 restore_line_pointer (c
);
740 demand_empty_rest_of_line ();
744 restore_line_pointer (c
);
745 as_bad ("invalid identifier for \".cpu\"");
746 ignore_rest_of_line ();
749 /* Smartly print an expression. */
752 debug_exp (expressionS
*t
)
754 const char *name ATTRIBUTE_UNUSED
;
755 const char *namemd ATTRIBUTE_UNUSED
;
757 pr_debug ("debug_exp: ");
761 default: name
= "unknown"; break;
762 case O_illegal
: name
= "O_illegal"; break;
763 case O_absent
: name
= "O_absent"; break;
764 case O_constant
: name
= "O_constant"; break;
765 case O_symbol
: name
= "O_symbol"; break;
766 case O_symbol_rva
: name
= "O_symbol_rva"; break;
767 case O_register
: name
= "O_register"; break;
768 case O_big
: name
= "O_big"; break;
769 case O_uminus
: name
= "O_uminus"; break;
770 case O_bit_not
: name
= "O_bit_not"; break;
771 case O_logical_not
: name
= "O_logical_not"; break;
772 case O_multiply
: name
= "O_multiply"; break;
773 case O_divide
: name
= "O_divide"; break;
774 case O_modulus
: name
= "O_modulus"; break;
775 case O_left_shift
: name
= "O_left_shift"; break;
776 case O_right_shift
: name
= "O_right_shift"; break;
777 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
778 case O_bit_or_not
: name
= "O_bit_or_not"; break;
779 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
780 case O_bit_and
: name
= "O_bit_and"; break;
781 case O_add
: name
= "O_add"; break;
782 case O_subtract
: name
= "O_subtract"; break;
783 case O_eq
: name
= "O_eq"; break;
784 case O_ne
: name
= "O_ne"; break;
785 case O_lt
: name
= "O_lt"; break;
786 case O_le
: name
= "O_le"; break;
787 case O_ge
: name
= "O_ge"; break;
788 case O_gt
: name
= "O_gt"; break;
789 case O_logical_and
: name
= "O_logical_and"; break;
790 case O_logical_or
: name
= "O_logical_or"; break;
791 case O_index
: name
= "O_index"; break;
792 case O_bracket
: name
= "O_bracket"; break;
797 default: namemd
= "unknown"; break;
798 case O_gotoff
: namemd
= "O_gotoff"; break;
799 case O_gotpc
: namemd
= "O_gotpc"; break;
800 case O_plt
: namemd
= "O_plt"; break;
801 case O_sda
: namemd
= "O_sda"; break;
802 case O_pcl
: namemd
= "O_pcl"; break;
803 case O_tlsgd
: namemd
= "O_tlsgd"; break;
804 case O_tlsie
: namemd
= "O_tlsie"; break;
805 case O_tpoff9
: namemd
= "O_tpoff9"; break;
806 case O_tpoff
: namemd
= "O_tpoff"; break;
807 case O_dtpoff9
: namemd
= "O_dtpoff9"; break;
808 case O_dtpoff
: namemd
= "O_dtpoff"; break;
811 pr_debug ("%s (%s, %s, %d, %s)", name
,
812 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
813 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
814 (int) t
->X_add_number
,
815 (t
->X_md
) ? namemd
: "--");
820 /* Parse the arguments to an opcode. */
823 tokenize_arguments (char *str
,
827 char *old_input_line_pointer
;
828 bfd_boolean saw_comma
= FALSE
;
829 bfd_boolean saw_arg
= FALSE
;
834 const struct arc_reloc_op_tag
*r
;
838 memset (tok
, 0, sizeof (*tok
) * ntok
);
840 /* Save and restore input_line_pointer around this function. */
841 old_input_line_pointer
= input_line_pointer
;
842 input_line_pointer
= str
;
844 while (*input_line_pointer
)
847 switch (*input_line_pointer
)
853 input_line_pointer
++;
854 if (saw_comma
|| !saw_arg
)
861 ++input_line_pointer
;
865 tok
->X_op
= O_bracket
;
872 input_line_pointer
++;
876 tok
->X_op
= O_bracket
;
882 /* We have labels, function names and relocations, all
883 starting with @ symbol. Sort them out. */
884 if (saw_arg
&& !saw_comma
)
888 tok
->X_op
= O_symbol
;
889 tok
->X_md
= O_absent
;
891 if (*input_line_pointer
!= '@')
892 goto normalsymbol
; /* This is not a relocation. */
896 /* A relocation opernad has the following form
897 @identifier@relocation_type. The identifier is already
899 if (tok
->X_op
!= O_symbol
)
901 as_bad (_("No valid label relocation operand"));
905 /* Parse @relocation_type. */
906 input_line_pointer
++;
907 c
= get_symbol_name (&reloc_name
);
908 len
= input_line_pointer
- reloc_name
;
911 as_bad (_("No relocation operand"));
915 /* Go through known relocation and try to find a match. */
916 r
= &arc_reloc_op
[0];
917 for (i
= arc_num_reloc_op
- 1; i
>= 0; i
--, r
++)
919 && memcmp (reloc_name
, r
->name
, len
) == 0)
923 as_bad (_("Unknown relocation operand: @%s"), reloc_name
);
927 *input_line_pointer
= c
;
928 SKIP_WHITESPACE_AFTER_NAME ();
929 /* Extra check for TLS: base. */
930 if (*input_line_pointer
== '@')
933 if (tok
->X_op_symbol
!= NULL
934 || tok
->X_op
!= O_symbol
)
936 as_bad (_("Unable to parse TLS base: %s"),
940 input_line_pointer
++;
942 c
= get_symbol_name (&sym_name
);
943 base
= symbol_find_or_make (sym_name
);
944 tok
->X_op
= O_subtract
;
945 tok
->X_op_symbol
= base
;
946 restore_line_pointer (c
);
947 tmpE
.X_add_number
= 0;
949 else if ((*input_line_pointer
!= '+')
950 && (*input_line_pointer
!= '-'))
952 tmpE
.X_add_number
= 0;
956 /* Parse the constant of a complex relocation expression
957 like @identifier@reloc +/- const. */
958 if (! r
->complex_expr
)
960 as_bad (_("@%s is not a complex relocation."), r
->name
);
964 if (tmpE
.X_op
!= O_constant
)
966 as_bad (_("Bad expression: @%s + %s."),
967 r
->name
, input_line_pointer
);
973 tok
->X_add_number
= tmpE
.X_add_number
;
984 /* Can be a register. */
985 ++input_line_pointer
;
989 if (saw_arg
&& !saw_comma
)
992 tok
->X_op
= O_absent
;
993 tok
->X_md
= O_absent
;
996 /* Legacy: There are cases when we have
997 identifier@relocation_type, if it is the case parse the
998 relocation type as well. */
999 if (*input_line_pointer
== '@')
1005 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1017 if (saw_comma
|| brk_lvl
)
1019 input_line_pointer
= old_input_line_pointer
;
1025 as_bad (_("Brackets in operand field incorrect"));
1027 as_bad (_("extra comma"));
1029 as_bad (_("missing argument"));
1031 as_bad (_("missing comma or colon"));
1032 input_line_pointer
= old_input_line_pointer
;
1036 /* Parse the flags to a structure. */
1039 tokenize_flags (const char *str
,
1040 struct arc_flags flags
[],
1043 char *old_input_line_pointer
;
1044 bfd_boolean saw_flg
= FALSE
;
1045 bfd_boolean saw_dot
= FALSE
;
1049 memset (flags
, 0, sizeof (*flags
) * nflg
);
1051 /* Save and restore input_line_pointer around this function. */
1052 old_input_line_pointer
= input_line_pointer
;
1053 input_line_pointer
= (char *) str
;
1055 while (*input_line_pointer
)
1057 switch (*input_line_pointer
)
1064 input_line_pointer
++;
1072 if (saw_flg
&& !saw_dot
)
1075 if (num_flags
>= nflg
)
1078 flgnamelen
= strspn (input_line_pointer
, "abcdefghilmnopqrstvwxz");
1079 if (flgnamelen
> MAX_FLAG_NAME_LENGHT
)
1082 memcpy (flags
->name
, input_line_pointer
, flgnamelen
);
1084 input_line_pointer
+= flgnamelen
;
1094 input_line_pointer
= old_input_line_pointer
;
1099 as_bad (_("extra dot"));
1101 as_bad (_("unrecognized flag"));
1103 as_bad (_("failed to parse flags"));
1104 input_line_pointer
= old_input_line_pointer
;
1108 /* Apply the fixups in order. */
1111 apply_fixups (struct arc_insn
*insn
, fragS
*fragP
, int fix
)
1115 for (i
= 0; i
< insn
->nfixups
; i
++)
1117 struct arc_fixup
*fixup
= &insn
->fixups
[i
];
1118 int size
, pcrel
, offset
= 0;
1120 /* FIXME! the reloc size is wrong in the BFD file.
1121 When it is fixed please delete me. */
1122 size
= (insn
->short_insn
&& !fixup
->islong
) ? 2 : 4;
1125 offset
= (insn
->short_insn
) ? 2 : 4;
1127 /* Some fixups are only used internally, thus no howto. */
1128 if ((int) fixup
->reloc
== 0)
1129 as_fatal (_("Unhandled reloc type"));
1131 if ((int) fixup
->reloc
< 0)
1133 /* FIXME! the reloc size is wrong in the BFD file.
1134 When it is fixed please enable me.
1135 size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
1136 pcrel
= fixup
->pcrel
;
1140 reloc_howto_type
*reloc_howto
=
1141 bfd_reloc_type_lookup (stdoutput
,
1142 (bfd_reloc_code_real_type
) fixup
->reloc
);
1143 gas_assert (reloc_howto
);
1145 /* FIXME! the reloc size is wrong in the BFD file.
1146 When it is fixed please enable me.
1147 size = bfd_get_reloc_size (reloc_howto); */
1148 pcrel
= reloc_howto
->pc_relative
;
1151 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1153 fragP
->fr_file
, fragP
->fr_line
,
1154 (fixup
->reloc
< 0) ? "Internal" :
1155 bfd_get_reloc_code_name (fixup
->reloc
),
1158 fix_new_exp (fragP
, fix
+ offset
,
1159 size
, &fixup
->exp
, pcrel
, fixup
->reloc
);
1161 /* Check for ZOLs, and update symbol info if any. */
1162 if (LP_INSN (insn
->insn
))
1164 gas_assert (fixup
->exp
.X_add_symbol
);
1165 ARC_SET_FLAG (fixup
->exp
.X_add_symbol
, ARC_FLAG_ZOL
);
1170 /* Actually output an instruction with its fixup. */
1173 emit_insn0 (struct arc_insn
*insn
, char *where
, bfd_boolean relax
)
1177 pr_debug ("Emit insn : 0x%x\n", insn
->insn
);
1178 pr_debug ("\tShort : 0x%d\n", insn
->short_insn
);
1179 pr_debug ("\tLong imm: 0x%lx\n", insn
->limm
);
1181 /* Write out the instruction. */
1182 if (insn
->short_insn
)
1188 md_number_to_chars (f
, insn
->insn
, 2);
1189 md_number_to_chars_midend (f
+ 2, insn
->limm
, 4);
1190 dwarf2_emit_insn (6);
1196 md_number_to_chars (f
, insn
->insn
, 2);
1197 dwarf2_emit_insn (2);
1206 md_number_to_chars_midend (f
, insn
->insn
, 4);
1207 md_number_to_chars_midend (f
+ 4, insn
->limm
, 4);
1208 dwarf2_emit_insn (8);
1214 md_number_to_chars_midend (f
, insn
->insn
, 4);
1215 dwarf2_emit_insn (4);
1220 apply_fixups (insn
, frag_now
, (f
- frag_now
->fr_literal
));
1224 emit_insn1 (struct arc_insn
*insn
)
1226 /* How frag_var's args are currently configured:
1227 - rs_machine_dependent, to dictate it's a relaxation frag.
1228 - FRAG_MAX_GROWTH, maximum size of instruction
1229 - 0, variable size that might grow...unused by generic relaxation.
1230 - frag_now->fr_subtype, fr_subtype starting value, set previously.
1231 - s, opand expression.
1232 - 0, offset but it's unused.
1233 - 0, opcode but it's unused. */
1234 symbolS
*s
= make_expr_symbol (&insn
->fixups
[0].exp
);
1235 frag_now
->tc_frag_data
.pcrel
= insn
->fixups
[0].pcrel
;
1237 if (frag_room () < FRAG_MAX_GROWTH
)
1239 /* Handle differently when frag literal memory is exhausted.
1240 This is used because when there's not enough memory left in
1241 the current frag, a new frag is created and the information
1242 we put into frag_now->tc_frag_data is disregarded. */
1244 struct arc_relax_type relax_info_copy
;
1245 relax_substateT subtype
= frag_now
->fr_subtype
;
1247 memcpy (&relax_info_copy
, &frag_now
->tc_frag_data
,
1248 sizeof (struct arc_relax_type
));
1250 frag_wane (frag_now
);
1251 frag_grow (FRAG_MAX_GROWTH
);
1253 memcpy (&frag_now
->tc_frag_data
, &relax_info_copy
,
1254 sizeof (struct arc_relax_type
));
1256 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1260 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1261 frag_now
->fr_subtype
, s
, 0, 0);
1265 emit_insn (struct arc_insn
*insn
)
1270 emit_insn0 (insn
, NULL
, FALSE
);
1273 /* Check whether a symbol involves a register. */
1276 contains_register (symbolS
*sym
)
1280 expressionS
*ex
= symbol_get_value_expression (sym
);
1282 return ((O_register
== ex
->X_op
)
1283 && !contains_register (ex
->X_add_symbol
)
1284 && !contains_register (ex
->X_op_symbol
));
1290 /* Returns the register number within a symbol. */
1293 get_register (symbolS
*sym
)
1295 if (!contains_register (sym
))
1298 expressionS
*ex
= symbol_get_value_expression (sym
);
1299 return regno (ex
->X_add_number
);
1302 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1303 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1306 generic_reloc_p (extended_bfd_reloc_code_real_type reloc
)
1313 case BFD_RELOC_ARC_SDA_LDST
:
1314 case BFD_RELOC_ARC_SDA_LDST1
:
1315 case BFD_RELOC_ARC_SDA_LDST2
:
1316 case BFD_RELOC_ARC_SDA16_LD
:
1317 case BFD_RELOC_ARC_SDA16_LD1
:
1318 case BFD_RELOC_ARC_SDA16_LD2
:
1319 case BFD_RELOC_ARC_SDA16_ST2
:
1320 case BFD_RELOC_ARC_SDA32_ME
:
1327 /* Allocates a tok entry. */
1330 allocate_tok (expressionS
*tok
, int ntok
, int cidx
)
1332 if (ntok
> MAX_INSN_ARGS
- 2)
1333 return 0; /* No space left. */
1336 return 0; /* Incorect args. */
1338 memcpy (&tok
[ntok
+1], &tok
[ntok
], sizeof (*tok
));
1341 return 1; /* Success. */
1342 return allocate_tok (tok
, ntok
- 1, cidx
);
1345 /* Search forward through all variants of an opcode looking for a
1348 static const struct arc_opcode
*
1349 find_opcode_match (const struct arc_opcode
*first_opcode
,
1352 struct arc_flags
*first_pflag
,
1356 const struct arc_opcode
*opcode
= first_opcode
;
1358 int got_cpu_match
= 0;
1359 expressionS bktok
[MAX_INSN_ARGS
];
1363 memset (&emptyE
, 0, sizeof (emptyE
));
1364 memcpy (bktok
, tok
, MAX_INSN_ARGS
* sizeof (*tok
));
1369 const unsigned char *opidx
;
1370 const unsigned char *flgidx
;
1372 const expressionS
*t
= &emptyE
;
1374 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
1375 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->opcode
);
1377 /* Don't match opcodes that don't exist on this
1379 if (!(opcode
->cpu
& arc_target
))
1382 if (is_code_density_p (opcode
) && !(arc_features
& ARC_CD
))
1388 /* Check the operands. */
1389 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1391 const struct arc_operand
*operand
= &arc_operands
[*opidx
];
1393 /* Only take input from real operands. */
1394 if ((operand
->flags
& ARC_OPERAND_FAKE
)
1395 && !(operand
->flags
& ARC_OPERAND_BRAKET
))
1398 /* When we expect input, make sure we have it. */
1402 /* Match operand type with expression type. */
1403 switch (operand
->flags
& ARC_OPERAND_TYPECHECK_MASK
)
1405 case ARC_OPERAND_IR
:
1406 /* Check to be a register. */
1407 if ((tok
[tokidx
].X_op
!= O_register
1408 || !is_ir_num (tok
[tokidx
].X_add_number
))
1409 && !(operand
->flags
& ARC_OPERAND_IGNORE
))
1412 /* If expect duplicate, make sure it is duplicate. */
1413 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1415 /* Check for duplicate. */
1416 if (t
->X_op
!= O_register
1417 || !is_ir_num (t
->X_add_number
)
1418 || (regno (t
->X_add_number
) !=
1419 regno (tok
[tokidx
].X_add_number
)))
1423 /* Special handling? */
1424 if (operand
->insert
)
1426 const char *errmsg
= NULL
;
1427 (*operand
->insert
)(0,
1428 regno (tok
[tokidx
].X_add_number
),
1432 if (operand
->flags
& ARC_OPERAND_IGNORE
)
1434 /* Missing argument, create one. */
1435 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1438 tok
[tokidx
].X_op
= O_absent
;
1449 case ARC_OPERAND_BRAKET
:
1450 /* Check if bracket is also in opcode table as
1452 if (tok
[tokidx
].X_op
!= O_bracket
)
1456 case ARC_OPERAND_LIMM
:
1457 case ARC_OPERAND_SIGNED
:
1458 case ARC_OPERAND_UNSIGNED
:
1459 switch (tok
[tokidx
].X_op
)
1467 /* Got an (too) early bracket, check if it is an
1468 ignored operand. N.B. This procedure works only
1469 when bracket is the last operand! */
1470 if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
1472 /* Insert the missing operand. */
1473 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1476 tok
[tokidx
].X_op
= O_absent
;
1481 /* Check the range. */
1482 if (operand
->bits
!= 32
1483 && !(operand
->flags
& ARC_OPERAND_NCHK
))
1485 offsetT min
, max
, val
;
1486 val
= tok
[tokidx
].X_add_number
;
1488 if (operand
->flags
& ARC_OPERAND_SIGNED
)
1490 max
= (1 << (operand
->bits
- 1)) - 1;
1491 min
= -(1 << (operand
->bits
- 1));
1495 max
= (1 << operand
->bits
) - 1;
1499 if (val
< min
|| val
> max
)
1502 /* Check alignmets. */
1503 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
1507 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
1511 else if (operand
->flags
& ARC_OPERAND_NCHK
)
1513 if (operand
->insert
)
1515 const char *errmsg
= NULL
;
1516 (*operand
->insert
)(0,
1517 tok
[tokidx
].X_add_number
,
1528 /* Check if it is register range. */
1529 if ((tok
[tokidx
].X_add_number
== 0)
1530 && contains_register (tok
[tokidx
].X_add_symbol
)
1531 && contains_register (tok
[tokidx
].X_op_symbol
))
1535 regs
= get_register (tok
[tokidx
].X_add_symbol
);
1537 regs
|= get_register (tok
[tokidx
].X_op_symbol
);
1538 if (operand
->insert
)
1540 const char *errmsg
= NULL
;
1541 (*operand
->insert
)(0,
1552 if (operand
->default_reloc
== 0)
1553 goto match_failed
; /* The operand needs relocation. */
1555 /* Relocs requiring long immediate. FIXME! make it
1556 generic and move it to a function. */
1557 switch (tok
[tokidx
].X_md
)
1566 if (!(operand
->flags
& ARC_OPERAND_LIMM
))
1569 if (!generic_reloc_p (operand
->default_reloc
))
1576 /* If expect duplicate, make sure it is duplicate. */
1577 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1579 if (t
->X_op
== O_illegal
1580 || t
->X_op
== O_absent
1581 || t
->X_op
== O_register
1582 || (t
->X_add_number
!= tok
[tokidx
].X_add_number
))
1589 /* Everything else should have been fake. */
1597 /* Check the flags. Iterate over the valid flag classes. */
1600 for (flgidx
= opcode
->flags
; *flgidx
&& lnflg
; ++flgidx
)
1602 /* Get a valid flag class. */
1603 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
1604 const unsigned *flgopridx
;
1606 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
1608 const struct arc_flag_operand
*flg_operand
;
1609 struct arc_flags
*pflag
= first_pflag
;
1612 flg_operand
= &arc_flag_operands
[*flgopridx
];
1613 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1615 /* Match against the parsed flags. */
1616 if (!strcmp (flg_operand
->name
, pflag
->name
))
1618 /*TODO: Check if it is duplicated. */
1619 pflag
->code
= *flgopridx
;
1621 break; /* goto next flag class and parsed flag. */
1626 /* Did I check all the parsed flags? */
1631 /* Possible match -- did we use all of our input? */
1641 /* Restore the original parameters. */
1642 memcpy (tok
, bktok
, MAX_INSN_ARGS
* sizeof (*tok
));
1645 while (++opcode
- arc_opcodes
< (int) arc_num_opcodes
1646 && !strcmp (opcode
->name
, first_opcode
->name
));
1649 *pcpumatch
= got_cpu_match
;
1654 /* Swap operand tokens. */
1657 swap_operand (expressionS
*operand_array
,
1659 unsigned destination
)
1661 expressionS cpy_operand
;
1662 expressionS
*src_operand
;
1663 expressionS
*dst_operand
;
1666 if (source
== destination
)
1669 src_operand
= &operand_array
[source
];
1670 dst_operand
= &operand_array
[destination
];
1671 size
= sizeof (expressionS
);
1673 /* Make copy of operand to swap with and swap. */
1674 memcpy (&cpy_operand
, dst_operand
, size
);
1675 memcpy (dst_operand
, src_operand
, size
);
1676 memcpy (src_operand
, &cpy_operand
, size
);
1679 /* Check if *op matches *tok type.
1680 Returns FALSE if they don't match, TRUE if they match. */
1683 pseudo_operand_match (const expressionS
*tok
,
1684 const struct arc_operand_operation
*op
)
1686 offsetT min
, max
, val
;
1688 const struct arc_operand
*operand_real
= &arc_operands
[op
->operand_idx
];
1694 if (operand_real
->bits
== 32 && (operand_real
->flags
& ARC_OPERAND_LIMM
))
1696 else if (!(operand_real
->flags
& ARC_OPERAND_IR
))
1698 val
= tok
->X_add_number
+ op
->count
;
1699 if (operand_real
->flags
& ARC_OPERAND_SIGNED
)
1701 max
= (1 << (operand_real
->bits
- 1)) - 1;
1702 min
= -(1 << (operand_real
->bits
- 1));
1706 max
= (1 << operand_real
->bits
) - 1;
1709 if (min
<= val
&& val
<= max
)
1715 /* Handle all symbols as long immediates or signed 9. */
1716 if (operand_real
->flags
& ARC_OPERAND_LIMM
||
1717 ((operand_real
->flags
& ARC_OPERAND_SIGNED
) && operand_real
->bits
== 9))
1722 if (operand_real
->flags
& ARC_OPERAND_IR
)
1727 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
1738 /* Find pseudo instruction in array. */
1740 static const struct arc_pseudo_insn
*
1741 find_pseudo_insn (const char *opname
,
1743 const expressionS
*tok
)
1745 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
1746 const struct arc_operand_operation
*op
;
1750 for (i
= 0; i
< arc_num_pseudo_insn
; ++i
)
1752 pseudo_insn
= &arc_pseudo_insns
[i
];
1753 if (strcmp (pseudo_insn
->mnemonic_p
, opname
) == 0)
1755 op
= pseudo_insn
->operand
;
1756 for (j
= 0; j
< ntok
; ++j
)
1757 if (!pseudo_operand_match (&tok
[j
], &op
[j
]))
1760 /* Found the right instruction. */
1768 /* Assumes the expressionS *tok is of sufficient size. */
1770 static const struct arc_opcode
*
1771 find_special_case_pseudo (const char *opname
,
1775 struct arc_flags
*pflags
)
1777 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
1778 const struct arc_operand_operation
*operand_pseudo
;
1779 const struct arc_operand
*operand_real
;
1781 char construct_operand
[MAX_CONSTR_STR
];
1783 /* Find whether opname is in pseudo instruction array. */
1784 pseudo_insn
= find_pseudo_insn (opname
, *ntok
, tok
);
1786 if (pseudo_insn
== NULL
)
1789 /* Handle flag, Limited to one flag at the moment. */
1790 if (pseudo_insn
->flag_r
!= NULL
)
1791 *nflgs
+= tokenize_flags (pseudo_insn
->flag_r
, &pflags
[*nflgs
],
1792 MAX_INSN_FLGS
- *nflgs
);
1794 /* Handle operand operations. */
1795 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
1797 operand_pseudo
= &pseudo_insn
->operand
[i
];
1798 operand_real
= &arc_operands
[operand_pseudo
->operand_idx
];
1800 if (operand_real
->flags
& ARC_OPERAND_BRAKET
&&
1801 !operand_pseudo
->needs_insert
)
1804 /* Has to be inserted (i.e. this token does not exist yet). */
1805 if (operand_pseudo
->needs_insert
)
1807 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
1809 tok
[i
].X_op
= O_bracket
;
1814 /* Check if operand is a register or constant and handle it
1816 if (operand_real
->flags
& ARC_OPERAND_IR
)
1817 snprintf (construct_operand
, MAX_CONSTR_STR
, "r%d",
1818 operand_pseudo
->count
);
1820 snprintf (construct_operand
, MAX_CONSTR_STR
, "%d",
1821 operand_pseudo
->count
);
1823 tokenize_arguments (construct_operand
, &tok
[i
], 1);
1827 else if (operand_pseudo
->count
)
1829 /* Operand number has to be adjusted accordingly (by operand
1831 switch (tok
[i
].X_op
)
1834 tok
[i
].X_add_number
+= operand_pseudo
->count
;
1847 /* Swap operands if necessary. Only supports one swap at the
1849 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
1851 operand_pseudo
= &pseudo_insn
->operand
[i
];
1853 if (operand_pseudo
->swap_operand_idx
== i
)
1856 swap_operand (tok
, i
, operand_pseudo
->swap_operand_idx
);
1858 /* Prevent a swap back later by breaking out. */
1862 return (const struct arc_opcode
*)
1863 hash_find (arc_opcode_hash
, pseudo_insn
->mnemonic_r
);
1866 static const struct arc_opcode
*
1867 find_special_case_flag (const char *opname
,
1869 struct arc_flags
*pflags
)
1873 unsigned flag_idx
, flag_arr_idx
;
1874 size_t flaglen
, oplen
;
1875 const struct arc_flag_special
*arc_flag_special_opcode
;
1876 const struct arc_opcode
*opcode
;
1878 /* Search for special case instruction. */
1879 for (i
= 0; i
< arc_num_flag_special
; i
++)
1881 arc_flag_special_opcode
= &arc_flag_special_cases
[i
];
1882 oplen
= strlen (arc_flag_special_opcode
->name
);
1884 if (strncmp (opname
, arc_flag_special_opcode
->name
, oplen
) != 0)
1887 /* Found a potential special case instruction, now test for
1889 for (flag_arr_idx
= 0;; ++flag_arr_idx
)
1891 flag_idx
= arc_flag_special_opcode
->flags
[flag_arr_idx
];
1893 break; /* End of array, nothing found. */
1895 flagnm
= arc_flag_operands
[flag_idx
].name
;
1896 flaglen
= strlen (flagnm
);
1897 if (strcmp (opname
+ oplen
, flagnm
) == 0)
1899 opcode
= (const struct arc_opcode
*)
1900 hash_find (arc_opcode_hash
,
1901 arc_flag_special_opcode
->name
);
1903 if (*nflgs
+ 1 > MAX_INSN_FLGS
)
1905 memcpy (pflags
[*nflgs
].name
, flagnm
, flaglen
);
1906 pflags
[*nflgs
].name
[flaglen
] = '\0';
1915 /* Used to find special case opcode. */
1917 static const struct arc_opcode
*
1918 find_special_case (const char *opname
,
1920 struct arc_flags
*pflags
,
1924 const struct arc_opcode
*opcode
;
1926 opcode
= find_special_case_pseudo (opname
, ntok
, tok
, nflgs
, pflags
);
1929 opcode
= find_special_case_flag (opname
, nflgs
, pflags
);
1935 preprocess_operands (const struct arc_opcode
*opcode
,
1943 const struct arc_aux_reg
*auxr
;
1945 for (i
= 0; i
< ntok
; i
++)
1947 switch (tok
[i
].X_op
)
1951 break; /* Throw and error. */
1954 if (opcode
->class != AUXREG
)
1956 /* Convert the symbol to a constant if possible. */
1957 p
= S_GET_NAME (tok
[i
].X_add_symbol
);
1960 auxr
= &arc_aux_regs
[0];
1961 for (j
= 0; j
< arc_num_aux_regs
; j
++, auxr
++)
1962 if (len
== auxr
->length
1963 && strcasecmp (auxr
->name
, p
) == 0)
1965 tok
[i
].X_op
= O_constant
;
1966 tok
[i
].X_add_number
= auxr
->address
;
1976 /* Given an opcode name, pre-tockenized set of argumenst and the
1977 opcode flags, take it all the way through emission. */
1980 assemble_tokens (const char *opname
,
1983 struct arc_flags
*pflags
,
1986 bfd_boolean found_something
= FALSE
;
1987 const struct arc_opcode
*opcode
;
1990 /* Search opcodes. */
1991 opcode
= (const struct arc_opcode
*) hash_find (arc_opcode_hash
, opname
);
1993 /* Couldn't find opcode conventional way, try special cases. */
1995 opcode
= find_special_case (opname
, &nflgs
, pflags
, tok
, &ntok
);
1999 pr_debug ("%s:%d: assemble_tokens: %s trying opcode 0x%08X\n",
2000 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->name
,
2003 preprocess_operands (opcode
, tok
, ntok
);
2005 found_something
= TRUE
;
2006 opcode
= find_opcode_match (opcode
, tok
, &ntok
, pflags
, nflgs
, &cpumatch
);
2009 struct arc_insn insn
;
2010 assemble_insn (opcode
, tok
, ntok
, pflags
, nflgs
, &insn
);
2016 if (found_something
)
2019 as_bad (_("inappropriate arguments for opcode '%s'"), opname
);
2021 as_bad (_("opcode '%s' not supported for target %s"), opname
,
2025 as_bad (_("unknown opcode '%s'"), opname
);
2028 /* The public interface to the instruction assembler. */
2031 md_assemble (char *str
)
2034 expressionS tok
[MAX_INSN_ARGS
];
2037 struct arc_flags flags
[MAX_INSN_FLGS
];
2039 /* Split off the opcode. */
2040 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_0123468");
2041 opname
= xmalloc (opnamelen
+ 1);
2042 memcpy (opname
, str
, opnamelen
);
2043 opname
[opnamelen
] = '\0';
2045 /* Signalize we are assmbling the instructions. */
2046 assembling_insn
= TRUE
;
2048 /* Tokenize the flags. */
2049 if ((nflg
= tokenize_flags (str
+ opnamelen
, flags
, MAX_INSN_FLGS
)) == -1)
2051 as_bad (_("syntax error"));
2055 /* Scan up to the end of the mnemonic which must end in space or end
2058 for (; *str
!= '\0'; str
++)
2062 /* Tokenize the rest of the line. */
2063 if ((ntok
= tokenize_arguments (str
, tok
, MAX_INSN_ARGS
)) < 0)
2065 as_bad (_("syntax error"));
2069 /* Finish it off. */
2070 assemble_tokens (opname
, tok
, ntok
, flags
, nflg
);
2071 assembling_insn
= FALSE
;
2074 /* Callback to insert a register into the hash table. */
2077 declare_register (const char *name
, int number
)
2080 symbolS
*regS
= symbol_create (name
, reg_section
,
2081 number
, &zero_address_frag
);
2083 err
= hash_insert (arc_reg_hash
, S_GET_NAME (regS
), (void *) regS
);
2085 as_fatal ("Inserting \"%s\" into register table failed: %s",
2089 /* Construct symbols for each of the general registers. */
2092 declare_register_set (void)
2095 for (i
= 0; i
< 64; ++i
)
2099 sprintf (name
, "r%d", i
);
2100 declare_register (name
, i
);
2101 if ((i
& 0x01) == 0)
2103 sprintf (name
, "r%dr%d", i
, i
+1);
2104 declare_register (name
, i
);
2109 /* Port-specific assembler initialization. This function is called
2110 once, at assembler startup time. */
2117 if (!mach_type_specified_p
)
2118 arc_select_cpu ("arc700");
2120 /* The endianness can be chosen "at the factory". */
2121 target_big_endian
= byte_order
== BIG_ENDIAN
;
2123 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, arc_mach_type
))
2124 as_warn (_("could not set architecture and machine"));
2126 /* Set elf header flags. */
2127 bfd_set_private_flags (stdoutput
, arc_eflag
);
2129 /* Set up a hash table for the instructions. */
2130 arc_opcode_hash
= hash_new ();
2131 if (arc_opcode_hash
== NULL
)
2132 as_fatal (_("Virtual memory exhausted"));
2134 /* Initialize the hash table with the insns. */
2135 for (i
= 0; i
< arc_num_opcodes
;)
2137 const char *name
, *retval
;
2139 name
= arc_opcodes
[i
].name
;
2140 retval
= hash_insert (arc_opcode_hash
, name
, (void *) &arc_opcodes
[i
]);
2142 as_fatal (_("internal error: can't hash opcode '%s': %s"),
2145 while (++i
< arc_num_opcodes
2146 && (arc_opcodes
[i
].name
== name
2147 || !strcmp (arc_opcodes
[i
].name
, name
)))
2151 /* Register declaration. */
2152 arc_reg_hash
= hash_new ();
2153 if (arc_reg_hash
== NULL
)
2154 as_fatal (_("Virtual memory exhausted"));
2156 declare_register_set ();
2157 declare_register ("gp", 26);
2158 declare_register ("fp", 27);
2159 declare_register ("sp", 28);
2160 declare_register ("ilink", 29);
2161 declare_register ("ilink1", 29);
2162 declare_register ("ilink2", 30);
2163 declare_register ("blink", 31);
2165 declare_register ("mlo", 57);
2166 declare_register ("mmid", 58);
2167 declare_register ("mhi", 59);
2169 declare_register ("acc1", 56);
2170 declare_register ("acc2", 57);
2172 declare_register ("lp_count", 60);
2173 declare_register ("pcl", 63);
2175 /* Initialize the last instructions. */
2176 memset (&arc_last_insns
[0], 0, sizeof (arc_last_insns
));
2179 /* Write a value out to the object file, using the appropriate
2183 md_number_to_chars (char *buf
,
2187 if (target_big_endian
)
2188 number_to_chars_bigendian (buf
, val
, n
);
2190 number_to_chars_littleendian (buf
, val
, n
);
2193 /* Round up a section size to the appropriate boundary. */
2196 md_section_align (segT segment
,
2199 int align
= bfd_get_section_alignment (stdoutput
, segment
);
2201 return ((size
+ (1 << align
) - 1) & (-((valueT
) 1 << align
)));
2204 /* The location from which a PC relative jump should be calculated,
2205 given a PC relative reloc. */
2208 md_pcrel_from_section (fixS
*fixP
,
2211 offsetT base
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2213 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP
->fx_offset
);
2215 if (fixP
->fx_addsy
!= (symbolS
*) NULL
2216 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2217 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
2219 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP
->fx_addsy
));
2221 /* The symbol is undefined (or is defined but not in this section).
2222 Let the linker figure it out. */
2226 if ((int) fixP
->fx_r_type
< 0)
2228 /* These are the "internal" relocations. Align them to
2229 32 bit boundary (PCL), for the moment. */
2234 switch (fixP
->fx_r_type
)
2236 case BFD_RELOC_ARC_PC32
:
2237 /* The hardware calculates relative to the start of the
2238 insn, but this relocation is relative to location of the
2239 LIMM, compensate. The base always needs to be
2240 substracted by 4 as we do not support this type of PCrel
2241 relocation for short instructions. */
2244 case BFD_RELOC_ARC_PLT32
:
2245 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2246 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2247 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2248 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2250 case BFD_RELOC_ARC_S21H_PCREL
:
2251 case BFD_RELOC_ARC_S25H_PCREL
:
2252 case BFD_RELOC_ARC_S13_PCREL
:
2253 case BFD_RELOC_ARC_S21W_PCREL
:
2254 case BFD_RELOC_ARC_S25W_PCREL
:
2258 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2259 _("unhandled reloc %s in md_pcrel_from_section"),
2260 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2265 pr_debug ("pcrel from %x + %lx = %x, symbol: %s (%x)\n",
2266 fixP
->fx_frag
->fr_address
, fixP
->fx_where
, base
,
2267 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "(null)",
2268 fixP
->fx_addsy
? S_GET_VALUE (fixP
->fx_addsy
) : 0);
2273 /* Given a BFD relocation find the coresponding operand. */
2275 static const struct arc_operand
*
2276 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc
)
2280 for (i
= 0; i
< arc_num_operands
; i
++)
2281 if (arc_operands
[i
].default_reloc
== reloc
)
2282 return &arc_operands
[i
];
2286 /* Insert an operand value into an instruction. */
2289 insert_operand (unsigned insn
,
2290 const struct arc_operand
*operand
,
2295 offsetT min
= 0, max
= 0;
2297 if (operand
->bits
!= 32
2298 && !(operand
->flags
& ARC_OPERAND_NCHK
)
2299 && !(operand
->flags
& ARC_OPERAND_FAKE
))
2301 if (operand
->flags
& ARC_OPERAND_SIGNED
)
2303 max
= (1 << (operand
->bits
- 1)) - 1;
2304 min
= -(1 << (operand
->bits
- 1));
2308 max
= (1 << operand
->bits
) - 1;
2312 if (val
< min
|| val
> max
)
2313 as_bad_value_out_of_range (_("operand"),
2314 val
, min
, max
, file
, line
);
2317 pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
2318 min
, val
, max
, insn
);
2320 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
2322 as_bad_where (file
, line
,
2323 _("Unaligned operand. Needs to be 32bit aligned"));
2325 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
2327 as_bad_where (file
, line
,
2328 _("Unaligned operand. Needs to be 16bit aligned"));
2330 if (operand
->insert
)
2332 const char *errmsg
= NULL
;
2334 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2336 as_warn_where (file
, line
, "%s", errmsg
);
2340 if (operand
->flags
& ARC_OPERAND_TRUNCATE
)
2342 if (operand
->flags
& ARC_OPERAND_ALIGNED32
)
2344 if (operand
->flags
& ARC_OPERAND_ALIGNED16
)
2347 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2352 /* Apply a fixup to the object code. At this point all symbol values
2353 should be fully resolved, and we attempt to completely resolve the
2354 reloc. If we can not do that, we determine the correct reloc code
2355 and put it back in the fixup. To indicate that a fixup has been
2356 eliminated, set fixP->fx_done. */
2359 md_apply_fix (fixS
*fixP
,
2363 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2364 valueT value
= *valP
;
2366 symbolS
*fx_addsy
, *fx_subsy
;
2368 segT add_symbol_segment
= absolute_section
;
2369 segT sub_symbol_segment
= absolute_section
;
2370 const struct arc_operand
*operand
= NULL
;
2371 extended_bfd_reloc_code_real_type reloc
;
2373 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2374 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2375 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2376 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2379 fx_addsy
= fixP
->fx_addsy
;
2380 fx_subsy
= fixP
->fx_subsy
;
2385 add_symbol_segment
= S_GET_SEGMENT (fx_addsy
);
2389 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF
2390 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF_S9
2391 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_GD_LD
)
2393 resolve_symbol_value (fx_subsy
);
2394 sub_symbol_segment
= S_GET_SEGMENT (fx_subsy
);
2396 if (sub_symbol_segment
== absolute_section
)
2398 /* The symbol is really a constant. */
2399 fx_offset
-= S_GET_VALUE (fx_subsy
);
2404 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2405 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
2406 fx_addsy
? S_GET_NAME (fx_addsy
) : "0",
2407 segment_name (add_symbol_segment
),
2408 S_GET_NAME (fx_subsy
),
2409 segment_name (sub_symbol_segment
));
2415 && !S_IS_WEAK (fx_addsy
))
2417 if (add_symbol_segment
== seg
2420 value
+= S_GET_VALUE (fx_addsy
);
2421 value
-= md_pcrel_from_section (fixP
, seg
);
2423 fixP
->fx_pcrel
= FALSE
;
2425 else if (add_symbol_segment
== absolute_section
)
2427 value
= fixP
->fx_offset
;
2428 fx_offset
+= S_GET_VALUE (fixP
->fx_addsy
);
2430 fixP
->fx_pcrel
= FALSE
;
2435 fixP
->fx_done
= TRUE
;
2440 && ((S_IS_DEFINED (fx_addsy
)
2441 && S_GET_SEGMENT (fx_addsy
) != seg
)
2442 || S_IS_WEAK (fx_addsy
)))
2443 value
+= md_pcrel_from_section (fixP
, seg
);
2445 switch (fixP
->fx_r_type
)
2447 case BFD_RELOC_ARC_32_ME
:
2448 /* This is a pc-relative value in a LIMM. Adjust it to the
2449 address of the instruction not to the address of the
2450 LIMM. Note: it is not anylonger valid this afirmation as
2451 the linker consider ARC_PC32 a fixup to entire 64 bit
2453 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
;
2456 fixP
->fx_r_type
= BFD_RELOC_ARC_PC32
;
2458 case BFD_RELOC_ARC_PC32
:
2459 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
2462 if ((int) fixP
->fx_r_type
< 0)
2463 as_fatal (_("PC relative relocation not allowed for (internal) type %d"),
2469 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2470 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2471 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2472 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2476 /* Now check for TLS relocations. */
2477 reloc
= fixP
->fx_r_type
;
2480 case BFD_RELOC_ARC_TLS_DTPOFF
:
2481 case BFD_RELOC_ARC_TLS_LE_32
:
2485 case BFD_RELOC_ARC_TLS_GD_GOT
:
2486 case BFD_RELOC_ARC_TLS_IE_GOT
:
2487 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2490 case BFD_RELOC_ARC_TLS_GD_LD
:
2491 gas_assert (!fixP
->fx_offset
);
2494 = (S_GET_VALUE (fixP
->fx_subsy
)
2495 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
2496 fixP
->fx_subsy
= NULL
;
2498 case BFD_RELOC_ARC_TLS_GD_CALL
:
2499 /* These two relocs are there just to allow ld to change the tls
2500 model for this symbol, by patching the code. The offset -
2501 and scale, if any - will be installed by the linker. */
2502 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2505 case BFD_RELOC_ARC_TLS_LE_S9
:
2506 case BFD_RELOC_ARC_TLS_DTPOFF_S9
:
2507 as_bad (_("TLS_*_S9 relocs are not supported yet"));
2519 /* Addjust the value if we have a constant. */
2522 /* For hosts with longs bigger than 32-bits make sure that the top
2523 bits of a 32-bit negative value read in by the parser are set,
2524 so that the correct comparisons are made. */
2525 if (value
& 0x80000000)
2526 value
|= (-1L << 31);
2528 reloc
= fixP
->fx_r_type
;
2536 case BFD_RELOC_ARC_32_PCREL
:
2537 md_number_to_chars (fixpos
, value
, fixP
->fx_size
);
2540 case BFD_RELOC_ARC_GOTPC32
:
2541 /* I cannot fix an GOTPC relocation because I need to relax it
2542 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
2543 as_bad (_("Unsupported operation on reloc"));
2546 case BFD_RELOC_ARC_TLS_DTPOFF
:
2547 case BFD_RELOC_ARC_TLS_LE_32
:
2548 gas_assert (!fixP
->fx_addsy
);
2549 gas_assert (!fixP
->fx_subsy
);
2551 case BFD_RELOC_ARC_GOTOFF
:
2552 case BFD_RELOC_ARC_32_ME
:
2553 case BFD_RELOC_ARC_PC32
:
2554 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
2557 case BFD_RELOC_ARC_PLT32
:
2558 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
2561 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2562 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
2565 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2566 reloc
= BFD_RELOC_ARC_S21H_PCREL
;
2569 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2570 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
2573 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2574 reloc
= BFD_RELOC_ARC_S21W_PCREL
;
2576 case BFD_RELOC_ARC_S25W_PCREL
:
2577 case BFD_RELOC_ARC_S21W_PCREL
:
2578 case BFD_RELOC_ARC_S21H_PCREL
:
2579 case BFD_RELOC_ARC_S25H_PCREL
:
2580 case BFD_RELOC_ARC_S13_PCREL
:
2582 operand
= find_operand_for_reloc (reloc
);
2583 gas_assert (operand
);
2588 if ((int) fixP
->fx_r_type
>= 0)
2589 as_fatal (_("unhandled relocation type %s"),
2590 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2592 /* The rest of these fixups needs to be completely resolved as
2594 if (fixP
->fx_addsy
!= 0
2595 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
2596 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2597 _("non-absolute expression in constant field"));
2599 gas_assert (-(int) fixP
->fx_r_type
< (int) arc_num_operands
);
2600 operand
= &arc_operands
[-(int) fixP
->fx_r_type
];
2605 if (target_big_endian
)
2607 switch (fixP
->fx_size
)
2610 insn
= bfd_getb32 (fixpos
);
2613 insn
= bfd_getb16 (fixpos
);
2616 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2617 _("unknown fixup size"));
2623 switch (fixP
->fx_size
)
2626 insn
= bfd_getl16 (fixpos
) << 16 | bfd_getl16 (fixpos
+ 2);
2629 insn
= bfd_getl16 (fixpos
);
2632 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2633 _("unknown fixup size"));
2637 insn
= insert_operand (insn
, operand
, (offsetT
) value
,
2638 fixP
->fx_file
, fixP
->fx_line
);
2640 md_number_to_chars_midend (fixpos
, insn
, fixP
->fx_size
);
2643 /* Prepare machine-dependent frags for relaxation.
2645 Called just before relaxation starts. Any symbol that is now undefined
2646 will not become defined.
2648 Return the correct fr_subtype in the frag.
2650 Return the initial "guess for fr_var" to caller. The guess for fr_var
2651 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
2652 or fr_var contributes to our returned value.
2654 Although it may not be explicit in the frag, pretend
2655 fr_var starts with a value. */
2658 md_estimate_size_before_relax (fragS
*fragP
,
2663 /* If the symbol is not located within the same section AND it's not
2664 an absolute section, use the maximum. OR if the symbol is a
2665 constant AND the insn is by nature not pc-rel, use the maximum.
2666 OR if the symbol is being equated against another symbol, use the
2667 maximum. OR if the symbol is weak use the maximum. */
2668 if ((S_GET_SEGMENT (fragP
->fr_symbol
) != segment
2669 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
2670 || (symbol_constant_p (fragP
->fr_symbol
)
2671 && !fragP
->tc_frag_data
.pcrel
)
2672 || symbol_equated_p (fragP
->fr_symbol
)
2673 || S_IS_WEAK (fragP
->fr_symbol
))
2675 while (md_relax_table
[fragP
->fr_subtype
].rlx_more
!= ARC_RLX_NONE
)
2676 ++fragP
->fr_subtype
;
2679 growth
= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
2680 fragP
->fr_var
= growth
;
2682 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
2683 fragP
->fr_file
, fragP
->fr_line
, growth
);
2688 /* Translate internal representation of relocation info to BFD target
2692 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
,
2696 bfd_reloc_code_real_type code
;
2698 reloc
= (arelent
*) xmalloc (sizeof (* reloc
));
2699 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2700 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
2701 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
2703 /* Make sure none of our internal relocations make it this far.
2704 They'd better have been fully resolved by this point. */
2705 gas_assert ((int) fixP
->fx_r_type
> 0);
2707 code
= fixP
->fx_r_type
;
2709 /* if we have something like add gp, pcl,
2710 _GLOBAL_OFFSET_TABLE_@gotpc. */
2711 if (code
== BFD_RELOC_ARC_GOTPC32
2713 && fixP
->fx_addsy
== GOT_symbol
)
2714 code
= BFD_RELOC_ARC_GOTPC
;
2716 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2717 if (reloc
->howto
== NULL
)
2719 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2720 _("cannot represent `%s' relocation in object file"),
2721 bfd_get_reloc_code_name (code
));
2725 if (!fixP
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
2726 as_fatal (_("internal error? cannot generate `%s' relocation"),
2727 bfd_get_reloc_code_name (code
));
2729 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
2731 if (code
== BFD_RELOC_ARC_TLS_DTPOFF
2732 || code
== BFD_RELOC_ARC_TLS_DTPOFF_S9
)
2735 = fixP
->fx_subsy
? symbol_get_bfdsym (fixP
->fx_subsy
) : NULL
;
2736 /* We just want to store a 24 bit index, but we have to wait
2737 till after write_contents has been called via
2738 bfd_map_over_sections before we can get the index from
2739 _bfd_elf_symbol_from_bfd_symbol. Thus, the write_relocs
2740 function is elf32-arc.c has to pick up the slack.
2741 Unfortunately, this leads to problems with hosts that have
2742 pointers wider than long (bfd_vma). There would be various
2743 ways to handle this, all error-prone :-( */
2744 reloc
->addend
= (bfd_vma
) sym
;
2745 if ((asymbol
*) reloc
->addend
!= sym
)
2747 as_bad ("Can't store pointer\n");
2752 reloc
->addend
= fixP
->fx_offset
;
2757 /* Perform post-processing of machine-dependent frags after relaxation.
2758 Called after relaxation is finished.
2759 In: Address of frag.
2760 fr_type == rs_machine_dependent.
2761 fr_subtype is what the address relaxed to.
2763 Out: Any fixS:s and constants are set up. */
2766 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
2767 segT segment ATTRIBUTE_UNUSED
,
2770 const relax_typeS
*table_entry
;
2772 const struct arc_opcode
*opcode
;
2773 struct arc_insn insn
;
2775 struct arc_relax_type
*relax_arg
= &fragP
->tc_frag_data
;
2777 fix
= (fragP
->fr_fix
< 0 ? 0 : fragP
->fr_fix
);
2778 dest
= fragP
->fr_literal
+ fix
;
2779 table_entry
= TC_GENERIC_RELAX_TABLE
+ fragP
->fr_subtype
;
2781 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, var: %d\n",
2782 fragP
->fr_file
, fragP
->fr_line
,
2783 fragP
->fr_subtype
, fix
, fragP
->fr_var
);
2785 if (fragP
->fr_subtype
<= 0
2786 && fragP
->fr_subtype
>= arc_num_relax_opcodes
)
2787 as_fatal (_("no relaxation found for this instruction."));
2789 opcode
= &arc_relax_opcodes
[fragP
->fr_subtype
];
2791 assemble_insn (opcode
, relax_arg
->tok
, relax_arg
->ntok
, relax_arg
->pflags
,
2792 relax_arg
->nflg
, &insn
);
2794 apply_fixups (&insn
, fragP
, fix
);
2796 size
= insn
.short_insn
? (insn
.has_limm
? 6 : 2) : (insn
.has_limm
? 8 : 4);
2797 gas_assert (table_entry
->rlx_length
== size
);
2798 emit_insn0 (&insn
, dest
, TRUE
);
2800 fragP
->fr_fix
+= table_entry
->rlx_length
;
2804 /* We have no need to default values of symbols. We could catch
2805 register names here, but that is handled by inserting them all in
2806 the symbol table to begin with. */
2809 md_undefined_symbol (char *name
)
2811 /* The arc abi demands that a GOT[0] should be referencible as
2812 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
2813 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
2815 && (*(name
+1) == 'G')
2816 && (strcmp (name
, GLOBAL_OFFSET_TABLE_NAME
) == 0))
2818 && (*(name
+1) == 'D')
2819 && (strcmp (name
, DYNAMIC_STRUCT_NAME
) == 0)))
2823 if (symbol_find (name
))
2824 as_bad ("GOT already in symbol table");
2826 GOT_symbol
= symbol_new (GLOBAL_OFFSET_TABLE_NAME
, undefined_section
,
2827 (valueT
) 0, &zero_address_frag
);
2834 /* Turn a string in input_line_pointer into a floating point constant
2835 of type type, and store the appropriate bytes in *litP. The number
2836 of LITTLENUMS emitted is stored in *sizeP. An error message is
2837 returned, or NULL on OK. */
2840 md_atof (int type
, char *litP
, int *sizeP
)
2842 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
2845 /* Called for any expression that can not be recognized. When the
2846 function is called, `input_line_pointer' will point to the start of
2850 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
2852 char *p
= input_line_pointer
;
2855 input_line_pointer
++;
2856 expressionP
->X_op
= O_symbol
;
2857 expression (expressionP
);
2861 /* This function is called from the function 'expression', it attempts
2862 to parse special names (in our case register names). It fills in
2863 the expression with the identified register. It returns TRUE if
2864 it is a register and FALSE otherwise. */
2867 arc_parse_name (const char *name
,
2868 struct expressionS
*e
)
2872 if (!assembling_insn
)
2875 /* Handle only registers. */
2876 if (e
->X_op
!= O_absent
)
2879 sym
= hash_find (arc_reg_hash
, name
);
2882 e
->X_op
= O_register
;
2883 e
->X_add_number
= S_GET_VALUE (sym
);
2890 Invocation line includes a switch not recognized by the base assembler.
2891 See if it's a processor-specific option.
2893 New options (supported) are:
2895 -mcpu=<cpu name> Assemble for selected processor
2896 -EB/-mbig-endian Big-endian
2897 -EL/-mlittle-endian Little-endian
2898 -mrelax Enable relaxation
2900 The following CPU names are recognized:
2901 arc700, av2em, av2hs. */
2904 md_parse_option (int c
, char *arg ATTRIBUTE_UNUSED
)
2910 return md_parse_option (OPTION_MCPU
, "arc600");
2913 return md_parse_option (OPTION_MCPU
, "arc700");
2916 return md_parse_option (OPTION_MCPU
, "arcem");
2919 return md_parse_option (OPTION_MCPU
, "archs");
2923 arc_select_cpu (arg
);
2924 mach_type_specified_p
= 1;
2929 arc_target_format
= "elf32-bigarc";
2930 byte_order
= BIG_ENDIAN
;
2934 arc_target_format
= "elf32-littlearc";
2935 byte_order
= LITTLE_ENDIAN
;
2939 /* This option has an effect only on ARC EM. */
2940 if (arc_target
& ARC_OPCODE_ARCv2EM
)
2941 arc_features
|= ARC_CD
;
2945 relaxation_state
= 1;
2948 case OPTION_USER_MODE
:
2949 case OPTION_LD_EXT_MASK
:
2952 case OPTION_BARREL_SHIFT
:
2953 case OPTION_MIN_MAX
:
2960 case OPTION_XMAC_D16
:
2961 case OPTION_XMAC_24
:
2962 case OPTION_DSP_PACKA
:
2965 case OPTION_TELEPHONY
:
2966 case OPTION_XYMEMORY
:
2971 /* Dummy options are accepted but have no effect. */
2982 md_show_usage (FILE *stream
)
2984 fprintf (stream
, _("ARC-specific assembler options:\n"));
2986 fprintf (stream
, " -mcpu=<cpu name>\t assemble for CPU <cpu name>\n");
2988 " -mcode-density\t enable code density option for ARC EM\n");
2990 fprintf (stream
, _("\
2991 -EB assemble code for a big-endian cpu\n"));
2992 fprintf (stream
, _("\
2993 -EL assemble code for a little-endian cpu\n"));
2994 fprintf (stream
, _("\
2995 -mrelax Enable relaxation\n"));
2999 /* Find the proper relocation for the given opcode. */
3001 static extended_bfd_reloc_code_real_type
3002 find_reloc (const char *name
,
3003 const char *opcodename
,
3004 const struct arc_flags
*pflags
,
3006 extended_bfd_reloc_code_real_type reloc
)
3010 bfd_boolean found_flag
, tmp
;
3011 extended_bfd_reloc_code_real_type ret
= BFD_RELOC_UNUSED
;
3013 for (i
= 0; i
< arc_num_equiv_tab
; i
++)
3015 const struct arc_reloc_equiv_tab
*r
= &arc_reloc_equiv
[i
];
3017 /* Find the entry. */
3018 if (strcmp (name
, r
->name
))
3020 if (r
->mnemonic
&& (strcmp (r
->mnemonic
, opcodename
)))
3027 unsigned * psflg
= (unsigned *)r
->flags
;
3031 for (j
= 0; j
< nflg
; j
++)
3032 if (!strcmp (pflags
[j
].name
,
3033 arc_flag_operands
[*psflg
].name
))
3054 if (reloc
!= r
->oldreloc
)
3061 if (ret
== BFD_RELOC_UNUSED
)
3062 as_bad (_("Unable to find %s relocation for instruction %s"),
3067 /* All the symbol types that are allowed to be used for
3071 may_relax_expr (expressionS tok
)
3073 /* Check if we have unrelaxable relocs. */
3098 /* Checks if flags are in line with relaxable insn. */
3101 relaxable_flag (const struct arc_relaxable_ins
*ins
,
3102 const struct arc_flags
*pflags
,
3105 unsigned flag_class
,
3110 const struct arc_flag_operand
*flag_opand
;
3111 int i
, counttrue
= 0;
3113 /* Iterate through flags classes. */
3114 while ((flag_class
= ins
->flag_classes
[flag_class_idx
]) != 0)
3116 /* Iterate through flags in flag class. */
3117 while ((flag
= arc_flag_classes
[flag_class
].flags
[flag_idx
])
3120 flag_opand
= &arc_flag_operands
[flag
];
3121 /* Iterate through flags in ins to compare. */
3122 for (i
= 0; i
< nflgs
; ++i
)
3124 if (strcmp (flag_opand
->name
, pflags
[i
].name
) == 0)
3135 /* If counttrue == nflgs, then all flags have been found. */
3136 return (counttrue
== nflgs
? TRUE
: FALSE
);
3139 /* Checks if operands are in line with relaxable insn. */
3142 relaxable_operand (const struct arc_relaxable_ins
*ins
,
3143 const expressionS
*tok
,
3146 const enum rlx_operand_type
*operand
= &ins
->operands
[0];
3149 while (*operand
!= EMPTY
)
3151 const expressionS
*epr
= &tok
[i
];
3153 if (i
!= 0 && i
>= ntok
)
3159 if (!(epr
->X_op
== O_multiply
3160 || epr
->X_op
== O_divide
3161 || epr
->X_op
== O_modulus
3162 || epr
->X_op
== O_add
3163 || epr
->X_op
== O_subtract
3164 || epr
->X_op
== O_symbol
))
3170 || (epr
->X_add_number
!= tok
[i
- 1].X_add_number
))
3174 if (epr
->X_op
!= O_register
)
3179 if (epr
->X_op
!= O_register
)
3182 switch (epr
->X_add_number
)
3184 case 0: case 1: case 2: case 3:
3185 case 12: case 13: case 14: case 15:
3192 case REGISTER_NO_GP
:
3193 if ((epr
->X_op
!= O_register
)
3194 || (epr
->X_add_number
== 26)) /* 26 is the gp register. */
3199 if (epr
->X_op
!= O_bracket
)
3204 /* Don't understand, bail out. */
3210 operand
= &ins
->operands
[i
];
3213 return (i
== ntok
? TRUE
: FALSE
);
3216 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3219 relax_insn_p (const struct arc_opcode
*opcode
,
3220 const expressionS
*tok
,
3222 const struct arc_flags
*pflags
,
3226 bfd_boolean rv
= FALSE
;
3228 /* Check the relaxation table. */
3229 for (i
= 0; i
< arc_num_relaxable_ins
&& relaxation_state
; ++i
)
3231 const struct arc_relaxable_ins
*arc_rlx_ins
= &arc_relaxable_insns
[i
];
3233 if ((strcmp (opcode
->name
, arc_rlx_ins
->mnemonic_r
) == 0)
3234 && may_relax_expr (tok
[arc_rlx_ins
->opcheckidx
])
3235 && relaxable_operand (arc_rlx_ins
, tok
, ntok
)
3236 && relaxable_flag (arc_rlx_ins
, pflags
, nflg
))
3239 frag_now
->fr_subtype
= arc_relaxable_insns
[i
].subtype
;
3240 memcpy (&frag_now
->tc_frag_data
.tok
, tok
,
3241 sizeof (expressionS
) * ntok
);
3242 memcpy (&frag_now
->tc_frag_data
.pflags
, pflags
,
3243 sizeof (struct arc_flags
) * nflg
);
3244 frag_now
->tc_frag_data
.nflg
= nflg
;
3245 frag_now
->tc_frag_data
.ntok
= ntok
;
3253 /* Turn an opcode description and a set of arguments into
3254 an instruction and a fixup. */
3257 assemble_insn (const struct arc_opcode
*opcode
,
3258 const expressionS
*tok
,
3260 const struct arc_flags
*pflags
,
3262 struct arc_insn
*insn
)
3264 const expressionS
*reloc_exp
= NULL
;
3266 const unsigned char *argidx
;
3269 unsigned char pcrel
= 0;
3270 bfd_boolean needGOTSymbol
;
3271 bfd_boolean has_delay_slot
= FALSE
;
3272 extended_bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
3274 memset (insn
, 0, sizeof (*insn
));
3275 image
= opcode
->opcode
;
3277 pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
3278 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->name
,
3281 /* Handle operands. */
3282 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
3284 const struct arc_operand
*operand
= &arc_operands
[*argidx
];
3285 const expressionS
*t
= (const expressionS
*) 0;
3287 if ((operand
->flags
& ARC_OPERAND_FAKE
)
3288 && !(operand
->flags
& ARC_OPERAND_BRAKET
))
3291 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
3293 /* Duplicate operand, already inserted. */
3305 /* Regardless if we have a reloc or not mark the instruction
3306 limm if it is the case. */
3307 if (operand
->flags
& ARC_OPERAND_LIMM
)
3308 insn
->has_limm
= TRUE
;
3313 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
3318 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
3320 if (operand
->flags
& ARC_OPERAND_LIMM
)
3321 insn
->limm
= t
->X_add_number
;
3325 /* Ignore brackets. */
3329 gas_assert (operand
->flags
& ARC_OPERAND_IGNORE
);
3333 /* Maybe register range. */
3334 if ((t
->X_add_number
== 0)
3335 && contains_register (t
->X_add_symbol
)
3336 && contains_register (t
->X_op_symbol
))
3340 regs
= get_register (t
->X_add_symbol
);
3342 regs
|= get_register (t
->X_op_symbol
);
3343 image
= insert_operand (image
, operand
, regs
, NULL
, 0);
3348 /* This operand needs a relocation. */
3349 needGOTSymbol
= FALSE
;
3354 needGOTSymbol
= TRUE
;
3355 reloc
= find_reloc ("plt", opcode
->name
,
3357 operand
->default_reloc
);
3362 needGOTSymbol
= TRUE
;
3363 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3366 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3367 if (ARC_SHORT (opcode
->mask
))
3368 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3369 _("Unable to use @pcl relocation for insn %s"),
3373 reloc
= find_reloc ("sda", opcode
->name
,
3375 operand
->default_reloc
);
3379 needGOTSymbol
= TRUE
;
3384 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3387 case O_tpoff9
: /*FIXME! Check for the conditionality of
3389 case O_dtpoff9
: /*FIXME! Check for the conditionality of
3391 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3395 /* Just consider the default relocation. */
3396 reloc
= operand
->default_reloc
;
3400 if (needGOTSymbol
&& (GOT_symbol
== NULL
))
3401 GOT_symbol
= symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME
);
3408 /* sanity checks. */
3409 reloc_howto_type
*reloc_howto
3410 = bfd_reloc_type_lookup (stdoutput
,
3411 (bfd_reloc_code_real_type
) reloc
);
3412 unsigned reloc_bitsize
= reloc_howto
->bitsize
;
3413 if (reloc_howto
->rightshift
)
3414 reloc_bitsize
-= reloc_howto
->rightshift
;
3415 if (reloc_bitsize
!= operand
->bits
)
3417 as_bad (_("invalid relocation %s for field"),
3418 bfd_get_reloc_code_name (reloc
));
3423 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
3424 as_fatal (_("too many fixups"));
3426 struct arc_fixup
*fixup
;
3427 fixup
= &insn
->fixups
[insn
->nfixups
++];
3429 fixup
->reloc
= reloc
;
3430 pcrel
= (operand
->flags
& ARC_OPERAND_PCREL
) ? 1 : 0;
3431 fixup
->pcrel
= pcrel
;
3432 fixup
->islong
= (operand
->flags
& ARC_OPERAND_LIMM
) ?
3439 for (i
= 0; i
< nflg
; i
++)
3441 const struct arc_flag_operand
*flg_operand
=
3442 &arc_flag_operands
[pflags
[i
].code
];
3444 /* Check if the instruction has a delay slot. */
3445 if (!strcmp (flg_operand
->name
, "d"))
3446 has_delay_slot
= TRUE
;
3448 /* There is an exceptional case when we cannot insert a flag
3449 just as it is. The .T flag must be handled in relation with
3450 the relative address. */
3451 if (!strcmp (flg_operand
->name
, "t")
3452 || !strcmp (flg_operand
->name
, "nt"))
3454 unsigned bitYoperand
= 0;
3455 /* FIXME! move selection bbit/brcc in arc-opc.c. */
3456 if (!strcmp (flg_operand
->name
, "t"))
3457 if (!strcmp (opcode
->name
, "bbit0")
3458 || !strcmp (opcode
->name
, "bbit1"))
3459 bitYoperand
= arc_NToperand
;
3461 bitYoperand
= arc_Toperand
;
3463 if (!strcmp (opcode
->name
, "bbit0")
3464 || !strcmp (opcode
->name
, "bbit1"))
3465 bitYoperand
= arc_Toperand
;
3467 bitYoperand
= arc_NToperand
;
3469 gas_assert (reloc_exp
!= NULL
);
3470 if (reloc_exp
->X_op
== O_constant
)
3472 /* Check if we have a constant and solved it
3474 offsetT val
= reloc_exp
->X_add_number
;
3475 image
|= insert_operand (image
, &arc_operands
[bitYoperand
],
3480 struct arc_fixup
*fixup
;
3482 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
3483 as_fatal (_("too many fixups"));
3485 fixup
= &insn
->fixups
[insn
->nfixups
++];
3486 fixup
->exp
= *reloc_exp
;
3487 fixup
->reloc
= -bitYoperand
;
3488 fixup
->pcrel
= pcrel
;
3489 fixup
->islong
= FALSE
;
3493 image
|= (flg_operand
->code
& ((1 << flg_operand
->bits
) - 1))
3494 << flg_operand
->shift
;
3497 insn
->relax
= relax_insn_p (opcode
, tok
, ntok
, pflags
, nflg
);
3499 /* Short instruction? */
3500 insn
->short_insn
= ARC_SHORT (opcode
->mask
) ? TRUE
: FALSE
;
3504 /* Update last insn status. */
3505 arc_last_insns
[1] = arc_last_insns
[0];
3506 arc_last_insns
[0].opcode
= opcode
;
3507 arc_last_insns
[0].has_limm
= insn
->has_limm
;
3508 arc_last_insns
[0].has_delay_slot
= has_delay_slot
;
3510 /* Check if the current instruction is legally used. */
3511 if (arc_last_insns
[1].has_delay_slot
3512 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
3513 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3514 _("A jump/branch instruction in delay slot."));
3518 arc_handle_align (fragS
* fragP
)
3520 if ((fragP
)->fr_type
== rs_align_code
)
3522 char *dest
= (fragP
)->fr_literal
+ (fragP
)->fr_fix
;
3523 valueT count
= ((fragP
)->fr_next
->fr_address
3524 - (fragP
)->fr_address
- (fragP
)->fr_fix
);
3526 (fragP
)->fr_var
= 2;
3528 if (count
& 1)/* Padding in the gap till the next 2-byte
3529 boundary with 0s. */
3534 /* Writing nop_s. */
3535 md_number_to_chars (dest
, NOP_OPCODE_S
, 2);
3539 /* Here we decide which fixups can be adjusted to make them relative
3540 to the beginning of the section instead of the symbol. Basically
3541 we need to make sure that the dynamic relocations are done
3542 correctly, so in some cases we force the original symbol to be
3546 tc_arc_fix_adjustable (fixS
*fixP
)
3549 /* Prevent all adjustments to global symbols. */
3550 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
3552 if (S_IS_WEAK (fixP
->fx_addsy
))
3555 /* Adjust_reloc_syms doesn't know about the GOT. */
3556 switch (fixP
->fx_r_type
)
3558 case BFD_RELOC_ARC_GOTPC32
:
3559 case BFD_RELOC_ARC_PLT32
:
3560 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
3561 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
3562 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
3563 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
3573 /* Compute the reloc type of an expression EXP. */
3576 arc_check_reloc (expressionS
*exp
,
3577 bfd_reloc_code_real_type
*r_type_p
)
3579 if (*r_type_p
== BFD_RELOC_32
3580 && exp
->X_op
== O_subtract
3581 && exp
->X_op_symbol
!= NULL
3582 && exp
->X_op_symbol
->bsym
->section
== now_seg
)
3583 *r_type_p
= BFD_RELOC_ARC_32_PCREL
;
3587 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
3590 arc_cons_fix_new (fragS
*frag
,
3594 bfd_reloc_code_real_type r_type
)
3596 r_type
= BFD_RELOC_UNUSED
;
3601 r_type
= BFD_RELOC_8
;
3605 r_type
= BFD_RELOC_16
;
3609 r_type
= BFD_RELOC_24
;
3613 r_type
= BFD_RELOC_32
;
3614 arc_check_reloc (exp
, &r_type
);
3618 r_type
= BFD_RELOC_64
;
3622 as_bad (_("unsupported BFD relocation size %u"), size
);
3623 r_type
= BFD_RELOC_UNUSED
;
3626 fix_new_exp (frag
, off
, size
, exp
, 0, r_type
);
3629 /* The actual routine that checks the ZOL conditions. */
3632 check_zol (symbolS
*s
)
3634 switch (arc_mach_type
)
3636 case bfd_mach_arc_arcv2
:
3637 if (arc_target
& ARC_OPCODE_ARCv2EM
)
3640 if (is_br_jmp_insn_p (arc_last_insns
[0].opcode
)
3641 || arc_last_insns
[1].has_delay_slot
)
3642 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
3646 case bfd_mach_arc_arc600
:
3648 if (is_kernel_insn_p (arc_last_insns
[0].opcode
))
3649 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
3652 if (arc_last_insns
[0].has_limm
3653 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
3654 as_bad (_("A jump instruction with long immediate detected at the \
3655 end of the ZOL label @%s"), S_GET_NAME (s
));
3658 case bfd_mach_arc_arc700
:
3659 if (arc_last_insns
[0].has_delay_slot
)
3660 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
3669 /* If ZOL end check the last two instruction for illegals. */
3671 arc_frob_label (symbolS
* sym
)
3673 if (ARC_GET_FLAG (sym
) & ARC_FLAG_ZOL
)
3676 dwarf2_emit_label (sym
);
3679 /* Used because generic relaxation assumes a pc-rel value whilst we
3680 also relax instructions that use an absolute value resolved out of
3681 relative values (if that makes any sense). An example: 'add r1,
3682 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
3683 but if they're in the same section we can subtract the section
3684 offset relocation which ends up in a resolved value. So if @.L2 is
3685 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
3686 .text + 0x40 = 0x10. */
3688 arc_pcrel_adjust (fragS
*fragP
)
3690 if (!fragP
->tc_frag_data
.pcrel
)
3691 return fragP
->fr_address
+ fragP
->fr_fix
;
3696 /* Initialize the DWARF-2 unwind information for this procedure. */
3699 tc_arc_frame_initial_instructions (void)
3701 /* Stack pointer is register 28. */
3702 cfi_add_CFA_def_cfa_register (28);
3706 tc_arc_regname_to_dw2regnum (char *regname
)
3710 sym
= hash_find (arc_reg_hash
, regname
);
3712 return S_GET_VALUE (sym
);