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