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