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