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