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