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