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