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