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