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