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