[ARC] Prepare strings for automatic translation.
[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,
1084 "abcdefghijklmnopqrstuvwxyz0123456789");
1085 if (flgnamelen > MAX_FLAG_NAME_LENGTH)
1086 goto err;
1087
1088 memcpy (flags->name, input_line_pointer, flgnamelen);
1089
1090 input_line_pointer += flgnamelen;
1091 flags++;
1092 saw_dot = FALSE;
1093 saw_flg = TRUE;
1094 num_flags++;
1095 break;
1096 }
1097 }
1098
1099 fini:
1100 input_line_pointer = old_input_line_pointer;
1101 return num_flags;
1102
1103 err:
1104 if (saw_dot)
1105 as_bad (_("extra dot"));
1106 else if (!saw_flg)
1107 as_bad (_("unrecognized flag"));
1108 else
1109 as_bad (_("failed to parse flags"));
1110 input_line_pointer = old_input_line_pointer;
1111 return -1;
1112 }
1113
1114 /* Apply the fixups in order. */
1115
1116 static void
1117 apply_fixups (struct arc_insn *insn, fragS *fragP, int fix)
1118 {
1119 int i;
1120
1121 for (i = 0; i < insn->nfixups; i++)
1122 {
1123 struct arc_fixup *fixup = &insn->fixups[i];
1124 int size, pcrel, offset = 0;
1125
1126 /* FIXME! the reloc size is wrong in the BFD file.
1127 When it is fixed please delete me. */
1128 size = (insn->short_insn && !fixup->islong) ? 2 : 4;
1129
1130 if (fixup->islong)
1131 offset = (insn->short_insn) ? 2 : 4;
1132
1133 /* Some fixups are only used internally, thus no howto. */
1134 if ((int) fixup->reloc == 0)
1135 as_fatal (_("Unhandled reloc type"));
1136
1137 if ((int) fixup->reloc < 0)
1138 {
1139 /* FIXME! the reloc size is wrong in the BFD file.
1140 When it is fixed please enable me.
1141 size = (insn->short_insn && !fixup->islong) ? 2 : 4; */
1142 pcrel = fixup->pcrel;
1143 }
1144 else
1145 {
1146 reloc_howto_type *reloc_howto =
1147 bfd_reloc_type_lookup (stdoutput,
1148 (bfd_reloc_code_real_type) fixup->reloc);
1149 gas_assert (reloc_howto);
1150
1151 /* FIXME! the reloc size is wrong in the BFD file.
1152 When it is fixed please enable me.
1153 size = bfd_get_reloc_size (reloc_howto); */
1154 pcrel = reloc_howto->pc_relative;
1155 }
1156
1157 pr_debug ("%s:%d: apply_fixups: new %s fixup (PCrel:%s) of size %d @ \
1158 offset %d + %d\n",
1159 fragP->fr_file, fragP->fr_line,
1160 (fixup->reloc < 0) ? "Internal" :
1161 bfd_get_reloc_code_name (fixup->reloc),
1162 pcrel ? "Y" : "N",
1163 size, fix, offset);
1164 fix_new_exp (fragP, fix + offset,
1165 size, &fixup->exp, pcrel, fixup->reloc);
1166
1167 /* Check for ZOLs, and update symbol info if any. */
1168 if (LP_INSN (insn->insn))
1169 {
1170 gas_assert (fixup->exp.X_add_symbol);
1171 ARC_SET_FLAG (fixup->exp.X_add_symbol, ARC_FLAG_ZOL);
1172 }
1173 }
1174 }
1175
1176 /* Actually output an instruction with its fixup. */
1177
1178 static void
1179 emit_insn0 (struct arc_insn *insn, char *where, bfd_boolean relax)
1180 {
1181 char *f = where;
1182
1183 pr_debug ("Emit insn : 0x%x\n", insn->insn);
1184 pr_debug ("\tShort : 0x%d\n", insn->short_insn);
1185 pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
1186
1187 /* Write out the instruction. */
1188 if (insn->short_insn)
1189 {
1190 if (insn->has_limm)
1191 {
1192 if (!relax)
1193 f = frag_more (6);
1194 md_number_to_chars (f, insn->insn, 2);
1195 md_number_to_chars_midend (f + 2, insn->limm, 4);
1196 dwarf2_emit_insn (6);
1197 }
1198 else
1199 {
1200 if (!relax)
1201 f = frag_more (2);
1202 md_number_to_chars (f, insn->insn, 2);
1203 dwarf2_emit_insn (2);
1204 }
1205 }
1206 else
1207 {
1208 if (insn->has_limm)
1209 {
1210 if (!relax)
1211 f = frag_more (8);
1212 md_number_to_chars_midend (f, insn->insn, 4);
1213 md_number_to_chars_midend (f + 4, insn->limm, 4);
1214 dwarf2_emit_insn (8);
1215 }
1216 else
1217 {
1218 if (!relax)
1219 f = frag_more (4);
1220 md_number_to_chars_midend (f, insn->insn, 4);
1221 dwarf2_emit_insn (4);
1222 }
1223 }
1224
1225 if (!relax)
1226 apply_fixups (insn, frag_now, (f - frag_now->fr_literal));
1227 }
1228
1229 static void
1230 emit_insn1 (struct arc_insn *insn)
1231 {
1232 /* How frag_var's args are currently configured:
1233 - rs_machine_dependent, to dictate it's a relaxation frag.
1234 - FRAG_MAX_GROWTH, maximum size of instruction
1235 - 0, variable size that might grow...unused by generic relaxation.
1236 - frag_now->fr_subtype, fr_subtype starting value, set previously.
1237 - s, opand expression.
1238 - 0, offset but it's unused.
1239 - 0, opcode but it's unused. */
1240 symbolS *s = make_expr_symbol (&insn->fixups[0].exp);
1241 frag_now->tc_frag_data.pcrel = insn->fixups[0].pcrel;
1242
1243 if (frag_room () < FRAG_MAX_GROWTH)
1244 {
1245 /* Handle differently when frag literal memory is exhausted.
1246 This is used because when there's not enough memory left in
1247 the current frag, a new frag is created and the information
1248 we put into frag_now->tc_frag_data is disregarded. */
1249
1250 struct arc_relax_type relax_info_copy;
1251 relax_substateT subtype = frag_now->fr_subtype;
1252
1253 memcpy (&relax_info_copy, &frag_now->tc_frag_data,
1254 sizeof (struct arc_relax_type));
1255
1256 frag_wane (frag_now);
1257 frag_grow (FRAG_MAX_GROWTH);
1258
1259 memcpy (&frag_now->tc_frag_data, &relax_info_copy,
1260 sizeof (struct arc_relax_type));
1261
1262 frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1263 subtype, s, 0, 0);
1264 }
1265 else
1266 frag_var (rs_machine_dependent, FRAG_MAX_GROWTH, 0,
1267 frag_now->fr_subtype, s, 0, 0);
1268 }
1269
1270 static void
1271 emit_insn (struct arc_insn *insn)
1272 {
1273 if (insn->relax)
1274 emit_insn1 (insn);
1275 else
1276 emit_insn0 (insn, NULL, FALSE);
1277 }
1278
1279 /* Check whether a symbol involves a register. */
1280
1281 static bfd_boolean
1282 contains_register (symbolS *sym)
1283 {
1284 if (sym)
1285 {
1286 expressionS *ex = symbol_get_value_expression (sym);
1287
1288 return ((O_register == ex->X_op)
1289 && !contains_register (ex->X_add_symbol)
1290 && !contains_register (ex->X_op_symbol));
1291 }
1292
1293 return FALSE;
1294 }
1295
1296 /* Returns the register number within a symbol. */
1297
1298 static int
1299 get_register (symbolS *sym)
1300 {
1301 if (!contains_register (sym))
1302 return -1;
1303
1304 expressionS *ex = symbol_get_value_expression (sym);
1305 return regno (ex->X_add_number);
1306 }
1307
1308 /* Return true if a RELOC is generic. A generic reloc is PC-rel of a
1309 simple ME relocation (e.g. RELOC_ARC_32_ME, BFD_RELOC_ARC_PC32. */
1310
1311 static bfd_boolean
1312 generic_reloc_p (extended_bfd_reloc_code_real_type reloc)
1313 {
1314 if (!reloc)
1315 return FALSE;
1316
1317 switch (reloc)
1318 {
1319 case BFD_RELOC_ARC_SDA_LDST:
1320 case BFD_RELOC_ARC_SDA_LDST1:
1321 case BFD_RELOC_ARC_SDA_LDST2:
1322 case BFD_RELOC_ARC_SDA16_LD:
1323 case BFD_RELOC_ARC_SDA16_LD1:
1324 case BFD_RELOC_ARC_SDA16_LD2:
1325 case BFD_RELOC_ARC_SDA16_ST2:
1326 case BFD_RELOC_ARC_SDA32_ME:
1327 return FALSE;
1328 default:
1329 return TRUE;
1330 }
1331 }
1332
1333 /* Allocates a tok entry. */
1334
1335 static int
1336 allocate_tok (expressionS *tok, int ntok, int cidx)
1337 {
1338 if (ntok > MAX_INSN_ARGS - 2)
1339 return 0; /* No space left. */
1340
1341 if (cidx > ntok)
1342 return 0; /* Incorect args. */
1343
1344 memcpy (&tok[ntok+1], &tok[ntok], sizeof (*tok));
1345
1346 if (cidx == ntok)
1347 return 1; /* Success. */
1348 return allocate_tok (tok, ntok - 1, cidx);
1349 }
1350
1351 /* Check if an particular ARC feature is enabled. */
1352
1353 static bfd_boolean
1354 check_cpu_feature (insn_subclass_t sc)
1355 {
1356 if (!(arc_features & ARC_CD)
1357 && is_code_density_p (sc))
1358 return FALSE;
1359
1360 if (!(arc_features & ARC_SPFP)
1361 && is_spfp_p (sc))
1362 return FALSE;
1363
1364 if (!(arc_features & ARC_DPFP)
1365 && is_dpfp_p (sc))
1366 return FALSE;
1367
1368 if (!(arc_features & ARC_FPUDA)
1369 && is_fpuda_p (sc))
1370 return FALSE;
1371
1372 return TRUE;
1373 }
1374
1375 /* Search forward through all variants of an opcode looking for a
1376 syntax match. */
1377
1378 static const struct arc_opcode *
1379 find_opcode_match (const struct arc_opcode *first_opcode,
1380 expressionS *tok,
1381 int *pntok,
1382 struct arc_flags *first_pflag,
1383 int nflgs,
1384 int *pcpumatch)
1385 {
1386 const struct arc_opcode *opcode = first_opcode;
1387 int ntok = *pntok;
1388 int got_cpu_match = 0;
1389 expressionS bktok[MAX_INSN_ARGS];
1390 int bkntok;
1391 expressionS emptyE;
1392
1393 memset (&emptyE, 0, sizeof (emptyE));
1394 memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
1395 bkntok = ntok;
1396
1397 do
1398 {
1399 const unsigned char *opidx;
1400 const unsigned char *flgidx;
1401 int tokidx = 0, lnflg, i;
1402 const expressionS *t = &emptyE;
1403
1404 pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
1405 frag_now->fr_file, frag_now->fr_line, opcode->opcode);
1406
1407 /* Don't match opcodes that don't exist on this
1408 architecture. */
1409 if (!(opcode->cpu & arc_target))
1410 goto match_failed;
1411
1412 if (!check_cpu_feature (opcode->subclass))
1413 goto match_failed;
1414
1415 got_cpu_match = 1;
1416 pr_debug ("cpu ");
1417
1418 /* Check the operands. */
1419 for (opidx = opcode->operands; *opidx; ++opidx)
1420 {
1421 const struct arc_operand *operand = &arc_operands[*opidx];
1422
1423 /* Only take input from real operands. */
1424 if ((operand->flags & ARC_OPERAND_FAKE)
1425 && !(operand->flags & ARC_OPERAND_BRAKET))
1426 continue;
1427
1428 /* When we expect input, make sure we have it. */
1429 if (tokidx >= ntok)
1430 goto match_failed;
1431
1432 /* Match operand type with expression type. */
1433 switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
1434 {
1435 case ARC_OPERAND_IR:
1436 /* Check to be a register. */
1437 if ((tok[tokidx].X_op != O_register
1438 || !is_ir_num (tok[tokidx].X_add_number))
1439 && !(operand->flags & ARC_OPERAND_IGNORE))
1440 goto match_failed;
1441
1442 /* If expect duplicate, make sure it is duplicate. */
1443 if (operand->flags & ARC_OPERAND_DUPLICATE)
1444 {
1445 /* Check for duplicate. */
1446 if (t->X_op != O_register
1447 || !is_ir_num (t->X_add_number)
1448 || (regno (t->X_add_number) !=
1449 regno (tok[tokidx].X_add_number)))
1450 goto match_failed;
1451 }
1452
1453 /* Special handling? */
1454 if (operand->insert)
1455 {
1456 const char *errmsg = NULL;
1457 (*operand->insert)(0,
1458 regno (tok[tokidx].X_add_number),
1459 &errmsg);
1460 if (errmsg)
1461 {
1462 if (operand->flags & ARC_OPERAND_IGNORE)
1463 {
1464 /* Missing argument, create one. */
1465 if (!allocate_tok (tok, ntok - 1, tokidx))
1466 goto match_failed;
1467
1468 tok[tokidx].X_op = O_absent;
1469 ++ntok;
1470 }
1471 else
1472 goto match_failed;
1473 }
1474 }
1475
1476 t = &tok[tokidx];
1477 break;
1478
1479 case ARC_OPERAND_BRAKET:
1480 /* Check if bracket is also in opcode table as
1481 operand. */
1482 if (tok[tokidx].X_op != O_bracket)
1483 goto match_failed;
1484 break;
1485
1486 case ARC_OPERAND_LIMM:
1487 case ARC_OPERAND_SIGNED:
1488 case ARC_OPERAND_UNSIGNED:
1489 switch (tok[tokidx].X_op)
1490 {
1491 case O_illegal:
1492 case O_absent:
1493 case O_register:
1494 goto match_failed;
1495
1496 case O_bracket:
1497 /* Got an (too) early bracket, check if it is an
1498 ignored operand. N.B. This procedure works only
1499 when bracket is the last operand! */
1500 if (!(operand->flags & ARC_OPERAND_IGNORE))
1501 goto match_failed;
1502 /* Insert the missing operand. */
1503 if (!allocate_tok (tok, ntok - 1, tokidx))
1504 goto match_failed;
1505
1506 tok[tokidx].X_op = O_absent;
1507 ++ntok;
1508 break;
1509
1510 case O_symbol:
1511 {
1512 const char *p;
1513 size_t len;
1514 const struct arc_aux_reg *auxr;
1515 unsigned j;
1516
1517 if (opcode->class != AUXREG)
1518 goto de_fault;
1519 p = S_GET_NAME (tok[tokidx].X_add_symbol);
1520 len = strlen (p);
1521
1522 auxr = &arc_aux_regs[0];
1523 for (j = 0; j < arc_num_aux_regs; j++, auxr++)
1524 if (len == auxr->length
1525 && strcasecmp (auxr->name, p) == 0
1526 && ((auxr->subclass == NONE)
1527 || check_cpu_feature (auxr->subclass)))
1528 {
1529 /* We modify the token array here, safe in the
1530 knowledge, that if this was the wrong choice
1531 then the original contents will be restored
1532 from BKTOK. */
1533 tok[tokidx].X_op = O_constant;
1534 tok[tokidx].X_add_number = auxr->address;
1535 break;
1536 }
1537
1538 if (tok[tokidx].X_op != O_constant)
1539 goto de_fault;
1540 }
1541 /* Fall-through */
1542 case O_constant:
1543 /* Check the range. */
1544 if (operand->bits != 32
1545 && !(operand->flags & ARC_OPERAND_NCHK))
1546 {
1547 offsetT min, max, val;
1548 val = tok[tokidx].X_add_number;
1549
1550 if (operand->flags & ARC_OPERAND_SIGNED)
1551 {
1552 max = (1 << (operand->bits - 1)) - 1;
1553 min = -(1 << (operand->bits - 1));
1554 }
1555 else
1556 {
1557 max = (1 << operand->bits) - 1;
1558 min = 0;
1559 }
1560
1561 if (val < min || val > max)
1562 goto match_failed;
1563
1564 /* Check alignmets. */
1565 if ((operand->flags & ARC_OPERAND_ALIGNED32)
1566 && (val & 0x03))
1567 goto match_failed;
1568
1569 if ((operand->flags & ARC_OPERAND_ALIGNED16)
1570 && (val & 0x01))
1571 goto match_failed;
1572 }
1573 else if (operand->flags & ARC_OPERAND_NCHK)
1574 {
1575 if (operand->insert)
1576 {
1577 const char *errmsg = NULL;
1578 (*operand->insert)(0,
1579 tok[tokidx].X_add_number,
1580 &errmsg);
1581 if (errmsg)
1582 goto match_failed;
1583 }
1584 else
1585 goto match_failed;
1586 }
1587 break;
1588
1589 case O_subtract:
1590 /* Check if it is register range. */
1591 if ((tok[tokidx].X_add_number == 0)
1592 && contains_register (tok[tokidx].X_add_symbol)
1593 && contains_register (tok[tokidx].X_op_symbol))
1594 {
1595 int regs;
1596
1597 regs = get_register (tok[tokidx].X_add_symbol);
1598 regs <<= 16;
1599 regs |= get_register (tok[tokidx].X_op_symbol);
1600 if (operand->insert)
1601 {
1602 const char *errmsg = NULL;
1603 (*operand->insert)(0,
1604 regs,
1605 &errmsg);
1606 if (errmsg)
1607 goto match_failed;
1608 }
1609 else
1610 goto match_failed;
1611 break;
1612 }
1613 default:
1614 de_fault:
1615 if (operand->default_reloc == 0)
1616 goto match_failed; /* The operand needs relocation. */
1617
1618 /* Relocs requiring long immediate. FIXME! make it
1619 generic and move it to a function. */
1620 switch (tok[tokidx].X_md)
1621 {
1622 case O_gotoff:
1623 case O_gotpc:
1624 case O_pcl:
1625 case O_tpoff:
1626 case O_dtpoff:
1627 case O_tlsgd:
1628 case O_tlsie:
1629 if (!(operand->flags & ARC_OPERAND_LIMM))
1630 goto match_failed;
1631 case O_absent:
1632 if (!generic_reloc_p (operand->default_reloc))
1633 goto match_failed;
1634 default:
1635 break;
1636 }
1637 break;
1638 }
1639 /* If expect duplicate, make sure it is duplicate. */
1640 if (operand->flags & ARC_OPERAND_DUPLICATE)
1641 {
1642 if (t->X_op == O_illegal
1643 || t->X_op == O_absent
1644 || t->X_op == O_register
1645 || (t->X_add_number != tok[tokidx].X_add_number))
1646 goto match_failed;
1647 }
1648 t = &tok[tokidx];
1649 break;
1650
1651 default:
1652 /* Everything else should have been fake. */
1653 abort ();
1654 }
1655
1656 ++tokidx;
1657 }
1658 pr_debug ("opr ");
1659
1660 /* Setup ready for flag parsing. */
1661 lnflg = nflgs;
1662 for (i = 0; i < nflgs; i++)
1663 first_pflag [i].code = 0;
1664
1665 /* Check the flags. Iterate over the valid flag classes. */
1666 for (flgidx = opcode->flags; *flgidx; ++flgidx)
1667 {
1668 /* Get a valid flag class. */
1669 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
1670 const unsigned *flgopridx;
1671 int cl_matches = 0;
1672
1673 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
1674 {
1675 const struct arc_flag_operand *flg_operand;
1676 struct arc_flags *pflag = first_pflag;
1677
1678 flg_operand = &arc_flag_operands[*flgopridx];
1679 for (i = 0; i < nflgs; i++, pflag++)
1680 {
1681 /* Match against the parsed flags. */
1682 if (!strcmp (flg_operand->name, pflag->name))
1683 {
1684 if (pflag->code != 0)
1685 goto match_failed;
1686 cl_matches++;
1687 pflag->code = *flgopridx;
1688 lnflg--;
1689 break; /* goto next flag class and parsed flag. */
1690 }
1691 }
1692 }
1693
1694 if (cl_flags->class == F_CLASS_REQUIRED && cl_matches == 0)
1695 goto match_failed;
1696 if (cl_flags->class == F_CLASS_OPTIONAL && cl_matches > 1)
1697 goto match_failed;
1698 }
1699 /* Did I check all the parsed flags? */
1700 if (lnflg)
1701 goto match_failed;
1702
1703 pr_debug ("flg");
1704 /* Possible match -- did we use all of our input? */
1705 if (tokidx == ntok)
1706 {
1707 *pntok = ntok;
1708 pr_debug ("\n");
1709 return opcode;
1710 }
1711
1712 match_failed:;
1713 pr_debug ("\n");
1714 /* Restore the original parameters. */
1715 memcpy (tok, bktok, MAX_INSN_ARGS * sizeof (*tok));
1716 ntok = bkntok;
1717 }
1718 while (++opcode - arc_opcodes < (int) arc_num_opcodes
1719 && !strcmp (opcode->name, first_opcode->name));
1720
1721 if (*pcpumatch)
1722 *pcpumatch = got_cpu_match;
1723
1724 return NULL;
1725 }
1726
1727 /* Swap operand tokens. */
1728
1729 static void
1730 swap_operand (expressionS *operand_array,
1731 unsigned source,
1732 unsigned destination)
1733 {
1734 expressionS cpy_operand;
1735 expressionS *src_operand;
1736 expressionS *dst_operand;
1737 size_t size;
1738
1739 if (source == destination)
1740 return;
1741
1742 src_operand = &operand_array[source];
1743 dst_operand = &operand_array[destination];
1744 size = sizeof (expressionS);
1745
1746 /* Make copy of operand to swap with and swap. */
1747 memcpy (&cpy_operand, dst_operand, size);
1748 memcpy (dst_operand, src_operand, size);
1749 memcpy (src_operand, &cpy_operand, size);
1750 }
1751
1752 /* Check if *op matches *tok type.
1753 Returns FALSE if they don't match, TRUE if they match. */
1754
1755 static bfd_boolean
1756 pseudo_operand_match (const expressionS *tok,
1757 const struct arc_operand_operation *op)
1758 {
1759 offsetT min, max, val;
1760 bfd_boolean ret;
1761 const struct arc_operand *operand_real = &arc_operands[op->operand_idx];
1762
1763 ret = FALSE;
1764 switch (tok->X_op)
1765 {
1766 case O_constant:
1767 if (operand_real->bits == 32 && (operand_real->flags & ARC_OPERAND_LIMM))
1768 ret = 1;
1769 else if (!(operand_real->flags & ARC_OPERAND_IR))
1770 {
1771 val = tok->X_add_number + op->count;
1772 if (operand_real->flags & ARC_OPERAND_SIGNED)
1773 {
1774 max = (1 << (operand_real->bits - 1)) - 1;
1775 min = -(1 << (operand_real->bits - 1));
1776 }
1777 else
1778 {
1779 max = (1 << operand_real->bits) - 1;
1780 min = 0;
1781 }
1782 if (min <= val && val <= max)
1783 ret = TRUE;
1784 }
1785 break;
1786
1787 case O_symbol:
1788 /* Handle all symbols as long immediates or signed 9. */
1789 if (operand_real->flags & ARC_OPERAND_LIMM ||
1790 ((operand_real->flags & ARC_OPERAND_SIGNED) && operand_real->bits == 9))
1791 ret = TRUE;
1792 break;
1793
1794 case O_register:
1795 if (operand_real->flags & ARC_OPERAND_IR)
1796 ret = TRUE;
1797 break;
1798
1799 case O_bracket:
1800 if (operand_real->flags & ARC_OPERAND_BRAKET)
1801 ret = TRUE;
1802 break;
1803
1804 default:
1805 /* Unknown. */
1806 break;
1807 }
1808 return ret;
1809 }
1810
1811 /* Find pseudo instruction in array. */
1812
1813 static const struct arc_pseudo_insn *
1814 find_pseudo_insn (const char *opname,
1815 int ntok,
1816 const expressionS *tok)
1817 {
1818 const struct arc_pseudo_insn *pseudo_insn = NULL;
1819 const struct arc_operand_operation *op;
1820 unsigned int i;
1821 int j;
1822
1823 for (i = 0; i < arc_num_pseudo_insn; ++i)
1824 {
1825 pseudo_insn = &arc_pseudo_insns[i];
1826 if (strcmp (pseudo_insn->mnemonic_p, opname) == 0)
1827 {
1828 op = pseudo_insn->operand;
1829 for (j = 0; j < ntok; ++j)
1830 if (!pseudo_operand_match (&tok[j], &op[j]))
1831 break;
1832
1833 /* Found the right instruction. */
1834 if (j == ntok)
1835 return pseudo_insn;
1836 }
1837 }
1838 return NULL;
1839 }
1840
1841 /* Assumes the expressionS *tok is of sufficient size. */
1842
1843 static const struct arc_opcode *
1844 find_special_case_pseudo (const char *opname,
1845 int *ntok,
1846 expressionS *tok,
1847 int *nflgs,
1848 struct arc_flags *pflags)
1849 {
1850 const struct arc_pseudo_insn *pseudo_insn = NULL;
1851 const struct arc_operand_operation *operand_pseudo;
1852 const struct arc_operand *operand_real;
1853 unsigned i;
1854 char construct_operand[MAX_CONSTR_STR];
1855
1856 /* Find whether opname is in pseudo instruction array. */
1857 pseudo_insn = find_pseudo_insn (opname, *ntok, tok);
1858
1859 if (pseudo_insn == NULL)
1860 return NULL;
1861
1862 /* Handle flag, Limited to one flag at the moment. */
1863 if (pseudo_insn->flag_r != NULL)
1864 *nflgs += tokenize_flags (pseudo_insn->flag_r, &pflags[*nflgs],
1865 MAX_INSN_FLGS - *nflgs);
1866
1867 /* Handle operand operations. */
1868 for (i = 0; i < pseudo_insn->operand_cnt; ++i)
1869 {
1870 operand_pseudo = &pseudo_insn->operand[i];
1871 operand_real = &arc_operands[operand_pseudo->operand_idx];
1872
1873 if (operand_real->flags & ARC_OPERAND_BRAKET &&
1874 !operand_pseudo->needs_insert)
1875 continue;
1876
1877 /* Has to be inserted (i.e. this token does not exist yet). */
1878 if (operand_pseudo->needs_insert)
1879 {
1880 if (operand_real->flags & ARC_OPERAND_BRAKET)
1881 {
1882 tok[i].X_op = O_bracket;
1883 ++(*ntok);
1884 continue;
1885 }
1886
1887 /* Check if operand is a register or constant and handle it
1888 by type. */
1889 if (operand_real->flags & ARC_OPERAND_IR)
1890 snprintf (construct_operand, MAX_CONSTR_STR, "r%d",
1891 operand_pseudo->count);
1892 else
1893 snprintf (construct_operand, MAX_CONSTR_STR, "%d",
1894 operand_pseudo->count);
1895
1896 tokenize_arguments (construct_operand, &tok[i], 1);
1897 ++(*ntok);
1898 }
1899
1900 else if (operand_pseudo->count)
1901 {
1902 /* Operand number has to be adjusted accordingly (by operand
1903 type). */
1904 switch (tok[i].X_op)
1905 {
1906 case O_constant:
1907 tok[i].X_add_number += operand_pseudo->count;
1908 break;
1909
1910 case O_symbol:
1911 break;
1912
1913 default:
1914 /* Ignored. */
1915 break;
1916 }
1917 }
1918 }
1919
1920 /* Swap operands if necessary. Only supports one swap at the
1921 moment. */
1922 for (i = 0; i < pseudo_insn->operand_cnt; ++i)
1923 {
1924 operand_pseudo = &pseudo_insn->operand[i];
1925
1926 if (operand_pseudo->swap_operand_idx == i)
1927 continue;
1928
1929 swap_operand (tok, i, operand_pseudo->swap_operand_idx);
1930
1931 /* Prevent a swap back later by breaking out. */
1932 break;
1933 }
1934
1935 return (const struct arc_opcode *)
1936 hash_find (arc_opcode_hash, pseudo_insn->mnemonic_r);
1937 }
1938
1939 static const struct arc_opcode *
1940 find_special_case_flag (const char *opname,
1941 int *nflgs,
1942 struct arc_flags *pflags)
1943 {
1944 unsigned int i;
1945 const char *flagnm;
1946 unsigned flag_idx, flag_arr_idx;
1947 size_t flaglen, oplen;
1948 const struct arc_flag_special *arc_flag_special_opcode;
1949 const struct arc_opcode *opcode;
1950
1951 /* Search for special case instruction. */
1952 for (i = 0; i < arc_num_flag_special; i++)
1953 {
1954 arc_flag_special_opcode = &arc_flag_special_cases[i];
1955 oplen = strlen (arc_flag_special_opcode->name);
1956
1957 if (strncmp (opname, arc_flag_special_opcode->name, oplen) != 0)
1958 continue;
1959
1960 /* Found a potential special case instruction, now test for
1961 flags. */
1962 for (flag_arr_idx = 0;; ++flag_arr_idx)
1963 {
1964 flag_idx = arc_flag_special_opcode->flags[flag_arr_idx];
1965 if (flag_idx == 0)
1966 break; /* End of array, nothing found. */
1967
1968 flagnm = arc_flag_operands[flag_idx].name;
1969 flaglen = strlen (flagnm);
1970 if (strcmp (opname + oplen, flagnm) == 0)
1971 {
1972 opcode = (const struct arc_opcode *)
1973 hash_find (arc_opcode_hash,
1974 arc_flag_special_opcode->name);
1975
1976 if (*nflgs + 1 > MAX_INSN_FLGS)
1977 break;
1978 memcpy (pflags[*nflgs].name, flagnm, flaglen);
1979 pflags[*nflgs].name[flaglen] = '\0';
1980 (*nflgs)++;
1981 return opcode;
1982 }
1983 }
1984 }
1985 return NULL;
1986 }
1987
1988 /* Used to find special case opcode. */
1989
1990 static const struct arc_opcode *
1991 find_special_case (const char *opname,
1992 int *nflgs,
1993 struct arc_flags *pflags,
1994 expressionS *tok,
1995 int *ntok)
1996 {
1997 const struct arc_opcode *opcode;
1998
1999 opcode = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
2000
2001 if (opcode == NULL)
2002 opcode = find_special_case_flag (opname, nflgs, pflags);
2003
2004 return opcode;
2005 }
2006
2007 /* Given an opcode name, pre-tockenized set of argumenst and the
2008 opcode flags, take it all the way through emission. */
2009
2010 static void
2011 assemble_tokens (const char *opname,
2012 expressionS *tok,
2013 int ntok,
2014 struct arc_flags *pflags,
2015 int nflgs)
2016 {
2017 bfd_boolean found_something = FALSE;
2018 const struct arc_opcode *opcode;
2019 int cpumatch = 1;
2020
2021 /* Search opcodes. */
2022 opcode = (const struct arc_opcode *) hash_find (arc_opcode_hash, opname);
2023
2024 /* Couldn't find opcode conventional way, try special cases. */
2025 if (!opcode)
2026 opcode = find_special_case (opname, &nflgs, pflags, tok, &ntok);
2027
2028 if (opcode)
2029 {
2030 pr_debug ("%s:%d: assemble_tokens: %s trying opcode 0x%08X\n",
2031 frag_now->fr_file, frag_now->fr_line, opcode->name,
2032 opcode->opcode);
2033
2034 found_something = TRUE;
2035 opcode = find_opcode_match (opcode, tok, &ntok, pflags, nflgs, &cpumatch);
2036 if (opcode)
2037 {
2038 struct arc_insn insn;
2039 assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
2040 emit_insn (&insn);
2041 return;
2042 }
2043 }
2044
2045 if (found_something)
2046 {
2047 if (cpumatch)
2048 as_bad (_("inappropriate arguments for opcode '%s'"), opname);
2049 else
2050 as_bad (_("opcode '%s' not supported for target %s"), opname,
2051 arc_target_name);
2052 }
2053 else
2054 as_bad (_("unknown opcode '%s'"), opname);
2055 }
2056
2057 /* The public interface to the instruction assembler. */
2058
2059 void
2060 md_assemble (char *str)
2061 {
2062 char *opname;
2063 expressionS tok[MAX_INSN_ARGS];
2064 int ntok, nflg;
2065 size_t opnamelen;
2066 struct arc_flags flags[MAX_INSN_FLGS];
2067
2068 /* Split off the opcode. */
2069 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_0123468");
2070 opname = xmalloc (opnamelen + 1);
2071 memcpy (opname, str, opnamelen);
2072 opname[opnamelen] = '\0';
2073
2074 /* Signalize we are assmbling the instructions. */
2075 assembling_insn = TRUE;
2076
2077 /* Tokenize the flags. */
2078 if ((nflg = tokenize_flags (str + opnamelen, flags, MAX_INSN_FLGS)) == -1)
2079 {
2080 as_bad (_("syntax error"));
2081 return;
2082 }
2083
2084 /* Scan up to the end of the mnemonic which must end in space or end
2085 of string. */
2086 str += opnamelen;
2087 for (; *str != '\0'; str++)
2088 if (*str == ' ')
2089 break;
2090
2091 /* Tokenize the rest of the line. */
2092 if ((ntok = tokenize_arguments (str, tok, MAX_INSN_ARGS)) < 0)
2093 {
2094 as_bad (_("syntax error"));
2095 return;
2096 }
2097
2098 /* Finish it off. */
2099 assemble_tokens (opname, tok, ntok, flags, nflg);
2100 assembling_insn = FALSE;
2101 }
2102
2103 /* Callback to insert a register into the hash table. */
2104
2105 static void
2106 declare_register (const char *name, int number)
2107 {
2108 const char *err;
2109 symbolS *regS = symbol_create (name, reg_section,
2110 number, &zero_address_frag);
2111
2112 err = hash_insert (arc_reg_hash, S_GET_NAME (regS), (void *) regS);
2113 if (err)
2114 as_fatal (_("Inserting \"%s\" into register table failed: %s"),
2115 name, err);
2116 }
2117
2118 /* Construct symbols for each of the general registers. */
2119
2120 static void
2121 declare_register_set (void)
2122 {
2123 int i;
2124 for (i = 0; i < 64; ++i)
2125 {
2126 char name[7];
2127
2128 sprintf (name, "r%d", i);
2129 declare_register (name, i);
2130 if ((i & 0x01) == 0)
2131 {
2132 sprintf (name, "r%dr%d", i, i+1);
2133 declare_register (name, i);
2134 }
2135 }
2136 }
2137
2138 /* Port-specific assembler initialization. This function is called
2139 once, at assembler startup time. */
2140
2141 void
2142 md_begin (void)
2143 {
2144 unsigned int i;
2145
2146 if (!mach_type_specified_p)
2147 arc_select_cpu ("arc700");
2148
2149 /* The endianness can be chosen "at the factory". */
2150 target_big_endian = byte_order == BIG_ENDIAN;
2151
2152 if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
2153 as_warn (_("could not set architecture and machine"));
2154
2155 /* Set elf header flags. */
2156 bfd_set_private_flags (stdoutput, arc_eflag);
2157
2158 /* Set up a hash table for the instructions. */
2159 arc_opcode_hash = hash_new ();
2160 if (arc_opcode_hash == NULL)
2161 as_fatal (_("Virtual memory exhausted"));
2162
2163 /* Initialize the hash table with the insns. */
2164 for (i = 0; i < arc_num_opcodes;)
2165 {
2166 const char *name, *retval;
2167
2168 name = arc_opcodes[i].name;
2169 retval = hash_insert (arc_opcode_hash, name, (void *) &arc_opcodes[i]);
2170 if (retval)
2171 as_fatal (_("internal error: can't hash opcode '%s': %s"),
2172 name, retval);
2173
2174 while (++i < arc_num_opcodes
2175 && (arc_opcodes[i].name == name
2176 || !strcmp (arc_opcodes[i].name, name)))
2177 continue;
2178 }
2179
2180 /* Register declaration. */
2181 arc_reg_hash = hash_new ();
2182 if (arc_reg_hash == NULL)
2183 as_fatal (_("Virtual memory exhausted"));
2184
2185 declare_register_set ();
2186 declare_register ("gp", 26);
2187 declare_register ("fp", 27);
2188 declare_register ("sp", 28);
2189 declare_register ("ilink", 29);
2190 declare_register ("ilink1", 29);
2191 declare_register ("ilink2", 30);
2192 declare_register ("blink", 31);
2193
2194 declare_register ("mlo", 57);
2195 declare_register ("mmid", 58);
2196 declare_register ("mhi", 59);
2197
2198 declare_register ("acc1", 56);
2199 declare_register ("acc2", 57);
2200
2201 declare_register ("lp_count", 60);
2202 declare_register ("pcl", 63);
2203
2204 /* Initialize the last instructions. */
2205 memset (&arc_last_insns[0], 0, sizeof (arc_last_insns));
2206 }
2207
2208 /* Write a value out to the object file, using the appropriate
2209 endianness. */
2210
2211 void
2212 md_number_to_chars (char *buf,
2213 valueT val,
2214 int n)
2215 {
2216 if (target_big_endian)
2217 number_to_chars_bigendian (buf, val, n);
2218 else
2219 number_to_chars_littleendian (buf, val, n);
2220 }
2221
2222 /* Round up a section size to the appropriate boundary. */
2223
2224 valueT
2225 md_section_align (segT segment,
2226 valueT size)
2227 {
2228 int align = bfd_get_section_alignment (stdoutput, segment);
2229
2230 return ((size + (1 << align) - 1) & (-((valueT) 1 << align)));
2231 }
2232
2233 /* The location from which a PC relative jump should be calculated,
2234 given a PC relative reloc. */
2235
2236 long
2237 md_pcrel_from_section (fixS *fixP,
2238 segT sec)
2239 {
2240 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
2241
2242 pr_debug ("pcrel_from_section, fx_offset = %d\n", (int) fixP->fx_offset);
2243
2244 if (fixP->fx_addsy != (symbolS *) NULL
2245 && (!S_IS_DEFINED (fixP->fx_addsy)
2246 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
2247 {
2248 pr_debug ("Unknown pcrel symbol: %s\n", S_GET_NAME (fixP->fx_addsy));
2249
2250 /* The symbol is undefined (or is defined but not in this section).
2251 Let the linker figure it out. */
2252 return 0;
2253 }
2254
2255 if ((int) fixP->fx_r_type < 0)
2256 {
2257 /* These are the "internal" relocations. Align them to
2258 32 bit boundary (PCL), for the moment. */
2259 base &= ~3;
2260 }
2261 else
2262 {
2263 switch (fixP->fx_r_type)
2264 {
2265 case BFD_RELOC_ARC_PC32:
2266 /* The hardware calculates relative to the start of the
2267 insn, but this relocation is relative to location of the
2268 LIMM, compensate. The base always needs to be
2269 substracted by 4 as we do not support this type of PCrel
2270 relocation for short instructions. */
2271 base -= 4;
2272 /* Fall through. */
2273 case BFD_RELOC_ARC_PLT32:
2274 case BFD_RELOC_ARC_S25H_PCREL_PLT:
2275 case BFD_RELOC_ARC_S21H_PCREL_PLT:
2276 case BFD_RELOC_ARC_S25W_PCREL_PLT:
2277 case BFD_RELOC_ARC_S21W_PCREL_PLT:
2278
2279 case BFD_RELOC_ARC_S21H_PCREL:
2280 case BFD_RELOC_ARC_S25H_PCREL:
2281 case BFD_RELOC_ARC_S13_PCREL:
2282 case BFD_RELOC_ARC_S21W_PCREL:
2283 case BFD_RELOC_ARC_S25W_PCREL:
2284 base &= ~3;
2285 break;
2286 default:
2287 as_bad_where (fixP->fx_file, fixP->fx_line,
2288 _("unhandled reloc %s in md_pcrel_from_section"),
2289 bfd_get_reloc_code_name (fixP->fx_r_type));
2290 break;
2291 }
2292 }
2293
2294 pr_debug ("pcrel from %x + %lx = %x, symbol: %s (%x)\n",
2295 fixP->fx_frag->fr_address, fixP->fx_where, base,
2296 fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "(null)",
2297 fixP->fx_addsy ? S_GET_VALUE (fixP->fx_addsy) : 0);
2298
2299 return base;
2300 }
2301
2302 /* Given a BFD relocation find the coresponding operand. */
2303
2304 static const struct arc_operand *
2305 find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc)
2306 {
2307 unsigned i;
2308
2309 for (i = 0; i < arc_num_operands; i++)
2310 if (arc_operands[i].default_reloc == reloc)
2311 return &arc_operands[i];
2312 return NULL;
2313 }
2314
2315 /* Insert an operand value into an instruction. */
2316
2317 static unsigned
2318 insert_operand (unsigned insn,
2319 const struct arc_operand *operand,
2320 offsetT val,
2321 const char *file,
2322 unsigned line)
2323 {
2324 offsetT min = 0, max = 0;
2325
2326 if (operand->bits != 32
2327 && !(operand->flags & ARC_OPERAND_NCHK)
2328 && !(operand->flags & ARC_OPERAND_FAKE))
2329 {
2330 if (operand->flags & ARC_OPERAND_SIGNED)
2331 {
2332 max = (1 << (operand->bits - 1)) - 1;
2333 min = -(1 << (operand->bits - 1));
2334 }
2335 else
2336 {
2337 max = (1 << operand->bits) - 1;
2338 min = 0;
2339 }
2340
2341 if (val < min || val > max)
2342 as_bad_value_out_of_range (_("operand"),
2343 val, min, max, file, line);
2344 }
2345
2346 pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
2347 min, val, max, insn);
2348
2349 if ((operand->flags & ARC_OPERAND_ALIGNED32)
2350 && (val & 0x03))
2351 as_bad_where (file, line,
2352 _("Unaligned operand. Needs to be 32bit aligned"));
2353
2354 if ((operand->flags & ARC_OPERAND_ALIGNED16)
2355 && (val & 0x01))
2356 as_bad_where (file, line,
2357 _("Unaligned operand. Needs to be 16bit aligned"));
2358
2359 if (operand->insert)
2360 {
2361 const char *errmsg = NULL;
2362
2363 insn = (*operand->insert) (insn, val, &errmsg);
2364 if (errmsg)
2365 as_warn_where (file, line, "%s", errmsg);
2366 }
2367 else
2368 {
2369 if (operand->flags & ARC_OPERAND_TRUNCATE)
2370 {
2371 if (operand->flags & ARC_OPERAND_ALIGNED32)
2372 val >>= 2;
2373 if (operand->flags & ARC_OPERAND_ALIGNED16)
2374 val >>= 1;
2375 }
2376 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2377 }
2378 return insn;
2379 }
2380
2381 /* Apply a fixup to the object code. At this point all symbol values
2382 should be fully resolved, and we attempt to completely resolve the
2383 reloc. If we can not do that, we determine the correct reloc code
2384 and put it back in the fixup. To indicate that a fixup has been
2385 eliminated, set fixP->fx_done. */
2386
2387 void
2388 md_apply_fix (fixS *fixP,
2389 valueT *valP,
2390 segT seg)
2391 {
2392 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
2393 valueT value = *valP;
2394 unsigned insn = 0;
2395 symbolS *fx_addsy, *fx_subsy;
2396 offsetT fx_offset;
2397 segT add_symbol_segment = absolute_section;
2398 segT sub_symbol_segment = absolute_section;
2399 const struct arc_operand *operand = NULL;
2400 extended_bfd_reloc_code_real_type reloc;
2401
2402 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2403 fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
2404 ((int) fixP->fx_r_type < 0) ? "Internal":
2405 bfd_get_reloc_code_name (fixP->fx_r_type), value,
2406 fixP->fx_offset);
2407
2408 fx_addsy = fixP->fx_addsy;
2409 fx_subsy = fixP->fx_subsy;
2410 fx_offset = 0;
2411
2412 if (fx_addsy)
2413 {
2414 add_symbol_segment = S_GET_SEGMENT (fx_addsy);
2415 }
2416
2417 if (fx_subsy
2418 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF
2419 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_DTPOFF_S9
2420 && fixP->fx_r_type != BFD_RELOC_ARC_TLS_GD_LD)
2421 {
2422 resolve_symbol_value (fx_subsy);
2423 sub_symbol_segment = S_GET_SEGMENT (fx_subsy);
2424
2425 if (sub_symbol_segment == absolute_section)
2426 {
2427 /* The symbol is really a constant. */
2428 fx_offset -= S_GET_VALUE (fx_subsy);
2429 fx_subsy = NULL;
2430 }
2431 else
2432 {
2433 as_bad_where (fixP->fx_file, fixP->fx_line,
2434 _("can't resolve `%s' {%s section} - `%s' {%s section}"),
2435 fx_addsy ? S_GET_NAME (fx_addsy) : "0",
2436 segment_name (add_symbol_segment),
2437 S_GET_NAME (fx_subsy),
2438 segment_name (sub_symbol_segment));
2439 return;
2440 }
2441 }
2442
2443 if (fx_addsy
2444 && !S_IS_WEAK (fx_addsy))
2445 {
2446 if (add_symbol_segment == seg
2447 && fixP->fx_pcrel)
2448 {
2449 value += S_GET_VALUE (fx_addsy);
2450 value -= md_pcrel_from_section (fixP, seg);
2451 fx_addsy = NULL;
2452 fixP->fx_pcrel = FALSE;
2453 }
2454 else if (add_symbol_segment == absolute_section)
2455 {
2456 value = fixP->fx_offset;
2457 fx_offset += S_GET_VALUE (fixP->fx_addsy);
2458 fx_addsy = NULL;
2459 fixP->fx_pcrel = FALSE;
2460 }
2461 }
2462
2463 if (!fx_addsy)
2464 fixP->fx_done = TRUE;
2465
2466 if (fixP->fx_pcrel)
2467 {
2468 if (fx_addsy
2469 && ((S_IS_DEFINED (fx_addsy)
2470 && S_GET_SEGMENT (fx_addsy) != seg)
2471 || S_IS_WEAK (fx_addsy)))
2472 value += md_pcrel_from_section (fixP, seg);
2473
2474 switch (fixP->fx_r_type)
2475 {
2476 case BFD_RELOC_ARC_32_ME:
2477 /* This is a pc-relative value in a LIMM. Adjust it to the
2478 address of the instruction not to the address of the
2479 LIMM. Note: it is not anylonger valid this afirmation as
2480 the linker consider ARC_PC32 a fixup to entire 64 bit
2481 insn. */
2482 fixP->fx_offset += fixP->fx_frag->fr_address;
2483 /* Fall through. */
2484 case BFD_RELOC_32:
2485 fixP->fx_r_type = BFD_RELOC_ARC_PC32;
2486 /* Fall through. */
2487 case BFD_RELOC_ARC_PC32:
2488 /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
2489 break;
2490 default:
2491 if ((int) fixP->fx_r_type < 0)
2492 as_fatal (_("PC relative relocation not allowed for (internal) type %d"),
2493 fixP->fx_r_type);
2494 break;
2495 }
2496 }
2497
2498 pr_debug ("%s:%u: apply_fix: r_type=%d (%s) value=0x%lX offset=0x%lX\n",
2499 fixP->fx_file, fixP->fx_line, fixP->fx_r_type,
2500 ((int) fixP->fx_r_type < 0) ? "Internal":
2501 bfd_get_reloc_code_name (fixP->fx_r_type), value,
2502 fixP->fx_offset);
2503
2504
2505 /* Now check for TLS relocations. */
2506 reloc = fixP->fx_r_type;
2507 switch (reloc)
2508 {
2509 case BFD_RELOC_ARC_TLS_DTPOFF:
2510 case BFD_RELOC_ARC_TLS_LE_32:
2511 if (fixP->fx_done)
2512 break;
2513 /* Fall through. */
2514 case BFD_RELOC_ARC_TLS_GD_GOT:
2515 case BFD_RELOC_ARC_TLS_IE_GOT:
2516 S_SET_THREAD_LOCAL (fixP->fx_addsy);
2517 break;
2518
2519 case BFD_RELOC_ARC_TLS_GD_LD:
2520 gas_assert (!fixP->fx_offset);
2521 if (fixP->fx_subsy)
2522 fixP->fx_offset
2523 = (S_GET_VALUE (fixP->fx_subsy)
2524 - fixP->fx_frag->fr_address- fixP->fx_where);
2525 fixP->fx_subsy = NULL;
2526 /* Fall through. */
2527 case BFD_RELOC_ARC_TLS_GD_CALL:
2528 /* These two relocs are there just to allow ld to change the tls
2529 model for this symbol, by patching the code. The offset -
2530 and scale, if any - will be installed by the linker. */
2531 S_SET_THREAD_LOCAL (fixP->fx_addsy);
2532 break;
2533
2534 case BFD_RELOC_ARC_TLS_LE_S9:
2535 case BFD_RELOC_ARC_TLS_DTPOFF_S9:
2536 as_bad (_("TLS_*_S9 relocs are not supported yet"));
2537 break;
2538
2539 default:
2540 break;
2541 }
2542
2543 if (!fixP->fx_done)
2544 {
2545 return;
2546 }
2547
2548 /* Addjust the value if we have a constant. */
2549 value += fx_offset;
2550
2551 /* For hosts with longs bigger than 32-bits make sure that the top
2552 bits of a 32-bit negative value read in by the parser are set,
2553 so that the correct comparisons are made. */
2554 if (value & 0x80000000)
2555 value |= (-1L << 31);
2556
2557 reloc = fixP->fx_r_type;
2558 switch (reloc)
2559 {
2560 case BFD_RELOC_8:
2561 case BFD_RELOC_16:
2562 case BFD_RELOC_24:
2563 case BFD_RELOC_32:
2564 case BFD_RELOC_64:
2565 case BFD_RELOC_ARC_32_PCREL:
2566 md_number_to_chars (fixpos, value, fixP->fx_size);
2567 return;
2568
2569 case BFD_RELOC_ARC_GOTPC32:
2570 /* I cannot fix an GOTPC relocation because I need to relax it
2571 from ld rx,[pcl,@sym@gotpc] to add rx,pcl,@sym@gotpc. */
2572 as_bad (_("Unsupported operation on reloc"));
2573 return;
2574
2575 case BFD_RELOC_ARC_TLS_DTPOFF:
2576 case BFD_RELOC_ARC_TLS_LE_32:
2577 gas_assert (!fixP->fx_addsy);
2578 gas_assert (!fixP->fx_subsy);
2579
2580 case BFD_RELOC_ARC_GOTOFF:
2581 case BFD_RELOC_ARC_32_ME:
2582 case BFD_RELOC_ARC_PC32:
2583 md_number_to_chars_midend (fixpos, value, fixP->fx_size);
2584 return;
2585
2586 case BFD_RELOC_ARC_PLT32:
2587 md_number_to_chars_midend (fixpos, value, fixP->fx_size);
2588 return;
2589
2590 case BFD_RELOC_ARC_S25H_PCREL_PLT:
2591 reloc = BFD_RELOC_ARC_S25W_PCREL;
2592 goto solve_plt;
2593
2594 case BFD_RELOC_ARC_S21H_PCREL_PLT:
2595 reloc = BFD_RELOC_ARC_S21H_PCREL;
2596 goto solve_plt;
2597
2598 case BFD_RELOC_ARC_S25W_PCREL_PLT:
2599 reloc = BFD_RELOC_ARC_S25W_PCREL;
2600 goto solve_plt;
2601
2602 case BFD_RELOC_ARC_S21W_PCREL_PLT:
2603 reloc = BFD_RELOC_ARC_S21W_PCREL;
2604
2605 case BFD_RELOC_ARC_S25W_PCREL:
2606 case BFD_RELOC_ARC_S21W_PCREL:
2607 case BFD_RELOC_ARC_S21H_PCREL:
2608 case BFD_RELOC_ARC_S25H_PCREL:
2609 case BFD_RELOC_ARC_S13_PCREL:
2610 solve_plt:
2611 operand = find_operand_for_reloc (reloc);
2612 gas_assert (operand);
2613 break;
2614
2615 default:
2616 {
2617 if ((int) fixP->fx_r_type >= 0)
2618 as_fatal (_("unhandled relocation type %s"),
2619 bfd_get_reloc_code_name (fixP->fx_r_type));
2620
2621 /* The rest of these fixups needs to be completely resolved as
2622 constants. */
2623 if (fixP->fx_addsy != 0
2624 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
2625 as_bad_where (fixP->fx_file, fixP->fx_line,
2626 _("non-absolute expression in constant field"));
2627
2628 gas_assert (-(int) fixP->fx_r_type < (int) arc_num_operands);
2629 operand = &arc_operands[-(int) fixP->fx_r_type];
2630 break;
2631 }
2632 }
2633
2634 if (target_big_endian)
2635 {
2636 switch (fixP->fx_size)
2637 {
2638 case 4:
2639 insn = bfd_getb32 (fixpos);
2640 break;
2641 case 2:
2642 insn = bfd_getb16 (fixpos);
2643 break;
2644 default:
2645 as_bad_where (fixP->fx_file, fixP->fx_line,
2646 _("unknown fixup size"));
2647 }
2648 }
2649 else
2650 {
2651 insn = 0;
2652 switch (fixP->fx_size)
2653 {
2654 case 4:
2655 insn = bfd_getl16 (fixpos) << 16 | bfd_getl16 (fixpos + 2);
2656 break;
2657 case 2:
2658 insn = bfd_getl16 (fixpos);
2659 break;
2660 default:
2661 as_bad_where (fixP->fx_file, fixP->fx_line,
2662 _("unknown fixup size"));
2663 }
2664 }
2665
2666 insn = insert_operand (insn, operand, (offsetT) value,
2667 fixP->fx_file, fixP->fx_line);
2668
2669 md_number_to_chars_midend (fixpos, insn, fixP->fx_size);
2670 }
2671
2672 /* Prepare machine-dependent frags for relaxation.
2673
2674 Called just before relaxation starts. Any symbol that is now undefined
2675 will not become defined.
2676
2677 Return the correct fr_subtype in the frag.
2678
2679 Return the initial "guess for fr_var" to caller. The guess for fr_var
2680 is *actually* the growth beyond fr_fix. Whatever we do to grow fr_fix
2681 or fr_var contributes to our returned value.
2682
2683 Although it may not be explicit in the frag, pretend
2684 fr_var starts with a value. */
2685
2686 int
2687 md_estimate_size_before_relax (fragS *fragP,
2688 segT segment)
2689 {
2690 int growth;
2691
2692 /* If the symbol is not located within the same section AND it's not
2693 an absolute section, use the maximum. OR if the symbol is a
2694 constant AND the insn is by nature not pc-rel, use the maximum.
2695 OR if the symbol is being equated against another symbol, use the
2696 maximum. OR if the symbol is weak use the maximum. */
2697 if ((S_GET_SEGMENT (fragP->fr_symbol) != segment
2698 && S_GET_SEGMENT (fragP->fr_symbol) != absolute_section)
2699 || (symbol_constant_p (fragP->fr_symbol)
2700 && !fragP->tc_frag_data.pcrel)
2701 || symbol_equated_p (fragP->fr_symbol)
2702 || S_IS_WEAK (fragP->fr_symbol))
2703 {
2704 while (md_relax_table[fragP->fr_subtype].rlx_more != ARC_RLX_NONE)
2705 ++fragP->fr_subtype;
2706 }
2707
2708 growth = md_relax_table[fragP->fr_subtype].rlx_length;
2709 fragP->fr_var = growth;
2710
2711 pr_debug ("%s:%d: md_estimate_size_before_relax: %d\n",
2712 fragP->fr_file, fragP->fr_line, growth);
2713
2714 return growth;
2715 }
2716
2717 /* Translate internal representation of relocation info to BFD target
2718 format. */
2719
2720 arelent *
2721 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
2722 fixS *fixP)
2723 {
2724 arelent *reloc;
2725 bfd_reloc_code_real_type code;
2726
2727 reloc = (arelent *) xmalloc (sizeof (* reloc));
2728 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2729 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
2730 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
2731
2732 /* Make sure none of our internal relocations make it this far.
2733 They'd better have been fully resolved by this point. */
2734 gas_assert ((int) fixP->fx_r_type > 0);
2735
2736 code = fixP->fx_r_type;
2737
2738 /* if we have something like add gp, pcl,
2739 _GLOBAL_OFFSET_TABLE_@gotpc. */
2740 if (code == BFD_RELOC_ARC_GOTPC32
2741 && GOT_symbol
2742 && fixP->fx_addsy == GOT_symbol)
2743 code = BFD_RELOC_ARC_GOTPC;
2744
2745 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
2746 if (reloc->howto == NULL)
2747 {
2748 as_bad_where (fixP->fx_file, fixP->fx_line,
2749 _("cannot represent `%s' relocation in object file"),
2750 bfd_get_reloc_code_name (code));
2751 return NULL;
2752 }
2753
2754 if (!fixP->fx_pcrel != !reloc->howto->pc_relative)
2755 as_fatal (_("internal error? cannot generate `%s' relocation"),
2756 bfd_get_reloc_code_name (code));
2757
2758 gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
2759
2760 if (code == BFD_RELOC_ARC_TLS_DTPOFF
2761 || code == BFD_RELOC_ARC_TLS_DTPOFF_S9)
2762 {
2763 asymbol *sym
2764 = fixP->fx_subsy ? symbol_get_bfdsym (fixP->fx_subsy) : NULL;
2765 /* We just want to store a 24 bit index, but we have to wait
2766 till after write_contents has been called via
2767 bfd_map_over_sections before we can get the index from
2768 _bfd_elf_symbol_from_bfd_symbol. Thus, the write_relocs
2769 function is elf32-arc.c has to pick up the slack.
2770 Unfortunately, this leads to problems with hosts that have
2771 pointers wider than long (bfd_vma). There would be various
2772 ways to handle this, all error-prone :-( */
2773 reloc->addend = (bfd_vma) sym;
2774 if ((asymbol *) reloc->addend != sym)
2775 {
2776 as_bad ("Can't store pointer\n");
2777 return NULL;
2778 }
2779 }
2780 else
2781 reloc->addend = fixP->fx_offset;
2782
2783 return reloc;
2784 }
2785
2786 /* Perform post-processing of machine-dependent frags after relaxation.
2787 Called after relaxation is finished.
2788 In: Address of frag.
2789 fr_type == rs_machine_dependent.
2790 fr_subtype is what the address relaxed to.
2791
2792 Out: Any fixS:s and constants are set up. */
2793
2794 void
2795 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
2796 segT segment ATTRIBUTE_UNUSED,
2797 fragS *fragP)
2798 {
2799 const relax_typeS *table_entry;
2800 char *dest;
2801 const struct arc_opcode *opcode;
2802 struct arc_insn insn;
2803 int size, fix;
2804 struct arc_relax_type *relax_arg = &fragP->tc_frag_data;
2805
2806 fix = (fragP->fr_fix < 0 ? 0 : fragP->fr_fix);
2807 dest = fragP->fr_literal + fix;
2808 table_entry = TC_GENERIC_RELAX_TABLE + fragP->fr_subtype;
2809
2810 pr_debug ("%s:%d: md_convert_frag, subtype: %d, fix: %d, var: %d\n",
2811 fragP->fr_file, fragP->fr_line,
2812 fragP->fr_subtype, fix, fragP->fr_var);
2813
2814 if (fragP->fr_subtype <= 0
2815 && fragP->fr_subtype >= arc_num_relax_opcodes)
2816 as_fatal (_("no relaxation found for this instruction."));
2817
2818 opcode = &arc_relax_opcodes[fragP->fr_subtype];
2819
2820 assemble_insn (opcode, relax_arg->tok, relax_arg->ntok, relax_arg->pflags,
2821 relax_arg->nflg, &insn);
2822
2823 apply_fixups (&insn, fragP, fix);
2824
2825 size = insn.short_insn ? (insn.has_limm ? 6 : 2) : (insn.has_limm ? 8 : 4);
2826 gas_assert (table_entry->rlx_length == size);
2827 emit_insn0 (&insn, dest, TRUE);
2828
2829 fragP->fr_fix += table_entry->rlx_length;
2830 fragP->fr_var = 0;
2831 }
2832
2833 /* We have no need to default values of symbols. We could catch
2834 register names here, but that is handled by inserting them all in
2835 the symbol table to begin with. */
2836
2837 symbolS *
2838 md_undefined_symbol (char *name)
2839 {
2840 /* The arc abi demands that a GOT[0] should be referencible as
2841 [pc+_DYNAMIC@gotpc]. Hence we convert a _DYNAMIC@gotpc to a
2842 GOTPC reference to _GLOBAL_OFFSET_TABLE_. */
2843 if (((*name == '_')
2844 && (*(name+1) == 'G')
2845 && (strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0))
2846 || ((*name == '_')
2847 && (*(name+1) == 'D')
2848 && (strcmp (name, DYNAMIC_STRUCT_NAME) == 0)))
2849 {
2850 if (!GOT_symbol)
2851 {
2852 if (symbol_find (name))
2853 as_bad ("GOT already in symbol table");
2854
2855 GOT_symbol = symbol_new (GLOBAL_OFFSET_TABLE_NAME, undefined_section,
2856 (valueT) 0, &zero_address_frag);
2857 };
2858 return GOT_symbol;
2859 }
2860 return NULL;
2861 }
2862
2863 /* Turn a string in input_line_pointer into a floating point constant
2864 of type type, and store the appropriate bytes in *litP. The number
2865 of LITTLENUMS emitted is stored in *sizeP. An error message is
2866 returned, or NULL on OK. */
2867
2868 const char *
2869 md_atof (int type, char *litP, int *sizeP)
2870 {
2871 return ieee_md_atof (type, litP, sizeP, target_big_endian);
2872 }
2873
2874 /* Called for any expression that can not be recognized. When the
2875 function is called, `input_line_pointer' will point to the start of
2876 the expression. */
2877
2878 void
2879 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
2880 {
2881 char *p = input_line_pointer;
2882 if (*p == '@')
2883 {
2884 input_line_pointer++;
2885 expressionP->X_op = O_symbol;
2886 expression (expressionP);
2887 }
2888 }
2889
2890 /* This function is called from the function 'expression', it attempts
2891 to parse special names (in our case register names). It fills in
2892 the expression with the identified register. It returns TRUE if
2893 it is a register and FALSE otherwise. */
2894
2895 bfd_boolean
2896 arc_parse_name (const char *name,
2897 struct expressionS *e)
2898 {
2899 struct symbol *sym;
2900
2901 if (!assembling_insn)
2902 return FALSE;
2903
2904 /* Handle only registers. */
2905 if (e->X_op != O_absent)
2906 return FALSE;
2907
2908 sym = hash_find (arc_reg_hash, name);
2909 if (sym)
2910 {
2911 e->X_op = O_register;
2912 e->X_add_number = S_GET_VALUE (sym);
2913 return TRUE;
2914 }
2915 return FALSE;
2916 }
2917
2918 /* md_parse_option
2919 Invocation line includes a switch not recognized by the base assembler.
2920 See if it's a processor-specific option.
2921
2922 New options (supported) are:
2923
2924 -mcpu=<cpu name> Assemble for selected processor
2925 -EB/-mbig-endian Big-endian
2926 -EL/-mlittle-endian Little-endian
2927 -mrelax Enable relaxation
2928
2929 The following CPU names are recognized:
2930 arc700, av2em, av2hs. */
2931
2932 int
2933 md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
2934 {
2935 switch (c)
2936 {
2937 case OPTION_ARC600:
2938 case OPTION_ARC601:
2939 return md_parse_option (OPTION_MCPU, "arc600");
2940
2941 case OPTION_ARC700:
2942 return md_parse_option (OPTION_MCPU, "arc700");
2943
2944 case OPTION_ARCEM:
2945 return md_parse_option (OPTION_MCPU, "arcem");
2946
2947 case OPTION_ARCHS:
2948 return md_parse_option (OPTION_MCPU, "archs");
2949
2950 case OPTION_MCPU:
2951 {
2952 arc_select_cpu (arg);
2953 mach_type_specified_p = 1;
2954 break;
2955 }
2956
2957 case OPTION_EB:
2958 arc_target_format = "elf32-bigarc";
2959 byte_order = BIG_ENDIAN;
2960 break;
2961
2962 case OPTION_EL:
2963 arc_target_format = "elf32-littlearc";
2964 byte_order = LITTLE_ENDIAN;
2965 break;
2966
2967 case OPTION_CD:
2968 /* This option has an effect only on ARC EM. */
2969 if (arc_target & ARC_OPCODE_ARCv2EM)
2970 arc_features |= ARC_CD;
2971 else
2972 as_warn (_("Code density option invalid for selected CPU"));
2973 break;
2974
2975 case OPTION_RELAX:
2976 relaxation_state = 1;
2977 break;
2978
2979 case OPTION_USER_MODE:
2980 case OPTION_LD_EXT_MASK:
2981 case OPTION_SWAP:
2982 case OPTION_NORM:
2983 case OPTION_BARREL_SHIFT:
2984 case OPTION_MIN_MAX:
2985 case OPTION_NO_MPY:
2986 case OPTION_EA:
2987 case OPTION_MUL64:
2988 case OPTION_SIMD:
2989 /* Dummy options are accepted but have no effect. */
2990 break;
2991
2992 case OPTION_SPFP:
2993 arc_features |= ARC_SPFP;
2994 break;
2995
2996 case OPTION_DPFP:
2997 arc_features |= ARC_DPFP;
2998 break;
2999
3000 case OPTION_XMAC_D16:
3001 case OPTION_XMAC_24:
3002 case OPTION_DSP_PACKA:
3003 case OPTION_CRC:
3004 case OPTION_DVBF:
3005 case OPTION_TELEPHONY:
3006 case OPTION_XYMEMORY:
3007 case OPTION_LOCK:
3008 case OPTION_SWAPE:
3009 case OPTION_RTSC:
3010 /* Dummy options are accepted but have no effect. */
3011 break;
3012
3013 case OPTION_FPUDA:
3014 /* This option has an effect only on ARC EM. */
3015 if (arc_target & ARC_OPCODE_ARCv2EM)
3016 arc_features |= ARC_FPUDA;
3017 else
3018 as_warn (_("FPUDA invalid for selected CPU"));
3019 break;
3020
3021 default:
3022 return 0;
3023 }
3024
3025 return 1;
3026 }
3027
3028 void
3029 md_show_usage (FILE *stream)
3030 {
3031 fprintf (stream, _("ARC-specific assembler options:\n"));
3032
3033 fprintf (stream, " -mcpu=<cpu name>\t assemble for CPU <cpu name>\n");
3034 fprintf (stream,
3035 " -mcode-density\t enable code density option for ARC EM\n");
3036
3037 fprintf (stream, _("\
3038 -EB assemble code for a big-endian cpu\n"));
3039 fprintf (stream, _("\
3040 -EL assemble code for a little-endian cpu\n"));
3041 fprintf (stream, _("\
3042 -mrelax Enable relaxation\n"));
3043
3044 }
3045
3046 /* Find the proper relocation for the given opcode. */
3047
3048 static extended_bfd_reloc_code_real_type
3049 find_reloc (const char *name,
3050 const char *opcodename,
3051 const struct arc_flags *pflags,
3052 int nflg,
3053 extended_bfd_reloc_code_real_type reloc)
3054 {
3055 unsigned int i;
3056 int j;
3057 bfd_boolean found_flag, tmp;
3058 extended_bfd_reloc_code_real_type ret = BFD_RELOC_UNUSED;
3059
3060 for (i = 0; i < arc_num_equiv_tab; i++)
3061 {
3062 const struct arc_reloc_equiv_tab *r = &arc_reloc_equiv[i];
3063
3064 /* Find the entry. */
3065 if (strcmp (name, r->name))
3066 continue;
3067 if (r->mnemonic && (strcmp (r->mnemonic, opcodename)))
3068 continue;
3069 if (r->flags[0])
3070 {
3071 if (!nflg)
3072 continue;
3073 found_flag = FALSE;
3074 unsigned * psflg = (unsigned *)r->flags;
3075 do
3076 {
3077 tmp = FALSE;
3078 for (j = 0; j < nflg; j++)
3079 if (!strcmp (pflags[j].name,
3080 arc_flag_operands[*psflg].name))
3081 {
3082 tmp = TRUE;
3083 break;
3084 }
3085 if (!tmp)
3086 {
3087 found_flag = FALSE;
3088 break;
3089 }
3090 else
3091 {
3092 found_flag = TRUE;
3093 }
3094 ++ psflg;
3095 } while (*psflg);
3096
3097 if (!found_flag)
3098 continue;
3099 }
3100
3101 if (reloc != r->oldreloc)
3102 continue;
3103 /* Found it. */
3104 ret = r->newreloc;
3105 break;
3106 }
3107
3108 if (ret == BFD_RELOC_UNUSED)
3109 as_bad (_("Unable to find %s relocation for instruction %s"),
3110 name, opcodename);
3111 return ret;
3112 }
3113
3114 /* All the symbol types that are allowed to be used for
3115 relaxation. */
3116
3117 static bfd_boolean
3118 may_relax_expr (expressionS tok)
3119 {
3120 /* Check if we have unrelaxable relocs. */
3121 switch (tok.X_md)
3122 {
3123 default:
3124 break;
3125 case O_plt:
3126 return FALSE;
3127 }
3128
3129 switch (tok.X_op)
3130 {
3131 case O_symbol:
3132 case O_multiply:
3133 case O_divide:
3134 case O_modulus:
3135 case O_add:
3136 case O_subtract:
3137 break;
3138
3139 default:
3140 return FALSE;
3141 }
3142 return TRUE;
3143 }
3144
3145 /* Checks if flags are in line with relaxable insn. */
3146
3147 static bfd_boolean
3148 relaxable_flag (const struct arc_relaxable_ins *ins,
3149 const struct arc_flags *pflags,
3150 int nflgs)
3151 {
3152 unsigned flag_class,
3153 flag,
3154 flag_class_idx = 0,
3155 flag_idx = 0;
3156
3157 const struct arc_flag_operand *flag_opand;
3158 int i, counttrue = 0;
3159
3160 /* Iterate through flags classes. */
3161 while ((flag_class = ins->flag_classes[flag_class_idx]) != 0)
3162 {
3163 /* Iterate through flags in flag class. */
3164 while ((flag = arc_flag_classes[flag_class].flags[flag_idx])
3165 != 0)
3166 {
3167 flag_opand = &arc_flag_operands[flag];
3168 /* Iterate through flags in ins to compare. */
3169 for (i = 0; i < nflgs; ++i)
3170 {
3171 if (strcmp (flag_opand->name, pflags[i].name) == 0)
3172 ++counttrue;
3173 }
3174
3175 ++flag_idx;
3176 }
3177
3178 ++flag_class_idx;
3179 flag_idx = 0;
3180 }
3181
3182 /* If counttrue == nflgs, then all flags have been found. */
3183 return (counttrue == nflgs ? TRUE : FALSE);
3184 }
3185
3186 /* Checks if operands are in line with relaxable insn. */
3187
3188 static bfd_boolean
3189 relaxable_operand (const struct arc_relaxable_ins *ins,
3190 const expressionS *tok,
3191 int ntok)
3192 {
3193 const enum rlx_operand_type *operand = &ins->operands[0];
3194 int i = 0;
3195
3196 while (*operand != EMPTY)
3197 {
3198 const expressionS *epr = &tok[i];
3199
3200 if (i != 0 && i >= ntok)
3201 return FALSE;
3202
3203 switch (*operand)
3204 {
3205 case IMMEDIATE:
3206 if (!(epr->X_op == O_multiply
3207 || epr->X_op == O_divide
3208 || epr->X_op == O_modulus
3209 || epr->X_op == O_add
3210 || epr->X_op == O_subtract
3211 || epr->X_op == O_symbol))
3212 return FALSE;
3213 break;
3214
3215 case REGISTER_DUP:
3216 if ((i <= 0)
3217 || (epr->X_add_number != tok[i - 1].X_add_number))
3218 return FALSE;
3219 /* Fall through. */
3220 case REGISTER:
3221 if (epr->X_op != O_register)
3222 return FALSE;
3223 break;
3224
3225 case REGISTER_S:
3226 if (epr->X_op != O_register)
3227 return FALSE;
3228
3229 switch (epr->X_add_number)
3230 {
3231 case 0: case 1: case 2: case 3:
3232 case 12: case 13: case 14: case 15:
3233 break;
3234 default:
3235 return FALSE;
3236 }
3237 break;
3238
3239 case REGISTER_NO_GP:
3240 if ((epr->X_op != O_register)
3241 || (epr->X_add_number == 26)) /* 26 is the gp register. */
3242 return FALSE;
3243 break;
3244
3245 case BRACKET:
3246 if (epr->X_op != O_bracket)
3247 return FALSE;
3248 break;
3249
3250 default:
3251 /* Don't understand, bail out. */
3252 return FALSE;
3253 break;
3254 }
3255
3256 ++i;
3257 operand = &ins->operands[i];
3258 }
3259
3260 return (i == ntok ? TRUE : FALSE);
3261 }
3262
3263 /* Return TRUE if this OPDCODE is a candidate for relaxation. */
3264
3265 static bfd_boolean
3266 relax_insn_p (const struct arc_opcode *opcode,
3267 const expressionS *tok,
3268 int ntok,
3269 const struct arc_flags *pflags,
3270 int nflg)
3271 {
3272 unsigned i;
3273 bfd_boolean rv = FALSE;
3274
3275 /* Check the relaxation table. */
3276 for (i = 0; i < arc_num_relaxable_ins && relaxation_state; ++i)
3277 {
3278 const struct arc_relaxable_ins *arc_rlx_ins = &arc_relaxable_insns[i];
3279
3280 if ((strcmp (opcode->name, arc_rlx_ins->mnemonic_r) == 0)
3281 && may_relax_expr (tok[arc_rlx_ins->opcheckidx])
3282 && relaxable_operand (arc_rlx_ins, tok, ntok)
3283 && relaxable_flag (arc_rlx_ins, pflags, nflg))
3284 {
3285 rv = TRUE;
3286 frag_now->fr_subtype = arc_relaxable_insns[i].subtype;
3287 memcpy (&frag_now->tc_frag_data.tok, tok,
3288 sizeof (expressionS) * ntok);
3289 memcpy (&frag_now->tc_frag_data.pflags, pflags,
3290 sizeof (struct arc_flags) * nflg);
3291 frag_now->tc_frag_data.nflg = nflg;
3292 frag_now->tc_frag_data.ntok = ntok;
3293 break;
3294 }
3295 }
3296
3297 return rv;
3298 }
3299
3300 /* Turn an opcode description and a set of arguments into
3301 an instruction and a fixup. */
3302
3303 static void
3304 assemble_insn (const struct arc_opcode *opcode,
3305 const expressionS *tok,
3306 int ntok,
3307 const struct arc_flags *pflags,
3308 int nflg,
3309 struct arc_insn *insn)
3310 {
3311 const expressionS *reloc_exp = NULL;
3312 unsigned image;
3313 const unsigned char *argidx;
3314 int i;
3315 int tokidx = 0;
3316 unsigned char pcrel = 0;
3317 bfd_boolean needGOTSymbol;
3318 bfd_boolean has_delay_slot = FALSE;
3319 extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
3320
3321 memset (insn, 0, sizeof (*insn));
3322 image = opcode->opcode;
3323
3324 pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
3325 frag_now->fr_file, frag_now->fr_line, opcode->name,
3326 opcode->opcode);
3327
3328 /* Handle operands. */
3329 for (argidx = opcode->operands; *argidx; ++argidx)
3330 {
3331 const struct arc_operand *operand = &arc_operands[*argidx];
3332 const expressionS *t = (const expressionS *) 0;
3333
3334 if ((operand->flags & ARC_OPERAND_FAKE)
3335 && !(operand->flags & ARC_OPERAND_BRAKET))
3336 continue;
3337
3338 if (operand->flags & ARC_OPERAND_DUPLICATE)
3339 {
3340 /* Duplicate operand, already inserted. */
3341 tokidx ++;
3342 continue;
3343 }
3344
3345 if (tokidx >= ntok)
3346 {
3347 abort ();
3348 }
3349 else
3350 t = &tok[tokidx++];
3351
3352 /* Regardless if we have a reloc or not mark the instruction
3353 limm if it is the case. */
3354 if (operand->flags & ARC_OPERAND_LIMM)
3355 insn->has_limm = TRUE;
3356
3357 switch (t->X_op)
3358 {
3359 case O_register:
3360 image = insert_operand (image, operand, regno (t->X_add_number),
3361 NULL, 0);
3362 break;
3363
3364 case O_constant:
3365 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
3366 reloc_exp = t;
3367 if (operand->flags & ARC_OPERAND_LIMM)
3368 insn->limm = t->X_add_number;
3369 break;
3370
3371 case O_bracket:
3372 /* Ignore brackets. */
3373 break;
3374
3375 case O_absent:
3376 gas_assert (operand->flags & ARC_OPERAND_IGNORE);
3377 break;
3378
3379 case O_subtract:
3380 /* Maybe register range. */
3381 if ((t->X_add_number == 0)
3382 && contains_register (t->X_add_symbol)
3383 && contains_register (t->X_op_symbol))
3384 {
3385 int regs;
3386
3387 regs = get_register (t->X_add_symbol);
3388 regs <<= 16;
3389 regs |= get_register (t->X_op_symbol);
3390 image = insert_operand (image, operand, regs, NULL, 0);
3391 break;
3392 }
3393
3394 default:
3395 /* This operand needs a relocation. */
3396 needGOTSymbol = FALSE;
3397
3398 switch (t->X_md)
3399 {
3400 case O_plt:
3401 if (opcode->class == JUMP)
3402 as_bad_where (frag_now->fr_file, frag_now->fr_line,
3403 _("Unable to use @plt relocatio for insn %s"),
3404 opcode->name);
3405 needGOTSymbol = TRUE;
3406 reloc = find_reloc ("plt", opcode->name,
3407 pflags, nflg,
3408 operand->default_reloc);
3409 break;
3410
3411 case O_gotoff:
3412 case O_gotpc:
3413 needGOTSymbol = TRUE;
3414 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3415 break;
3416 case O_pcl:
3417 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3418 if (ARC_SHORT (opcode->mask) || opcode->class == JUMP)
3419 as_bad_where (frag_now->fr_file, frag_now->fr_line,
3420 _("Unable to use @pcl relocation for insn %s"),
3421 opcode->name);
3422 break;
3423 case O_sda:
3424 reloc = find_reloc ("sda", opcode->name,
3425 pflags, nflg,
3426 operand->default_reloc);
3427 break;
3428 case O_tlsgd:
3429 case O_tlsie:
3430 needGOTSymbol = TRUE;
3431 /* Fall-through. */
3432
3433 case O_tpoff:
3434 case O_dtpoff:
3435 reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
3436 break;
3437
3438 case O_tpoff9: /*FIXME! Check for the conditionality of
3439 the insn. */
3440 case O_dtpoff9: /*FIXME! Check for the conditionality of
3441 the insn. */
3442 as_bad (_("TLS_*_S9 relocs are not supported yet"));
3443 break;
3444
3445 default:
3446 /* Just consider the default relocation. */
3447 reloc = operand->default_reloc;
3448 break;
3449 }
3450
3451 if (needGOTSymbol && (GOT_symbol == NULL))
3452 GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
3453
3454 reloc_exp = t;
3455
3456 #if 0
3457 if (reloc > 0)
3458 {
3459 /* sanity checks. */
3460 reloc_howto_type *reloc_howto
3461 = bfd_reloc_type_lookup (stdoutput,
3462 (bfd_reloc_code_real_type) reloc);
3463 unsigned reloc_bitsize = reloc_howto->bitsize;
3464 if (reloc_howto->rightshift)
3465 reloc_bitsize -= reloc_howto->rightshift;
3466 if (reloc_bitsize != operand->bits)
3467 {
3468 as_bad (_("invalid relocation %s for field"),
3469 bfd_get_reloc_code_name (reloc));
3470 return;
3471 }
3472 }
3473 #endif
3474 if (insn->nfixups >= MAX_INSN_FIXUPS)
3475 as_fatal (_("too many fixups"));
3476
3477 struct arc_fixup *fixup;
3478 fixup = &insn->fixups[insn->nfixups++];
3479 fixup->exp = *t;
3480 fixup->reloc = reloc;
3481 pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
3482 fixup->pcrel = pcrel;
3483 fixup->islong = (operand->flags & ARC_OPERAND_LIMM) ?
3484 TRUE : FALSE;
3485 break;
3486 }
3487 }
3488
3489 /* Handle flags. */
3490 for (i = 0; i < nflg; i++)
3491 {
3492 const struct arc_flag_operand *flg_operand =
3493 &arc_flag_operands[pflags[i].code];
3494
3495 /* Check if the instruction has a delay slot. */
3496 if (!strcmp (flg_operand->name, "d"))
3497 has_delay_slot = TRUE;
3498
3499 /* There is an exceptional case when we cannot insert a flag
3500 just as it is. The .T flag must be handled in relation with
3501 the relative address. */
3502 if (!strcmp (flg_operand->name, "t")
3503 || !strcmp (flg_operand->name, "nt"))
3504 {
3505 unsigned bitYoperand = 0;
3506 /* FIXME! move selection bbit/brcc in arc-opc.c. */
3507 if (!strcmp (flg_operand->name, "t"))
3508 if (!strcmp (opcode->name, "bbit0")
3509 || !strcmp (opcode->name, "bbit1"))
3510 bitYoperand = arc_NToperand;
3511 else
3512 bitYoperand = arc_Toperand;
3513 else
3514 if (!strcmp (opcode->name, "bbit0")
3515 || !strcmp (opcode->name, "bbit1"))
3516 bitYoperand = arc_Toperand;
3517 else
3518 bitYoperand = arc_NToperand;
3519
3520 gas_assert (reloc_exp != NULL);
3521 if (reloc_exp->X_op == O_constant)
3522 {
3523 /* Check if we have a constant and solved it
3524 immediately. */
3525 offsetT val = reloc_exp->X_add_number;
3526 image |= insert_operand (image, &arc_operands[bitYoperand],
3527 val, NULL, 0);
3528 }
3529 else
3530 {
3531 struct arc_fixup *fixup;
3532
3533 if (insn->nfixups >= MAX_INSN_FIXUPS)
3534 as_fatal (_("too many fixups"));
3535
3536 fixup = &insn->fixups[insn->nfixups++];
3537 fixup->exp = *reloc_exp;
3538 fixup->reloc = -bitYoperand;
3539 fixup->pcrel = pcrel;
3540 fixup->islong = FALSE;
3541 }
3542 }
3543 else
3544 image |= (flg_operand->code & ((1 << flg_operand->bits) - 1))
3545 << flg_operand->shift;
3546 }
3547
3548 insn->relax = relax_insn_p (opcode, tok, ntok, pflags, nflg);
3549
3550 /* Short instruction? */
3551 insn->short_insn = ARC_SHORT (opcode->mask) ? TRUE : FALSE;
3552
3553 insn->insn = image;
3554
3555 /* Update last insn status. */
3556 arc_last_insns[1] = arc_last_insns[0];
3557 arc_last_insns[0].opcode = opcode;
3558 arc_last_insns[0].has_limm = insn->has_limm;
3559 arc_last_insns[0].has_delay_slot = has_delay_slot;
3560
3561 /* Check if the current instruction is legally used. */
3562 if (arc_last_insns[1].has_delay_slot
3563 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
3564 as_bad_where (frag_now->fr_file, frag_now->fr_line,
3565 _("A jump/branch instruction in delay slot."));
3566 }
3567
3568 void
3569 arc_handle_align (fragS* fragP)
3570 {
3571 if ((fragP)->fr_type == rs_align_code)
3572 {
3573 char *dest = (fragP)->fr_literal + (fragP)->fr_fix;
3574 valueT count = ((fragP)->fr_next->fr_address
3575 - (fragP)->fr_address - (fragP)->fr_fix);
3576
3577 (fragP)->fr_var = 2;
3578
3579 if (count & 1)/* Padding in the gap till the next 2-byte
3580 boundary with 0s. */
3581 {
3582 (fragP)->fr_fix++;
3583 *dest++ = 0;
3584 }
3585 /* Writing nop_s. */
3586 md_number_to_chars (dest, NOP_OPCODE_S, 2);
3587 }
3588 }
3589
3590 /* Here we decide which fixups can be adjusted to make them relative
3591 to the beginning of the section instead of the symbol. Basically
3592 we need to make sure that the dynamic relocations are done
3593 correctly, so in some cases we force the original symbol to be
3594 used. */
3595
3596 int
3597 tc_arc_fix_adjustable (fixS *fixP)
3598 {
3599
3600 /* Prevent all adjustments to global symbols. */
3601 if (S_IS_EXTERNAL (fixP->fx_addsy))
3602 return 0;
3603 if (S_IS_WEAK (fixP->fx_addsy))
3604 return 0;
3605
3606 /* Adjust_reloc_syms doesn't know about the GOT. */
3607 switch (fixP->fx_r_type)
3608 {
3609 case BFD_RELOC_ARC_GOTPC32:
3610 case BFD_RELOC_ARC_PLT32:
3611 case BFD_RELOC_ARC_S25H_PCREL_PLT:
3612 case BFD_RELOC_ARC_S21H_PCREL_PLT:
3613 case BFD_RELOC_ARC_S25W_PCREL_PLT:
3614 case BFD_RELOC_ARC_S21W_PCREL_PLT:
3615 return 0;
3616
3617 default:
3618 break;
3619 }
3620
3621 return 1;
3622 }
3623
3624 /* Compute the reloc type of an expression EXP. */
3625
3626 static void
3627 arc_check_reloc (expressionS *exp,
3628 bfd_reloc_code_real_type *r_type_p)
3629 {
3630 if (*r_type_p == BFD_RELOC_32
3631 && exp->X_op == O_subtract
3632 && exp->X_op_symbol != NULL
3633 && exp->X_op_symbol->bsym->section == now_seg)
3634 *r_type_p = BFD_RELOC_ARC_32_PCREL;
3635 }
3636
3637
3638 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */
3639
3640 void
3641 arc_cons_fix_new (fragS *frag,
3642 int off,
3643 int size,
3644 expressionS *exp,
3645 bfd_reloc_code_real_type r_type)
3646 {
3647 r_type = BFD_RELOC_UNUSED;
3648
3649 switch (size)
3650 {
3651 case 1:
3652 r_type = BFD_RELOC_8;
3653 break;
3654
3655 case 2:
3656 r_type = BFD_RELOC_16;
3657 break;
3658
3659 case 3:
3660 r_type = BFD_RELOC_24;
3661 break;
3662
3663 case 4:
3664 r_type = BFD_RELOC_32;
3665 arc_check_reloc (exp, &r_type);
3666 break;
3667
3668 case 8:
3669 r_type = BFD_RELOC_64;
3670 break;
3671
3672 default:
3673 as_bad (_("unsupported BFD relocation size %u"), size);
3674 r_type = BFD_RELOC_UNUSED;
3675 }
3676
3677 fix_new_exp (frag, off, size, exp, 0, r_type);
3678 }
3679
3680 /* The actual routine that checks the ZOL conditions. */
3681
3682 static void
3683 check_zol (symbolS *s)
3684 {
3685 switch (arc_mach_type)
3686 {
3687 case bfd_mach_arc_arcv2:
3688 if (arc_target & ARC_OPCODE_ARCv2EM)
3689 return;
3690
3691 if (is_br_jmp_insn_p (arc_last_insns[0].opcode)
3692 || arc_last_insns[1].has_delay_slot)
3693 as_bad (_("Jump/Branch instruction detected at the end of the ZOL label @%s"),
3694 S_GET_NAME (s));
3695
3696 break;
3697 case bfd_mach_arc_arc600:
3698
3699 if (is_kernel_insn_p (arc_last_insns[0].opcode))
3700 as_bad (_("Kernel instruction detected at the end of the ZOL label @%s"),
3701 S_GET_NAME (s));
3702
3703 if (arc_last_insns[0].has_limm
3704 && is_br_jmp_insn_p (arc_last_insns[0].opcode))
3705 as_bad (_("A jump instruction with long immediate detected at the \
3706 end of the ZOL label @%s"), S_GET_NAME (s));
3707
3708 /* Fall through. */
3709 case bfd_mach_arc_nps400:
3710 case bfd_mach_arc_arc700:
3711 if (arc_last_insns[0].has_delay_slot)
3712 as_bad (_("An illegal use of delay slot detected at the end of the ZOL label @%s"),
3713 S_GET_NAME (s));
3714
3715 break;
3716 default:
3717 break;
3718 }
3719 }
3720
3721 /* If ZOL end check the last two instruction for illegals. */
3722 void
3723 arc_frob_label (symbolS * sym)
3724 {
3725 if (ARC_GET_FLAG (sym) & ARC_FLAG_ZOL)
3726 check_zol (sym);
3727
3728 dwarf2_emit_label (sym);
3729 }
3730
3731 /* Used because generic relaxation assumes a pc-rel value whilst we
3732 also relax instructions that use an absolute value resolved out of
3733 relative values (if that makes any sense). An example: 'add r1,
3734 r2, @.L2 - .' The symbols . and @.L2 are relative to the section
3735 but if they're in the same section we can subtract the section
3736 offset relocation which ends up in a resolved value. So if @.L2 is
3737 .text + 0x50 and . is .text + 0x10, we can say that .text + 0x50 -
3738 .text + 0x40 = 0x10. */
3739 int
3740 arc_pcrel_adjust (fragS *fragP)
3741 {
3742 if (!fragP->tc_frag_data.pcrel)
3743 return fragP->fr_address + fragP->fr_fix;
3744
3745 return 0;
3746 }
3747
3748 /* Initialize the DWARF-2 unwind information for this procedure. */
3749
3750 void
3751 tc_arc_frame_initial_instructions (void)
3752 {
3753 /* Stack pointer is register 28. */
3754 cfi_add_CFA_def_cfa_register (28);
3755 }
3756
3757 int
3758 tc_arc_regname_to_dw2regnum (char *regname)
3759 {
3760 struct symbol *sym;
3761
3762 sym = hash_find (arc_reg_hash, regname);
3763 if (sym)
3764 return S_GET_VALUE (sym);
3765
3766 return -1;
3767 }
This page took 0.165289 seconds and 5 git commands to generate.