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