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