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