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