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
= ARC_OPCODE_BASE
;
315 static const char *arc_target_name
= "<all>";
316 static unsigned arc_features
= 0x00;
318 /* The default architecture. */
319 static int arc_mach_type
= bfd_mach_arc_arcv2
;
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
},
349 { "all", ARC_OPCODE_BASE
, bfd_mach_arc_arcv2
,
354 /* Used by the arc_reloc_op table. Order is important. */
355 #define O_gotoff O_md1 /* @gotoff relocation. */
356 #define O_gotpc O_md2 /* @gotpc relocation. */
357 #define O_plt O_md3 /* @plt relocation. */
358 #define O_sda O_md4 /* @sda relocation. */
359 #define O_pcl O_md5 /* @pcl relocation. */
360 #define O_tlsgd O_md6 /* @tlsgd relocation. */
361 #define O_tlsie O_md7 /* @tlsie relocation. */
362 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
363 #define O_tpoff O_md9 /* @tpoff relocation. */
364 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
365 #define O_dtpoff O_md11 /* @dtpoff relocation. */
366 #define O_last O_dtpoff
368 /* Used to define a bracket as operand in tokens. */
369 #define O_bracket O_md32
371 /* Dummy relocation, to be sorted out. */
372 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
374 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
376 /* A table to map the spelling of a relocation operand into an appropriate
377 bfd_reloc_code_real_type type. The table is assumed to be ordered such
378 that op-O_literal indexes into it. */
379 #define ARC_RELOC_TABLE(op) \
380 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
382 : (int) (op) - (int) O_gotoff) ])
384 #define DEF(NAME, RELOC, REQ) \
385 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
387 static const struct arc_reloc_op_tag
389 /* String to lookup. */
391 /* Size of the string. */
393 /* Which operator to use. */
395 extended_bfd_reloc_code_real_type reloc
;
396 /* Allows complex relocation expression like identifier@reloc +
398 unsigned int complex_expr
: 1;
402 DEF (gotoff
, BFD_RELOC_ARC_GOTOFF
, 1),
403 DEF (gotpc
, BFD_RELOC_ARC_GOTPC32
, 0),
404 DEF (plt
, BFD_RELOC_ARC_PLT32
, 0),
405 DEF (sda
, DUMMY_RELOC_ARC_ENTRY
, 1),
406 DEF (pcl
, BFD_RELOC_ARC_PC32
, 1),
407 DEF (tlsgd
, BFD_RELOC_ARC_TLS_GD_GOT
, 0),
408 DEF (tlsie
, BFD_RELOC_ARC_TLS_IE_GOT
, 0),
409 DEF (tpoff9
, BFD_RELOC_ARC_TLS_LE_S9
, 0),
410 DEF (tpoff
, BFD_RELOC_ARC_TLS_LE_32
, 1),
411 DEF (dtpoff9
, BFD_RELOC_ARC_TLS_DTPOFF_S9
, 0),
412 DEF (dtpoff
, BFD_RELOC_ARC_TLS_DTPOFF
, 0),
415 static const int arc_num_reloc_op
416 = sizeof (arc_reloc_op
) / sizeof (*arc_reloc_op
);
418 /* Structure for relaxable instruction that have to be swapped with a
419 smaller alternative instruction. */
420 struct arc_relaxable_ins
422 /* Mnemonic that should be checked. */
423 const char *mnemonic_r
;
425 /* Operands that should be checked.
426 Indexes of operands from operand array. */
427 enum rlx_operand_type operands
[6];
429 /* Flags that should be checked. */
430 unsigned flag_classes
[5];
432 /* Mnemonic (smaller) alternative to be used later for relaxation. */
433 const char *mnemonic_alt
;
435 /* Index of operand that generic relaxation has to check. */
438 /* Base subtype index used. */
439 enum arc_rlx_types subtype
;
442 #define RELAX_TABLE_ENTRY(BITS, ISSIGNED, SIZE, NEXT) \
443 { (ISSIGNED) ? ((1 << ((BITS) - 1)) - 1) : ((1 << (BITS)) - 1), \
444 (ISSIGNED) ? -(1 << ((BITS) - 1)) : 0, \
448 #define RELAX_TABLE_ENTRY_MAX(ISSIGNED, SIZE, NEXT) \
449 { (ISSIGNED) ? 0x7FFFFFFF : 0xFFFFFFFF, \
450 (ISSIGNED) ? -(0x7FFFFFFF) : 0, \
455 /* ARC relaxation table. */
456 const relax_typeS md_relax_table
[] =
463 RELAX_TABLE_ENTRY(13, 1, 2, ARC_RLX_BL
),
464 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE
),
468 RELAX_TABLE_ENTRY(10, 1, 2, ARC_RLX_B
),
469 RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE
),
474 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_ADD_U6
),
475 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_LIMM
),
476 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
478 /* LD_S a, [b, u7] ->
479 LD<zz><.x><.aa><.di> a, [b, s9] ->
480 LD<zz><.x><.aa><.di> a, [b, limm] */
481 RELAX_TABLE_ENTRY(7, 0, 2, ARC_RLX_LD_S9
),
482 RELAX_TABLE_ENTRY(9, 1, 4, ARC_RLX_LD_LIMM
),
483 RELAX_TABLE_ENTRY_MAX(1, 8, ARC_RLX_NONE
),
488 RELAX_TABLE_ENTRY(8, 0, 2, ARC_RLX_MOV_S12
),
489 RELAX_TABLE_ENTRY(8, 0, 4, ARC_RLX_MOV_LIMM
),
490 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
494 SUB<.f> a, b, limm. */
495 RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_SUB_U6
),
496 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_SUB_LIMM
),
497 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
499 /* MPY<.f> a, b, u6 ->
500 MPY<.f> a, b, limm. */
501 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MPY_LIMM
),
502 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
504 /* MOV<.f><.cc> b, u6 ->
505 MOV<.f><.cc> b, limm. */
506 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MOV_RLIMM
),
507 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
509 /* ADD<.f><.cc> b, b, u6 ->
510 ADD<.f><.cc> b, b, limm. */
511 RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_RRLIMM
),
512 RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE
),
515 /* Order of this table's entries matters! */
516 const struct arc_relaxable_ins arc_relaxable_insns
[] =
518 { "bl", { IMMEDIATE
}, { 0 }, "bl_s", 0, ARC_RLX_BL_S
},
519 { "b", { IMMEDIATE
}, { 0 }, "b_s", 0, ARC_RLX_B_S
},
520 { "add", { REGISTER
, REGISTER_DUP
, IMMEDIATE
}, { 5, 1, 0 }, "add",
521 2, ARC_RLX_ADD_RRU6
},
522 { "add", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "add_s", 2,
524 { "add", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "add", 2,
526 { "ld", { REGISTER_S
, BRACKET
, REGISTER_S
, IMMEDIATE
, BRACKET
},
527 { 0 }, "ld_s", 3, ARC_RLX_LD_U7
},
528 { "ld", { REGISTER
, BRACKET
, REGISTER_NO_GP
, IMMEDIATE
, BRACKET
},
529 { 11, 4, 14, 17, 0 }, "ld", 3, ARC_RLX_LD_S9
},
530 { "mov", { REGISTER_S
, IMMEDIATE
}, { 0 }, "mov_s", 1, ARC_RLX_MOV_U8
},
531 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 0 }, "mov", 1, ARC_RLX_MOV_S12
},
532 { "mov", { REGISTER
, IMMEDIATE
}, { 5, 1, 0 },"mov", 1, ARC_RLX_MOV_RU6
},
533 { "sub", { REGISTER_S
, REGISTER_S
, IMMEDIATE
}, { 0 }, "sub_s", 2,
535 { "sub", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "sub", 2,
537 { "mpy", { REGISTER
, REGISTER
, IMMEDIATE
}, { 5, 0 }, "mpy", 2,
541 const unsigned arc_num_relaxable_ins
= ARRAY_SIZE (arc_relaxable_insns
);
543 /* Flags to set in the elf header. */
544 static flagword arc_eflag
= 0x00;
546 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
547 symbolS
* GOT_symbol
= 0;
549 /* Set to TRUE when we assemble instructions. */
550 static bfd_boolean assembling_insn
= FALSE
;
552 /* Functions implementation. */
554 /* Like md_number_to_chars but used for limms. The 4-byte limm value,
555 is encoded as 'middle-endian' for a little-endian target. FIXME!
556 this function is used for regular 4 byte instructions as well. */
559 md_number_to_chars_midend (char *buf
, valueT val
, int n
)
563 md_number_to_chars (buf
, (val
& 0xffff0000) >> 16, 2);
564 md_number_to_chars (buf
+ 2, (val
& 0xffff), 2);
568 md_number_to_chars (buf
, val
, n
);
572 /* Here ends all the ARCompact extension instruction assembling
576 arc_extra_reloc (int r_type
)
579 symbolS
*sym
, *lab
= NULL
;
581 if (*input_line_pointer
== '@')
582 input_line_pointer
++;
583 c
= get_symbol_name (&sym_name
);
584 sym
= symbol_find_or_make (sym_name
);
585 restore_line_pointer (c
);
586 if (c
== ',' && r_type
== BFD_RELOC_ARC_TLS_GD_LD
)
588 ++input_line_pointer
;
590 c
= get_symbol_name (&lab_name
);
591 lab
= symbol_find_or_make (lab_name
);
592 restore_line_pointer (c
);
595 = fix_new (frag_now
, /* Which frag? */
596 frag_now_fix (), /* Where in that frag? */
597 2, /* size: 1, 2, or 4 usually. */
598 sym
, /* X_add_symbol. */
599 0, /* X_add_number. */
600 FALSE
, /* TRUE if PC-relative relocation. */
601 r_type
/* Relocation type. */);
602 fixP
->fx_subsy
= lab
;
606 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED
,
607 symbolS
*symbolP
, addressT size
)
612 if (*input_line_pointer
== ',')
614 align
= parse_align (1);
616 if (align
== (addressT
) -1)
631 bss_alloc (symbolP
, size
, align
);
632 S_CLEAR_EXTERNAL (symbolP
);
638 arc_lcomm (int ignore
)
640 symbolS
*symbolP
= s_comm_internal (ignore
, arc_lcomm_internal
);
643 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
646 /* Select the cpu we're assembling for. */
649 arc_option (int ignore ATTRIBUTE_UNUSED
)
655 c
= get_symbol_name (&cpu
);
656 mach
= arc_get_mach (cpu
);
661 if (!mach_type_specified_p
)
663 if ((!strcmp ("ARC600", cpu
))
664 || (!strcmp ("ARC601", cpu
))
665 || (!strcmp ("A6", cpu
)))
667 md_parse_option (OPTION_MCPU
, "arc600");
669 else if ((!strcmp ("ARC700", cpu
))
670 || (!strcmp ("A7", cpu
)))
672 md_parse_option (OPTION_MCPU
, "arc700");
674 else if (!strcmp ("EM", cpu
))
676 md_parse_option (OPTION_MCPU
, "arcem");
678 else if (!strcmp ("HS", cpu
))
680 md_parse_option (OPTION_MCPU
, "archs");
683 as_fatal ("could not find the architecture");
685 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, mach
))
686 as_fatal ("could not set architecture and machine");
689 if (arc_mach_type
!= mach
)
690 as_warn ("Command-line value overrides \".cpu\" directive");
692 restore_line_pointer (c
);
693 demand_empty_rest_of_line ();
697 restore_line_pointer (c
);
698 as_bad ("invalid identifier for \".cpu\"");
699 ignore_rest_of_line ();
702 /* Smartly print an expression. */
705 debug_exp (expressionS
*t
)
707 const char *name ATTRIBUTE_UNUSED
;
708 const char *namemd ATTRIBUTE_UNUSED
;
710 pr_debug ("debug_exp: ");
714 default: name
= "unknown"; break;
715 case O_illegal
: name
= "O_illegal"; break;
716 case O_absent
: name
= "O_absent"; break;
717 case O_constant
: name
= "O_constant"; break;
718 case O_symbol
: name
= "O_symbol"; break;
719 case O_symbol_rva
: name
= "O_symbol_rva"; break;
720 case O_register
: name
= "O_register"; break;
721 case O_big
: name
= "O_big"; break;
722 case O_uminus
: name
= "O_uminus"; break;
723 case O_bit_not
: name
= "O_bit_not"; break;
724 case O_logical_not
: name
= "O_logical_not"; break;
725 case O_multiply
: name
= "O_multiply"; break;
726 case O_divide
: name
= "O_divide"; break;
727 case O_modulus
: name
= "O_modulus"; break;
728 case O_left_shift
: name
= "O_left_shift"; break;
729 case O_right_shift
: name
= "O_right_shift"; break;
730 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
731 case O_bit_or_not
: name
= "O_bit_or_not"; break;
732 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
733 case O_bit_and
: name
= "O_bit_and"; break;
734 case O_add
: name
= "O_add"; break;
735 case O_subtract
: name
= "O_subtract"; break;
736 case O_eq
: name
= "O_eq"; break;
737 case O_ne
: name
= "O_ne"; break;
738 case O_lt
: name
= "O_lt"; break;
739 case O_le
: name
= "O_le"; break;
740 case O_ge
: name
= "O_ge"; break;
741 case O_gt
: name
= "O_gt"; break;
742 case O_logical_and
: name
= "O_logical_and"; break;
743 case O_logical_or
: name
= "O_logical_or"; break;
744 case O_index
: name
= "O_index"; break;
745 case O_bracket
: name
= "O_bracket"; break;
750 default: namemd
= "unknown"; break;
751 case O_gotoff
: namemd
= "O_gotoff"; break;
752 case O_gotpc
: namemd
= "O_gotpc"; break;
753 case O_plt
: namemd
= "O_plt"; break;
754 case O_sda
: namemd
= "O_sda"; break;
755 case O_pcl
: namemd
= "O_pcl"; break;
756 case O_tlsgd
: namemd
= "O_tlsgd"; break;
757 case O_tlsie
: namemd
= "O_tlsie"; break;
758 case O_tpoff9
: namemd
= "O_tpoff9"; break;
759 case O_tpoff
: namemd
= "O_tpoff"; break;
760 case O_dtpoff9
: namemd
= "O_dtpoff9"; break;
761 case O_dtpoff
: namemd
= "O_dtpoff"; break;
764 pr_debug ("%s (%s, %s, %d, %s)", name
,
765 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
766 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
767 (int) t
->X_add_number
,
768 (t
->X_md
) ? namemd
: "--");
773 /* Parse the arguments to an opcode. */
776 tokenize_arguments (char *str
,
780 char *old_input_line_pointer
;
781 bfd_boolean saw_comma
= FALSE
;
782 bfd_boolean saw_arg
= FALSE
;
787 const struct arc_reloc_op_tag
*r
;
791 memset (tok
, 0, sizeof (*tok
) * ntok
);
793 /* Save and restore input_line_pointer around this function. */
794 old_input_line_pointer
= input_line_pointer
;
795 input_line_pointer
= str
;
797 while (*input_line_pointer
)
800 switch (*input_line_pointer
)
806 input_line_pointer
++;
807 if (saw_comma
|| !saw_arg
)
814 ++input_line_pointer
;
818 tok
->X_op
= O_bracket
;
825 input_line_pointer
++;
829 tok
->X_op
= O_bracket
;
835 /* We have labels, function names and relocations, all
836 starting with @ symbol. Sort them out. */
837 if (saw_arg
&& !saw_comma
)
841 tok
->X_op
= O_symbol
;
842 tok
->X_md
= O_absent
;
844 if (*input_line_pointer
!= '@')
845 goto normalsymbol
; /* This is not a relocation. */
849 /* A relocation opernad has the following form
850 @identifier@relocation_type. The identifier is already
852 if (tok
->X_op
!= O_symbol
)
854 as_bad (_("No valid label relocation operand"));
858 /* Parse @relocation_type. */
859 input_line_pointer
++;
860 c
= get_symbol_name (&reloc_name
);
861 len
= input_line_pointer
- reloc_name
;
864 as_bad (_("No relocation operand"));
868 /* Go through known relocation and try to find a match. */
869 r
= &arc_reloc_op
[0];
870 for (i
= arc_num_reloc_op
- 1; i
>= 0; i
--, r
++)
872 && memcmp (reloc_name
, r
->name
, len
) == 0)
876 as_bad (_("Unknown relocation operand: @%s"), reloc_name
);
880 *input_line_pointer
= c
;
881 SKIP_WHITESPACE_AFTER_NAME ();
882 /* Extra check for TLS: base. */
883 if (*input_line_pointer
== '@')
886 if (tok
->X_op_symbol
!= NULL
887 || tok
->X_op
!= O_symbol
)
889 as_bad (_("Unable to parse TLS base: %s"),
893 input_line_pointer
++;
895 c
= get_symbol_name (&sym_name
);
896 base
= symbol_find_or_make (sym_name
);
897 tok
->X_op
= O_subtract
;
898 tok
->X_op_symbol
= base
;
899 restore_line_pointer (c
);
900 tmpE
.X_add_number
= 0;
902 else if ((*input_line_pointer
!= '+')
903 && (*input_line_pointer
!= '-'))
905 tmpE
.X_add_number
= 0;
909 /* Parse the constant of a complex relocation expression
910 like @identifier@reloc +/- const. */
911 if (! r
->complex_expr
)
913 as_bad (_("@%s is not a complex relocation."), r
->name
);
917 if (tmpE
.X_op
!= O_constant
)
919 as_bad (_("Bad expression: @%s + %s."),
920 r
->name
, input_line_pointer
);
926 tok
->X_add_number
= tmpE
.X_add_number
;
937 /* Can be a register. */
938 ++input_line_pointer
;
942 if (saw_arg
&& !saw_comma
)
945 tok
->X_op
= O_absent
;
946 tok
->X_md
= O_absent
;
949 /* Legacy: There are cases when we have
950 identifier@relocation_type, if it is the case parse the
951 relocation type as well. */
952 if (*input_line_pointer
== '@')
958 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
970 if (saw_comma
|| brk_lvl
)
972 input_line_pointer
= old_input_line_pointer
;
978 as_bad (_("Brackets in operand field incorrect"));
980 as_bad (_("extra comma"));
982 as_bad (_("missing argument"));
984 as_bad (_("missing comma or colon"));
985 input_line_pointer
= old_input_line_pointer
;
989 /* Parse the flags to a structure. */
992 tokenize_flags (const char *str
,
993 struct arc_flags flags
[],
996 char *old_input_line_pointer
;
997 bfd_boolean saw_flg
= FALSE
;
998 bfd_boolean saw_dot
= FALSE
;
1002 memset (flags
, 0, sizeof (*flags
) * nflg
);
1004 /* Save and restore input_line_pointer around this function. */
1005 old_input_line_pointer
= input_line_pointer
;
1006 input_line_pointer
= (char *) str
;
1008 while (*input_line_pointer
)
1010 switch (*input_line_pointer
)
1017 input_line_pointer
++;
1025 if (saw_flg
&& !saw_dot
)
1028 if (num_flags
>= nflg
)
1031 flgnamelen
= strspn (input_line_pointer
, "abcdefghilmnopqrstvwxz");
1032 if (flgnamelen
> MAX_FLAG_NAME_LENGHT
)
1035 memcpy (flags
->name
, input_line_pointer
, flgnamelen
);
1037 input_line_pointer
+= flgnamelen
;
1047 input_line_pointer
= old_input_line_pointer
;
1052 as_bad (_("extra dot"));
1054 as_bad (_("unrecognized flag"));
1056 as_bad (_("failed to parse flags"));
1057 input_line_pointer
= old_input_line_pointer
;
1061 /* Apply the fixups in order. */
1064 apply_fixups (struct arc_insn
*insn
, fragS
*fragP
, int fix
)
1068 for (i
= 0; i
< insn
->nfixups
; i
++)
1070 struct arc_fixup
*fixup
= &insn
->fixups
[i
];
1071 int size
, pcrel
, offset
= 0;
1073 /* FIXME! the reloc size is wrong in the BFD file.
1074 When it is fixed please delete me. */
1075 size
= (insn
->short_insn
&& !fixup
->islong
) ? 2 : 4;
1078 offset
= (insn
->short_insn
) ? 2 : 4;
1080 /* Some fixups are only used internally, thus no howto. */
1081 if ((int) fixup
->reloc
== 0)
1082 as_fatal (_("Unhandled reloc type"));
1084 if ((int) fixup
->reloc
< 0)
1086 /* FIXME! the reloc size is wrong in the BFD file.
1087 When it is fixed please enable me.
1088 size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
1089 pcrel
= fixup
->pcrel
;
1093 reloc_howto_type
*reloc_howto
=
1094 bfd_reloc_type_lookup (stdoutput
,
1095 (bfd_reloc_code_real_type
) fixup
->reloc
);
1096 gas_assert (reloc_howto
);
1098 /* FIXME! the reloc size is wrong in the BFD file.
1099 When it is fixed please enable me.
1100 size = bfd_get_reloc_size (reloc_howto); */
1101 pcrel
= reloc_howto
->pc_relative
;
1104 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1106 fragP
->fr_file
, fragP
->fr_line
,
1107 (fixup
->reloc
< 0) ? "Internal" :
1108 bfd_get_reloc_code_name (fixup
->reloc
),
1111 fix_new_exp (fragP
, fix
+ offset
,
1112 size
, &fixup
->exp
, pcrel
, fixup
->reloc
);
1114 /* Check for ZOLs, and update symbol info if any. */
1115 if (LP_INSN (insn
->insn
))
1117 gas_assert (fixup
->exp
.X_add_symbol
);
1118 ARC_SET_FLAG (fixup
->exp
.X_add_symbol
, ARC_FLAG_ZOL
);
1123 /* Actually output an instruction with its fixup. */
1126 emit_insn0 (struct arc_insn
*insn
, char *where
, bfd_boolean relax
)
1130 pr_debug ("Emit insn : 0x%x\n", insn
->insn
);
1131 pr_debug ("\tShort : 0x%d\n", insn
->short_insn
);
1132 pr_debug ("\tLong imm: 0x%lx\n", insn
->limm
);
1134 /* Write out the instruction. */
1135 if (insn
->short_insn
)
1141 md_number_to_chars (f
, insn
->insn
, 2);
1142 md_number_to_chars_midend (f
+ 2, insn
->limm
, 4);
1143 dwarf2_emit_insn (6);
1149 md_number_to_chars (f
, insn
->insn
, 2);
1150 dwarf2_emit_insn (2);
1159 md_number_to_chars_midend (f
, insn
->insn
, 4);
1160 md_number_to_chars_midend (f
+ 4, insn
->limm
, 4);
1161 dwarf2_emit_insn (8);
1167 md_number_to_chars_midend (f
, insn
->insn
, 4);
1168 dwarf2_emit_insn (4);
1173 apply_fixups (insn
, frag_now
, (f
- frag_now
->fr_literal
));
1177 emit_insn1 (struct arc_insn
*insn
)
1179 /* How frag_var's args are currently configured:
1180 - rs_machine_dependent, to dictate it's a relaxation frag.
1181 - FRAG_MAX_GROWTH, maximum size of instruction
1182 - 0, variable size that might grow...unused by generic relaxation.
1183 - frag_now->fr_subtype, fr_subtype starting value, set previously.
1184 - s, opand expression.
1185 - 0, offset but it's unused.
1186 - 0, opcode but it's unused. */
1187 symbolS
*s
= make_expr_symbol (&insn
->fixups
[0].exp
);
1188 frag_now
->tc_frag_data
.pcrel
= insn
->fixups
[0].pcrel
;
1190 if (frag_room () < FRAG_MAX_GROWTH
)
1192 /* Handle differently when frag literal memory is exhausted.
1193 This is used because when there's not enough memory left in
1194 the current frag, a new frag is created and the information
1195 we put into frag_now->tc_frag_data is disregarded. */
1197 struct arc_relax_type relax_info_copy
;
1198 relax_substateT subtype
= frag_now
->fr_subtype
;
1200 memcpy (&relax_info_copy
, &frag_now
->tc_frag_data
,
1201 sizeof (struct arc_relax_type
));
1203 frag_wane (frag_now
);
1204 frag_grow (FRAG_MAX_GROWTH
);
1206 memcpy (&frag_now
->tc_frag_data
, &relax_info_copy
,
1207 sizeof (struct arc_relax_type
));
1209 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1213 frag_var (rs_machine_dependent
, FRAG_MAX_GROWTH
, 0,
1214 frag_now
->fr_subtype
, s
, 0, 0);
1218 emit_insn (struct arc_insn
*insn
)
1223 emit_insn0 (insn
, NULL
, FALSE
);
1226 /* Check whether a symbol involves a register. */
1229 contains_register (symbolS
*sym
)
1233 expressionS
*ex
= symbol_get_value_expression (sym
);
1235 return ((O_register
== ex
->X_op
)
1236 && !contains_register (ex
->X_add_symbol
)
1237 && !contains_register (ex
->X_op_symbol
));
1243 /* Returns the register number within a symbol. */
1246 get_register (symbolS
*sym
)
1248 if (!contains_register (sym
))
1251 expressionS
*ex
= symbol_get_value_expression (sym
);
1252 return regno (ex
->X_add_number
);
1255 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1256 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1259 generic_reloc_p (extended_bfd_reloc_code_real_type reloc
)
1266 case BFD_RELOC_ARC_SDA_LDST
:
1267 case BFD_RELOC_ARC_SDA_LDST1
:
1268 case BFD_RELOC_ARC_SDA_LDST2
:
1269 case BFD_RELOC_ARC_SDA16_LD
:
1270 case BFD_RELOC_ARC_SDA16_LD1
:
1271 case BFD_RELOC_ARC_SDA16_LD2
:
1272 case BFD_RELOC_ARC_SDA16_ST2
:
1273 case BFD_RELOC_ARC_SDA32_ME
:
1280 /* Allocates a tok entry. */
1283 allocate_tok (expressionS
*tok
, int ntok
, int cidx
)
1285 if (ntok
> MAX_INSN_ARGS
- 2)
1286 return 0; /* No space left. */
1289 return 0; /* Incorect args. */
1291 memcpy (&tok
[ntok
+1], &tok
[ntok
], sizeof (*tok
));
1294 return 1; /* Success. */
1295 return allocate_tok (tok
, ntok
- 1, cidx
);
1298 /* Search forward through all variants of an opcode looking for a
1301 static const struct arc_opcode
*
1302 find_opcode_match (const struct arc_opcode
*first_opcode
,
1305 struct arc_flags
*first_pflag
,
1309 const struct arc_opcode
*opcode
= first_opcode
;
1311 int got_cpu_match
= 0;
1312 expressionS bktok
[MAX_INSN_ARGS
];
1316 memset (&emptyE
, 0, sizeof (emptyE
));
1317 memcpy (bktok
, tok
, MAX_INSN_ARGS
* sizeof (*tok
));
1322 const unsigned char *opidx
;
1323 const unsigned char *flgidx
;
1325 const expressionS
*t
= &emptyE
;
1327 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
1328 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->opcode
);
1330 /* Don't match opcodes that don't exist on this
1332 if (!(opcode
->cpu
& arc_target
))
1335 if (is_code_density_p (opcode
) && !(arc_features
& ARC_CD
))
1341 /* Check the operands. */
1342 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1344 const struct arc_operand
*operand
= &arc_operands
[*opidx
];
1346 /* Only take input from real operands. */
1347 if ((operand
->flags
& ARC_OPERAND_FAKE
)
1348 && !(operand
->flags
& ARC_OPERAND_BRAKET
))
1351 /* When we expect input, make sure we have it. */
1355 /* Match operand type with expression type. */
1356 switch (operand
->flags
& ARC_OPERAND_TYPECHECK_MASK
)
1358 case ARC_OPERAND_IR
:
1359 /* Check to be a register. */
1360 if ((tok
[tokidx
].X_op
!= O_register
1361 || !is_ir_num (tok
[tokidx
].X_add_number
))
1362 && !(operand
->flags
& ARC_OPERAND_IGNORE
))
1365 /* If expect duplicate, make sure it is duplicate. */
1366 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1368 /* Check for duplicate. */
1369 if (t
->X_op
!= O_register
1370 || !is_ir_num (t
->X_add_number
)
1371 || (regno (t
->X_add_number
) !=
1372 regno (tok
[tokidx
].X_add_number
)))
1376 /* Special handling? */
1377 if (operand
->insert
)
1379 const char *errmsg
= NULL
;
1380 (*operand
->insert
)(0,
1381 regno (tok
[tokidx
].X_add_number
),
1385 if (operand
->flags
& ARC_OPERAND_IGNORE
)
1387 /* Missing argument, create one. */
1388 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1391 tok
[tokidx
].X_op
= O_absent
;
1402 case ARC_OPERAND_BRAKET
:
1403 /* Check if bracket is also in opcode table as
1405 if (tok
[tokidx
].X_op
!= O_bracket
)
1409 case ARC_OPERAND_LIMM
:
1410 case ARC_OPERAND_SIGNED
:
1411 case ARC_OPERAND_UNSIGNED
:
1412 switch (tok
[tokidx
].X_op
)
1420 /* Got an (too) early bracket, check if it is an
1421 ignored operand. N.B. This procedure works only
1422 when bracket is the last operand! */
1423 if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
1425 /* Insert the missing operand. */
1426 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
1429 tok
[tokidx
].X_op
= O_absent
;
1434 /* Check the range. */
1435 if (operand
->bits
!= 32
1436 && !(operand
->flags
& ARC_OPERAND_NCHK
))
1438 offsetT min
, max
, val
;
1439 val
= tok
[tokidx
].X_add_number
;
1441 if (operand
->flags
& ARC_OPERAND_SIGNED
)
1443 max
= (1 << (operand
->bits
- 1)) - 1;
1444 min
= -(1 << (operand
->bits
- 1));
1448 max
= (1 << operand
->bits
) - 1;
1452 if (val
< min
|| val
> max
)
1455 /* Check alignmets. */
1456 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
1460 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
1464 else if (operand
->flags
& ARC_OPERAND_NCHK
)
1466 if (operand
->insert
)
1468 const char *errmsg
= NULL
;
1469 (*operand
->insert
)(0,
1470 tok
[tokidx
].X_add_number
,
1481 /* Check if it is register range. */
1482 if ((tok
[tokidx
].X_add_number
== 0)
1483 && contains_register (tok
[tokidx
].X_add_symbol
)
1484 && contains_register (tok
[tokidx
].X_op_symbol
))
1488 regs
= get_register (tok
[tokidx
].X_add_symbol
);
1490 regs
|= get_register (tok
[tokidx
].X_op_symbol
);
1491 if (operand
->insert
)
1493 const char *errmsg
= NULL
;
1494 (*operand
->insert
)(0,
1505 if (operand
->default_reloc
== 0)
1506 goto match_failed
; /* The operand needs relocation. */
1508 /* Relocs requiring long immediate. FIXME! make it
1509 generic and move it to a function. */
1510 switch (tok
[tokidx
].X_md
)
1519 if (!(operand
->flags
& ARC_OPERAND_LIMM
))
1522 if (!generic_reloc_p (operand
->default_reloc
))
1529 /* If expect duplicate, make sure it is duplicate. */
1530 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
1532 if (t
->X_op
== O_illegal
1533 || t
->X_op
== O_absent
1534 || t
->X_op
== O_register
1535 || (t
->X_add_number
!= tok
[tokidx
].X_add_number
))
1542 /* Everything else should have been fake. */
1550 /* Check the flags. Iterate over the valid flag classes. */
1553 for (flgidx
= opcode
->flags
; *flgidx
&& lnflg
; ++flgidx
)
1555 /* Get a valid flag class. */
1556 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
1557 const unsigned *flgopridx
;
1559 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
1561 const struct arc_flag_operand
*flg_operand
;
1562 struct arc_flags
*pflag
= first_pflag
;
1565 flg_operand
= &arc_flag_operands
[*flgopridx
];
1566 for (i
= 0; i
< nflgs
; i
++, pflag
++)
1568 /* Match against the parsed flags. */
1569 if (!strcmp (flg_operand
->name
, pflag
->name
))
1571 /*TODO: Check if it is duplicated. */
1572 pflag
->code
= *flgopridx
;
1574 break; /* goto next flag class and parsed flag. */
1579 /* Did I check all the parsed flags? */
1584 /* Possible match -- did we use all of our input? */
1594 /* Restore the original parameters. */
1595 memcpy (tok
, bktok
, MAX_INSN_ARGS
* sizeof (*tok
));
1598 while (++opcode
- arc_opcodes
< (int) arc_num_opcodes
1599 && !strcmp (opcode
->name
, first_opcode
->name
));
1602 *pcpumatch
= got_cpu_match
;
1607 /* Swap operand tokens. */
1610 swap_operand (expressionS
*operand_array
,
1612 unsigned destination
)
1614 expressionS cpy_operand
;
1615 expressionS
*src_operand
;
1616 expressionS
*dst_operand
;
1619 if (source
== destination
)
1622 src_operand
= &operand_array
[source
];
1623 dst_operand
= &operand_array
[destination
];
1624 size
= sizeof (expressionS
);
1626 /* Make copy of operand to swap with and swap. */
1627 memcpy (&cpy_operand
, dst_operand
, size
);
1628 memcpy (dst_operand
, src_operand
, size
);
1629 memcpy (src_operand
, &cpy_operand
, size
);
1632 /* Check if *op matches *tok type.
1633 Returns FALSE if they don't match, TRUE if they match. */
1636 pseudo_operand_match (const expressionS
*tok
,
1637 const struct arc_operand_operation
*op
)
1639 offsetT min
, max
, val
;
1641 const struct arc_operand
*operand_real
= &arc_operands
[op
->operand_idx
];
1647 if (operand_real
->bits
== 32 && (operand_real
->flags
& ARC_OPERAND_LIMM
))
1649 else if (!(operand_real
->flags
& ARC_OPERAND_IR
))
1651 val
= tok
->X_add_number
+ op
->count
;
1652 if (operand_real
->flags
& ARC_OPERAND_SIGNED
)
1654 max
= (1 << (operand_real
->bits
- 1)) - 1;
1655 min
= -(1 << (operand_real
->bits
- 1));
1659 max
= (1 << operand_real
->bits
) - 1;
1662 if (min
<= val
&& val
<= max
)
1668 /* Handle all symbols as long immediates or signed 9. */
1669 if (operand_real
->flags
& ARC_OPERAND_LIMM
||
1670 ((operand_real
->flags
& ARC_OPERAND_SIGNED
) && operand_real
->bits
== 9))
1675 if (operand_real
->flags
& ARC_OPERAND_IR
)
1680 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
1691 /* Find pseudo instruction in array. */
1693 static const struct arc_pseudo_insn
*
1694 find_pseudo_insn (const char *opname
,
1696 const expressionS
*tok
)
1698 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
1699 const struct arc_operand_operation
*op
;
1703 for (i
= 0; i
< arc_num_pseudo_insn
; ++i
)
1705 pseudo_insn
= &arc_pseudo_insns
[i
];
1706 if (strcmp (pseudo_insn
->mnemonic_p
, opname
) == 0)
1708 op
= pseudo_insn
->operand
;
1709 for (j
= 0; j
< ntok
; ++j
)
1710 if (!pseudo_operand_match (&tok
[j
], &op
[j
]))
1713 /* Found the right instruction. */
1721 /* Assumes the expressionS *tok is of sufficient size. */
1723 static const struct arc_opcode
*
1724 find_special_case_pseudo (const char *opname
,
1728 struct arc_flags
*pflags
)
1730 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
1731 const struct arc_operand_operation
*operand_pseudo
;
1732 const struct arc_operand
*operand_real
;
1734 char construct_operand
[MAX_CONSTR_STR
];
1736 /* Find whether opname is in pseudo instruction array. */
1737 pseudo_insn
= find_pseudo_insn (opname
, *ntok
, tok
);
1739 if (pseudo_insn
== NULL
)
1742 /* Handle flag, Limited to one flag at the moment. */
1743 if (pseudo_insn
->flag_r
!= NULL
)
1744 *nflgs
+= tokenize_flags (pseudo_insn
->flag_r
, &pflags
[*nflgs
],
1745 MAX_INSN_FLGS
- *nflgs
);
1747 /* Handle operand operations. */
1748 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
1750 operand_pseudo
= &pseudo_insn
->operand
[i
];
1751 operand_real
= &arc_operands
[operand_pseudo
->operand_idx
];
1753 if (operand_real
->flags
& ARC_OPERAND_BRAKET
&&
1754 !operand_pseudo
->needs_insert
)
1757 /* Has to be inserted (i.e. this token does not exist yet). */
1758 if (operand_pseudo
->needs_insert
)
1760 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
1762 tok
[i
].X_op
= O_bracket
;
1767 /* Check if operand is a register or constant and handle it
1769 if (operand_real
->flags
& ARC_OPERAND_IR
)
1770 snprintf (construct_operand
, MAX_CONSTR_STR
, "r%d",
1771 operand_pseudo
->count
);
1773 snprintf (construct_operand
, MAX_CONSTR_STR
, "%d",
1774 operand_pseudo
->count
);
1776 tokenize_arguments (construct_operand
, &tok
[i
], 1);
1780 else if (operand_pseudo
->count
)
1782 /* Operand number has to be adjusted accordingly (by operand
1784 switch (tok
[i
].X_op
)
1787 tok
[i
].X_add_number
+= operand_pseudo
->count
;
1800 /* Swap operands if necessary. Only supports one swap at the
1802 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
1804 operand_pseudo
= &pseudo_insn
->operand
[i
];
1806 if (operand_pseudo
->swap_operand_idx
== i
)
1809 swap_operand (tok
, i
, operand_pseudo
->swap_operand_idx
);
1811 /* Prevent a swap back later by breaking out. */
1815 return (const struct arc_opcode
*)
1816 hash_find (arc_opcode_hash
, pseudo_insn
->mnemonic_r
);
1819 static const struct arc_opcode
*
1820 find_special_case_flag (const char *opname
,
1822 struct arc_flags
*pflags
)
1826 unsigned flag_idx
, flag_arr_idx
;
1827 size_t flaglen
, oplen
;
1828 const struct arc_flag_special
*arc_flag_special_opcode
;
1829 const struct arc_opcode
*opcode
;
1831 /* Search for special case instruction. */
1832 for (i
= 0; i
< arc_num_flag_special
; i
++)
1834 arc_flag_special_opcode
= &arc_flag_special_cases
[i
];
1835 oplen
= strlen (arc_flag_special_opcode
->name
);
1837 if (strncmp (opname
, arc_flag_special_opcode
->name
, oplen
) != 0)
1840 /* Found a potential special case instruction, now test for
1842 for (flag_arr_idx
= 0;; ++flag_arr_idx
)
1844 flag_idx
= arc_flag_special_opcode
->flags
[flag_arr_idx
];
1846 break; /* End of array, nothing found. */
1848 flagnm
= arc_flag_operands
[flag_idx
].name
;
1849 flaglen
= strlen (flagnm
);
1850 if (strcmp (opname
+ oplen
, flagnm
) == 0)
1852 opcode
= (const struct arc_opcode
*)
1853 hash_find (arc_opcode_hash
,
1854 arc_flag_special_opcode
->name
);
1856 if (*nflgs
+ 1 > MAX_INSN_FLGS
)
1858 memcpy (pflags
[*nflgs
].name
, flagnm
, flaglen
);
1859 pflags
[*nflgs
].name
[flaglen
] = '\0';
1868 /* Used to find special case opcode. */
1870 static const struct arc_opcode
*
1871 find_special_case (const char *opname
,
1873 struct arc_flags
*pflags
,
1877 const struct arc_opcode
*opcode
;
1879 opcode
= find_special_case_pseudo (opname
, ntok
, tok
, nflgs
, pflags
);
1882 opcode
= find_special_case_flag (opname
, nflgs
, pflags
);
1888 preprocess_operands (const struct arc_opcode
*opcode
,
1896 const struct arc_aux_reg
*auxr
;
1898 for (i
= 0; i
< ntok
; i
++)
1900 switch (tok
[i
].X_op
)
1904 break; /* Throw and error. */
1907 if (opcode
->class != AUXREG
)
1909 /* Convert the symbol to a constant if possible. */
1910 p
= S_GET_NAME (tok
[i
].X_add_symbol
);
1913 auxr
= &arc_aux_regs
[0];
1914 for (j
= 0; j
< arc_num_aux_regs
; j
++, auxr
++)
1915 if (len
== auxr
->length
1916 && strcasecmp (auxr
->name
, p
) == 0)
1918 tok
[i
].X_op
= O_constant
;
1919 tok
[i
].X_add_number
= auxr
->address
;
1929 /* Given an opcode name, pre-tockenized set of argumenst and the
1930 opcode flags, take it all the way through emission. */
1933 assemble_tokens (const char *opname
,
1936 struct arc_flags
*pflags
,
1939 bfd_boolean found_something
= FALSE
;
1940 const struct arc_opcode
*opcode
;
1943 /* Search opcodes. */
1944 opcode
= (const struct arc_opcode
*) hash_find (arc_opcode_hash
, opname
);
1946 /* Couldn't find opcode conventional way, try special cases. */
1948 opcode
= find_special_case (opname
, &nflgs
, pflags
, tok
, &ntok
);
1952 pr_debug ("%s:%d: assemble_tokens: %s trying opcode 0x%08X\n",
1953 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->name
,
1956 preprocess_operands (opcode
, tok
, ntok
);
1958 found_something
= TRUE
;
1959 opcode
= find_opcode_match (opcode
, tok
, &ntok
, pflags
, nflgs
, &cpumatch
);
1962 struct arc_insn insn
;
1963 assemble_insn (opcode
, tok
, ntok
, pflags
, nflgs
, &insn
);
1969 if (found_something
)
1972 as_bad (_("inappropriate arguments for opcode '%s'"), opname
);
1974 as_bad (_("opcode '%s' not supported for target %s"), opname
,
1978 as_bad (_("unknown opcode '%s'"), opname
);
1981 /* The public interface to the instruction assembler. */
1984 md_assemble (char *str
)
1987 expressionS tok
[MAX_INSN_ARGS
];
1990 struct arc_flags flags
[MAX_INSN_FLGS
];
1992 /* Split off the opcode. */
1993 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_0123468");
1994 opname
= xmalloc (opnamelen
+ 1);
1995 memcpy (opname
, str
, opnamelen
);
1996 opname
[opnamelen
] = '\0';
1998 /* Signalize we are assmbling the instructions. */
1999 assembling_insn
= TRUE
;
2001 /* Tokenize the flags. */
2002 if ((nflg
= tokenize_flags (str
+ opnamelen
, flags
, MAX_INSN_FLGS
)) == -1)
2004 as_bad (_("syntax error"));
2008 /* Scan up to the end of the mnemonic which must end in space or end
2011 for (; *str
!= '\0'; str
++)
2015 /* Tokenize the rest of the line. */
2016 if ((ntok
= tokenize_arguments (str
, tok
, MAX_INSN_ARGS
)) < 0)
2018 as_bad (_("syntax error"));
2022 /* Finish it off. */
2023 assemble_tokens (opname
, tok
, ntok
, flags
, nflg
);
2024 assembling_insn
= FALSE
;
2027 /* Callback to insert a register into the hash table. */
2030 declare_register (char *name
, int number
)
2033 symbolS
*regS
= symbol_create (name
, reg_section
,
2034 number
, &zero_address_frag
);
2036 err
= hash_insert (arc_reg_hash
, S_GET_NAME (regS
), (void *) regS
);
2038 as_fatal ("Inserting \"%s\" into register table failed: %s",
2042 /* Construct symbols for each of the general registers. */
2045 declare_register_set (void)
2048 for (i
= 0; i
< 64; ++i
)
2052 sprintf (name
, "r%d", i
);
2053 declare_register (name
, i
);
2054 if ((i
& 0x01) == 0)
2056 sprintf (name
, "r%dr%d", i
, i
+1);
2057 declare_register (name
, i
);
2062 /* Port-specific assembler initialization. This function is called
2063 once, at assembler startup time. */
2070 /* The endianness can be chosen "at the factory". */
2071 target_big_endian
= byte_order
== BIG_ENDIAN
;
2073 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, arc_mach_type
))
2074 as_warn (_("could not set architecture and machine"));
2076 /* Set elf header flags. */
2077 bfd_set_private_flags (stdoutput
, arc_eflag
);
2079 /* Set up a hash table for the instructions. */
2080 arc_opcode_hash
= hash_new ();
2081 if (arc_opcode_hash
== NULL
)
2082 as_fatal (_("Virtual memory exhausted"));
2084 /* Initialize the hash table with the insns. */
2085 for (i
= 0; i
< arc_num_opcodes
;)
2087 const char *name
, *retval
;
2089 name
= arc_opcodes
[i
].name
;
2090 retval
= hash_insert (arc_opcode_hash
, name
, (void *) &arc_opcodes
[i
]);
2092 as_fatal (_("internal error: can't hash opcode '%s': %s"),
2095 while (++i
< arc_num_opcodes
2096 && (arc_opcodes
[i
].name
== name
2097 || !strcmp (arc_opcodes
[i
].name
, name
)))
2101 /* Register declaration. */
2102 arc_reg_hash
= hash_new ();
2103 if (arc_reg_hash
== NULL
)
2104 as_fatal (_("Virtual memory exhausted"));
2106 declare_register_set ();
2107 declare_register ("gp", 26);
2108 declare_register ("fp", 27);
2109 declare_register ("sp", 28);
2110 declare_register ("ilink", 29);
2111 declare_register ("ilink1", 29);
2112 declare_register ("ilink2", 30);
2113 declare_register ("blink", 31);
2115 declare_register ("mlo", 57);
2116 declare_register ("mmid", 58);
2117 declare_register ("mhi", 59);
2119 declare_register ("acc1", 56);
2120 declare_register ("acc2", 57);
2122 declare_register ("lp_count", 60);
2123 declare_register ("pcl", 63);
2125 /* Initialize the last instructions. */
2126 memset (&arc_last_insns
[0], 0, sizeof (arc_last_insns
));
2129 /* Write a value out to the object file, using the appropriate
2133 md_number_to_chars (char *buf
,
2137 if (target_big_endian
)
2138 number_to_chars_bigendian (buf
, val
, n
);
2140 number_to_chars_littleendian (buf
, val
, n
);
2143 /* Round up a section size to the appropriate boundary. */
2146 md_section_align (segT segment
,
2149 int align
= bfd_get_section_alignment (stdoutput
, segment
);
2151 return ((size
+ (1 << align
) - 1) & (-((valueT
) 1 << align
)));
2154 /* The location from which a PC relative jump should be calculated,
2155 given a PC relative reloc. */
2158 md_pcrel_from_section (fixS
*fixP
,
2161 offsetT base
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2163 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP
->fx_offset
);
2165 if (fixP
->fx_addsy
!= (symbolS
*) NULL
2166 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2167 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
2169 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP
->fx_addsy
));
2171 /* The symbol is undefined (or is defined but not in this section).
2172 Let the linker figure it out. */
2176 if ((int) fixP
->fx_r_type
< 0)
2178 /* These are the "internal" relocations. Align them to
2179 32 bit boundary (PCL), for the moment. */
2184 switch (fixP
->fx_r_type
)
2186 case BFD_RELOC_ARC_PC32
:
2187 /* The hardware calculates relative to the start of the
2188 insn, but this relocation is relative to location of the
2189 LIMM, compensate. The base always needs to be
2190 substracted by 4 as we do not support this type of PCrel
2191 relocation for short instructions. */
2194 case BFD_RELOC_ARC_PLT32
:
2195 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2196 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2197 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2198 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2200 case BFD_RELOC_ARC_S21H_PCREL
:
2201 case BFD_RELOC_ARC_S25H_PCREL
:
2202 case BFD_RELOC_ARC_S13_PCREL
:
2203 case BFD_RELOC_ARC_S21W_PCREL
:
2204 case BFD_RELOC_ARC_S25W_PCREL
:
2208 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2209 _("unhandled reloc %s in md_pcrel_from_section"),
2210 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2215 pr_debug ("pcrel from %x + %lx = %x, symbol: %s (%x)\n",
2216 fixP
->fx_frag
->fr_address
, fixP
->fx_where
, base
,
2217 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "(null)",
2218 fixP
->fx_addsy
? S_GET_VALUE (fixP
->fx_addsy
) : 0);
2223 /* Given a BFD relocation find the coresponding operand. */
2225 static const struct arc_operand
*
2226 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc
)
2230 for (i
= 0; i
< arc_num_operands
; i
++)
2231 if (arc_operands
[i
].default_reloc
== reloc
)
2232 return &arc_operands
[i
];
2236 /* Insert an operand value into an instruction. */
2239 insert_operand (unsigned insn
,
2240 const struct arc_operand
*operand
,
2245 offsetT min
= 0, max
= 0;
2247 if (operand
->bits
!= 32
2248 && !(operand
->flags
& ARC_OPERAND_NCHK
)
2249 && !(operand
->flags
& ARC_OPERAND_FAKE
))
2251 if (operand
->flags
& ARC_OPERAND_SIGNED
)
2253 max
= (1 << (operand
->bits
- 1)) - 1;
2254 min
= -(1 << (operand
->bits
- 1));
2258 max
= (1 << operand
->bits
) - 1;
2262 if (val
< min
|| val
> max
)
2263 as_bad_value_out_of_range (_("operand"),
2264 val
, min
, max
, file
, line
);
2267 pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
2268 min
, val
, max
, insn
);
2270 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
2272 as_bad_where (file
, line
,
2273 _("Unaligned operand. Needs to be 32bit aligned"));
2275 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
2277 as_bad_where (file
, line
,
2278 _("Unaligned operand. Needs to be 16bit aligned"));
2280 if (operand
->insert
)
2282 const char *errmsg
= NULL
;
2284 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2286 as_warn_where (file
, line
, "%s", errmsg
);
2290 if (operand
->flags
& ARC_OPERAND_TRUNCATE
)
2292 if (operand
->flags
& ARC_OPERAND_ALIGNED32
)
2294 if (operand
->flags
& ARC_OPERAND_ALIGNED16
)
2297 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2302 /* Apply a fixup to the object code. At this point all symbol values
2303 should be fully resolved, and we attempt to completely resolve the
2304 reloc. If we can not do that, we determine the correct reloc code
2305 and put it back in the fixup. To indicate that a fixup has been
2306 eliminated, set fixP->fx_done. */
2309 md_apply_fix (fixS
*fixP
,
2313 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2314 valueT value
= *valP
;
2316 symbolS
*fx_addsy
, *fx_subsy
;
2318 segT add_symbol_segment
= absolute_section
;
2319 segT sub_symbol_segment
= absolute_section
;
2320 const struct arc_operand
*operand
= NULL
;
2321 extended_bfd_reloc_code_real_type reloc
;
2323 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2324 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2325 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2326 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2329 fx_addsy
= fixP
->fx_addsy
;
2330 fx_subsy
= fixP
->fx_subsy
;
2335 add_symbol_segment
= S_GET_SEGMENT (fx_addsy
);
2339 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF
2340 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF_S9
2341 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_GD_LD
)
2343 resolve_symbol_value (fx_subsy
);
2344 sub_symbol_segment
= S_GET_SEGMENT (fx_subsy
);
2346 if (sub_symbol_segment
== absolute_section
)
2348 /* The symbol is really a constant. */
2349 fx_offset
-= S_GET_VALUE (fx_subsy
);
2354 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2355 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
2356 fx_addsy
? S_GET_NAME (fx_addsy
) : "0",
2357 segment_name (add_symbol_segment
),
2358 S_GET_NAME (fx_subsy
),
2359 segment_name (sub_symbol_segment
));
2365 && !S_IS_WEAK (fx_addsy
))
2367 if (add_symbol_segment
== seg
2370 value
+= S_GET_VALUE (fx_addsy
);
2371 value
-= md_pcrel_from_section (fixP
, seg
);
2373 fixP
->fx_pcrel
= FALSE
;
2375 else if (add_symbol_segment
== absolute_section
)
2377 value
= fixP
->fx_offset
;
2378 fx_offset
+= S_GET_VALUE (fixP
->fx_addsy
);
2380 fixP
->fx_pcrel
= FALSE
;
2385 fixP
->fx_done
= TRUE
;
2390 && ((S_IS_DEFINED (fx_addsy
)
2391 && S_GET_SEGMENT (fx_addsy
) != seg
)
2392 || S_IS_WEAK (fx_addsy
)))
2393 value
+= md_pcrel_from_section (fixP
, seg
);
2395 switch (fixP
->fx_r_type
)
2397 case BFD_RELOC_ARC_32_ME
:
2398 /* This is a pc-relative value in a LIMM. Adjust it to the
2399 address of the instruction not to the address of the
2400 LIMM. Note: it is not anylonger valid this afirmation as
2401 the linker consider ARC_PC32 a fixup to entire 64 bit
2403 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
;
2406 fixP
->fx_r_type
= BFD_RELOC_ARC_PC32
;
2408 case BFD_RELOC_ARC_PC32
:
2409 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
2412 if ((int) fixP
->fx_r_type
< 0)
2413 as_fatal (_("PC relative relocation not allowed for (internal) type %d"),
2419 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2420 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
2421 ((int) fixP
->fx_r_type
< 0) ? "Internal":
2422 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
2426 /* Now check for TLS relocations. */
2427 reloc
= fixP
->fx_r_type
;
2430 case BFD_RELOC_ARC_TLS_DTPOFF
:
2431 case BFD_RELOC_ARC_TLS_LE_32
:
2435 case BFD_RELOC_ARC_TLS_GD_GOT
:
2436 case BFD_RELOC_ARC_TLS_IE_GOT
:
2437 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2440 case BFD_RELOC_ARC_TLS_GD_LD
:
2441 gas_assert (!fixP
->fx_offset
);
2444 = (S_GET_VALUE (fixP
->fx_subsy
)
2445 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
2446 fixP
->fx_subsy
= NULL
;
2448 case BFD_RELOC_ARC_TLS_GD_CALL
:
2449 /* These two relocs are there just to allow ld to change the tls
2450 model for this symbol, by patching the code. The offset -
2451 and scale, if any - will be installed by the linker. */
2452 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2455 case BFD_RELOC_ARC_TLS_LE_S9
:
2456 case BFD_RELOC_ARC_TLS_DTPOFF_S9
:
2457 as_bad (_("TLS_*_S9 relocs are not supported yet"));
2469 /* Addjust the value if we have a constant. */
2472 /* For hosts with longs bigger than 32-bits make sure that the top
2473 bits of a 32-bit negative value read in by the parser are set,
2474 so that the correct comparisons are made. */
2475 if (value
& 0x80000000)
2476 value
|= (-1L << 31);
2478 reloc
= fixP
->fx_r_type
;
2486 case BFD_RELOC_ARC_32_PCREL
:
2487 md_number_to_chars (fixpos
, value
, fixP
->fx_size
);
2490 case BFD_RELOC_ARC_GOTPC32
:
2491 /* I cannot fix an GOTPC relocation because I need to relax it
2492 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
2493 as_bad (_("Unsupported operation on reloc"));
2496 case BFD_RELOC_ARC_TLS_DTPOFF
:
2497 case BFD_RELOC_ARC_TLS_LE_32
:
2498 gas_assert (!fixP
->fx_addsy
);
2499 gas_assert (!fixP
->fx_subsy
);
2501 case BFD_RELOC_ARC_GOTOFF
:
2502 case BFD_RELOC_ARC_32_ME
:
2503 case BFD_RELOC_ARC_PC32
:
2504 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
2507 case BFD_RELOC_ARC_PLT32
:
2508 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
2511 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
2512 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
2515 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
2516 reloc
= BFD_RELOC_ARC_S21H_PCREL
;
2519 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
2520 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
2523 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
2524 reloc
= BFD_RELOC_ARC_S21W_PCREL
;
2526 case BFD_RELOC_ARC_S25W_PCREL
:
2527 case BFD_RELOC_ARC_S21W_PCREL
:
2528 case BFD_RELOC_ARC_S21H_PCREL
:
2529 case BFD_RELOC_ARC_S25H_PCREL
:
2530 case BFD_RELOC_ARC_S13_PCREL
:
2532 operand
= find_operand_for_reloc (reloc
);
2533 gas_assert (operand
);
2538 if ((int) fixP
->fx_r_type
>= 0)
2539 as_fatal (_("unhandled relocation type %s"),
2540 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2542 /* The rest of these fixups needs to be completely resolved as
2544 if (fixP
->fx_addsy
!= 0
2545 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
2546 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2547 _("non-absolute expression in constant field"));
2549 gas_assert (-(int) fixP
->fx_r_type
< (int) arc_num_operands
);
2550 operand
= &arc_operands
[-(int) fixP
->fx_r_type
];
2555 if (target_big_endian
)
2557 switch (fixP
->fx_size
)
2560 insn
= bfd_getb32 (fixpos
);
2563 insn
= bfd_getb16 (fixpos
);
2566 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2567 _("unknown fixup size"));
2573 switch (fixP
->fx_size
)
2576 insn
= bfd_getl16 (fixpos
) << 16 | bfd_getl16 (fixpos
+ 2);
2579 insn
= bfd_getl16 (fixpos
);
2582 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2583 _("unknown fixup size"));
2587 insn
= insert_operand (insn
, operand
, (offsetT
) value
,
2588 fixP
->fx_file
, fixP
->fx_line
);
2590 md_number_to_chars_midend (fixpos
, insn
, fixP
->fx_size
);
2593 /* Prepare machine-dependent frags for relaxation.
2595 Called just before relaxation starts. Any symbol that is now undefined
2596 will not become defined.
2598 Return the correct fr_subtype in the frag.
2600 Return the initial "guess for fr_var" to caller. The guess for fr_var
2601 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
2602 or fr_var contributes to our returned value.
2604 Although it may not be explicit in the frag, pretend
2605 fr_var starts with a value. */
2608 md_estimate_size_before_relax (fragS
*fragP
,
2613 /* If the symbol is not located within the same section AND it's not
2614 an absolute section, use the maximum. OR if the symbol is a
2615 constant AND the insn is by nature not pc-rel, use the maximum.
2616 OR if the symbol is being equated against another symbol, use the
2617 maximum. OR if the symbol is weak use the maximum. */
2618 if ((S_GET_SEGMENT (fragP
->fr_symbol
) != segment
2619 && S_GET_SEGMENT (fragP
->fr_symbol
) != absolute_section
)
2620 || (symbol_constant_p (fragP
->fr_symbol
)
2621 && !fragP
->tc_frag_data
.pcrel
)
2622 || symbol_equated_p (fragP
->fr_symbol
)
2623 || S_IS_WEAK (fragP
->fr_symbol
))
2625 while (md_relax_table
[fragP
->fr_subtype
].rlx_more
!= ARC_RLX_NONE
)
2626 ++fragP
->fr_subtype
;
2629 growth
= md_relax_table
[fragP
->fr_subtype
].rlx_length
;
2630 fragP
->fr_var
= growth
;
2632 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
2633 fragP
->fr_file
, fragP
->fr_line
, growth
);
2638 /* Translate internal representation of relocation info to BFD target
2642 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
,
2646 bfd_reloc_code_real_type code
;
2648 reloc
= (arelent
*) xmalloc (sizeof (* reloc
));
2649 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2650 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
2651 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
2653 /* Make sure none of our internal relocations make it this far.
2654 They'd better have been fully resolved by this point. */
2655 gas_assert ((int) fixP
->fx_r_type
> 0);
2657 code
= fixP
->fx_r_type
;
2659 /* if we have something like add gp, pcl,
2660 _GLOBAL_OFFSET_TABLE_@gotpc. */
2661 if (code
== BFD_RELOC_ARC_GOTPC32
2663 && fixP
->fx_addsy
== GOT_symbol
)
2664 code
= BFD_RELOC_ARC_GOTPC
;
2666 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2667 if (reloc
->howto
== NULL
)
2669 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2670 _("cannot represent `%s' relocation in object file"),
2671 bfd_get_reloc_code_name (code
));
2675 if (!fixP
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
2676 as_fatal (_("internal error? cannot generate `%s' relocation"),
2677 bfd_get_reloc_code_name (code
));
2679 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
2681 if (code
== BFD_RELOC_ARC_TLS_DTPOFF
2682 || code
== BFD_RELOC_ARC_TLS_DTPOFF_S9
)
2685 = fixP
->fx_subsy
? symbol_get_bfdsym (fixP
->fx_subsy
) : NULL
;
2686 /* We just want to store a 24 bit index, but we have to wait
2687 till after write_contents has been called via
2688 bfd_map_over_sections before we can get the index from
2689 _bfd_elf_symbol_from_bfd_symbol. Thus, the write_relocs
2690 function is elf32-arc.c has to pick up the slack.
2691 Unfortunately, this leads to problems with hosts that have
2692 pointers wider than long (bfd_vma). There would be various
2693 ways to handle this, all error-prone :-( */
2694 reloc
->addend
= (bfd_vma
) sym
;
2695 if ((asymbol
*) reloc
->addend
!= sym
)
2697 as_bad ("Can't store pointer\n");
2702 reloc
->addend
= fixP
->fx_offset
;
2707 /* Perform post-processing of machine-dependent frags after relaxation.
2708 Called after relaxation is finished.
2709 In: Address of frag.
2710 fr_type == rs_machine_dependent.
2711 fr_subtype is what the address relaxed to.
2713 Out: Any fixS:s and constants are set up. */
2716 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
2717 segT segment ATTRIBUTE_UNUSED
,
2720 const relax_typeS
*table_entry
;
2722 const struct arc_opcode
*opcode
;
2723 struct arc_insn insn
;
2725 struct arc_relax_type
*relax_arg
= &fragP
->tc_frag_data
;
2727 fix
= (fragP
->fr_fix
< 0 ? 0 : fragP
->fr_fix
);
2728 dest
= fragP
->fr_literal
+ fix
;
2729 table_entry
= TC_GENERIC_RELAX_TABLE
+ fragP
->fr_subtype
;
2731 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, var: %d\n",
2732 fragP
->fr_file
, fragP
->fr_line
,
2733 fragP
->fr_subtype
, fix
, fragP
->fr_var
);
2735 if (fragP
->fr_subtype
<= 0
2736 && fragP
->fr_subtype
>= arc_num_relax_opcodes
)
2737 as_fatal (_("no relaxation found for this instruction."));
2739 opcode
= &arc_relax_opcodes
[fragP
->fr_subtype
];
2741 assemble_insn (opcode
, relax_arg
->tok
, relax_arg
->ntok
, relax_arg
->pflags
,
2742 relax_arg
->nflg
, &insn
);
2744 apply_fixups (&insn
, fragP
, fix
);
2746 size
= insn
.short_insn
? (insn
.has_limm
? 6 : 2) : (insn
.has_limm
? 8 : 4);
2747 gas_assert (table_entry
->rlx_length
== size
);
2748 emit_insn0 (&insn
, dest
, TRUE
);
2750 fragP
->fr_fix
+= table_entry
->rlx_length
;
2754 /* We have no need to default values of symbols. We could catch
2755 register names here, but that is handled by inserting them all in
2756 the symbol table to begin with. */
2759 md_undefined_symbol (char *name
)
2761 /* The arc abi demands that a GOT[0] should be referencible as
2762 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
2763 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
2765 && (*(name
+1) == 'G')
2766 && (strcmp (name
, GLOBAL_OFFSET_TABLE_NAME
) == 0))
2768 && (*(name
+1) == 'D')
2769 && (strcmp (name
, DYNAMIC_STRUCT_NAME
) == 0)))
2773 if (symbol_find (name
))
2774 as_bad ("GOT already in symbol table");
2776 GOT_symbol
= symbol_new (GLOBAL_OFFSET_TABLE_NAME
, undefined_section
,
2777 (valueT
) 0, &zero_address_frag
);
2784 /* Turn a string in input_line_pointer into a floating point constant
2785 of type type, and store the appropriate bytes in *litP. The number
2786 of LITTLENUMS emitted is stored in *sizeP. An error message is
2787 returned, or NULL on OK. */
2790 md_atof (int type
, char *litP
, int *sizeP
)
2792 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
2795 /* Called for any expression that can not be recognized. When the
2796 function is called, `input_line_pointer' will point to the start of
2800 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
2802 char *p
= input_line_pointer
;
2805 input_line_pointer
++;
2806 expressionP
->X_op
= O_symbol
;
2807 expression (expressionP
);
2811 /* This function is called from the function 'expression', it attempts
2812 to parse special names (in our case register names). It fills in
2813 the expression with the identified register. It returns TRUE if
2814 it is a register and FALSE otherwise. */
2817 arc_parse_name (const char *name
,
2818 struct expressionS
*e
)
2822 if (!assembling_insn
)
2825 /* Handle only registers. */
2826 if (e
->X_op
!= O_absent
)
2829 sym
= hash_find (arc_reg_hash
, name
);
2832 e
->X_op
= O_register
;
2833 e
->X_add_number
= S_GET_VALUE (sym
);
2840 Invocation line includes a switch not recognized by the base assembler.
2841 See if it's a processor-specific option.
2843 New options (supported) are:
2845 -mcpu=<cpu name> Assemble for selected processor
2846 -EB/-mbig-endian Big-endian
2847 -EL/-mlittle-endian Little-endian
2848 -mrelax Enable relaxation
2850 The following CPU names are recognized:
2851 arc700, av2em, av2hs. */
2854 md_parse_option (int c
, char *arg ATTRIBUTE_UNUSED
)
2856 int cpu_flags
= EF_ARC_CPU_GENERIC
;
2862 return md_parse_option (OPTION_MCPU
, "arc600");
2865 return md_parse_option (OPTION_MCPU
, "arc700");
2868 return md_parse_option (OPTION_MCPU
, "arcem");
2871 return md_parse_option (OPTION_MCPU
, "archs");
2876 char *s
= alloca (strlen (arg
) + 1);
2883 *t
= TOLOWER (*arg1
++);
2887 for (i
= 0; cpu_types
[i
].name
; ++i
)
2889 if (!strcmp (cpu_types
[i
].name
, s
))
2891 arc_target
= cpu_types
[i
].flags
;
2892 arc_target_name
= cpu_types
[i
].name
;
2893 arc_features
= cpu_types
[i
].features
;
2894 arc_mach_type
= cpu_types
[i
].mach
;
2895 cpu_flags
= cpu_types
[i
].eflags
;
2897 mach_type_specified_p
= 1;
2902 if (!cpu_types
[i
].name
)
2904 as_fatal (_("unknown architecture: %s\n"), arg
);
2910 arc_target_format
= "elf32-bigarc";
2911 byte_order
= BIG_ENDIAN
;
2915 arc_target_format
= "elf32-littlearc";
2916 byte_order
= LITTLE_ENDIAN
;
2920 /* This option has an effect only on ARC EM. */
2921 if (arc_target
& ARC_OPCODE_ARCv2EM
)
2922 arc_features
|= ARC_CD
;
2926 relaxation_state
= 1;
2929 case OPTION_USER_MODE
:
2930 case OPTION_LD_EXT_MASK
:
2933 case OPTION_BARREL_SHIFT
:
2934 case OPTION_MIN_MAX
:
2941 case OPTION_XMAC_D16
:
2942 case OPTION_XMAC_24
:
2943 case OPTION_DSP_PACKA
:
2946 case OPTION_TELEPHONY
:
2947 case OPTION_XYMEMORY
:
2952 /* Dummy options are accepted but have no effect. */
2959 if (cpu_flags
!= EF_ARC_CPU_GENERIC
)
2960 arc_eflag
= (arc_eflag
& ~EF_ARC_MACH_MSK
) | cpu_flags
;
2966 md_show_usage (FILE *stream
)
2968 fprintf (stream
, _("ARC-specific assembler options:\n"));
2970 fprintf (stream
, " -mcpu=<cpu name>\t assemble for CPU <cpu name>\n");
2972 " -mcode-density\t enable code density option for ARC EM\n");
2974 fprintf (stream
, _("\
2975 -EB assemble code for a big-endian cpu\n"));
2976 fprintf (stream
, _("\
2977 -EL assemble code for a little-endian cpu\n"));
2978 fprintf (stream
, _("\
2979 -mrelax Enable relaxation\n"));
2983 /* Find the proper relocation for the given opcode. */
2985 static extended_bfd_reloc_code_real_type
2986 find_reloc (const char *name
,
2987 const char *opcodename
,
2988 const struct arc_flags
*pflags
,
2990 extended_bfd_reloc_code_real_type reloc
)
2994 bfd_boolean found_flag
, tmp
;
2995 extended_bfd_reloc_code_real_type ret
= BFD_RELOC_UNUSED
;
2997 for (i
= 0; i
< arc_num_equiv_tab
; i
++)
2999 const struct arc_reloc_equiv_tab
*r
= &arc_reloc_equiv
[i
];
3001 /* Find the entry. */
3002 if (strcmp (name
, r
->name
))
3004 if (r
->mnemonic
&& (strcmp (r
->mnemonic
, opcodename
)))
3011 unsigned * psflg
= (unsigned *)r
->flags
;
3015 for (j
= 0; j
< nflg
; j
++)
3016 if (!strcmp (pflags
[j
].name
,
3017 arc_flag_operands
[*psflg
].name
))
3038 if (reloc
!= r
->oldreloc
)
3045 if (ret
== BFD_RELOC_UNUSED
)
3046 as_bad (_("Unable to find %s relocation for instruction %s"),
3051 /* All the symbol types that are allowed to be used for
3055 may_relax_expr (expressionS tok
)
3057 /* Check if we have unrelaxable relocs. */
3082 /* Checks if flags are in line with relaxable insn. */
3085 relaxable_flag (const struct arc_relaxable_ins
*ins
,
3086 const struct arc_flags
*pflags
,
3089 unsigned flag_class
,
3094 const struct arc_flag_operand
*flag_opand
;
3095 int i
, counttrue
= 0;
3097 /* Iterate through flags classes. */
3098 while ((flag_class
= ins
->flag_classes
[flag_class_idx
]) != 0)
3100 /* Iterate through flags in flag class. */
3101 while ((flag
= arc_flag_classes
[flag_class
].flags
[flag_idx
])
3104 flag_opand
= &arc_flag_operands
[flag
];
3105 /* Iterate through flags in ins to compare. */
3106 for (i
= 0; i
< nflgs
; ++i
)
3108 if (strcmp (flag_opand
->name
, pflags
[i
].name
) == 0)
3119 /* If counttrue == nflgs, then all flags have been found. */
3120 return (counttrue
== nflgs
? TRUE
: FALSE
);
3123 /* Checks if operands are in line with relaxable insn. */
3126 relaxable_operand (const struct arc_relaxable_ins
*ins
,
3127 const expressionS
*tok
,
3130 const enum rlx_operand_type
*operand
= &ins
->operands
[0];
3133 while (*operand
!= EMPTY
)
3135 const expressionS
*epr
= &tok
[i
];
3137 if (i
!= 0 && i
>= ntok
)
3143 if (!(epr
->X_op
== O_multiply
3144 || epr
->X_op
== O_divide
3145 || epr
->X_op
== O_modulus
3146 || epr
->X_op
== O_add
3147 || epr
->X_op
== O_subtract
3148 || epr
->X_op
== O_symbol
))
3154 || (epr
->X_add_number
!= tok
[i
- 1].X_add_number
))
3158 if (epr
->X_op
!= O_register
)
3163 if (epr
->X_op
!= O_register
)
3166 switch (epr
->X_add_number
)
3168 case 0: case 1: case 2: case 3:
3169 case 12: case 13: case 14: case 15:
3176 case REGISTER_NO_GP
:
3177 if ((epr
->X_op
!= O_register
)
3178 || (epr
->X_add_number
== 26)) /* 26 is the gp register. */
3183 if (epr
->X_op
!= O_bracket
)
3188 /* Don't understand, bail out. */
3194 operand
= &ins
->operands
[i
];
3197 return (i
== ntok
? TRUE
: FALSE
);
3200 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3203 relax_insn_p (const struct arc_opcode
*opcode
,
3204 const expressionS
*tok
,
3206 const struct arc_flags
*pflags
,
3210 bfd_boolean rv
= FALSE
;
3212 /* Check the relaxation table. */
3213 for (i
= 0; i
< arc_num_relaxable_ins
&& relaxation_state
; ++i
)
3215 const struct arc_relaxable_ins
*arc_rlx_ins
= &arc_relaxable_insns
[i
];
3217 if ((strcmp (opcode
->name
, arc_rlx_ins
->mnemonic_r
) == 0)
3218 && may_relax_expr (tok
[arc_rlx_ins
->opcheckidx
])
3219 && relaxable_operand (arc_rlx_ins
, tok
, ntok
)
3220 && relaxable_flag (arc_rlx_ins
, pflags
, nflg
))
3223 frag_now
->fr_subtype
= arc_relaxable_insns
[i
].subtype
;
3224 memcpy (&frag_now
->tc_frag_data
.tok
, tok
,
3225 sizeof (expressionS
) * ntok
);
3226 memcpy (&frag_now
->tc_frag_data
.pflags
, pflags
,
3227 sizeof (struct arc_flags
) * nflg
);
3228 frag_now
->tc_frag_data
.nflg
= nflg
;
3229 frag_now
->tc_frag_data
.ntok
= ntok
;
3237 /* Turn an opcode description and a set of arguments into
3238 an instruction and a fixup. */
3241 assemble_insn (const struct arc_opcode
*opcode
,
3242 const expressionS
*tok
,
3244 const struct arc_flags
*pflags
,
3246 struct arc_insn
*insn
)
3248 const expressionS
*reloc_exp
= NULL
;
3250 const unsigned char *argidx
;
3253 unsigned char pcrel
= 0;
3254 bfd_boolean needGOTSymbol
;
3255 bfd_boolean has_delay_slot
= FALSE
;
3256 extended_bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
3258 memset (insn
, 0, sizeof (*insn
));
3259 image
= opcode
->opcode
;
3261 pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
3262 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->name
,
3265 /* Handle operands. */
3266 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
3268 const struct arc_operand
*operand
= &arc_operands
[*argidx
];
3269 const expressionS
*t
= (const expressionS
*) 0;
3271 if ((operand
->flags
& ARC_OPERAND_FAKE
)
3272 && !(operand
->flags
& ARC_OPERAND_BRAKET
))
3275 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
3277 /* Duplicate operand, already inserted. */
3289 /* Regardless if we have a reloc or not mark the instruction
3290 limm if it is the case. */
3291 if (operand
->flags
& ARC_OPERAND_LIMM
)
3292 insn
->has_limm
= TRUE
;
3297 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
3302 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
3304 if (operand
->flags
& ARC_OPERAND_LIMM
)
3305 insn
->limm
= t
->X_add_number
;
3309 /* Ignore brackets. */
3313 gas_assert (operand
->flags
& ARC_OPERAND_IGNORE
);
3317 /* Maybe register range. */
3318 if ((t
->X_add_number
== 0)
3319 && contains_register (t
->X_add_symbol
)
3320 && contains_register (t
->X_op_symbol
))
3324 regs
= get_register (t
->X_add_symbol
);
3326 regs
|= get_register (t
->X_op_symbol
);
3327 image
= insert_operand (image
, operand
, regs
, NULL
, 0);
3332 /* This operand needs a relocation. */
3333 needGOTSymbol
= FALSE
;
3338 needGOTSymbol
= TRUE
;
3339 reloc
= find_reloc ("plt", opcode
->name
,
3341 operand
->default_reloc
);
3346 needGOTSymbol
= TRUE
;
3347 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3350 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3351 if (ARC_SHORT (opcode
->mask
))
3352 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3353 _("Unable to use @pcl relocation for insn %s"),
3357 reloc
= find_reloc ("sda", opcode
->name
,
3359 operand
->default_reloc
);
3363 needGOTSymbol
= TRUE
;
3368 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
3371 case O_tpoff9
: /*FIXME! Check for the conditionality of
3373 case O_dtpoff9
: /*FIXME! Check for the conditionality of
3375 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3379 /* Just consider the default relocation. */
3380 reloc
= operand
->default_reloc
;
3384 if (needGOTSymbol
&& (GOT_symbol
== NULL
))
3385 GOT_symbol
= symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME
);
3392 /* sanity checks. */
3393 reloc_howto_type
*reloc_howto
3394 = bfd_reloc_type_lookup (stdoutput
,
3395 (bfd_reloc_code_real_type
) reloc
);
3396 unsigned reloc_bitsize
= reloc_howto
->bitsize
;
3397 if (reloc_howto
->rightshift
)
3398 reloc_bitsize
-= reloc_howto
->rightshift
;
3399 if (reloc_bitsize
!= operand
->bits
)
3401 as_bad (_("invalid relocation %s for field"),
3402 bfd_get_reloc_code_name (reloc
));
3407 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
3408 as_fatal (_("too many fixups"));
3410 struct arc_fixup
*fixup
;
3411 fixup
= &insn
->fixups
[insn
->nfixups
++];
3413 fixup
->reloc
= reloc
;
3414 pcrel
= (operand
->flags
& ARC_OPERAND_PCREL
) ? 1 : 0;
3415 fixup
->pcrel
= pcrel
;
3416 fixup
->islong
= (operand
->flags
& ARC_OPERAND_LIMM
) ?
3423 for (i
= 0; i
< nflg
; i
++)
3425 const struct arc_flag_operand
*flg_operand
=
3426 &arc_flag_operands
[pflags
[i
].code
];
3428 /* Check if the instruction has a delay slot. */
3429 if (!strcmp (flg_operand
->name
, "d"))
3430 has_delay_slot
= TRUE
;
3432 /* There is an exceptional case when we cannot insert a flag
3433 just as it is. The .T flag must be handled in relation with
3434 the relative address. */
3435 if (!strcmp (flg_operand
->name
, "t")
3436 || !strcmp (flg_operand
->name
, "nt"))
3438 unsigned bitYoperand
= 0;
3439 /* FIXME! move selection bbit/brcc in arc-opc.c. */
3440 if (!strcmp (flg_operand
->name
, "t"))
3441 if (!strcmp (opcode
->name
, "bbit0")
3442 || !strcmp (opcode
->name
, "bbit1"))
3443 bitYoperand
= arc_NToperand
;
3445 bitYoperand
= arc_Toperand
;
3447 if (!strcmp (opcode
->name
, "bbit0")
3448 || !strcmp (opcode
->name
, "bbit1"))
3449 bitYoperand
= arc_Toperand
;
3451 bitYoperand
= arc_NToperand
;
3453 gas_assert (reloc_exp
!= NULL
);
3454 if (reloc_exp
->X_op
== O_constant
)
3456 /* Check if we have a constant and solved it
3458 offsetT val
= reloc_exp
->X_add_number
;
3459 image
|= insert_operand (image
, &arc_operands
[bitYoperand
],
3464 struct arc_fixup
*fixup
;
3466 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
3467 as_fatal (_("too many fixups"));
3469 fixup
= &insn
->fixups
[insn
->nfixups
++];
3470 fixup
->exp
= *reloc_exp
;
3471 fixup
->reloc
= -bitYoperand
;
3472 fixup
->pcrel
= pcrel
;
3473 fixup
->islong
= FALSE
;
3477 image
|= (flg_operand
->code
& ((1 << flg_operand
->bits
) - 1))
3478 << flg_operand
->shift
;
3481 insn
->relax
= relax_insn_p (opcode
, tok
, ntok
, pflags
, nflg
);
3483 /* Short instruction? */
3484 insn
->short_insn
= ARC_SHORT (opcode
->mask
) ? TRUE
: FALSE
;
3488 /* Update last insn status. */
3489 arc_last_insns
[1] = arc_last_insns
[0];
3490 arc_last_insns
[0].opcode
= opcode
;
3491 arc_last_insns
[0].has_limm
= insn
->has_limm
;
3492 arc_last_insns
[0].has_delay_slot
= has_delay_slot
;
3494 /* Check if the current instruction is legally used. */
3495 if (arc_last_insns
[1].has_delay_slot
3496 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
3497 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
3498 _("A jump/branch instruction in delay slot."));
3502 arc_handle_align (fragS
* fragP
)
3504 if ((fragP
)->fr_type
== rs_align_code
)
3506 char *dest
= (fragP
)->fr_literal
+ (fragP
)->fr_fix
;
3507 valueT count
= ((fragP
)->fr_next
->fr_address
3508 - (fragP
)->fr_address
- (fragP
)->fr_fix
);
3510 (fragP
)->fr_var
= 2;
3512 if (count
& 1)/* Padding in the gap till the next 2-byte
3513 boundary with 0s. */
3518 /* Writing nop_s. */
3519 md_number_to_chars (dest
, NOP_OPCODE_S
, 2);
3523 /* Here we decide which fixups can be adjusted to make them relative
3524 to the beginning of the section instead of the symbol. Basically
3525 we need to make sure that the dynamic relocations are done
3526 correctly, so in some cases we force the original symbol to be
3530 tc_arc_fix_adjustable (fixS
*fixP
)
3533 /* Prevent all adjustments to global symbols. */
3534 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
3536 if (S_IS_WEAK (fixP
->fx_addsy
))
3539 /* Adjust_reloc_syms doesn't know about the GOT. */
3540 switch (fixP
->fx_r_type
)
3542 case BFD_RELOC_ARC_GOTPC32
:
3543 case BFD_RELOC_ARC_PLT32
:
3544 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
3545 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
3546 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
3547 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
3554 return 0; /* FIXME! return 1, fix it in the linker. */
3557 /* Compute the reloc type of an expression EXP. */
3560 arc_check_reloc (expressionS
*exp
,
3561 bfd_reloc_code_real_type
*r_type_p
)
3563 if (*r_type_p
== BFD_RELOC_32
3564 && exp
->X_op
== O_subtract
3565 && exp
->X_op_symbol
!= NULL
3566 && exp
->X_op_symbol
->bsym
->section
== now_seg
)
3567 *r_type_p
= BFD_RELOC_ARC_32_PCREL
;
3571 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
3574 arc_cons_fix_new (fragS
*frag
,
3578 bfd_reloc_code_real_type r_type
)
3580 r_type
= BFD_RELOC_UNUSED
;
3585 r_type
= BFD_RELOC_8
;
3589 r_type
= BFD_RELOC_16
;
3593 r_type
= BFD_RELOC_24
;
3597 r_type
= BFD_RELOC_32
;
3598 arc_check_reloc (exp
, &r_type
);
3602 r_type
= BFD_RELOC_64
;
3606 as_bad (_("unsupported BFD relocation size %u"), size
);
3607 r_type
= BFD_RELOC_UNUSED
;
3610 fix_new_exp (frag
, off
, size
, exp
, 0, r_type
);
3613 /* The actual routine that checks the ZOL conditions. */
3616 check_zol (symbolS
*s
)
3618 switch (arc_mach_type
)
3620 case bfd_mach_arc_arcv2
:
3621 if (arc_target
& ARC_OPCODE_ARCv2EM
)
3624 if (is_br_jmp_insn_p (arc_last_insns
[0].opcode
)
3625 || arc_last_insns
[1].has_delay_slot
)
3626 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
3630 case bfd_mach_arc_arc600
:
3632 if (is_kernel_insn_p (arc_last_insns
[0].opcode
))
3633 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
3636 if (arc_last_insns
[0].has_limm
3637 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
3638 as_bad (_("A jump instruction with long immediate detected at the \
3639 end of the ZOL label @%s"), S_GET_NAME (s
));
3642 case bfd_mach_arc_arc700
:
3643 if (arc_last_insns
[0].has_delay_slot
)
3644 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
3653 /* If ZOL end check the last two instruction for illegals. */
3655 arc_frob_label (symbolS
* sym
)
3657 if (ARC_GET_FLAG (sym
) & ARC_FLAG_ZOL
)
3660 dwarf2_emit_label (sym
);
3663 /* Used because generic relaxation assumes a pc-rel value whilst we
3664 also relax instructions that use an absolute value resolved out of
3665 relative values (if that makes any sense). An example: 'add r1,
3666 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
3667 but if they're in the same section we can subtract the section
3668 offset relocation which ends up in a resolved value. So if @.L2 is
3669 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
3670 .text + 0x40 = 0x10. */
3672 arc_pcrel_adjust (fragS
*fragP
)
3674 if (!fragP
->tc_frag_data
.pcrel
)
3675 return fragP
->fr_address
+ fragP
->fr_fix
;
3680 /* Initialize the DWARF-2 unwind information for this procedure. */
3683 tc_arc_frame_initial_instructions (void)
3685 /* Stack pointer is register 28. */
3686 cfi_add_CFA_def_cfa_register (28);
3690 tc_arc_regname_to_dw2regnum (char *regname
)
3694 sym
= hash_find (arc_reg_hash
, regname
);
3696 return S_GET_VALUE (sym
);