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 "safe-ctype.h"
29 #include "opcode/arc.h"
32 /* Defines section. */
34 #define MAX_FLAG_NAME_LENGHT 3
35 #define MAX_INSN_FIXUPS 2
36 #define MAX_CONSTR_STR 20
39 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
41 # define pr_debug(fmt, args...)
44 #define MAJOR_OPCODE(x) (((x) & 0xF8000000) >> 27)
45 #define SUB_OPCODE(x) (((x) & 0x003F0000) >> 16)
46 #define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) && \
47 (SUB_OPCODE (x) == 0x28))
49 /* Equal to MAX_PRECISION in atof-ieee.c. */
50 #define MAX_LITTLENUMS 6
54 #define regno(x) ((x) & 0x3F)
55 #define is_ir_num(x) (((x) & ~0x3F) == 0)
56 #define is_code_density_p(op) (((op)->subclass == CD1 || (op)->subclass == CD2))
57 #define is_br_jmp_insn_p(op) (((op)->class == BRANCH || (op)->class == JUMP))
58 #define is_kernel_insn_p(op) (((op)->class == KERNEL))
60 /* Generic assembler global variables which must be defined by all
63 /* Characters which always start a comment. */
64 const char comment_chars
[] = "#;";
66 /* Characters which start a comment at the beginning of a line. */
67 const char line_comment_chars
[] = "#";
69 /* Characters which may be used to separate multiple commands on a
71 const char line_separator_chars
[] = "`";
73 /* Characters which are used to indicate an exponent in a floating
75 const char EXP_CHARS
[] = "eE";
77 /* Chars that mean this number is a floating point constant
78 As in 0f12.456 or 0d1.2345e12. */
79 const char FLT_CHARS
[] = "rRsSfFdD";
82 extern int target_big_endian
;
83 const char *arc_target_format
= DEFAULT_TARGET_FORMAT
;
84 static int byte_order
= DEFAULT_BYTE_ORDER
;
86 extern int arc_get_mach (char *);
88 /* Forward declaration. */
89 static void arc_lcomm (int);
90 static void arc_option (int);
91 static void arc_extra_reloc (int);
93 const pseudo_typeS md_pseudo_table
[] =
95 /* Make sure that .word is 32 bits. */
98 { "align", s_align_bytes
, 0 }, /* Defaulting is invalid (0). */
99 { "lcomm", arc_lcomm
, 0 },
100 { "lcommon", arc_lcomm
, 0 },
101 { "cpu", arc_option
, 0 },
103 { "tls_gd_ld", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_LD
},
104 { "tls_gd_call", arc_extra_reloc
, BFD_RELOC_ARC_TLS_GD_CALL
},
109 const char *md_shortopts
= "";
113 OPTION_EB
= OPTION_MD_BASE
,
125 /* The following options are deprecated and provided here only for
126 compatibility reasons. */
152 struct option md_longopts
[] =
154 { "EB", no_argument
, NULL
, OPTION_EB
},
155 { "EL", no_argument
, NULL
, OPTION_EL
},
156 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
157 { "mA6", no_argument
, NULL
, OPTION_ARC600
},
158 { "mARC600", no_argument
, NULL
, OPTION_ARC600
},
159 { "mARC601", no_argument
, NULL
, OPTION_ARC601
},
160 { "mARC700", no_argument
, NULL
, OPTION_ARC700
},
161 { "mA7", no_argument
, NULL
, OPTION_ARC700
},
162 { "mEM", no_argument
, NULL
, OPTION_ARCEM
},
163 { "mHS", no_argument
, NULL
, OPTION_ARCHS
},
164 { "mcode-density", no_argument
, NULL
, OPTION_CD
},
166 /* The following options are deprecated and provided here only for
167 compatibility reasons. */
168 { "mav2em", no_argument
, NULL
, OPTION_ARCEM
},
169 { "mav2hs", no_argument
, NULL
, OPTION_ARCHS
},
170 { "muser-mode-only", no_argument
, NULL
, OPTION_USER_MODE
},
171 { "mld-extension-reg-mask", required_argument
, NULL
, OPTION_LD_EXT_MASK
},
172 { "mswap", no_argument
, NULL
, OPTION_SWAP
},
173 { "mnorm", no_argument
, NULL
, OPTION_NORM
},
174 { "mbarrel-shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
175 { "mbarrel_shifter", no_argument
, NULL
, OPTION_BARREL_SHIFT
},
176 { "mmin-max", no_argument
, NULL
, OPTION_MIN_MAX
},
177 { "mmin_max", no_argument
, NULL
, OPTION_MIN_MAX
},
178 { "mno-mpy", no_argument
, NULL
, OPTION_NO_MPY
},
179 { "mea", no_argument
, NULL
, OPTION_EA
},
180 { "mEA", no_argument
, NULL
, OPTION_EA
},
181 { "mmul64", no_argument
, NULL
, OPTION_MUL64
},
182 { "msimd", no_argument
, NULL
, OPTION_SIMD
},
183 { "mspfp", no_argument
, NULL
, OPTION_SPFP
},
184 { "mspfp-compact", no_argument
, NULL
, OPTION_SPFP
},
185 { "mspfp_compact", no_argument
, NULL
, OPTION_SPFP
},
186 { "mspfp-fast", no_argument
, NULL
, OPTION_SPFP
},
187 { "mspfp_fast", no_argument
, NULL
, OPTION_SPFP
},
188 { "mdpfp", no_argument
, NULL
, OPTION_DPFP
},
189 { "mdpfp-compact", no_argument
, NULL
, OPTION_DPFP
},
190 { "mdpfp_compact", no_argument
, NULL
, OPTION_DPFP
},
191 { "mdpfp-fast", no_argument
, NULL
, OPTION_DPFP
},
192 { "mdpfp_fast", no_argument
, NULL
, OPTION_DPFP
},
193 { "mmac-d16", no_argument
, NULL
, OPTION_XMAC_D16
},
194 { "mmac_d16", no_argument
, NULL
, OPTION_XMAC_D16
},
195 { "mmac-24", no_argument
, NULL
, OPTION_XMAC_24
},
196 { "mmac_24", no_argument
, NULL
, OPTION_XMAC_24
},
197 { "mdsp-packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
198 { "mdsp_packa", no_argument
, NULL
, OPTION_DSP_PACKA
},
199 { "mcrc", no_argument
, NULL
, OPTION_CRC
},
200 { "mdvbf", no_argument
, NULL
, OPTION_DVBF
},
201 { "mtelephony", no_argument
, NULL
, OPTION_TELEPHONY
},
202 { "mxy", no_argument
, NULL
, OPTION_XYMEMORY
},
203 { "mlock", no_argument
, NULL
, OPTION_LOCK
},
204 { "mswape", no_argument
, NULL
, OPTION_SWAPE
},
205 { "mrtsc", no_argument
, NULL
, OPTION_RTSC
},
206 { "mfpuda", no_argument
, NULL
, OPTION_FPUDA
},
208 { NULL
, no_argument
, NULL
, 0 }
211 size_t md_longopts_size
= sizeof (md_longopts
);
213 /* Local data and data types. */
215 /* Used since new relocation types are introduced in this
216 file (DUMMY_RELOC_LITUSE_*). */
217 typedef int extended_bfd_reloc_code_real_type
;
223 extended_bfd_reloc_code_real_type reloc
;
225 /* index into arc_operands. */
226 unsigned int opindex
;
228 /* PC-relative, used by internals fixups. */
231 /* TRUE if this fixup is for LIMM operand. */
239 struct arc_fixup fixups
[MAX_INSN_FIXUPS
];
241 bfd_boolean short_insn
; /* Boolean value: TRUE if current insn is
243 bfd_boolean has_limm
; /* Boolean value: TRUE if limm field is
247 /* Structure to hold any last two instructions. */
248 static struct arc_last_insn
250 /* Saved instruction opcode. */
251 const struct arc_opcode
*opcode
;
253 /* Boolean value: TRUE if current insn is short. */
254 bfd_boolean has_limm
;
256 /* Boolean value: TRUE if current insn has delay slot. */
257 bfd_boolean has_delay_slot
;
260 /* The cpu for which we are generating code. */
261 static unsigned arc_target
= ARC_OPCODE_BASE
;
262 static const char *arc_target_name
= "<all>";
263 static unsigned arc_features
= 0x00;
265 /* The default architecture. */
266 static int arc_mach_type
= bfd_mach_arc_arcv2
;
268 /* Non-zero if the cpu type has been explicitly specified. */
269 static int mach_type_specified_p
= 0;
271 /* The hash table of instruction opcodes. */
272 static struct hash_control
*arc_opcode_hash
;
274 /* The hash table of register symbols. */
275 static struct hash_control
*arc_reg_hash
;
277 /* A table of CPU names and opcode sets. */
278 static const struct cpu_type
288 { "arc600", ARC_OPCODE_ARC600
, bfd_mach_arc_arc600
,
289 E_ARC_MACH_ARC600
, 0x00},
290 { "arc700", ARC_OPCODE_ARC700
, bfd_mach_arc_arc700
,
291 E_ARC_MACH_ARC700
, 0x00},
292 { "arcem", ARC_OPCODE_ARCv2EM
, bfd_mach_arc_arcv2
,
293 EF_ARC_CPU_ARCV2EM
, 0x00},
294 { "archs", ARC_OPCODE_ARCv2HS
, bfd_mach_arc_arcv2
,
295 EF_ARC_CPU_ARCV2HS
, ARC_CD
},
296 { "all", ARC_OPCODE_BASE
, bfd_mach_arc_arcv2
,
303 /* Name of the parsed flag. */
304 char name
[MAX_FLAG_NAME_LENGHT
+1];
306 /* The code of the parsed flag. Valid when is not zero. */
310 /* Used by the arc_reloc_op table. Order is important. */
311 #define O_gotoff O_md1 /* @gotoff relocation. */
312 #define O_gotpc O_md2 /* @gotpc relocation. */
313 #define O_plt O_md3 /* @plt relocation. */
314 #define O_sda O_md4 /* @sda relocation. */
315 #define O_pcl O_md5 /* @pcl relocation. */
316 #define O_tlsgd O_md6 /* @tlsgd relocation. */
317 #define O_tlsie O_md7 /* @tlsie relocation. */
318 #define O_tpoff9 O_md8 /* @tpoff9 relocation. */
319 #define O_tpoff O_md9 /* @tpoff relocation. */
320 #define O_dtpoff9 O_md10 /* @dtpoff9 relocation. */
321 #define O_dtpoff O_md11 /* @dtpoff relocation. */
322 #define O_last O_dtpoff
324 /* Used to define a bracket as operand in tokens. */
325 #define O_bracket O_md32
327 /* Dummy relocation, to be sorted out. */
328 #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1)
330 #define USER_RELOC_P(R) ((R) >= O_gotoff && (R) <= O_last)
332 /* A table to map the spelling of a relocation operand into an appropriate
333 bfd_reloc_code_real_type type. The table is assumed to be ordered such
334 that op-O_literal indexes into it. */
335 #define ARC_RELOC_TABLE(op) \
336 (&arc_reloc_op[ ((!USER_RELOC_P (op)) \
338 : (int) (op) - (int) O_gotoff) ])
340 #define DEF(NAME, RELOC, REQ) \
341 { #NAME, sizeof (#NAME)-1, O_##NAME, RELOC, REQ}
343 static const struct arc_reloc_op_tag
345 /* String to lookup. */
347 /* Size of the string. */
349 /* Which operator to use. */
351 extended_bfd_reloc_code_real_type reloc
;
352 /* Allows complex relocation expression like identifier@reloc +
354 unsigned int complex_expr
: 1;
358 DEF (gotoff
, BFD_RELOC_ARC_GOTOFF
, 1),
359 DEF (gotpc
, BFD_RELOC_ARC_GOTPC32
, 0),
360 DEF (plt
, BFD_RELOC_ARC_PLT32
, 0),
361 DEF (sda
, DUMMY_RELOC_ARC_ENTRY
, 1),
362 DEF (pcl
, BFD_RELOC_ARC_PC32
, 1),
363 DEF (tlsgd
, BFD_RELOC_ARC_TLS_GD_GOT
, 0),
364 DEF (tlsie
, BFD_RELOC_ARC_TLS_IE_GOT
, 0),
365 DEF (tpoff9
, BFD_RELOC_ARC_TLS_LE_S9
, 0),
366 DEF (tpoff
, BFD_RELOC_ARC_TLS_LE_32
, 0),
367 DEF (dtpoff9
, BFD_RELOC_ARC_TLS_DTPOFF_S9
, 0),
368 DEF (dtpoff
, BFD_RELOC_ARC_TLS_DTPOFF
, 0),
371 static const int arc_num_reloc_op
372 = sizeof (arc_reloc_op
) / sizeof (*arc_reloc_op
);
374 /* Flags to set in the elf header. */
375 static flagword arc_eflag
= 0x00;
377 /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */
378 symbolS
* GOT_symbol
= 0;
380 /* Set to TRUE when we assemble instructions. */
381 static bfd_boolean assembling_insn
= FALSE
;
383 /* Functions declaration. */
385 static void assemble_tokens (const char *, expressionS
*, int,
386 struct arc_flags
*, int);
387 static const struct arc_opcode
*find_opcode_match (const struct arc_opcode
*,
388 expressionS
*, int *,
391 static void assemble_insn (const struct arc_opcode
*, const expressionS
*,
392 int, const struct arc_flags
*, int,
394 static void emit_insn (struct arc_insn
*);
395 static unsigned insert_operand (unsigned, const struct arc_operand
*,
396 offsetT
, char *, unsigned);
397 static const struct arc_opcode
*find_special_case_flag (const char *,
400 static const struct arc_opcode
*find_special_case (const char *,
403 expressionS
*, int *);
404 static const struct arc_opcode
*find_special_case_pseudo (const char *,
410 /* Functions implementation. */
412 /* Like md_number_to_chars but used for limms. The 4-byte limm value,
413 is encoded as 'middle-endian' for a little-endian target. FIXME!
414 this function is used for regular 4 byte instructions as well. */
417 md_number_to_chars_midend (char *buf
, valueT val
, int n
)
421 md_number_to_chars (buf
, (val
& 0xffff0000) >> 16, 2);
422 md_number_to_chars (buf
+ 2, (val
& 0xffff), 2);
426 md_number_to_chars (buf
, val
, n
);
430 /* Here ends all the ARCompact extension instruction assembling
434 arc_extra_reloc (int r_type
)
437 symbolS
*sym
, *lab
= NULL
;
439 if (*input_line_pointer
== '@')
440 input_line_pointer
++;
441 c
= get_symbol_name (&sym_name
);
442 sym
= symbol_find_or_make (sym_name
);
443 restore_line_pointer (c
);
444 if (c
== ',' && r_type
== BFD_RELOC_ARC_TLS_GD_LD
)
446 ++input_line_pointer
;
448 c
= get_symbol_name (&lab_name
);
449 lab
= symbol_find_or_make (lab_name
);
450 restore_line_pointer (c
);
453 = fix_new (frag_now
, /* Which frag? */
454 frag_now_fix (), /* Where in that frag? */
455 2, /* size: 1, 2, or 4 usually. */
456 sym
, /* X_add_symbol. */
457 0, /* X_add_number. */
458 FALSE
, /* TRUE if PC-relative relocation. */
459 r_type
/* Relocation type. */);
460 fixP
->fx_subsy
= lab
;
464 arc_lcomm_internal (int ignore ATTRIBUTE_UNUSED
,
465 symbolS
*symbolP
, addressT size
)
470 if (*input_line_pointer
== ',')
472 align
= parse_align (1);
474 if (align
== (addressT
) -1)
489 bss_alloc (symbolP
, size
, align
);
490 S_CLEAR_EXTERNAL (symbolP
);
496 arc_lcomm (int ignore
)
498 symbolS
*symbolP
= s_comm_internal (ignore
, arc_lcomm_internal
);
501 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
504 /* Select the cpu we're assembling for. */
507 arc_option (int ignore ATTRIBUTE_UNUSED
)
513 c
= get_symbol_name (&cpu
);
514 mach
= arc_get_mach (cpu
);
519 if (!mach_type_specified_p
)
521 if ((!strcmp ("ARC600", cpu
))
522 || (!strcmp ("ARC601", cpu
))
523 || (!strcmp ("A6", cpu
)))
525 md_parse_option (OPTION_MCPU
, "arc600");
527 else if ((!strcmp ("ARC700", cpu
))
528 || (!strcmp ("A7", cpu
)))
530 md_parse_option (OPTION_MCPU
, "arc700");
532 else if (!strcmp ("EM", cpu
))
534 md_parse_option (OPTION_MCPU
, "arcem");
536 else if (!strcmp ("HS", cpu
))
538 md_parse_option (OPTION_MCPU
, "archs");
541 as_fatal ("could not find the architecture");
543 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, mach
))
544 as_fatal ("could not set architecture and machine");
547 if (arc_mach_type
!= mach
)
548 as_warn ("Command-line value overrides \".cpu\" directive");
550 restore_line_pointer (c
);
551 demand_empty_rest_of_line ();
555 restore_line_pointer (c
);
556 as_bad ("invalid identifier for \".cpu\"");
557 ignore_rest_of_line ();
560 /* Smartly print an expression. */
563 debug_exp (expressionS
*t
)
565 const char *name ATTRIBUTE_UNUSED
;
566 const char *namemd ATTRIBUTE_UNUSED
;
568 pr_debug ("debug_exp: ");
572 default: name
= "unknown"; break;
573 case O_illegal
: name
= "O_illegal"; break;
574 case O_absent
: name
= "O_absent"; break;
575 case O_constant
: name
= "O_constant"; break;
576 case O_symbol
: name
= "O_symbol"; break;
577 case O_symbol_rva
: name
= "O_symbol_rva"; break;
578 case O_register
: name
= "O_register"; break;
579 case O_big
: name
= "O_big"; break;
580 case O_uminus
: name
= "O_uminus"; break;
581 case O_bit_not
: name
= "O_bit_not"; break;
582 case O_logical_not
: name
= "O_logical_not"; break;
583 case O_multiply
: name
= "O_multiply"; break;
584 case O_divide
: name
= "O_divide"; break;
585 case O_modulus
: name
= "O_modulus"; break;
586 case O_left_shift
: name
= "O_left_shift"; break;
587 case O_right_shift
: name
= "O_right_shift"; break;
588 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
589 case O_bit_or_not
: name
= "O_bit_or_not"; break;
590 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
591 case O_bit_and
: name
= "O_bit_and"; break;
592 case O_add
: name
= "O_add"; break;
593 case O_subtract
: name
= "O_subtract"; break;
594 case O_eq
: name
= "O_eq"; break;
595 case O_ne
: name
= "O_ne"; break;
596 case O_lt
: name
= "O_lt"; break;
597 case O_le
: name
= "O_le"; break;
598 case O_ge
: name
= "O_ge"; break;
599 case O_gt
: name
= "O_gt"; break;
600 case O_logical_and
: name
= "O_logical_and"; break;
601 case O_logical_or
: name
= "O_logical_or"; break;
602 case O_index
: name
= "O_index"; break;
603 case O_bracket
: name
= "O_bracket"; break;
608 default: namemd
= "unknown"; break;
609 case O_gotoff
: namemd
= "O_gotoff"; break;
610 case O_gotpc
: namemd
= "O_gotpc"; break;
611 case O_plt
: namemd
= "O_plt"; break;
612 case O_sda
: namemd
= "O_sda"; break;
613 case O_pcl
: namemd
= "O_pcl"; break;
614 case O_tlsgd
: namemd
= "O_tlsgd"; break;
615 case O_tlsie
: namemd
= "O_tlsie"; break;
616 case O_tpoff9
: namemd
= "O_tpoff9"; break;
617 case O_tpoff
: namemd
= "O_tpoff"; break;
618 case O_dtpoff9
: namemd
= "O_dtpoff9"; break;
619 case O_dtpoff
: namemd
= "O_dtpoff"; break;
622 pr_debug ("%s (%s, %s, %d, %s)", name
,
623 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
624 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
625 (int) t
->X_add_number
,
626 (t
->X_md
) ? namemd
: "--");
631 /* Parse the arguments to an opcode. */
634 tokenize_arguments (char *str
,
638 char *old_input_line_pointer
;
639 bfd_boolean saw_comma
= FALSE
;
640 bfd_boolean saw_arg
= FALSE
;
645 const struct arc_reloc_op_tag
*r
;
649 memset (tok
, 0, sizeof (*tok
) * ntok
);
651 /* Save and restore input_line_pointer around this function. */
652 old_input_line_pointer
= input_line_pointer
;
653 input_line_pointer
= str
;
655 while (*input_line_pointer
)
658 switch (*input_line_pointer
)
664 input_line_pointer
++;
665 if (saw_comma
|| !saw_arg
)
672 ++input_line_pointer
;
676 tok
->X_op
= O_bracket
;
683 input_line_pointer
++;
687 tok
->X_op
= O_bracket
;
693 /* We have labels, function names and relocations, all
694 starting with @ symbol. Sort them out. */
695 if (saw_arg
&& !saw_comma
)
699 tok
->X_op
= O_symbol
;
700 tok
->X_md
= O_absent
;
702 if (*input_line_pointer
!= '@')
703 goto normalsymbol
; /* This is not a relocation. */
707 /* A relocation opernad has the following form
708 @identifier@relocation_type. The identifier is already
710 if (tok
->X_op
!= O_symbol
)
712 as_bad (_("No valid label relocation operand"));
716 /* Parse @relocation_type. */
717 input_line_pointer
++;
718 c
= get_symbol_name (&reloc_name
);
719 len
= input_line_pointer
- reloc_name
;
722 as_bad (_("No relocation operand"));
726 /* Go through known relocation and try to find a match. */
727 r
= &arc_reloc_op
[0];
728 for (i
= arc_num_reloc_op
- 1; i
>= 0; i
--, r
++)
730 && memcmp (reloc_name
, r
->name
, len
) == 0)
734 as_bad (_("Unknown relocation operand: @%s"), reloc_name
);
738 *input_line_pointer
= c
;
739 SKIP_WHITESPACE_AFTER_NAME ();
740 /* Extra check for TLS: base. */
741 if (*input_line_pointer
== '@')
744 if (tok
->X_op_symbol
!= NULL
745 || tok
->X_op
!= O_symbol
)
747 as_bad (_("Unable to parse TLS base: %s"),
751 input_line_pointer
++;
753 c
= get_symbol_name (&sym_name
);
754 base
= symbol_find_or_make (sym_name
);
755 tok
->X_op
= O_subtract
;
756 tok
->X_op_symbol
= base
;
757 restore_line_pointer (c
);
758 tmpE
.X_add_number
= 0;
760 else if ((*input_line_pointer
!= '+')
761 && (*input_line_pointer
!= '-'))
763 tmpE
.X_add_number
= 0;
767 /* Parse the constant of a complex relocation expression
768 like @identifier@reloc +/- const. */
769 if (! r
->complex_expr
)
771 as_bad (_("@%s is not a complex relocation."), r
->name
);
775 if (tmpE
.X_op
!= O_constant
)
777 as_bad (_("Bad expression: @%s + %s."),
778 r
->name
, input_line_pointer
);
784 tok
->X_add_number
= tmpE
.X_add_number
;
795 /* Can be a register. */
796 ++input_line_pointer
;
800 if (saw_arg
&& !saw_comma
)
803 tok
->X_op
= O_absent
;
804 tok
->X_md
= O_absent
;
807 /* Legacy: There are cases when we have
808 identifier@relocation_type, if it is the case parse the
809 relocation type as well. */
810 if (*input_line_pointer
== '@')
816 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
828 if (saw_comma
|| brk_lvl
)
830 input_line_pointer
= old_input_line_pointer
;
836 as_bad (_("Brackets in operand field incorrect"));
838 as_bad (_("extra comma"));
840 as_bad (_("missing argument"));
842 as_bad (_("missing comma or colon"));
843 input_line_pointer
= old_input_line_pointer
;
847 /* Parse the flags to a structure. */
850 tokenize_flags (const char *str
,
851 struct arc_flags flags
[],
854 char *old_input_line_pointer
;
855 bfd_boolean saw_flg
= FALSE
;
856 bfd_boolean saw_dot
= FALSE
;
860 memset (flags
, 0, sizeof (*flags
) * nflg
);
862 /* Save and restore input_line_pointer around this function. */
863 old_input_line_pointer
= input_line_pointer
;
864 input_line_pointer
= (char *) str
;
866 while (*input_line_pointer
)
868 switch (*input_line_pointer
)
875 input_line_pointer
++;
883 if (saw_flg
&& !saw_dot
)
886 if (num_flags
>= nflg
)
889 flgnamelen
= strspn (input_line_pointer
, "abcdefghilmnopqrstvwxz");
890 if (flgnamelen
> MAX_FLAG_NAME_LENGHT
)
893 memcpy (flags
->name
, input_line_pointer
, flgnamelen
);
895 input_line_pointer
+= flgnamelen
;
905 input_line_pointer
= old_input_line_pointer
;
910 as_bad (_("extra dot"));
912 as_bad (_("unrecognized flag"));
914 as_bad (_("failed to parse flags"));
915 input_line_pointer
= old_input_line_pointer
;
919 /* The public interface to the instruction assembler. */
922 md_assemble (char *str
)
925 expressionS tok
[MAX_INSN_ARGS
];
928 struct arc_flags flags
[MAX_INSN_FLGS
];
930 /* Split off the opcode. */
931 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_0123468");
932 opname
= xmalloc (opnamelen
+ 1);
933 memcpy (opname
, str
, opnamelen
);
934 opname
[opnamelen
] = '\0';
936 /* Signalize we are assmbling the instructions. */
937 assembling_insn
= TRUE
;
939 /* Tokenize the flags. */
940 if ((nflg
= tokenize_flags (str
+ opnamelen
, flags
, MAX_INSN_FLGS
)) == -1)
942 as_bad (_("syntax error"));
946 /* Scan up to the end of the mnemonic which must end in space or end
949 for (; *str
!= '\0'; str
++)
953 /* Tokenize the rest of the line. */
954 if ((ntok
= tokenize_arguments (str
, tok
, MAX_INSN_ARGS
)) < 0)
956 as_bad (_("syntax error"));
961 assemble_tokens (opname
, tok
, ntok
, flags
, nflg
);
962 assembling_insn
= FALSE
;
965 /* Callback to insert a register into the hash table. */
968 declare_register (char *name
, int number
)
971 symbolS
*regS
= symbol_create (name
, reg_section
,
972 number
, &zero_address_frag
);
974 err
= hash_insert (arc_reg_hash
, S_GET_NAME (regS
), (void *) regS
);
976 as_fatal ("Inserting \"%s\" into register table failed: %s",
980 /* Construct symbols for each of the general registers. */
983 declare_register_set (void)
986 for (i
= 0; i
< 64; ++i
)
990 sprintf (name
, "r%d", i
);
991 declare_register (name
, i
);
994 sprintf (name
, "r%dr%d", i
, i
+1);
995 declare_register (name
, i
);
1000 /* Port-specific assembler initialization. This function is called
1001 once, at assembler startup time. */
1008 /* The endianness can be chosen "at the factory". */
1009 target_big_endian
= byte_order
== BIG_ENDIAN
;
1011 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_arc
, arc_mach_type
))
1012 as_warn (_("could not set architecture and machine"));
1014 /* Set elf header flags. */
1015 bfd_set_private_flags (stdoutput
, arc_eflag
);
1017 /* Set up a hash table for the instructions. */
1018 arc_opcode_hash
= hash_new ();
1019 if (arc_opcode_hash
== NULL
)
1020 as_fatal (_("Virtual memory exhausted"));
1022 /* Initialize the hash table with the insns. */
1023 for (i
= 0; i
< arc_num_opcodes
;)
1025 const char *name
, *retval
;
1027 name
= arc_opcodes
[i
].name
;
1028 retval
= hash_insert (arc_opcode_hash
, name
, (void *) &arc_opcodes
[i
]);
1030 as_fatal (_("internal error: can't hash opcode '%s': %s"),
1033 while (++i
< arc_num_opcodes
1034 && (arc_opcodes
[i
].name
== name
1035 || !strcmp (arc_opcodes
[i
].name
, name
)))
1039 /* Register declaration. */
1040 arc_reg_hash
= hash_new ();
1041 if (arc_reg_hash
== NULL
)
1042 as_fatal (_("Virtual memory exhausted"));
1044 declare_register_set ();
1045 declare_register ("gp", 26);
1046 declare_register ("fp", 27);
1047 declare_register ("sp", 28);
1048 declare_register ("ilink", 29);
1049 declare_register ("ilink1", 29);
1050 declare_register ("ilink2", 30);
1051 declare_register ("blink", 31);
1053 declare_register ("mlo", 57);
1054 declare_register ("mmid", 58);
1055 declare_register ("mhi", 59);
1057 declare_register ("acc1", 56);
1058 declare_register ("acc2", 57);
1060 declare_register ("lp_count", 60);
1061 declare_register ("pcl", 63);
1063 /* Initialize the last instructions. */
1064 memset (&arc_last_insns
[0], 0, sizeof (arc_last_insns
));
1067 /* Write a value out to the object file, using the appropriate
1071 md_number_to_chars (char *buf
,
1075 if (target_big_endian
)
1076 number_to_chars_bigendian (buf
, val
, n
);
1078 number_to_chars_littleendian (buf
, val
, n
);
1081 /* Round up a section size to the appropriate boundary. */
1084 md_section_align (segT segment
,
1087 int align
= bfd_get_section_alignment (stdoutput
, segment
);
1089 return ((size
+ (1 << align
) - 1) & (-((valueT
) 1 << align
)));
1092 /* The location from which a PC relative jump should be calculated,
1093 given a PC relative reloc. */
1096 md_pcrel_from_section (fixS
*fixP
,
1099 offsetT base
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1101 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP
->fx_offset
);
1103 if (fixP
->fx_addsy
!= (symbolS
*) NULL
1104 && (!S_IS_DEFINED (fixP
->fx_addsy
)
1105 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
1107 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP
->fx_addsy
));
1109 /* The symbol is undefined (or is defined but not in this section).
1110 Let the linker figure it out. */
1114 if ((int) fixP
->fx_r_type
< 0)
1116 /* These are the "internal" relocations. Align them to
1117 32 bit boundary (PCL), for the moment. */
1122 switch (fixP
->fx_r_type
)
1124 case BFD_RELOC_ARC_PC32
:
1125 /* The hardware calculates relative to the start of the
1126 insn, but this relocation is relative to location of the
1127 LIMM, compensate. The base always needs to be
1128 substracted by 4 as we do not support this type of PCrel
1129 relocation for short instructions. */
1132 case BFD_RELOC_ARC_PLT32
:
1133 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
1134 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
1135 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
1136 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
1138 case BFD_RELOC_ARC_S21H_PCREL
:
1139 case BFD_RELOC_ARC_S25H_PCREL
:
1140 case BFD_RELOC_ARC_S13_PCREL
:
1141 case BFD_RELOC_ARC_S21W_PCREL
:
1142 case BFD_RELOC_ARC_S25W_PCREL
:
1146 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1147 _("unhandled reloc %s in md_pcrel_from_section"),
1148 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1153 pr_debug ("pcrel from %x + %lx = %x, symbol: %s (%x)\n",
1154 fixP
->fx_frag
->fr_address
, fixP
->fx_where
, base
,
1155 fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : "(null)",
1156 fixP
->fx_addsy
? S_GET_VALUE (fixP
->fx_addsy
) : 0);
1161 /* Given a BFD relocation find the coresponding operand. */
1163 static const struct arc_operand
*
1164 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc
)
1168 for (i
= 0; i
< arc_num_operands
; i
++)
1169 if (arc_operands
[i
].default_reloc
== reloc
)
1170 return &arc_operands
[i
];
1174 /* Apply a fixup to the object code. At this point all symbol values
1175 should be fully resolved, and we attempt to completely resolve the
1176 reloc. If we can not do that, we determine the correct reloc code
1177 and put it back in the fixup. To indicate that a fixup has been
1178 eliminated, set fixP->fx_done. */
1181 md_apply_fix (fixS
*fixP
,
1185 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1186 valueT value
= *valP
;
1188 symbolS
*fx_addsy
, *fx_subsy
;
1190 segT add_symbol_segment
= absolute_section
;
1191 segT sub_symbol_segment
= absolute_section
;
1192 const struct arc_operand
*operand
= NULL
;
1193 extended_bfd_reloc_code_real_type reloc
;
1195 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
1196 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
1197 ((int) fixP
->fx_r_type
< 0) ? "Internal":
1198 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
1201 fx_addsy
= fixP
->fx_addsy
;
1202 fx_subsy
= fixP
->fx_subsy
;
1207 add_symbol_segment
= S_GET_SEGMENT (fx_addsy
);
1211 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF
1212 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_DTPOFF_S9
1213 && fixP
->fx_r_type
!= BFD_RELOC_ARC_TLS_GD_LD
)
1215 resolve_symbol_value (fx_subsy
);
1216 sub_symbol_segment
= S_GET_SEGMENT (fx_subsy
);
1218 if (sub_symbol_segment
== absolute_section
)
1220 /* The symbol is really a constant. */
1221 fx_offset
-= S_GET_VALUE (fx_subsy
);
1226 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1227 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
1228 fx_addsy
? S_GET_NAME (fx_addsy
) : "0",
1229 segment_name (add_symbol_segment
),
1230 S_GET_NAME (fx_subsy
),
1231 segment_name (sub_symbol_segment
));
1237 && !S_IS_WEAK (fx_addsy
))
1239 if (add_symbol_segment
== seg
1242 value
+= S_GET_VALUE (fx_addsy
);
1243 value
-= md_pcrel_from_section (fixP
, seg
);
1245 fixP
->fx_pcrel
= FALSE
;
1247 else if (add_symbol_segment
== absolute_section
)
1249 value
= fixP
->fx_offset
;
1250 fx_offset
+= S_GET_VALUE (fixP
->fx_addsy
);
1252 fixP
->fx_pcrel
= FALSE
;
1257 fixP
->fx_done
= TRUE
;
1262 && ((S_IS_DEFINED (fx_addsy
)
1263 && S_GET_SEGMENT (fx_addsy
) != seg
)
1264 || S_IS_WEAK (fx_addsy
)))
1265 value
+= md_pcrel_from_section (fixP
, seg
);
1267 switch (fixP
->fx_r_type
)
1269 case BFD_RELOC_ARC_32_ME
:
1270 /* This is a pc-relative value in a LIMM. Adjust it to the
1271 address of the instruction not to the address of the
1272 LIMM. Note: it is not anylonger valid this afirmation as
1273 the linker consider ARC_PC32 a fixup to entire 64 bit
1275 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
;
1278 fixP
->fx_r_type
= BFD_RELOC_ARC_PC32
;
1280 case BFD_RELOC_ARC_PC32
:
1281 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
1284 if ((int) fixP
->fx_r_type
< 0)
1285 as_fatal (_("PC relative relocation not allowed for (internal) type %d"),
1291 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
1292 fixP
->fx_file
, fixP
->fx_line
, fixP
->fx_r_type
,
1293 ((int) fixP
->fx_r_type
< 0) ? "Internal":
1294 bfd_get_reloc_code_name (fixP
->fx_r_type
), value
,
1298 /* Now check for TLS relocations. */
1299 reloc
= fixP
->fx_r_type
;
1302 case BFD_RELOC_ARC_TLS_DTPOFF
:
1303 case BFD_RELOC_ARC_TLS_LE_32
:
1304 fixP
->fx_offset
= 0;
1306 case BFD_RELOC_ARC_TLS_GD_GOT
:
1307 case BFD_RELOC_ARC_TLS_IE_GOT
:
1308 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
1311 case BFD_RELOC_ARC_TLS_GD_LD
:
1312 gas_assert (!fixP
->fx_offset
);
1315 = (S_GET_VALUE (fixP
->fx_subsy
)
1316 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1317 fixP
->fx_subsy
= NULL
;
1319 case BFD_RELOC_ARC_TLS_GD_CALL
:
1320 /* These two relocs are there just to allow ld to change the tls
1321 model for this symbol, by patching the code. The offset -
1322 and scale, if any - will be installed by the linker. */
1323 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
1326 case BFD_RELOC_ARC_TLS_LE_S9
:
1327 case BFD_RELOC_ARC_TLS_DTPOFF_S9
:
1328 as_bad (_("TLS_*_S9 relocs are not supported yet"));
1340 /* Addjust the value if we have a constant. */
1343 /* For hosts with longs bigger than 32-bits make sure that the top
1344 bits of a 32-bit negative value read in by the parser are set,
1345 so that the correct comparisons are made. */
1346 if (value
& 0x80000000)
1347 value
|= (-1L << 31);
1349 reloc
= fixP
->fx_r_type
;
1357 case BFD_RELOC_ARC_32_PCREL
:
1358 md_number_to_chars (fixpos
, value
, fixP
->fx_size
);
1361 case BFD_RELOC_ARC_GOTPC32
:
1362 /* I cannot fix an GOTPC relocation because I need to relax it
1363 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
1364 as_bad (_("Unsupported operation on reloc"));
1366 case BFD_RELOC_ARC_GOTOFF
:
1367 case BFD_RELOC_ARC_32_ME
:
1368 case BFD_RELOC_ARC_PC32
:
1369 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
1372 case BFD_RELOC_ARC_PLT32
:
1373 md_number_to_chars_midend (fixpos
, value
, fixP
->fx_size
);
1376 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
1377 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
1380 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
1381 reloc
= BFD_RELOC_ARC_S21H_PCREL
;
1384 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
1385 reloc
= BFD_RELOC_ARC_S25W_PCREL
;
1388 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
1389 reloc
= BFD_RELOC_ARC_S21W_PCREL
;
1391 case BFD_RELOC_ARC_S25W_PCREL
:
1392 case BFD_RELOC_ARC_S21W_PCREL
:
1393 case BFD_RELOC_ARC_S21H_PCREL
:
1394 case BFD_RELOC_ARC_S25H_PCREL
:
1395 case BFD_RELOC_ARC_S13_PCREL
:
1397 operand
= find_operand_for_reloc (reloc
);
1398 gas_assert (operand
);
1403 if ((int) fixP
->fx_r_type
>= 0)
1404 as_fatal (_("unhandled relocation type %s"),
1405 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1407 /* The rest of these fixups needs to be completely resolved as
1409 if (fixP
->fx_addsy
!= 0
1410 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
1411 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1412 _("non-absolute expression in constant field"));
1414 gas_assert (-(int) fixP
->fx_r_type
< (int) arc_num_operands
);
1415 operand
= &arc_operands
[-(int) fixP
->fx_r_type
];
1420 if (target_big_endian
)
1422 switch (fixP
->fx_size
)
1425 insn
= bfd_getb32 (fixpos
);
1428 insn
= bfd_getb16 (fixpos
);
1431 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1432 _("unknown fixup size"));
1438 switch (fixP
->fx_size
)
1441 insn
= bfd_getl16 (fixpos
) << 16 | bfd_getl16 (fixpos
+ 2);
1444 insn
= bfd_getl16 (fixpos
);
1447 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1448 _("unknown fixup size"));
1452 insn
= insert_operand (insn
, operand
, (offsetT
) value
,
1453 fixP
->fx_file
, fixP
->fx_line
);
1455 md_number_to_chars_midend (fixpos
, insn
, fixP
->fx_size
);
1458 /* Prepare machine-dependent frags for relaxation.
1460 Called just before relaxation starts. Any symbol that is now undefined
1461 will not become defined.
1463 Return the correct fr_subtype in the frag.
1465 Return the initial "guess for fr_var" to caller. The guess for fr_var
1466 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
1467 or fr_var contributes to our returned value.
1469 Although it may not be explicit in the frag, pretend
1470 fr_var starts with a value. */
1473 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
,
1474 segT segment ATTRIBUTE_UNUSED
)
1479 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
1480 fragP
->fr_file
, fragP
->fr_line
, growth
);
1482 as_fatal (_("md_estimate_size_before_relax\n"));
1486 /* Translate internal representation of relocation info to BFD target
1490 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
,
1494 bfd_reloc_code_real_type code
;
1496 reloc
= (arelent
*) xmalloc (sizeof (* reloc
));
1497 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1498 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
1499 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1501 /* Make sure none of our internal relocations make it this far.
1502 They'd better have been fully resolved by this point. */
1503 gas_assert ((int) fixP
->fx_r_type
> 0);
1505 code
= fixP
->fx_r_type
;
1507 /* if we have something like add gp, pcl,
1508 _GLOBAL_OFFSET_TABLE_@gotpc. */
1509 if (code
== BFD_RELOC_ARC_GOTPC32
1511 && fixP
->fx_addsy
== GOT_symbol
)
1512 code
= BFD_RELOC_ARC_GOTPC
;
1514 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
1515 if (reloc
->howto
== NULL
)
1517 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1518 _("cannot represent `%s' relocation in object file"),
1519 bfd_get_reloc_code_name (code
));
1523 if (!fixP
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1524 as_fatal (_("internal error? cannot generate `%s' relocation"),
1525 bfd_get_reloc_code_name (code
));
1527 gas_assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1529 if (code
== BFD_RELOC_ARC_TLS_DTPOFF
1530 || code
== BFD_RELOC_ARC_TLS_DTPOFF_S9
)
1533 = fixP
->fx_subsy
? symbol_get_bfdsym (fixP
->fx_subsy
) : NULL
;
1534 /* We just want to store a 24 bit index, but we have to wait
1535 till after write_contents has been called via
1536 bfd_map_over_sections before we can get the index from
1537 _bfd_elf_symbol_from_bfd_symbol. Thus, the write_relocs
1538 function is elf32-arc.c has to pick up the slack.
1539 Unfortunately, this leads to problems with hosts that have
1540 pointers wider than long (bfd_vma). There would be various
1541 ways to handle this, all error-prone :-( */
1542 reloc
->addend
= (bfd_vma
) sym
;
1543 if ((asymbol
*) reloc
->addend
!= sym
)
1545 as_bad ("Can't store pointer\n");
1550 reloc
->addend
= fixP
->fx_offset
;
1555 /* Perform post-processing of machine-dependent frags after relaxation.
1556 Called after relaxation is finished.
1557 In: Address of frag.
1558 fr_type == rs_machine_dependent.
1559 fr_subtype is what the address relaxed to.
1561 Out: Any fixS:s and constants are set up. */
1564 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
1565 segT segment ATTRIBUTE_UNUSED
,
1566 fragS
*fragP ATTRIBUTE_UNUSED
)
1568 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, var: %d\n",
1569 fragP
->fr_file
, fragP
->fr_line
,
1570 fragP
->fr_subtype
, fragP
->fr_fix
, fragP
->fr_var
);
1574 /* We have no need to default values of symbols. We could catch
1575 register names here, but that is handled by inserting them all in
1576 the symbol table to begin with. */
1579 md_undefined_symbol (char *name
)
1581 /* The arc abi demands that a GOT[0] should be referencible as
1582 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
1583 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
1585 && (*(name
+1) == 'G')
1586 && (strcmp (name
, GLOBAL_OFFSET_TABLE_NAME
) == 0))
1588 && (*(name
+1) == 'D')
1589 && (strcmp (name
, DYNAMIC_STRUCT_NAME
) == 0)))
1593 if (symbol_find (name
))
1594 as_bad ("GOT already in symbol table");
1596 GOT_symbol
= symbol_new (GLOBAL_OFFSET_TABLE_NAME
, undefined_section
,
1597 (valueT
) 0, &zero_address_frag
);
1604 /* Turn a string in input_line_pointer into a floating point constant
1605 of type type, and store the appropriate bytes in *litP. The number
1606 of LITTLENUMS emitted is stored in *sizeP. An error message is
1607 returned, or NULL on OK. */
1610 md_atof (int type
, char *litP
, int *sizeP
)
1612 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
1615 /* Called for any expression that can not be recognized. When the
1616 function is called, `input_line_pointer' will point to the start of
1620 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
1622 char *p
= input_line_pointer
;
1625 input_line_pointer
++;
1626 expressionP
->X_op
= O_symbol
;
1627 expression (expressionP
);
1631 /* This function is called from the function 'expression', it attempts
1632 to parse special names (in our case register names). It fills in
1633 the expression with the identified register. It returns TRUE if
1634 it is a register and FALSE otherwise. */
1637 arc_parse_name (const char *name
,
1638 struct expressionS
*e
)
1642 if (!assembling_insn
)
1645 /* Handle only registers. */
1646 if (e
->X_op
!= O_absent
)
1649 sym
= hash_find (arc_reg_hash
, name
);
1652 e
->X_op
= O_register
;
1653 e
->X_add_number
= S_GET_VALUE (sym
);
1660 Invocation line includes a switch not recognized by the base assembler.
1661 See if it's a processor-specific option.
1663 New options (supported) are:
1665 -mcpu=<cpu name> Assemble for selected processor
1666 -EB/-mbig-endian Big-endian
1667 -EL/-mlittle-endian Little-endian
1669 The following CPU names are recognized:
1670 arc700, av2em, av2hs. */
1673 md_parse_option (int c
, char *arg ATTRIBUTE_UNUSED
)
1675 int cpu_flags
= EF_ARC_CPU_GENERIC
;
1681 return md_parse_option (OPTION_MCPU
, "arc600");
1684 return md_parse_option (OPTION_MCPU
, "arc700");
1687 return md_parse_option (OPTION_MCPU
, "arcem");
1690 return md_parse_option (OPTION_MCPU
, "archs");
1695 char *s
= alloca (strlen (arg
) + 1);
1702 *t
= TOLOWER (*arg1
++);
1706 for (i
= 0; cpu_types
[i
].name
; ++i
)
1708 if (!strcmp (cpu_types
[i
].name
, s
))
1710 arc_target
= cpu_types
[i
].flags
;
1711 arc_target_name
= cpu_types
[i
].name
;
1712 arc_features
= cpu_types
[i
].features
;
1713 arc_mach_type
= cpu_types
[i
].mach
;
1714 cpu_flags
= cpu_types
[i
].eflags
;
1716 mach_type_specified_p
= 1;
1721 if (!cpu_types
[i
].name
)
1723 as_fatal (_("unknown architecture: %s\n"), arg
);
1729 arc_target_format
= "elf32-bigarc";
1730 byte_order
= BIG_ENDIAN
;
1734 arc_target_format
= "elf32-littlearc";
1735 byte_order
= LITTLE_ENDIAN
;
1739 /* This option has an effect only on ARC EM. */
1740 if (arc_target
& ARC_OPCODE_ARCv2EM
)
1741 arc_features
|= ARC_CD
;
1744 case OPTION_USER_MODE
:
1745 case OPTION_LD_EXT_MASK
:
1748 case OPTION_BARREL_SHIFT
:
1749 case OPTION_MIN_MAX
:
1756 case OPTION_XMAC_D16
:
1757 case OPTION_XMAC_24
:
1758 case OPTION_DSP_PACKA
:
1761 case OPTION_TELEPHONY
:
1762 case OPTION_XYMEMORY
:
1767 /* Dummy options are accepted but have no effect. */
1774 if (cpu_flags
!= EF_ARC_CPU_GENERIC
)
1775 arc_eflag
= (arc_eflag
& ~EF_ARC_MACH_MSK
) | cpu_flags
;
1781 md_show_usage (FILE *stream
)
1783 fprintf (stream
, _("ARC-specific assembler options:\n"));
1785 fprintf (stream
, " -mcpu=<cpu name>\t assemble for CPU <cpu name>\n");
1787 " -mcode-density\t enable code density option for ARC EM\n");
1789 fprintf (stream
, _("\
1790 -EB assemble code for a big-endian cpu\n"));
1791 fprintf (stream
, _("\
1792 -EL assemble code for a little-endian cpu\n"));
1796 preprocess_operands (const struct arc_opcode
*opcode
,
1804 const struct arc_aux_reg
*auxr
;
1806 for (i
= 0; i
< ntok
; i
++)
1808 switch (tok
[i
].X_op
)
1812 break; /* Throw and error. */
1815 if (opcode
->class != AUXREG
)
1817 /* Convert the symbol to a constant if possible. */
1818 p
= S_GET_NAME (tok
[i
].X_add_symbol
);
1821 auxr
= &arc_aux_regs
[0];
1822 for (j
= 0; j
< arc_num_aux_regs
; j
++, auxr
++)
1823 if (len
== auxr
->length
1824 && strcasecmp (auxr
->name
, p
) == 0)
1826 tok
[i
].X_op
= O_constant
;
1827 tok
[i
].X_add_number
= auxr
->address
;
1837 /* Given an opcode name, pre-tockenized set of argumenst and the
1838 opcode flags, take it all the way through emission. */
1841 assemble_tokens (const char *opname
,
1844 struct arc_flags
*pflags
,
1847 bfd_boolean found_something
= FALSE
;
1848 const struct arc_opcode
*opcode
;
1851 /* Search opcodes. */
1852 opcode
= (const struct arc_opcode
*) hash_find (arc_opcode_hash
, opname
);
1854 /* Couldn't find opcode conventional way, try special cases. */
1856 opcode
= find_special_case (opname
, &nflgs
, pflags
, tok
, &ntok
);
1860 pr_debug ("%s:%d: assemble_tokens: %s trying opcode 0x%08X\n",
1861 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->name
,
1864 preprocess_operands (opcode
, tok
, ntok
);
1866 found_something
= TRUE
;
1867 opcode
= find_opcode_match (opcode
, tok
, &ntok
, pflags
, nflgs
, &cpumatch
);
1870 struct arc_insn insn
;
1871 assemble_insn (opcode
, tok
, ntok
, pflags
, nflgs
, &insn
);
1877 if (found_something
)
1880 as_bad (_("inappropriate arguments for opcode '%s'"), opname
);
1882 as_bad (_("opcode '%s' not supported for target %s"), opname
,
1886 as_bad (_("unknown opcode '%s'"), opname
);
1889 /* Used to find special case opcode. */
1891 static const struct arc_opcode
*
1892 find_special_case (const char *opname
,
1894 struct arc_flags
*pflags
,
1898 const struct arc_opcode
*opcode
;
1900 opcode
= find_special_case_pseudo (opname
, ntok
, tok
, nflgs
, pflags
);
1903 opcode
= find_special_case_flag (opname
, nflgs
, pflags
);
1908 /* Swap operand tokens. */
1911 swap_operand (expressionS
*operand_array
,
1913 unsigned destination
)
1915 expressionS cpy_operand
;
1916 expressionS
*src_operand
;
1917 expressionS
*dst_operand
;
1920 if (source
== destination
)
1923 src_operand
= &operand_array
[source
];
1924 dst_operand
= &operand_array
[destination
];
1925 size
= sizeof (expressionS
);
1927 /* Make copy of operand to swap with and swap. */
1928 memcpy (&cpy_operand
, dst_operand
, size
);
1929 memcpy (dst_operand
, src_operand
, size
);
1930 memcpy (src_operand
, &cpy_operand
, size
);
1933 /* Check if *op matches *tok type.
1934 Returns FALSE if they don't match, TRUE if they match. */
1937 pseudo_operand_match (const expressionS
*tok
,
1938 const struct arc_operand_operation
*op
)
1940 offsetT min
, max
, val
;
1942 const struct arc_operand
*operand_real
= &arc_operands
[op
->operand_idx
];
1948 if (operand_real
->bits
== 32 && (operand_real
->flags
& ARC_OPERAND_LIMM
))
1950 else if (!(operand_real
->flags
& ARC_OPERAND_IR
))
1952 val
= tok
->X_add_number
+ op
->count
;
1953 if (operand_real
->flags
& ARC_OPERAND_SIGNED
)
1955 max
= (1 << (operand_real
->bits
- 1)) - 1;
1956 min
= -(1 << (operand_real
->bits
- 1));
1960 max
= (1 << operand_real
->bits
) - 1;
1963 if (min
<= val
&& val
<= max
)
1969 /* Handle all symbols as long immediates or signed 9. */
1970 if (operand_real
->flags
& ARC_OPERAND_LIMM
||
1971 ((operand_real
->flags
& ARC_OPERAND_SIGNED
) && operand_real
->bits
== 9))
1976 if (operand_real
->flags
& ARC_OPERAND_IR
)
1981 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
1992 /* Find pseudo instruction in array. */
1994 static const struct arc_pseudo_insn
*
1995 find_pseudo_insn (const char *opname
,
1997 const expressionS
*tok
)
1999 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
2000 const struct arc_operand_operation
*op
;
2004 for (i
= 0; i
< arc_num_pseudo_insn
; ++i
)
2006 pseudo_insn
= &arc_pseudo_insns
[i
];
2007 if (strcmp (pseudo_insn
->mnemonic_p
, opname
) == 0)
2009 op
= pseudo_insn
->operand
;
2010 for (j
= 0; j
< ntok
; ++j
)
2011 if (!pseudo_operand_match (&tok
[j
], &op
[j
]))
2014 /* Found the right instruction. */
2022 /* Assumes the expressionS *tok is of sufficient size. */
2024 static const struct arc_opcode
*
2025 find_special_case_pseudo (const char *opname
,
2029 struct arc_flags
*pflags
)
2031 const struct arc_pseudo_insn
*pseudo_insn
= NULL
;
2032 const struct arc_operand_operation
*operand_pseudo
;
2033 const struct arc_operand
*operand_real
;
2035 char construct_operand
[MAX_CONSTR_STR
];
2037 /* Find whether opname is in pseudo instruction array. */
2038 pseudo_insn
= find_pseudo_insn (opname
, *ntok
, tok
);
2040 if (pseudo_insn
== NULL
)
2043 /* Handle flag, Limited to one flag at the moment. */
2044 if (pseudo_insn
->flag_r
!= NULL
)
2045 *nflgs
+= tokenize_flags (pseudo_insn
->flag_r
, &pflags
[*nflgs
],
2046 MAX_INSN_FLGS
- *nflgs
);
2048 /* Handle operand operations. */
2049 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
2051 operand_pseudo
= &pseudo_insn
->operand
[i
];
2052 operand_real
= &arc_operands
[operand_pseudo
->operand_idx
];
2054 if (operand_real
->flags
& ARC_OPERAND_BRAKET
&&
2055 !operand_pseudo
->needs_insert
)
2058 /* Has to be inserted (i.e. this token does not exist yet). */
2059 if (operand_pseudo
->needs_insert
)
2061 if (operand_real
->flags
& ARC_OPERAND_BRAKET
)
2063 tok
[i
].X_op
= O_bracket
;
2068 /* Check if operand is a register or constant and handle it
2070 if (operand_real
->flags
& ARC_OPERAND_IR
)
2071 snprintf (construct_operand
, MAX_CONSTR_STR
, "r%d",
2072 operand_pseudo
->count
);
2074 snprintf (construct_operand
, MAX_CONSTR_STR
, "%d",
2075 operand_pseudo
->count
);
2077 tokenize_arguments (construct_operand
, &tok
[i
], 1);
2081 else if (operand_pseudo
->count
)
2083 /* Operand number has to be adjusted accordingly (by operand
2085 switch (tok
[i
].X_op
)
2088 tok
[i
].X_add_number
+= operand_pseudo
->count
;
2101 /* Swap operands if necessary. Only supports one swap at the
2103 for (i
= 0; i
< pseudo_insn
->operand_cnt
; ++i
)
2105 operand_pseudo
= &pseudo_insn
->operand
[i
];
2107 if (operand_pseudo
->swap_operand_idx
== i
)
2110 swap_operand (tok
, i
, operand_pseudo
->swap_operand_idx
);
2112 /* Prevent a swap back later by breaking out. */
2116 return (const struct arc_opcode
*)
2117 hash_find (arc_opcode_hash
, pseudo_insn
->mnemonic_r
);
2120 static const struct arc_opcode
*
2121 find_special_case_flag (const char *opname
,
2123 struct arc_flags
*pflags
)
2127 unsigned flag_idx
, flag_arr_idx
;
2128 size_t flaglen
, oplen
;
2129 const struct arc_flag_special
*arc_flag_special_opcode
;
2130 const struct arc_opcode
*opcode
;
2132 /* Search for special case instruction. */
2133 for (i
= 0; i
< arc_num_flag_special
; i
++)
2135 arc_flag_special_opcode
= &arc_flag_special_cases
[i
];
2136 oplen
= strlen (arc_flag_special_opcode
->name
);
2138 if (strncmp (opname
, arc_flag_special_opcode
->name
, oplen
) != 0)
2141 /* Found a potential special case instruction, now test for
2143 for (flag_arr_idx
= 0;; ++flag_arr_idx
)
2145 flag_idx
= arc_flag_special_opcode
->flags
[flag_arr_idx
];
2147 break; /* End of array, nothing found. */
2149 flagnm
= arc_flag_operands
[flag_idx
].name
;
2150 flaglen
= strlen (flagnm
);
2151 if (strcmp (opname
+ oplen
, flagnm
) == 0)
2153 opcode
= (const struct arc_opcode
*)
2154 hash_find (arc_opcode_hash
,
2155 arc_flag_special_opcode
->name
);
2157 if (*nflgs
+ 1 > MAX_INSN_FLGS
)
2159 memcpy (pflags
[*nflgs
].name
, flagnm
, flaglen
);
2160 pflags
[*nflgs
].name
[flaglen
] = '\0';
2169 /* Check whether a symbol involves a register. */
2172 contains_register (symbolS
*sym
)
2176 expressionS
*ex
= symbol_get_value_expression (sym
);
2177 return ((O_register
== ex
->X_op
)
2178 && !contains_register (ex
->X_add_symbol
)
2179 && !contains_register (ex
->X_op_symbol
));
2185 /* Returns the register number within a symbol. */
2188 get_register (symbolS
*sym
)
2190 if (!contains_register (sym
))
2193 expressionS
*ex
= symbol_get_value_expression (sym
);
2194 return regno (ex
->X_add_number
);
2197 /* Allocates a tok entry. */
2200 allocate_tok (expressionS
*tok
, int ntok
, int cidx
)
2202 if (ntok
> MAX_INSN_ARGS
- 2)
2203 return 0; /* No space left. */
2206 return 0; /* Incorect args. */
2208 memcpy (&tok
[ntok
+1], &tok
[ntok
], sizeof (*tok
));
2211 return 1; /* Success. */
2212 return allocate_tok (tok
, ntok
- 1, cidx
);
2215 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
2216 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
2219 generic_reloc_p (extended_bfd_reloc_code_real_type reloc
)
2226 case BFD_RELOC_ARC_SDA_LDST
:
2227 case BFD_RELOC_ARC_SDA_LDST1
:
2228 case BFD_RELOC_ARC_SDA_LDST2
:
2229 case BFD_RELOC_ARC_SDA16_LD
:
2230 case BFD_RELOC_ARC_SDA16_LD1
:
2231 case BFD_RELOC_ARC_SDA16_LD2
:
2232 case BFD_RELOC_ARC_SDA16_ST2
:
2233 case BFD_RELOC_ARC_SDA32_ME
:
2241 /* Search forward through all variants of an opcode looking for a
2244 static const struct arc_opcode
*
2245 find_opcode_match (const struct arc_opcode
*first_opcode
,
2248 struct arc_flags
*first_pflag
,
2252 const struct arc_opcode
*opcode
= first_opcode
;
2254 int got_cpu_match
= 0;
2255 expressionS bktok
[MAX_INSN_ARGS
];
2259 memset (&emptyE
, 0, sizeof (emptyE
));
2260 memcpy (bktok
, tok
, MAX_INSN_ARGS
* sizeof (*tok
));
2265 const unsigned char *opidx
;
2266 const unsigned char *flgidx
;
2268 const expressionS
*t
= &emptyE
;
2270 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
2271 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->opcode
);
2273 /* Don't match opcodes that don't exist on this
2275 if (!(opcode
->cpu
& arc_target
))
2278 if (is_code_density_p (opcode
) && !(arc_features
& ARC_CD
))
2284 /* Check the operands. */
2285 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
2287 const struct arc_operand
*operand
= &arc_operands
[*opidx
];
2289 /* Only take input from real operands. */
2290 if ((operand
->flags
& ARC_OPERAND_FAKE
)
2291 && !(operand
->flags
& ARC_OPERAND_BRAKET
))
2294 /* When we expect input, make sure we have it. */
2298 /* Match operand type with expression type. */
2299 switch (operand
->flags
& ARC_OPERAND_TYPECHECK_MASK
)
2301 case ARC_OPERAND_IR
:
2302 /* Check to be a register. */
2303 if ((tok
[tokidx
].X_op
!= O_register
2304 || !is_ir_num (tok
[tokidx
].X_add_number
))
2305 && !(operand
->flags
& ARC_OPERAND_IGNORE
))
2308 /* If expect duplicate, make sure it is duplicate. */
2309 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
2311 /* Check for duplicate. */
2312 if (t
->X_op
!= O_register
2313 || !is_ir_num (t
->X_add_number
)
2314 || (regno (t
->X_add_number
) !=
2315 regno (tok
[tokidx
].X_add_number
)))
2319 /* Special handling? */
2320 if (operand
->insert
)
2322 const char *errmsg
= NULL
;
2323 (*operand
->insert
)(0,
2324 regno (tok
[tokidx
].X_add_number
),
2328 if (operand
->flags
& ARC_OPERAND_IGNORE
)
2330 /* Missing argument, create one. */
2331 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
2334 tok
[tokidx
].X_op
= O_absent
;
2345 case ARC_OPERAND_BRAKET
:
2346 /* Check if bracket is also in opcode table as
2348 if (tok
[tokidx
].X_op
!= O_bracket
)
2352 case ARC_OPERAND_LIMM
:
2353 case ARC_OPERAND_SIGNED
:
2354 case ARC_OPERAND_UNSIGNED
:
2355 switch (tok
[tokidx
].X_op
)
2363 /* Got an (too) early bracket, check if it is an
2364 ignored operand. N.B. This procedure works only
2365 when bracket is the last operand! */
2366 if (!(operand
->flags
& ARC_OPERAND_IGNORE
))
2368 /* Insert the missing operand. */
2369 if (!allocate_tok (tok
, ntok
- 1, tokidx
))
2372 tok
[tokidx
].X_op
= O_absent
;
2377 /* Check the range. */
2378 if (operand
->bits
!= 32
2379 && !(operand
->flags
& ARC_OPERAND_NCHK
))
2381 offsetT min
, max
, val
;
2382 val
= tok
[tokidx
].X_add_number
;
2384 if (operand
->flags
& ARC_OPERAND_SIGNED
)
2386 max
= (1 << (operand
->bits
- 1)) - 1;
2387 min
= -(1 << (operand
->bits
- 1));
2391 max
= (1 << operand
->bits
) - 1;
2395 if (val
< min
|| val
> max
)
2398 /* Check alignmets. */
2399 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
2403 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
2407 else if (operand
->flags
& ARC_OPERAND_NCHK
)
2409 if (operand
->insert
)
2411 const char *errmsg
= NULL
;
2412 (*operand
->insert
)(0,
2413 tok
[tokidx
].X_add_number
,
2424 /* Check if it is register range. */
2425 if ((tok
[tokidx
].X_add_number
== 0)
2426 && contains_register (tok
[tokidx
].X_add_symbol
)
2427 && contains_register (tok
[tokidx
].X_op_symbol
))
2431 regs
= get_register (tok
[tokidx
].X_add_symbol
);
2433 regs
|= get_register (tok
[tokidx
].X_op_symbol
);
2434 if (operand
->insert
)
2436 const char *errmsg
= NULL
;
2437 (*operand
->insert
)(0,
2448 if (operand
->default_reloc
== 0)
2449 goto match_failed
; /* The operand needs relocation. */
2451 /* Relocs requiring long immediate. FIXME! make it
2452 generic and move it to a function. */
2453 switch (tok
[tokidx
].X_md
)
2462 if (!(operand
->flags
& ARC_OPERAND_LIMM
))
2465 if (!generic_reloc_p (operand
->default_reloc
))
2472 /* If expect duplicate, make sure it is duplicate. */
2473 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
2475 if (t
->X_op
== O_illegal
2476 || t
->X_op
== O_absent
2477 || t
->X_op
== O_register
2478 || (t
->X_add_number
!= tok
[tokidx
].X_add_number
))
2485 /* Everything else should have been fake. */
2493 /* Check the flags. Iterate over the valid flag classes. */
2496 for (flgidx
= opcode
->flags
; *flgidx
&& lnflg
; ++flgidx
)
2498 /* Get a valid flag class. */
2499 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
2500 const unsigned *flgopridx
;
2502 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
2504 const struct arc_flag_operand
*flg_operand
;
2505 struct arc_flags
*pflag
= first_pflag
;
2508 flg_operand
= &arc_flag_operands
[*flgopridx
];
2509 for (i
= 0; i
< nflgs
; i
++, pflag
++)
2511 /* Match against the parsed flags. */
2512 if (!strcmp (flg_operand
->name
, pflag
->name
))
2514 /*TODO: Check if it is duplicated. */
2515 pflag
->code
= *flgopridx
;
2517 break; /* goto next flag class and parsed flag. */
2522 /* Did I check all the parsed flags? */
2527 /* Possible match -- did we use all of our input? */
2537 /* Restore the original parameters. */
2538 memcpy (tok
, bktok
, MAX_INSN_ARGS
* sizeof (*tok
));
2541 while (++opcode
- arc_opcodes
< (int) arc_num_opcodes
2542 && !strcmp (opcode
->name
, first_opcode
->name
));
2545 *pcpumatch
= got_cpu_match
;
2550 /* Find the proper relocation for the given opcode. */
2552 static extended_bfd_reloc_code_real_type
2553 find_reloc (const char *name
,
2554 const char *opcodename
,
2555 const struct arc_flags
*pflags
,
2557 extended_bfd_reloc_code_real_type reloc
)
2561 bfd_boolean found_flag
, tmp
;
2562 extended_bfd_reloc_code_real_type ret
= BFD_RELOC_UNUSED
;
2564 for (i
= 0; i
< arc_num_equiv_tab
; i
++)
2566 const struct arc_reloc_equiv_tab
*r
= &arc_reloc_equiv
[i
];
2568 /* Find the entry. */
2569 if (strcmp (name
, r
->name
))
2571 if (r
->mnemonic
&& (strcmp (r
->mnemonic
, opcodename
)))
2578 unsigned * psflg
= (unsigned *)r
->flags
;
2582 for (j
= 0; j
< nflg
; j
++)
2583 if (!strcmp (pflags
[j
].name
,
2584 arc_flag_operands
[*psflg
].name
))
2605 if (reloc
!= r
->oldreloc
)
2612 if (ret
== BFD_RELOC_UNUSED
)
2613 as_bad (_("Unable to find %s relocation for instruction %s"),
2618 /* Turn an opcode description and a set of arguments into
2619 an instruction and a fixup. */
2622 assemble_insn (const struct arc_opcode
*opcode
,
2623 const expressionS
*tok
,
2625 const struct arc_flags
*pflags
,
2627 struct arc_insn
*insn
)
2629 const expressionS
*reloc_exp
= NULL
;
2631 const unsigned char *argidx
;
2634 unsigned char pcrel
= 0;
2635 bfd_boolean needGOTSymbol
;
2636 bfd_boolean has_delay_slot
= FALSE
;
2637 extended_bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
2639 memset (insn
, 0, sizeof (*insn
));
2640 image
= opcode
->opcode
;
2642 pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
2643 frag_now
->fr_file
, frag_now
->fr_line
, opcode
->name
,
2646 /* Handle operands. */
2647 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2649 const struct arc_operand
*operand
= &arc_operands
[*argidx
];
2650 const expressionS
*t
= (const expressionS
*) 0;
2652 if ((operand
->flags
& ARC_OPERAND_FAKE
)
2653 && !(operand
->flags
& ARC_OPERAND_BRAKET
))
2656 if (operand
->flags
& ARC_OPERAND_DUPLICATE
)
2658 /* Duplicate operand, already inserted. */
2670 /* Regardless if we have a reloc or not mark the instruction
2671 limm if it is the case. */
2672 if (operand
->flags
& ARC_OPERAND_LIMM
)
2673 insn
->has_limm
= TRUE
;
2678 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
2683 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
2685 if (operand
->flags
& ARC_OPERAND_LIMM
)
2686 insn
->limm
= t
->X_add_number
;
2690 /* Ignore brackets. */
2694 gas_assert (operand
->flags
& ARC_OPERAND_IGNORE
);
2698 /* Maybe register range. */
2699 if ((t
->X_add_number
== 0)
2700 && contains_register (t
->X_add_symbol
)
2701 && contains_register (t
->X_op_symbol
))
2705 regs
= get_register (t
->X_add_symbol
);
2707 regs
|= get_register (t
->X_op_symbol
);
2708 image
= insert_operand (image
, operand
, regs
, NULL
, 0);
2713 /* This operand needs a relocation. */
2714 needGOTSymbol
= FALSE
;
2719 needGOTSymbol
= TRUE
;
2720 reloc
= find_reloc ("plt", opcode
->name
,
2722 operand
->default_reloc
);
2727 needGOTSymbol
= TRUE
;
2728 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
2731 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
2732 if (ARC_SHORT (opcode
->mask
))
2733 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
2734 _("Unable to use @pcl relocation for insn %s"),
2738 reloc
= find_reloc ("sda", opcode
->name
,
2740 operand
->default_reloc
);
2744 needGOTSymbol
= TRUE
;
2749 reloc
= ARC_RELOC_TABLE (t
->X_md
)->reloc
;
2752 case O_tpoff9
: /*FIXME! Check for the conditionality of
2754 case O_dtpoff9
: /*FIXME! Check for the conditionality of
2756 as_bad (_("TLS_*_S9 relocs are not supported yet"));
2760 /* Just consider the default relocation. */
2761 reloc
= operand
->default_reloc
;
2765 if (needGOTSymbol
&& (GOT_symbol
== NULL
))
2766 GOT_symbol
= symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME
);
2773 /* sanity checks. */
2774 reloc_howto_type
*reloc_howto
2775 = bfd_reloc_type_lookup (stdoutput
,
2776 (bfd_reloc_code_real_type
) reloc
);
2777 unsigned reloc_bitsize
= reloc_howto
->bitsize
;
2778 if (reloc_howto
->rightshift
)
2779 reloc_bitsize
-= reloc_howto
->rightshift
;
2780 if (reloc_bitsize
!= operand
->bits
)
2782 as_bad (_("invalid relocation %s for field"),
2783 bfd_get_reloc_code_name (reloc
));
2788 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2789 as_fatal (_("too many fixups"));
2791 struct arc_fixup
*fixup
;
2792 fixup
= &insn
->fixups
[insn
->nfixups
++];
2794 fixup
->reloc
= reloc
;
2795 pcrel
= (operand
->flags
& ARC_OPERAND_PCREL
) ? 1 : 0;
2796 fixup
->pcrel
= pcrel
;
2797 fixup
->islong
= (operand
->flags
& ARC_OPERAND_LIMM
) ?
2804 for (i
= 0; i
< nflg
; i
++)
2806 const struct arc_flag_operand
*flg_operand
=
2807 &arc_flag_operands
[pflags
[i
].code
];
2809 /* Check if the instruction has a delay slot. */
2810 if (!strcmp (flg_operand
->name
, "d"))
2811 has_delay_slot
= TRUE
;
2813 /* There is an exceptional case when we cannot insert a flag
2814 just as it is. The .T flag must be handled in relation with
2815 the relative address. */
2816 if (!strcmp (flg_operand
->name
, "t")
2817 || !strcmp (flg_operand
->name
, "nt"))
2819 unsigned bitYoperand
= 0;
2820 /* FIXME! move selection bbit/brcc in arc-opc.c. */
2821 if (!strcmp (flg_operand
->name
, "t"))
2822 if (!strcmp (opcode
->name
, "bbit0")
2823 || !strcmp (opcode
->name
, "bbit1"))
2824 bitYoperand
= arc_NToperand
;
2826 bitYoperand
= arc_Toperand
;
2828 if (!strcmp (opcode
->name
, "bbit0")
2829 || !strcmp (opcode
->name
, "bbit1"))
2830 bitYoperand
= arc_Toperand
;
2832 bitYoperand
= arc_NToperand
;
2834 gas_assert (reloc_exp
!= NULL
);
2835 if (reloc_exp
->X_op
== O_constant
)
2837 /* Check if we have a constant and solved it
2839 offsetT val
= reloc_exp
->X_add_number
;
2840 image
|= insert_operand (image
, &arc_operands
[bitYoperand
],
2845 struct arc_fixup
*fixup
;
2847 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2848 as_fatal (_("too many fixups"));
2850 fixup
= &insn
->fixups
[insn
->nfixups
++];
2851 fixup
->exp
= *reloc_exp
;
2852 fixup
->reloc
= -bitYoperand
;
2853 fixup
->pcrel
= pcrel
;
2854 fixup
->islong
= FALSE
;
2858 image
|= (flg_operand
->code
& ((1 << flg_operand
->bits
) - 1))
2859 << flg_operand
->shift
;
2862 /* Short instruction? */
2863 insn
->short_insn
= ARC_SHORT (opcode
->mask
) ? TRUE
: FALSE
;
2867 /* Update last insn status. */
2868 arc_last_insns
[1] = arc_last_insns
[0];
2869 arc_last_insns
[0].opcode
= opcode
;
2870 arc_last_insns
[0].has_limm
= insn
->has_limm
;
2871 arc_last_insns
[0].has_delay_slot
= has_delay_slot
;
2873 /* Check if the current instruction is legally used. */
2874 if (arc_last_insns
[1].has_delay_slot
2875 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
2876 as_bad_where (frag_now
->fr_file
, frag_now
->fr_line
,
2877 _("A jump/branch instruction in delay slot."));
2880 /* Actually output an instruction with its fixup. */
2883 emit_insn (struct arc_insn
*insn
)
2888 pr_debug ("Emit insn : 0x%x\n", insn
->insn
);
2889 pr_debug ("\tShort : 0x%d\n", insn
->short_insn
);
2890 pr_debug ("\tLong imm: 0x%lx\n", insn
->limm
);
2892 /* Write out the instruction. */
2893 if (insn
->short_insn
)
2898 md_number_to_chars (f
, insn
->insn
, 2);
2899 md_number_to_chars_midend (f
+ 2, insn
->limm
, 4);
2900 dwarf2_emit_insn (6);
2905 md_number_to_chars (f
, insn
->insn
, 2);
2906 dwarf2_emit_insn (2);
2914 md_number_to_chars_midend (f
, insn
->insn
, 4);
2915 md_number_to_chars_midend (f
+ 4, insn
->limm
, 4);
2916 dwarf2_emit_insn (8);
2921 md_number_to_chars_midend (f
, insn
->insn
, 4);
2922 dwarf2_emit_insn (4);
2926 /* Apply the fixups in order. */
2927 for (i
= 0; i
< insn
->nfixups
; i
++)
2929 struct arc_fixup
*fixup
= &insn
->fixups
[i
];
2930 int size
, pcrel
, offset
= 0;
2932 /*FIXME! the reloc size is wrong in the BFD file. When it will
2933 be fixed please delete me. */
2934 size
= (insn
->short_insn
&& !fixup
->islong
) ? 2 : 4;
2937 offset
= (insn
->short_insn
) ? 2 : 4;
2939 /* Some fixups are only used internally, thus no howto. */
2940 if ((int) fixup
->reloc
< 0)
2942 /*FIXME! the reloc size is wrong in the BFD file. When it
2943 will be fixed please enable me.
2944 size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
2945 pcrel
= fixup
->pcrel
;
2949 reloc_howto_type
*reloc_howto
=
2950 bfd_reloc_type_lookup (stdoutput
,
2951 (bfd_reloc_code_real_type
) fixup
->reloc
);
2952 gas_assert (reloc_howto
);
2953 /*FIXME! the reloc size is wrong in the BFD file. When it
2954 will be fixed please enable me.
2955 size = bfd_get_reloc_size (reloc_howto); */
2956 pcrel
= reloc_howto
->pc_relative
;
2959 pr_debug ("%s:%d: emit_insn: new %s fixup (PCrel:%s) of size %d @ offset %d\n",
2960 frag_now
->fr_file
, frag_now
->fr_line
,
2961 (fixup
->reloc
< 0) ? "Internal" :
2962 bfd_get_reloc_code_name (fixup
->reloc
),
2965 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
+ offset
,
2966 size
, &fixup
->exp
, pcrel
, fixup
->reloc
);
2968 /* Check for ZOLs, and update symbol info if any. */
2969 if (LP_INSN (insn
->insn
))
2971 gas_assert (fixup
->exp
.X_add_symbol
);
2972 ARC_SET_FLAG (fixup
->exp
.X_add_symbol
, ARC_FLAG_ZOL
);
2977 /* Insert an operand value into an instruction. */
2980 insert_operand (unsigned insn
,
2981 const struct arc_operand
*operand
,
2986 offsetT min
= 0, max
= 0;
2988 if (operand
->bits
!= 32
2989 && !(operand
->flags
& ARC_OPERAND_NCHK
)
2990 && !(operand
->flags
& ARC_OPERAND_FAKE
))
2992 if (operand
->flags
& ARC_OPERAND_SIGNED
)
2994 max
= (1 << (operand
->bits
- 1)) - 1;
2995 min
= -(1 << (operand
->bits
- 1));
2999 max
= (1 << operand
->bits
) - 1;
3003 if (val
< min
|| val
> max
)
3004 as_bad_value_out_of_range (_("operand"),
3005 val
, min
, max
, file
, line
);
3008 pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
3009 min
, val
, max
, insn
);
3011 if ((operand
->flags
& ARC_OPERAND_ALIGNED32
)
3013 as_bad_where (file
, line
,
3014 _("Unaligned operand. Needs to be 32bit aligned"));
3016 if ((operand
->flags
& ARC_OPERAND_ALIGNED16
)
3018 as_bad_where (file
, line
,
3019 _("Unaligned operand. Needs to be 16bit aligned"));
3021 if (operand
->insert
)
3023 const char *errmsg
= NULL
;
3025 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
3027 as_warn_where (file
, line
, "%s", errmsg
);
3031 if (operand
->flags
& ARC_OPERAND_TRUNCATE
)
3033 if (operand
->flags
& ARC_OPERAND_ALIGNED32
)
3035 if (operand
->flags
& ARC_OPERAND_ALIGNED16
)
3038 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
3044 arc_handle_align (fragS
* fragP
)
3046 if ((fragP
)->fr_type
== rs_align_code
)
3048 char *dest
= (fragP
)->fr_literal
+ (fragP
)->fr_fix
;
3049 valueT count
= ((fragP
)->fr_next
->fr_address
3050 - (fragP
)->fr_address
- (fragP
)->fr_fix
);
3052 (fragP
)->fr_var
= 2;
3054 if (count
& 1)/* Padding in the gap till the next 2-byte
3055 boundary with 0s. */
3060 /* Writing nop_s. */
3061 md_number_to_chars (dest
, NOP_OPCODE_S
, 2);
3065 /* Here we decide which fixups can be adjusted to make them relative
3066 to the beginning of the section instead of the symbol. Basically
3067 we need to make sure that the dynamic relocations are done
3068 correctly, so in some cases we force the original symbol to be
3072 tc_arc_fix_adjustable (fixS
*fixP
)
3075 /* Prevent all adjustments to global symbols. */
3076 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
3078 if (S_IS_WEAK (fixP
->fx_addsy
))
3081 /* Adjust_reloc_syms doesn't know about the GOT. */
3082 switch (fixP
->fx_r_type
)
3084 case BFD_RELOC_ARC_GOTPC32
:
3085 case BFD_RELOC_ARC_PLT32
:
3086 case BFD_RELOC_ARC_S25H_PCREL_PLT
:
3087 case BFD_RELOC_ARC_S21H_PCREL_PLT
:
3088 case BFD_RELOC_ARC_S25W_PCREL_PLT
:
3089 case BFD_RELOC_ARC_S21W_PCREL_PLT
:
3096 return 0; /* FIXME! return 1, fix it in the linker. */
3099 /* Compute the reloc type of an expression EXP. */
3102 arc_check_reloc (expressionS
*exp
,
3103 bfd_reloc_code_real_type
*r_type_p
)
3105 if (*r_type_p
== BFD_RELOC_32
3106 && exp
->X_op
== O_subtract
3107 && exp
->X_op_symbol
!= NULL
3108 && exp
->X_op_symbol
->bsym
->section
== now_seg
)
3109 *r_type_p
= BFD_RELOC_ARC_32_PCREL
;
3113 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
3116 arc_cons_fix_new (fragS
*frag
,
3120 bfd_reloc_code_real_type r_type
)
3122 r_type
= BFD_RELOC_UNUSED
;
3127 r_type
= BFD_RELOC_8
;
3131 r_type
= BFD_RELOC_16
;
3135 r_type
= BFD_RELOC_24
;
3139 r_type
= BFD_RELOC_32
;
3140 arc_check_reloc (exp
, &r_type
);
3144 r_type
= BFD_RELOC_64
;
3148 as_bad (_("unsupported BFD relocation size %u"), size
);
3149 r_type
= BFD_RELOC_UNUSED
;
3152 fix_new_exp (frag
, off
, size
, exp
, 0, r_type
);
3155 /* The actual routine that checks the ZOL conditions. */
3158 check_zol (symbolS
*s
)
3160 switch (arc_mach_type
)
3162 case bfd_mach_arc_arcv2
:
3163 if (arc_target
& ARC_OPCODE_ARCv2EM
)
3166 if (is_br_jmp_insn_p (arc_last_insns
[0].opcode
)
3167 || arc_last_insns
[1].has_delay_slot
)
3168 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
3172 case bfd_mach_arc_arc600
:
3174 if (is_kernel_insn_p (arc_last_insns
[0].opcode
))
3175 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
3178 if (arc_last_insns
[0].has_limm
3179 && is_br_jmp_insn_p (arc_last_insns
[0].opcode
))
3180 as_bad (_("A jump instruction with long immediate detected at the \
3181 end of the ZOL label @%s"), S_GET_NAME (s
));
3184 case bfd_mach_arc_arc700
:
3185 if (arc_last_insns
[0].has_delay_slot
)
3186 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
3195 /* If ZOL end check the last two instruction for illegals. */
3197 arc_frob_label (symbolS
* sym
)
3199 if (ARC_GET_FLAG (sym
) & ARC_FLAG_ZOL
)
3202 dwarf2_emit_label (sym
);