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