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