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