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