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