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