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