1 /* tc-arc.c -- Assembler for the ARC
2 Copyright (C) 1994-2015 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. */
1773 if (cpu_flags != EF_ARC_CPU_GENERIC)
1774 arc_eflag = (arc_eflag & ~EF_ARC_MACH_MSK) | cpu_flags;
1780 md_show_usage (FILE *stream)
1782 fprintf (stream, _("ARC-specific assembler options:\n"));
1784 fprintf (stream, " -mcpu=<cpu name>\t assemble for CPU <cpu name>\n");
1786 " -mcode-density\t enable code density option for ARC EM\n");
1788 fprintf (stream, _("\
1789 -EB assemble code for a big-endian cpu\n"));
1790 fprintf (stream, _("\
1791 -EL assemble code for a little-endian cpu\n"));
1795 preprocess_operands (const struct arc_opcode *opcode,
1803 const struct arc_aux_reg *auxr;
1805 for (i = 0; i < ntok; i++)
1807 switch (tok[i].X_op)
1811 break; /* Throw and error. */
1814 if (opcode->class != AUXREG)
1816 /* Convert the symbol to a constant if possible. */
1817 p = S_GET_NAME (tok[i].X_add_symbol);
1820 auxr = &arc_aux_regs[0];
1821 for (j = 0; j < arc_num_aux_regs; j++, auxr++)
1822 if (len == auxr->length
1823 && strcasecmp (auxr->name, p) == 0)
1825 tok[i].X_op = O_constant;
1826 tok[i].X_add_number = auxr->address;
1836 /* Given an opcode name, pre-tockenized set of argumenst and the
1837 opcode flags, take it all the way through emission. */
1840 assemble_tokens (const char *opname,
1843 struct arc_flags *pflags,
1846 bfd_boolean found_something = FALSE;
1847 const struct arc_opcode *opcode;
1850 /* Search opcodes. */
1851 opcode = (const struct arc_opcode *) hash_find (arc_opcode_hash, opname);
1853 /* Couldn't find opcode conventional way, try special cases. */
1855 opcode = find_special_case (opname, &nflgs, pflags, tok, &ntok);
1859 pr_debug ("%s:%d: assemble_tokens: %s trying opcode 0x%08X\n",
1860 frag_now->fr_file, frag_now->fr_line, opcode->name,
1863 preprocess_operands (opcode, tok, ntok);
1865 found_something = TRUE;
1866 opcode = find_opcode_match (opcode, tok, &ntok, pflags, nflgs, &cpumatch);
1869 struct arc_insn insn;
1870 assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
1876 if (found_something)
1879 as_bad (_("inappropriate arguments for opcode '%s'"), opname);
1881 as_bad (_("opcode '%s' not supported for target %s"), opname,
1885 as_bad (_("unknown opcode '%s'"), opname);
1888 /* Used to find special case opcode. */
1890 static const struct arc_opcode *
1891 find_special_case (const char *opname,
1893 struct arc_flags *pflags,
1897 const struct arc_opcode *opcode;
1899 opcode = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
1902 opcode = find_special_case_flag (opname, nflgs, pflags);
1907 /* Swap operand tokens. */
1910 swap_operand (expressionS *operand_array,
1912 unsigned destination)
1914 expressionS cpy_operand;
1915 expressionS *src_operand;
1916 expressionS *dst_operand;
1919 if (source == destination)
1922 src_operand = &operand_array[source];
1923 dst_operand = &operand_array[destination];
1924 size = sizeof (expressionS);
1926 /* Make copy of operand to swap with and swap. */
1927 memcpy (&cpy_operand, dst_operand, size);
1928 memcpy (dst_operand, src_operand, size);
1929 memcpy (src_operand, &cpy_operand, size);
1932 /* Check if *op matches *tok type.
1933 Returns FALSE if they don't match, TRUE if they match. */
1936 pseudo_operand_match (const expressionS *tok,
1937 const struct arc_operand_operation *op)
1939 offsetT min, max, val;
1941 const struct arc_operand *operand_real = &arc_operands[op->operand_idx];
1947 if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM))
1949 else if (!(operand_real->flags & ARC_OPERAND_IR))
1951 val = tok->X_add_number + op->count;
1952 if (operand_real->flags & ARC_OPERAND_SIGNED)
1954 max = (1 << (operand_real->bits - 1)) - 1;
1955 min = -(1 << (operand_real->bits - 1));
1959 max = (1 << operand_real->bits) - 1;
1962 if (min <= val && val <= max)
1968 /* Handle all symbols as long immediates or signed 9. */
1969 if (operand_real->flags & ARC_OPERAND_LIMM ||
1970 ((operand_real->flags & ARC_OPERAND_SIGNED) && operand_real->bits == 9))
1975 if (operand_real->flags & ARC_OPERAND_IR)
1980 if (operand_real->flags & ARC_OPERAND_BRAKET)
1991 /* Find pseudo instruction in array. */
1993 static const struct arc_pseudo_insn *
1994 find_pseudo_insn (const char *opname,
1996 const expressionS *tok)
1998 const struct arc_pseudo_insn *pseudo_insn = NULL;
1999 const struct arc_operand_operation *op;
2003 for (i = 0; i < arc_num_pseudo_insn; ++i)
2005 pseudo_insn = &arc_pseudo_insns[i];
2006 if (strcmp (pseudo_insn->mnemonic_p, opname) == 0)
2008 op = pseudo_insn->operand;
2009 for (j = 0; j < ntok; ++j)
2010 if (!pseudo_operand_match (&tok[j], &op[j]))
2013 /* Found the right instruction. */
2021 /* Assumes the expressionS *tok is of sufficient size. */
2023 static const struct arc_opcode *
2024 find_special_case_pseudo (const char *opname,
2028 struct arc_flags *pflags)
2030 const struct arc_pseudo_insn *pseudo_insn = NULL;
2031 const struct arc_operand_operation *operand_pseudo;
2032 const struct arc_operand *operand_real;
2034 char construct_operand[MAX_CONSTR_STR];
2036 /* Find whether opname is in pseudo instruction array. */
2037 pseudo_insn = find_pseudo_insn (opname, *ntok, tok);
2039 if (pseudo_insn == NULL)
2042 /* Handle flag, Limited to one flag at the moment. */
2043 if (pseudo_insn->flag_r != NULL)
2044 *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs],
2045 MAX_INSN_FLGS - *nflgs);
2047 /* Handle operand operations. */
2048 for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2050 operand_pseudo = &pseudo_insn->operand[i];
2051 operand_real = &arc_operands[operand_pseudo->operand_idx];
2053 if (operand_real->flags & ARC_OPERAND_BRAKET &&
2054 !operand_pseudo->needs_insert)
2057 /* Has to be inserted (i.e. this token does not exist yet). */
2058 if (operand_pseudo->needs_insert)
2060 if (operand_real->flags & ARC_OPERAND_BRAKET)
2062 tok[i].X_op = O_bracket;
2067 /* Check if operand is a register or constant and handle it
2069 if (operand_real->flags & ARC_OPERAND_IR)
2070 snprintf (construct_operand, MAX_CONSTR_STR, "r%d",
2071 operand_pseudo->count);
2073 snprintf (construct_operand, MAX_CONSTR_STR, "%d",
2074 operand_pseudo->count);
2076 tokenize_arguments (construct_operand, &tok[i], 1);
2080 else if (operand_pseudo->count)
2082 /* Operand number has to be adjusted accordingly (by operand
2084 switch (tok[i].X_op)
2087 tok[i].X_add_number += operand_pseudo->count;
2100 /* Swap operands if necessary. Only supports one swap at the
2102 for (i = 0; i < pseudo_insn->operand_cnt; ++i)
2104 operand_pseudo = &pseudo_insn->operand[i];
2106 if (operand_pseudo->swap_operand_idx == i)
2109 swap_operand (tok, i, operand_pseudo->swap_operand_idx);
2111 /* Prevent a swap back later by breaking out. */
2115 return (const struct arc_opcode *)
2116 hash_find (arc_opcode_hash, pseudo_insn->mnemonic_r);
2119 static const struct arc_opcode *
2120 find_special_case_flag (const char *opname,
2122 struct arc_flags *pflags)
2126 unsigned flag_idx, flag_arr_idx;
2127 size_t flaglen, oplen;
2128 const struct arc_flag_special *arc_flag_special_opcode;
2129 const struct arc_opcode *opcode;
2131 /* Search for special case instruction. */
2132 for (i = 0; i < arc_num_flag_special; i++)
2134 arc_flag_special_opcode = &arc_flag_special_cases[i];
2135 oplen = strlen (arc_flag_special_opcode->name);
2137 if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0)
2140 /* Found a potential special case instruction, now test for
2142 for (flag_arr_idx = 0;; ++flag_arr_idx)
2144 flag_idx = arc_flag_special_opcode->flags[flag_arr_idx];
2146 break; /* End of array, nothing found. */
2148 flagnm = arc_flag_operands[flag_idx].name;
2149 flaglen = strlen (flagnm);
2150 if (strcmp (opname + oplen, flagnm) == 0)
2152 opcode = (const struct arc_opcode *)
2153 hash_find (arc_opcode_hash,
2154 arc_flag_special_opcode->name);
2156 if (*nflgs + 1 > MAX_INSN_FLGS)
2158 memcpy (pflags[*nflgs].name, flagnm, flaglen);
2159 pflags[*nflgs].name[flaglen] = '\0';
2168 /* Check whether a symbol involves a register. */
2171 contains_register (symbolS *sym)
2175 expressionS *ex = symbol_get_value_expression (sym);
2176 return ((O_register == ex->X_op)
2177 && !contains_register (ex->X_add_symbol)
2178 && !contains_register (ex->X_op_symbol));
2184 /* Returns the register number within a symbol. */
2187 get_register (symbolS *sym)
2189 if (!contains_register (sym))
2192 expressionS *ex = symbol_get_value_expression (sym);
2193 return regno (ex->X_add_number);
2196 /* Allocates a tok entry. */
2199 allocate_tok (expressionS *tok, int ntok, int cidx)
2201 if (ntok > MAX_INSN_ARGS - 2)
2202 return 0; /* No space left. */
2205 return 0; /* Incorect args. */
2207 memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok));
2210 return 1; /* Success. */
2211 return allocate_tok (tok, ntok - 1, cidx);
2214 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
2215 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
2218 generic_reloc_p (extended_bfd_reloc_code_real_type reloc)
2225 case BFD_RELOC_ARC_SDA_LDST:
2226 case BFD_RELOC_ARC_SDA_LDST1:
2227 case BFD_RELOC_ARC_SDA_LDST2:
2228 case BFD_RELOC_ARC_SDA16_LD:
2229 case BFD_RELOC_ARC_SDA16_LD1:
2230 case BFD_RELOC_ARC_SDA16_LD2:
2231 case BFD_RELOC_ARC_SDA16_ST2:
2232 case BFD_RELOC_ARC_SDA32_ME:
2240 /* Search forward through all variants of an opcode looking for a
2243 static const struct arc_opcode *
2244 find_opcode_match (const struct arc_opcode *first_opcode,
2247 struct arc_flags *first_pflag,
2251 const struct arc_opcode *opcode = first_opcode;
2253 int got_cpu_match = 0;
2254 expressionS bktok[MAX_INSN_ARGS];
2258 memset (&emptyE, 0, sizeof (emptyE));
2259 memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
2264 const unsigned char *opidx;
2265 const unsigned char *flgidx;
2267 const expressionS *t = &emptyE;
2269 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
2270 frag_now->fr_file, frag_now->fr_line, opcode->opcode);
2272 /* Don't match opcodes that don't exist on this
2274 if (!(opcode->cpu & arc_target))
2277 if (is_code_density_p (opcode) && !(arc_features & ARC_CD))
2283 /* Check the operands. */
2284 for (opidx = opcode->operands; *opidx; ++opidx)
2286 const struct arc_operand *operand = &arc_operands[*opidx];
2288 /* Only take input from real operands. */
2289 if ((operand->flags & ARC_OPERAND_FAKE)
2290 && !(operand->flags & ARC_OPERAND_BRAKET))
2293 /* When we expect input, make sure we have it. */
2297 /* Match operand type with expression type. */
2298 switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
2300 case ARC_OPERAND_IR:
2301 /* Check to be a register. */
2302 if ((tok[tokidx].X_op != O_register
2303 || !is_ir_num (tok[tokidx].X_add_number))
2304 && !(operand->flags & ARC_OPERAND_IGNORE))
2307 /* If expect duplicate, make sure it is duplicate. */
2308 if (operand->flags & ARC_OPERAND_DUPLICATE)
2310 /* Check for duplicate. */
2311 if (t->X_op != O_register
2312 || !is_ir_num (t->X_add_number)
2313 || (regno (t->X_add_number) !=
2314 regno (tok[tokidx].X_add_number)))
2318 /* Special handling? */
2319 if (operand->insert)
2321 const char *errmsg = NULL;
2322 (*operand->insert)(0,
2323 regno (tok[tokidx].X_add_number),
2327 if (operand->flags & ARC_OPERAND_IGNORE)
2329 /* Missing argument, create one. */
2330 if (!allocate_tok (tok, ntok - 1, tokidx))
2333 tok[tokidx].X_op = O_absent;
2344 case ARC_OPERAND_BRAKET:
2345 /* Check if bracket is also in opcode table as
2347 if (tok[tokidx].X_op != O_bracket)
2351 case ARC_OPERAND_LIMM:
2352 case ARC_OPERAND_SIGNED:
2353 case ARC_OPERAND_UNSIGNED:
2354 switch (tok[tokidx].X_op)
2362 /* Got an (too) early bracket, check if it is an
2363 ignored operand. N.B. This procedure works only
2364 when bracket is the last operand! */
2365 if (!(operand->flags & ARC_OPERAND_IGNORE))
2367 /* Insert the missing operand. */
2368 if (!allocate_tok (tok, ntok - 1, tokidx))
2371 tok[tokidx].X_op = O_absent;
2376 /* Check the range. */
2377 if (operand->bits != 32
2378 && !(operand->flags & ARC_OPERAND_NCHK))
2380 offsetT min, max, val;
2381 val = tok[tokidx].X_add_number;
2383 if (operand->flags & ARC_OPERAND_SIGNED)
2385 max = (1 << (operand->bits - 1)) - 1;
2386 min = -(1 << (operand->bits - 1));
2390 max = (1 << operand->bits) - 1;
2394 if (val < min || val > max)
2397 /* Check alignmets. */
2398 if ((operand->flags & ARC_OPERAND_ALIGNED32)
2402 if ((operand->flags & ARC_OPERAND_ALIGNED16)
2406 else if (operand->flags & ARC_OPERAND_NCHK)
2408 if (operand->insert)
2410 const char *errmsg = NULL;
2411 (*operand->insert)(0,
2412 tok[tokidx].X_add_number,
2423 /* Check if it is register range. */
2424 if ((tok[tokidx].X_add_number == 0)
2425 && contains_register (tok[tokidx].X_add_symbol)
2426 && contains_register (tok[tokidx].X_op_symbol))
2430 regs = get_register (tok[tokidx].X_add_symbol);
2432 regs |= get_register (tok[tokidx].X_op_symbol);
2433 if (operand->insert)
2435 const char *errmsg = NULL;
2436 (*operand->insert)(0,
2447 if (operand->default_reloc == 0)
2448 goto match_failed; /* The operand needs relocation. */
2450 /* Relocs requiring long immediate. FIXME! make it
2451 generic and move it to a function. */
2452 switch (tok[tokidx].X_md)
2461 if (!(operand->flags & ARC_OPERAND_LIMM))
2464 if (!generic_reloc_p (operand->default_reloc))
2471 /* If expect duplicate, make sure it is duplicate. */
2472 if (operand->flags & ARC_OPERAND_DUPLICATE)
2474 if (t->X_op == O_illegal
2475 || t->X_op == O_absent
2476 || t->X_op == O_register
2477 || (t->X_add_number != tok[tokidx].X_add_number))
2484 /* Everything else should have been fake. */
2492 /* Check the flags. Iterate over the valid flag classes. */
2495 for (flgidx = opcode->flags; *flgidx && lnflg; ++flgidx)
2497 /* Get a valid flag class. */
2498 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
2499 const unsigned *flgopridx;
2501 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
2503 const struct arc_flag_operand *flg_operand;
2504 struct arc_flags *pflag = first_pflag;
2507 flg_operand = &arc_flag_operands[*flgopridx];
2508 for (i = 0; i < nflgs; i++, pflag++)
2510 /* Match against the parsed flags. */
2511 if (!strcmp (flg_operand->name, pflag->name))
2513 /*TODO: Check if it is duplicated. */
2514 pflag->code = *flgopridx;
2516 break; /* goto next flag class and parsed flag. */
2521 /* Did I check all the parsed flags? */
2526 /* Possible match -- did we use all of our input? */
2536 /* Restore the original parameters. */
2537 memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok));
2540 while (++opcode - arc_opcodes < (int) arc_num_opcodes
2541 && !strcmp (opcode->name, first_opcode->name));
2544 *pcpumatch = got_cpu_match;
2549 /* Find the proper relocation for the given opcode. */
2551 static extended_bfd_reloc_code_real_type
2552 find_reloc (const char *name,
2553 const char *opcodename,
2554 const struct arc_flags *pflags,
2556 extended_bfd_reloc_code_real_type reloc)
2560 bfd_boolean found_flag, tmp;
2561 extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED;
2563 for (i = 0; i < arc_num_equiv_tab; i++)
2565 const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i];
2567 /* Find the entry. */
2568 if (strcmp (name, r->name))
2570 if (r->mnemonic && (strcmp (r->mnemonic, opcodename)))
2577 unsigned * psflg = (unsigned *)r->flags;
2581 for (j = 0; j < nflg; j++)
2582 if (!strcmp (pflags[j].name,
2583 arc_flag_operands[*psflg].name))
2604 if (reloc != r->oldreloc)
2611 if (ret == BFD_RELOC_UNUSED)
2612 as_bad (_("Unable to find %s relocation for instruction %s"),
2617 /* Turn an opcode description and a set of arguments into
2618 an instruction and a fixup. */
2621 assemble_insn (const struct arc_opcode *opcode,
2622 const expressionS *tok,
2624 const struct arc_flags *pflags,
2626 struct arc_insn *insn)
2628 const expressionS *reloc_exp = NULL;
2630 const unsigned char *argidx;
2633 unsigned char pcrel = 0;
2634 bfd_boolean needGOTSymbol;
2635 bfd_boolean has_delay_slot = FALSE;
2636 extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
2638 memset (insn, 0, sizeof (*insn));
2639 image = opcode->opcode;
2641 pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
2642 frag_now->fr_file, frag_now->fr_line, opcode->name,
2645 /* Handle operands. */
2646 for (argidx = opcode->operands; *argidx; ++argidx)
2648 const struct arc_operand *operand = &arc_operands[*argidx];
2649 const expressionS *t = (const expressionS *) 0;
2651 if ((operand->flags & ARC_OPERAND_FAKE)
2652 && !(operand->flags & ARC_OPERAND_BRAKET))
2655 if (operand->flags & ARC_OPERAND_DUPLICATE)
2657 /* Duplicate operand, already inserted. */
2669 /* Regardless if we have a reloc or not mark the instruction
2670 limm if it is the case. */
2671 if (operand->flags & ARC_OPERAND_LIMM)
2672 insn->has_limm = TRUE;
2677 image = insert_operand (image, operand, regno (t->X_add_number),
2682 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2684 if (operand->flags & ARC_OPERAND_LIMM)
2685 insn->limm = t->X_add_number;
2689 /* Ignore brackets. */
2693 gas_assert (operand->flags & ARC_OPERAND_IGNORE);
2697 /* Maybe register range. */
2698 if ((t->X_add_number == 0)
2699 && contains_register (t->X_add_symbol)
2700 && contains_register (t->X_op_symbol))
2704 regs = get_register (t->X_add_symbol);
2706 regs |= get_register (t->X_op_symbol);
2707 image = insert_operand (image, operand, regs, NULL, 0);
2712 /* This operand needs a relocation. */
2713 needGOTSymbol = FALSE;
2718 needGOTSymbol = TRUE;
2719 reloc = find_reloc ("plt", opcode->name,
2721 operand->default_reloc);
2726 needGOTSymbol = TRUE;
2727 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
2730 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
2731 if (ARC_SHORT (opcode->mask))
2732 as_bad_where (frag_now->fr_file, frag_now->fr_line,
2733 _("Unable to use @pcl relocation for insn %s"),
2737 reloc = find_reloc ("sda", opcode->name,
2739 operand->default_reloc);
2743 needGOTSymbol = TRUE;
2748 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
2751 case O_tpoff9: /*FIXME! Check for the conditionality of
2753 case O_dtpoff9: /*FIXME! Check for the conditionality of
2755 as_bad (_("TLS_*_S9 relocs are not supported yet"));
2759 /* Just consider the default relocation. */
2760 reloc = operand->default_reloc;
2764 if (needGOTSymbol && (GOT_symbol == NULL))
2765 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
2772 /* sanity checks. */
2773 reloc_howto_type *reloc_howto
2774 = bfd_reloc_type_lookup (stdoutput,
2775 (bfd_reloc_code_real_type) reloc);
2776 unsigned reloc_bitsize = reloc_howto->bitsize;
2777 if (reloc_howto->rightshift)
2778 reloc_bitsize -= reloc_howto->rightshift;
2779 if (reloc_bitsize != operand->bits)
2781 as_bad (_("invalid relocation %s for field"),
2782 bfd_get_reloc_code_name (reloc));
2787 if (insn->nfixups >= MAX_INSN_FIXUPS)
2788 as_fatal (_("too many fixups"));
2790 struct arc_fixup *fixup;
2791 fixup = &insn->fixups[insn->nfixups++];
2793 fixup->reloc = reloc;
2794 pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
2795 fixup->pcrel = pcrel;
2796 fixup->islong = (operand->flags & ARC_OPERAND_LIMM) ?
2803 for (i = 0; i < nflg; i++)
2805 const struct arc_flag_operand *flg_operand =
2806 &arc_flag_operands[pflags[i].code];
2808 /* Check if the instruction has a delay slot. */
2809 if (!strcmp (flg_operand->name, "d"))
2810 has_delay_slot = TRUE;
2812 /* There is an exceptional case when we cannot insert a flag
2813 just as it is. The .T flag must be handled in relation with
2814 the relative address. */
2815 if (!strcmp (flg_operand->name, "t")
2816 || !strcmp (flg_operand->name, "nt"))
2818 unsigned bitYoperand = 0;
2819 /* FIXME! move selection bbit/brcc in arc-opc.c. */
2820 if (!strcmp (flg_operand->name, "t"))
2821 if (!strcmp (opcode->name, "bbit0")
2822 || !strcmp (opcode->name, "bbit1"))
2823 bitYoperand = arc_NToperand;
2825 bitYoperand = arc_Toperand;
2827 if (!strcmp (opcode->name, "bbit0")
2828 || !strcmp (opcode->name, "bbit1"))
2829 bitYoperand = arc_Toperand;
2831 bitYoperand = arc_NToperand;
2833 gas_assert (reloc_exp != NULL);
2834 if (reloc_exp->X_op == O_constant)
2836 /* Check if we have a constant and solved it
2838 offsetT val = reloc_exp->X_add_number;
2839 image |= insert_operand (image, &arc_operands[bitYoperand],
2844 struct arc_fixup *fixup;
2846 if (insn->nfixups >= MAX_INSN_FIXUPS)
2847 as_fatal (_("too many fixups"));
2849 fixup = &insn->fixups[insn->nfixups++];
2850 fixup->exp = *reloc_exp;
2851 fixup->reloc = -bitYoperand;
2852 fixup->pcrel = pcrel;
2853 fixup->islong = FALSE;
2857 image |= (flg_operand->code & ((1 << flg_operand->bits) - 1))
2858 << flg_operand->shift;
2861 /* Short instruction? */
2862 insn->short_insn = ARC_SHORT (opcode->mask) ? TRUE : FALSE;
2866 /* Update last insn status. */
2867 arc_last_insns[1] = arc_last_insns[0];
2868 arc_last_insns[0].opcode = opcode;
2869 arc_last_insns[0].has_limm = insn->has_limm;
2870 arc_last_insns[0].has_delay_slot = has_delay_slot;
2872 /* Check if the current instruction is legally used. */
2873 if (arc_last_insns[1].has_delay_slot
2874 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
2875 as_bad_where (frag_now->fr_file, frag_now->fr_line,
2876 _("A jump/branch instruction in delay slot."));
2879 /* Actually output an instruction with its fixup. */
2882 emit_insn (struct arc_insn *insn)
2887 pr_debug ("Emit insn : 0x%x\n", insn->insn);
2888 pr_debug ("\tShort : 0x%d\n", insn->short_insn);
2889 pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
2891 /* Write out the instruction. */
2892 if (insn->short_insn)
2897 md_number_to_chars (f, insn->insn, 2);
2898 md_number_to_chars_midend (f + 2, insn->limm, 4);
2899 dwarf2_emit_insn (6);
2904 md_number_to_chars (f, insn->insn, 2);
2905 dwarf2_emit_insn (2);
2913 md_number_to_chars_midend (f, insn->insn, 4);
2914 md_number_to_chars_midend (f + 4, insn->limm, 4);
2915 dwarf2_emit_insn (8);
2920 md_number_to_chars_midend (f, insn->insn, 4);
2921 dwarf2_emit_insn (4);
2925 /* Apply the fixups in order. */
2926 for (i = 0; i < insn->nfixups; i++)
2928 struct arc_fixup *fixup = &insn->fixups[i];
2929 int size, pcrel, offset = 0;
2931 /*FIXME! the reloc size is wrong in the BFD file. When it will
2932 be fixed please delete me. */
2933 size = (insn->short_insn && !fixup->islong) ? 2 : 4;
2936 offset = (insn->short_insn) ? 2 : 4;
2938 /* Some fixups are only used internally, thus no howto. */
2939 if ((int) fixup->reloc < 0)
2941 /*FIXME! the reloc size is wrong in the BFD file. When it
2942 will be fixed please enable me.
2943 size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
2944 pcrel = fixup->pcrel;
2948 reloc_howto_type *reloc_howto =
2949 bfd_reloc_type_lookup (stdoutput,
2950 (bfd_reloc_code_real_type) fixup->reloc);
2951 gas_assert (reloc_howto);
2952 /*FIXME! the reloc size is wrong in the BFD file. When it
2953 will be fixed please enable me.
2954 size = bfd_get_reloc_size (reloc_howto); */
2955 pcrel = reloc_howto->pc_relative;
2958 pr_debug ("%s:%d: emit_insn: new %s fixup (PCrel:%s) of size %d @ offset %d\n",
2959 frag_now->fr_file, frag_now->fr_line,
2960 (fixup->reloc < 0) ? "Internal" :
2961 bfd_get_reloc_code_name (fixup->reloc),
2964 fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
2965 size, &fixup->exp, pcrel, fixup->reloc);
2967 /* Check for ZOLs, and update symbol info if any. */
2968 if (LP_INSN (insn->insn))
2970 gas_assert (fixup->exp.X_add_symbol);
2971 ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL);
2976 /* Insert an operand value into an instruction. */
2979 insert_operand (unsigned insn,
2980 const struct arc_operand *operand,
2985 offsetT min = 0, max = 0;
2987 if (operand->bits != 32
2988 && !(operand->flags & ARC_OPERAND_NCHK)
2989 && !(operand->flags & ARC_OPERAND_FAKE))
2991 if (operand->flags & ARC_OPERAND_SIGNED)
2993 max = (1 << (operand->bits - 1)) - 1;
2994 min = -(1 << (operand->bits - 1));
2998 max = (1 << operand->bits) - 1;
3002 if (val < min || val > max)
3003 as_bad_value_out_of_range (_("operand"),
3004 val, min, max, file, line);
3007 pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
3008 min, val, max, insn);
3010 if ((operand->flags & ARC_OPERAND_ALIGNED32)
3012 as_bad_where (file, line,
3013 _("Unaligned operand. Needs to be 32bit aligned"));
3015 if ((operand->flags & ARC_OPERAND_ALIGNED16)
3017 as_bad_where (file, line,
3018 _("Unaligned operand. Needs to be 16bit aligned"));
3020 if (operand->insert)
3022 const char *errmsg = NULL;
3024 insn = (*operand->insert) (insn, val, &errmsg);
3026 as_warn_where (file, line, "%s", errmsg);
3030 if (operand->flags & ARC_OPERAND_TRUNCATE)
3032 if (operand->flags & ARC_OPERAND_ALIGNED32)
3034 if (operand->flags & ARC_OPERAND_ALIGNED16)
3037 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
3043 arc_handle_align (fragS* fragP)
3045 if ((fragP)->fr_type == rs_align_code)
3047 char *dest = (fragP)->fr_literal + (fragP)->fr_fix;
3048 valueT count = ((fragP)->fr_next->fr_address
3049 - (fragP)->fr_address - (fragP)->fr_fix);
3051 (fragP)->fr_var = 2;
3053 if (count & 1)/* Padding in the gap till the next 2-byte
3054 boundary with 0s. */
3059 /* Writing nop_s. */
3060 md_number_to_chars (dest, NOP_OPCODE_S, 2);
3064 /* Here we decide which fixups can be adjusted to make them relative
3065 to the beginning of the section instead of the symbol. Basically
3066 we need to make sure that the dynamic relocations are done
3067 correctly, so in some cases we force the original symbol to be
3071 tc_arc_fix_adjustable (fixS *fixP)
3074 /* Prevent all adjustments to global symbols. */
3075 if (S_IS_EXTERNAL (fixP->fx_addsy))
3077 if (S_IS_WEAK (fixP->fx_addsy))
3080 /* Adjust_reloc_syms doesn't know about the GOT. */
3081 switch (fixP->fx_r_type)
3083 case BFD_RELOC_ARC_GOTPC32:
3084 case BFD_RELOC_ARC_PLT32:
3085 case BFD_RELOC_ARC_S25H_PCREL_PLT:
3086 case BFD_RELOC_ARC_S21H_PCREL_PLT:
3087 case BFD_RELOC_ARC_S25W_PCREL_PLT:
3088 case BFD_RELOC_ARC_S21W_PCREL_PLT:
3095 return 0; /* FIXME! return 1, fix it in the linker. */
3098 /* Compute the reloc type of an expression EXP. */
3101 arc_check_reloc (expressionS *exp,
3102 bfd_reloc_code_real_type *r_type_p)
3104 if (*r_type_p == BFD_RELOC_32
3105 && exp->X_op == O_subtract
3106 && exp->X_op_symbol != NULL
3107 && exp->X_op_symbol->bsym->section == now_seg)
3108 *r_type_p = BFD_RELOC_ARC_32_PCREL;
3112 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
3115 arc_cons_fix_new (fragS *frag,
3119 bfd_reloc_code_real_type r_type)
3121 r_type = BFD_RELOC_UNUSED;
3126 r_type = BFD_RELOC_8;
3130 r_type = BFD_RELOC_16;
3134 r_type = BFD_RELOC_24;
3138 r_type = BFD_RELOC_32;
3139 arc_check_reloc (exp, &r_type);
3143 r_type = BFD_RELOC_64;
3147 as_bad (_("unsupported BFD relocation size %u"), size);
3148 r_type = BFD_RELOC_UNUSED;
3151 fix_new_exp (frag, off, size, exp, 0, r_type);
3154 /* The actual routine that checks the ZOL conditions. */
3157 check_zol (symbolS *s)
3159 switch (arc_mach_type)
3161 case bfd_mach_arc_arcv2:
3162 if (arc_target & ARC_OPCODE_ARCv2EM)
3165 if (is_br_jmp_insn_p (arc_last_insns[0].opcode)
3166 || arc_last_insns[1].has_delay_slot)
3167 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
3171 case bfd_mach_arc_arc600:
3173 if (is_kernel_insn_p (arc_last_insns[0].opcode))
3174 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
3177 if (arc_last_insns[0].has_limm
3178 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
3179 as_bad (_("A jump instruction with long immediate detected at the \
3180 end of the ZOL label @%s"), S_GET_NAME (s));
3183 case bfd_mach_arc_arc700:
3184 if (arc_last_insns[0].has_delay_slot)
3185 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
3194 /* If ZOL end check the last two instruction for illegals. */
3196 arc_frob_label (symbolS * sym)
3198 if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL)
3201 dwarf2_emit_label (sym);