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