tc-crx.c revision 1.8 1 1.1 christos /* tc-crx.c -- Assembler code for the CRX CPU core.
2 1.8 christos Copyright (C) 2004-2022 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos Contributed by Tomer Levi, NSC, Israel.
5 1.1 christos Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
6 1.1 christos Updates, BFDizing, GNUifying and ELF support by Tomer Levi.
7 1.1 christos
8 1.1 christos This file is part of GAS, the GNU Assembler.
9 1.1 christos
10 1.1 christos GAS is free software; you can redistribute it and/or modify
11 1.1 christos it under the terms of the GNU General Public License as published by
12 1.1 christos the Free Software Foundation; either version 3, or (at your option)
13 1.1 christos any later version.
14 1.1 christos
15 1.1 christos GAS is distributed in the hope that it will be useful,
16 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
17 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 1.1 christos GNU General Public License for more details.
19 1.1 christos
20 1.1 christos You should have received a copy of the GNU General Public License
21 1.1 christos along with GAS; see the file COPYING. If not, write to the
22 1.1 christos Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
23 1.1 christos MA 02110-1301, USA. */
24 1.1 christos
25 1.1 christos #include "as.h"
26 1.8 christos #include <stdint.h>
27 1.1 christos #include "safe-ctype.h"
28 1.1 christos #include "dwarf2dbg.h"
29 1.1 christos #include "opcode/crx.h"
30 1.1 christos #include "elf/crx.h"
31 1.1 christos
32 1.1 christos /* Word is considered here as a 16-bit unsigned short int. */
33 1.1 christos #define WORD_SHIFT 16
34 1.1 christos
35 1.1 christos /* Register is 4-bit size. */
36 1.1 christos #define REG_SIZE 4
37 1.1 christos
38 1.1 christos /* Maximum size of a single instruction (in words). */
39 1.1 christos #define INSN_MAX_SIZE 3
40 1.1 christos
41 1.1 christos /* Maximum bits which may be set in a `mask16' operand. */
42 1.1 christos #define MAX_REGS_IN_MASK16 8
43 1.1 christos
44 1.1 christos /* Utility macros for string comparison. */
45 1.1 christos #define streq(a, b) (strcmp (a, b) == 0)
46 1.1 christos
47 1.1 christos /* Assign a number NUM, shifted by SHIFT bytes, into a location
48 1.1 christos pointed by index BYTE of array 'output_opcode'. */
49 1.8 christos #define CRX_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM) << (SHIFT)
50 1.1 christos
51 1.1 christos /* Operand errors. */
52 1.1 christos typedef enum
53 1.1 christos {
54 1.1 christos OP_LEGAL = 0, /* Legal operand. */
55 1.1 christos OP_OUT_OF_RANGE, /* Operand not within permitted range. */
56 1.1 christos OP_NOT_EVEN, /* Operand is Odd number, should be even. */
57 1.1 christos OP_ILLEGAL_DISPU4, /* Operand is not within DISPU4 range. */
58 1.1 christos OP_ILLEGAL_CST4, /* Operand is not within CST4 range. */
59 1.3 christos OP_NOT_UPPER_64KB /* Operand is not within the upper 64KB
60 1.1 christos (0xFFFF0000-0xFFFFFFFF). */
61 1.1 christos }
62 1.1 christos op_err;
63 1.1 christos
64 1.1 christos /* Opcode mnemonics hash table. */
65 1.8 christos static htab_t crx_inst_hash;
66 1.1 christos /* CRX registers hash table. */
67 1.8 christos static htab_t reg_hash;
68 1.1 christos /* CRX coprocessor registers hash table. */
69 1.8 christos static htab_t copreg_hash;
70 1.1 christos /* Current instruction we're assembling. */
71 1.6 christos static const inst *instruction;
72 1.1 christos
73 1.1 christos /* Global variables. */
74 1.1 christos
75 1.1 christos /* Array to hold an instruction encoding. */
76 1.6 christos static long output_opcode[2];
77 1.1 christos
78 1.1 christos /* Nonzero means a relocatable symbol. */
79 1.6 christos static int relocatable;
80 1.1 christos
81 1.1 christos /* A copy of the original instruction (used in error messages). */
82 1.6 christos static char ins_parse[MAX_INST_LEN];
83 1.1 christos
84 1.1 christos /* The current processed argument number. */
85 1.6 christos static int cur_arg_num;
86 1.1 christos
87 1.1 christos /* Generic assembler global variables which must be defined by all targets. */
88 1.1 christos
89 1.1 christos /* Characters which always start a comment. */
90 1.1 christos const char comment_chars[] = "#";
91 1.1 christos
92 1.1 christos /* Characters which start a comment at the beginning of a line. */
93 1.1 christos const char line_comment_chars[] = "#";
94 1.1 christos
95 1.1 christos /* This array holds machine specific line separator characters. */
96 1.1 christos const char line_separator_chars[] = ";";
97 1.1 christos
98 1.1 christos /* Chars that can be used to separate mant from exp in floating point nums. */
99 1.1 christos const char EXP_CHARS[] = "eE";
100 1.1 christos
101 1.1 christos /* Chars that mean this number is a floating point constant as in 0f12.456 */
102 1.1 christos const char FLT_CHARS[] = "f'";
103 1.1 christos
104 1.1 christos /* Target-specific multicharacter options, not const-declared at usage. */
105 1.1 christos const char *md_shortopts = "";
106 1.1 christos struct option md_longopts[] =
107 1.1 christos {
108 1.1 christos {NULL, no_argument, NULL, 0}
109 1.1 christos };
110 1.1 christos size_t md_longopts_size = sizeof (md_longopts);
111 1.1 christos
112 1.1 christos /* This table describes all the machine specific pseudo-ops
113 1.1 christos the assembler has to support. The fields are:
114 1.1 christos *** Pseudo-op name without dot.
115 1.1 christos *** Function to call to execute this pseudo-op.
116 1.1 christos *** Integer arg to pass to the function. */
117 1.1 christos
118 1.1 christos const pseudo_typeS md_pseudo_table[] =
119 1.1 christos {
120 1.1 christos /* In CRX machine, align is in bytes (not a ptwo boundary). */
121 1.1 christos {"align", s_align_bytes, 0},
122 1.1 christos {0, 0, 0}
123 1.1 christos };
124 1.1 christos
125 1.1 christos /* CRX relaxation table. */
126 1.1 christos const relax_typeS md_relax_table[] =
127 1.1 christos {
128 1.1 christos /* bCC */
129 1.1 christos {0xfa, -0x100, 2, 1}, /* 8 */
130 1.1 christos {0xfffe, -0x10000, 4, 2}, /* 16 */
131 1.1 christos {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
132 1.1 christos
133 1.1 christos /* bal */
134 1.1 christos {0xfffe, -0x10000, 4, 4}, /* 16 */
135 1.1 christos {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
136 1.1 christos
137 1.1 christos /* cmpbr/bcop */
138 1.1 christos {0xfe, -0x100, 4, 6}, /* 8 */
139 1.1 christos {0xfffffe, -0x1000000, 6, 0} /* 24 */
140 1.1 christos };
141 1.1 christos
142 1.8 christos static int get_cinv_parameters (const char *);
143 1.8 christos static char * preprocess_reglist (char *, int *);
144 1.1 christos static void warn_if_needed (ins *);
145 1.1 christos static int adjust_if_needed (ins *);
146 1.1 christos
147 1.1 christos /* Return the bit size for a given operand. */
148 1.1 christos
149 1.1 christos static int
150 1.1 christos get_opbits (operand_type op)
151 1.1 christos {
152 1.1 christos if (op < MAX_OPRD)
153 1.1 christos return crx_optab[op].bit_size;
154 1.1 christos else
155 1.1 christos return 0;
156 1.1 christos }
157 1.1 christos
158 1.1 christos /* Return the argument type of a given operand. */
159 1.1 christos
160 1.1 christos static argtype
161 1.1 christos get_optype (operand_type op)
162 1.1 christos {
163 1.1 christos if (op < MAX_OPRD)
164 1.1 christos return crx_optab[op].arg_type;
165 1.1 christos else
166 1.1 christos return nullargs;
167 1.1 christos }
168 1.1 christos
169 1.1 christos /* Return the flags of a given operand. */
170 1.1 christos
171 1.1 christos static int
172 1.1 christos get_opflags (operand_type op)
173 1.1 christos {
174 1.1 christos if (op < MAX_OPRD)
175 1.1 christos return crx_optab[op].flags;
176 1.1 christos else
177 1.1 christos return 0;
178 1.1 christos }
179 1.1 christos
180 1.1 christos /* Get the core processor register 'reg_name'. */
181 1.1 christos
182 1.1 christos static reg
183 1.1 christos get_register (char *reg_name)
184 1.1 christos {
185 1.1 christos const reg_entry *rreg;
186 1.1 christos
187 1.8 christos rreg = (const reg_entry *) str_hash_find (reg_hash, reg_name);
188 1.1 christos
189 1.1 christos if (rreg != NULL)
190 1.1 christos return rreg->value.reg_val;
191 1.1 christos else
192 1.1 christos return nullregister;
193 1.1 christos }
194 1.1 christos
195 1.1 christos /* Get the coprocessor register 'copreg_name'. */
196 1.1 christos
197 1.1 christos static copreg
198 1.1 christos get_copregister (char *copreg_name)
199 1.1 christos {
200 1.1 christos const reg_entry *coreg;
201 1.1 christos
202 1.8 christos coreg = (const reg_entry *) str_hash_find (copreg_hash, copreg_name);
203 1.1 christos
204 1.1 christos if (coreg != NULL)
205 1.1 christos return coreg->value.copreg_val;
206 1.1 christos else
207 1.1 christos return nullcopregister;
208 1.1 christos }
209 1.1 christos
210 1.1 christos /* Round up a section size to the appropriate boundary. */
211 1.1 christos
212 1.1 christos valueT
213 1.1 christos md_section_align (segT seg, valueT val)
214 1.1 christos {
215 1.1 christos /* Round .text section to a multiple of 2. */
216 1.1 christos if (seg == text_section)
217 1.1 christos return (val + 1) & ~1;
218 1.1 christos return val;
219 1.1 christos }
220 1.1 christos
221 1.1 christos /* Parse an operand that is machine-specific (remove '*'). */
222 1.1 christos
223 1.1 christos void
224 1.1 christos md_operand (expressionS * exp)
225 1.1 christos {
226 1.1 christos char c = *input_line_pointer;
227 1.1 christos
228 1.1 christos switch (c)
229 1.1 christos {
230 1.1 christos case '*':
231 1.1 christos input_line_pointer++;
232 1.1 christos expression (exp);
233 1.1 christos break;
234 1.1 christos default:
235 1.1 christos break;
236 1.1 christos }
237 1.1 christos }
238 1.1 christos
239 1.1 christos /* Reset global variables before parsing a new instruction. */
240 1.1 christos
241 1.1 christos static void
242 1.1 christos reset_vars (char *op)
243 1.1 christos {
244 1.1 christos cur_arg_num = relocatable = 0;
245 1.1 christos memset (& output_opcode, '\0', sizeof (output_opcode));
246 1.1 christos
247 1.1 christos /* Save a copy of the original OP (used in error messages). */
248 1.1 christos strncpy (ins_parse, op, sizeof ins_parse - 1);
249 1.1 christos ins_parse [sizeof ins_parse - 1] = 0;
250 1.1 christos }
251 1.1 christos
252 1.1 christos /* This macro decides whether a particular reloc is an entry in a
253 1.1 christos switch table. It is used when relaxing, because the linker needs
254 1.1 christos to know about all such entries so that it can adjust them if
255 1.1 christos necessary. */
256 1.1 christos
257 1.1 christos #define SWITCH_TABLE(fix) \
258 1.1 christos ( (fix)->fx_addsy != NULL \
259 1.1 christos && (fix)->fx_subsy != NULL \
260 1.1 christos && S_GET_SEGMENT ((fix)->fx_addsy) == \
261 1.1 christos S_GET_SEGMENT ((fix)->fx_subsy) \
262 1.1 christos && S_GET_SEGMENT (fix->fx_addsy) != undefined_section \
263 1.1 christos && ( (fix)->fx_r_type == BFD_RELOC_CRX_NUM8 \
264 1.1 christos || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16 \
265 1.1 christos || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
266 1.1 christos
267 1.1 christos /* See whether we need to force a relocation into the output file.
268 1.1 christos This is used to force out switch and PC relative relocations when
269 1.1 christos relaxing. */
270 1.1 christos
271 1.1 christos int
272 1.1 christos crx_force_relocation (fixS *fix)
273 1.1 christos {
274 1.1 christos if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
275 1.1 christos return 1;
276 1.1 christos
277 1.1 christos return 0;
278 1.1 christos }
279 1.1 christos
280 1.1 christos /* Generate a relocation entry for a fixup. */
281 1.1 christos
282 1.1 christos arelent *
283 1.1 christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
284 1.1 christos {
285 1.1 christos arelent * reloc;
286 1.1 christos
287 1.5 christos reloc = XNEW (arelent);
288 1.5 christos reloc->sym_ptr_ptr = XNEW (asymbol *);
289 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
290 1.1 christos reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
291 1.1 christos reloc->addend = fixP->fx_offset;
292 1.1 christos
293 1.1 christos if (fixP->fx_subsy != NULL)
294 1.1 christos {
295 1.1 christos if (SWITCH_TABLE (fixP))
296 1.1 christos {
297 1.1 christos /* Keep the current difference in the addend. */
298 1.1 christos reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
299 1.1 christos - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
300 1.1 christos
301 1.1 christos switch (fixP->fx_r_type)
302 1.1 christos {
303 1.1 christos case BFD_RELOC_CRX_NUM8:
304 1.1 christos fixP->fx_r_type = BFD_RELOC_CRX_SWITCH8;
305 1.1 christos break;
306 1.1 christos case BFD_RELOC_CRX_NUM16:
307 1.1 christos fixP->fx_r_type = BFD_RELOC_CRX_SWITCH16;
308 1.1 christos break;
309 1.1 christos case BFD_RELOC_CRX_NUM32:
310 1.1 christos fixP->fx_r_type = BFD_RELOC_CRX_SWITCH32;
311 1.1 christos break;
312 1.1 christos default:
313 1.1 christos abort ();
314 1.1 christos break;
315 1.1 christos }
316 1.1 christos }
317 1.1 christos else
318 1.1 christos {
319 1.1 christos /* We only resolve difference expressions in the same section. */
320 1.8 christos as_bad_subtract (fixP);
321 1.8 christos free (reloc->sym_ptr_ptr);
322 1.8 christos free (reloc);
323 1.8 christos return NULL;
324 1.1 christos }
325 1.1 christos }
326 1.1 christos
327 1.1 christos gas_assert ((int) fixP->fx_r_type > 0);
328 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
329 1.1 christos
330 1.1 christos if (reloc->howto == (reloc_howto_type *) NULL)
331 1.1 christos {
332 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
333 1.1 christos _("internal error: reloc %d (`%s') not supported by object file format"),
334 1.1 christos fixP->fx_r_type,
335 1.1 christos bfd_get_reloc_code_name (fixP->fx_r_type));
336 1.1 christos return NULL;
337 1.1 christos }
338 1.1 christos gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
339 1.1 christos
340 1.1 christos return reloc;
341 1.1 christos }
342 1.1 christos
343 1.1 christos /* Prepare machine-dependent frags for relaxation. */
344 1.1 christos
345 1.1 christos int
346 1.1 christos md_estimate_size_before_relax (fragS *fragp, asection *seg)
347 1.1 christos {
348 1.1 christos /* If symbol is undefined or located in a different section,
349 1.1 christos select the largest supported relocation. */
350 1.1 christos relax_substateT subtype;
351 1.1 christos relax_substateT rlx_state[] = {0, 2,
352 1.1 christos 3, 4,
353 1.1 christos 5, 6};
354 1.1 christos
355 1.1 christos for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
356 1.1 christos {
357 1.1 christos if (fragp->fr_subtype == rlx_state[subtype]
358 1.1 christos && (!S_IS_DEFINED (fragp->fr_symbol)
359 1.1 christos || seg != S_GET_SEGMENT (fragp->fr_symbol)))
360 1.1 christos {
361 1.1 christos fragp->fr_subtype = rlx_state[subtype + 1];
362 1.1 christos break;
363 1.1 christos }
364 1.1 christos }
365 1.1 christos
366 1.1 christos if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
367 1.1 christos abort ();
368 1.1 christos
369 1.1 christos return md_relax_table[fragp->fr_subtype].rlx_length;
370 1.1 christos }
371 1.1 christos
372 1.1 christos void
373 1.1 christos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
374 1.1 christos {
375 1.1 christos /* 'opcode' points to the start of the instruction, whether
376 1.1 christos we need to change the instruction's fixed encoding. */
377 1.8 christos char *opcode = &fragP->fr_literal[0] + fragP->fr_fix;
378 1.1 christos bfd_reloc_code_real_type reloc;
379 1.1 christos
380 1.1 christos subseg_change (sec, 0);
381 1.1 christos
382 1.1 christos switch (fragP->fr_subtype)
383 1.1 christos {
384 1.1 christos case 0:
385 1.1 christos reloc = BFD_RELOC_CRX_REL8;
386 1.1 christos break;
387 1.1 christos case 1:
388 1.1 christos *opcode = 0x7e;
389 1.1 christos reloc = BFD_RELOC_CRX_REL16;
390 1.1 christos break;
391 1.1 christos case 2:
392 1.1 christos *opcode = 0x7f;
393 1.1 christos reloc = BFD_RELOC_CRX_REL32;
394 1.1 christos break;
395 1.1 christos case 3:
396 1.1 christos reloc = BFD_RELOC_CRX_REL16;
397 1.1 christos break;
398 1.1 christos case 4:
399 1.1 christos *++opcode = 0x31;
400 1.1 christos reloc = BFD_RELOC_CRX_REL32;
401 1.1 christos break;
402 1.1 christos case 5:
403 1.1 christos reloc = BFD_RELOC_CRX_REL8_CMP;
404 1.1 christos break;
405 1.1 christos case 6:
406 1.1 christos *++opcode = 0x31;
407 1.1 christos reloc = BFD_RELOC_CRX_REL24;
408 1.1 christos break;
409 1.1 christos default:
410 1.1 christos abort ();
411 1.1 christos break;
412 1.1 christos }
413 1.1 christos
414 1.1 christos fix_new (fragP, fragP->fr_fix,
415 1.1 christos bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
416 1.1 christos fragP->fr_symbol, fragP->fr_offset, 1, reloc);
417 1.1 christos fragP->fr_var = 0;
418 1.1 christos fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
419 1.1 christos }
420 1.1 christos
421 1.1 christos /* Process machine-dependent command line options. Called once for
422 1.1 christos each option on the command line that the machine-independent part of
423 1.1 christos GAS does not understand. */
424 1.1 christos
425 1.1 christos int
426 1.5 christos md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
427 1.1 christos {
428 1.1 christos return 0;
429 1.1 christos }
430 1.1 christos
431 1.1 christos /* Machine-dependent usage-output. */
432 1.1 christos
433 1.1 christos void
434 1.1 christos md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
435 1.1 christos {
436 1.1 christos return;
437 1.1 christos }
438 1.1 christos
439 1.5 christos const char *
440 1.1 christos md_atof (int type, char *litP, int *sizeP)
441 1.1 christos {
442 1.1 christos return ieee_md_atof (type, litP, sizeP, target_big_endian);
443 1.1 christos }
444 1.1 christos
445 1.1 christos /* Apply a fixS (fixup of an instruction or data that we didn't have
446 1.1 christos enough info to complete immediately) to the data in a frag.
447 1.1 christos Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
448 1.1 christos relaxation of debug sections, this function is called only when
449 1.1 christos fixuping relocations of debug sections. */
450 1.1 christos
451 1.1 christos void
452 1.1 christos md_apply_fix (fixS *fixP, valueT *valP, segT seg)
453 1.1 christos {
454 1.1 christos valueT val = * valP;
455 1.1 christos char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
456 1.1 christos fixP->fx_offset = 0;
457 1.1 christos
458 1.1 christos switch (fixP->fx_r_type)
459 1.1 christos {
460 1.1 christos case BFD_RELOC_CRX_NUM8:
461 1.1 christos bfd_put_8 (stdoutput, (unsigned char) val, buf);
462 1.1 christos break;
463 1.1 christos case BFD_RELOC_CRX_NUM16:
464 1.1 christos bfd_put_16 (stdoutput, val, buf);
465 1.1 christos break;
466 1.1 christos case BFD_RELOC_CRX_NUM32:
467 1.1 christos bfd_put_32 (stdoutput, val, buf);
468 1.1 christos break;
469 1.1 christos default:
470 1.1 christos /* We shouldn't ever get here because linkrelax is nonzero. */
471 1.1 christos abort ();
472 1.1 christos break;
473 1.1 christos }
474 1.1 christos
475 1.1 christos fixP->fx_done = 0;
476 1.1 christos
477 1.1 christos if (fixP->fx_addsy == NULL
478 1.1 christos && fixP->fx_pcrel == 0)
479 1.1 christos fixP->fx_done = 1;
480 1.1 christos
481 1.1 christos if (fixP->fx_pcrel == 1
482 1.1 christos && fixP->fx_addsy != NULL
483 1.1 christos && S_GET_SEGMENT (fixP->fx_addsy) == seg)
484 1.1 christos fixP->fx_done = 1;
485 1.1 christos }
486 1.1 christos
487 1.1 christos /* The location from which a PC relative jump should be calculated,
488 1.1 christos given a PC relative reloc. */
489 1.1 christos
490 1.1 christos long
491 1.1 christos md_pcrel_from (fixS *fixp)
492 1.1 christos {
493 1.1 christos return fixp->fx_frag->fr_address + fixp->fx_where;
494 1.1 christos }
495 1.1 christos
496 1.1 christos /* This function is called once, at assembler startup time. This should
497 1.1 christos set up all the tables, etc that the MD part of the assembler needs. */
498 1.1 christos
499 1.1 christos void
500 1.1 christos md_begin (void)
501 1.1 christos {
502 1.1 christos int i = 0;
503 1.1 christos
504 1.1 christos /* Set up a hash table for the instructions. */
505 1.8 christos crx_inst_hash = str_htab_create ();
506 1.3 christos
507 1.1 christos while (crx_instruction[i].mnemonic != NULL)
508 1.1 christos {
509 1.1 christos const char *mnemonic = crx_instruction[i].mnemonic;
510 1.1 christos
511 1.8 christos if (str_hash_insert (crx_inst_hash, mnemonic, &crx_instruction[i], 0))
512 1.8 christos as_fatal (_("duplicate %s"), mnemonic);
513 1.1 christos
514 1.1 christos /* Insert unique names into hash table. The CRX instruction set
515 1.1 christos has many identical opcode names that have different opcodes based
516 1.1 christos on the operands. This hash table then provides a quick index to
517 1.1 christos the first opcode with a particular name in the opcode table. */
518 1.1 christos do
519 1.1 christos {
520 1.1 christos ++i;
521 1.1 christos }
522 1.1 christos while (crx_instruction[i].mnemonic != NULL
523 1.1 christos && streq (crx_instruction[i].mnemonic, mnemonic));
524 1.1 christos }
525 1.1 christos
526 1.1 christos /* Initialize reg_hash hash table. */
527 1.8 christos reg_hash = str_htab_create ();
528 1.1 christos {
529 1.1 christos const reg_entry *regtab;
530 1.1 christos
531 1.1 christos for (regtab = crx_regtab;
532 1.1 christos regtab < (crx_regtab + NUMREGS); regtab++)
533 1.8 christos if (str_hash_insert (reg_hash, regtab->name, regtab, 0) != NULL)
534 1.8 christos as_fatal (_("duplicate %s"), regtab->name);
535 1.1 christos }
536 1.1 christos
537 1.1 christos /* Initialize copreg_hash hash table. */
538 1.8 christos copreg_hash = str_htab_create ();
539 1.1 christos {
540 1.1 christos const reg_entry *copregtab;
541 1.1 christos
542 1.1 christos for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
543 1.1 christos copregtab++)
544 1.8 christos if (str_hash_insert (copreg_hash, copregtab->name, copregtab, 0) != NULL)
545 1.8 christos as_fatal (_("duplicate %s"), copregtab->name);
546 1.1 christos }
547 1.1 christos /* Set linkrelax here to avoid fixups in most sections. */
548 1.1 christos linkrelax = 1;
549 1.1 christos }
550 1.1 christos
551 1.3 christos /* Process constants (immediate/absolute)
552 1.1 christos and labels (jump targets/Memory locations). */
553 1.1 christos
554 1.1 christos static void
555 1.1 christos process_label_constant (char *str, ins * crx_ins)
556 1.1 christos {
557 1.1 christos char *saved_input_line_pointer;
558 1.1 christos argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
559 1.1 christos
560 1.1 christos saved_input_line_pointer = input_line_pointer;
561 1.1 christos input_line_pointer = str;
562 1.1 christos
563 1.1 christos expression (&crx_ins->exp);
564 1.3 christos
565 1.1 christos switch (crx_ins->exp.X_op)
566 1.1 christos {
567 1.1 christos case O_big:
568 1.1 christos case O_absent:
569 1.1 christos /* Missing or bad expr becomes absolute 0. */
570 1.1 christos as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
571 1.1 christos str);
572 1.1 christos crx_ins->exp.X_op = O_constant;
573 1.1 christos crx_ins->exp.X_add_number = 0;
574 1.1 christos crx_ins->exp.X_add_symbol = (symbolS *) 0;
575 1.1 christos crx_ins->exp.X_op_symbol = (symbolS *) 0;
576 1.1 christos /* Fall through. */
577 1.1 christos
578 1.1 christos case O_constant:
579 1.1 christos cur_arg->X_op = O_constant;
580 1.1 christos cur_arg->constant = crx_ins->exp.X_add_number;
581 1.1 christos break;
582 1.1 christos
583 1.1 christos case O_symbol:
584 1.1 christos case O_subtract:
585 1.1 christos case O_add:
586 1.1 christos cur_arg->X_op = O_symbol;
587 1.1 christos crx_ins->rtype = BFD_RELOC_NONE;
588 1.1 christos relocatable = 1;
589 1.1 christos
590 1.1 christos switch (cur_arg->type)
591 1.1 christos {
592 1.1 christos case arg_cr:
593 1.8 christos if (IS_INSN_TYPE (LD_STOR_INS_INC))
594 1.1 christos crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
595 1.8 christos else if (IS_INSN_TYPE (CSTBIT_INS)
596 1.1 christos || IS_INSN_TYPE (STOR_IMM_INS))
597 1.1 christos crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
598 1.8 christos else
599 1.1 christos crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
600 1.1 christos break;
601 1.1 christos
602 1.1 christos case arg_idxr:
603 1.8 christos crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
604 1.1 christos break;
605 1.3 christos
606 1.1 christos case arg_c:
607 1.8 christos if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
608 1.1 christos crx_ins->rtype = BFD_RELOC_CRX_REL16;
609 1.1 christos else if (IS_INSN_TYPE (BRANCH_INS))
610 1.1 christos crx_ins->rtype = BFD_RELOC_CRX_REL8;
611 1.8 christos else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
612 1.1 christos || IS_INSN_TYPE (CSTBIT_INS))
613 1.1 christos crx_ins->rtype = BFD_RELOC_CRX_ABS32;
614 1.1 christos else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
615 1.1 christos crx_ins->rtype = BFD_RELOC_CRX_REL4;
616 1.8 christos else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
617 1.1 christos crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
618 1.1 christos break;
619 1.3 christos
620 1.1 christos case arg_ic:
621 1.8 christos if (IS_INSN_TYPE (ARITH_INS))
622 1.1 christos crx_ins->rtype = BFD_RELOC_CRX_IMM32;
623 1.1 christos else if (IS_INSN_TYPE (ARITH_BYTE_INS))
624 1.1 christos crx_ins->rtype = BFD_RELOC_CRX_IMM16;
625 1.1 christos break;
626 1.1 christos default:
627 1.1 christos break;
628 1.8 christos }
629 1.1 christos break;
630 1.1 christos
631 1.1 christos default:
632 1.1 christos cur_arg->X_op = crx_ins->exp.X_op;
633 1.1 christos break;
634 1.1 christos }
635 1.1 christos
636 1.1 christos input_line_pointer = saved_input_line_pointer;
637 1.1 christos return;
638 1.1 christos }
639 1.1 christos
640 1.1 christos /* Get the values of the scale to be encoded -
641 1.1 christos used for the scaled index mode of addressing. */
642 1.1 christos
643 1.1 christos static int
644 1.1 christos exponent2scale (int val)
645 1.1 christos {
646 1.1 christos int exponent;
647 1.1 christos
648 1.1 christos /* If 'val' is 0, the following 'for' will be an endless loop. */
649 1.1 christos if (val == 0)
650 1.1 christos return 0;
651 1.1 christos
652 1.1 christos for (exponent = 0; (val != 1); val >>= 1, exponent++)
653 1.1 christos ;
654 1.1 christos
655 1.1 christos return exponent;
656 1.1 christos }
657 1.1 christos
658 1.1 christos /* Parsing different types of operands
659 1.1 christos -> constants Immediate/Absolute/Relative numbers
660 1.1 christos -> Labels Relocatable symbols
661 1.1 christos -> (rbase) Register base
662 1.1 christos -> disp(rbase) Register relative
663 1.1 christos -> disp(rbase)+ Post-increment mode
664 1.1 christos -> disp(rbase,ridx,scl) Register index mode */
665 1.1 christos
666 1.1 christos static void
667 1.1 christos set_operand (char *operand, ins * crx_ins)
668 1.1 christos {
669 1.6 christos char *operandS; /* Pointer to start of sub-operand. */
670 1.6 christos char *operandE; /* Pointer to end of sub-operand. */
671 1.1 christos expressionS scale;
672 1.1 christos int scale_val;
673 1.1 christos char *input_save, c;
674 1.1 christos argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
675 1.1 christos
676 1.1 christos /* Initialize pointers. */
677 1.1 christos operandS = operandE = operand;
678 1.1 christos
679 1.1 christos switch (cur_arg->type)
680 1.1 christos {
681 1.1 christos case arg_sc: /* Case *+0x18. */
682 1.1 christos case arg_ic: /* Case $0x18. */
683 1.1 christos operandS++;
684 1.6 christos /* Fall through. */
685 1.1 christos case arg_c: /* Case 0x18. */
686 1.1 christos /* Set constant. */
687 1.1 christos process_label_constant (operandS, crx_ins);
688 1.3 christos
689 1.1 christos if (cur_arg->type != arg_ic)
690 1.1 christos cur_arg->type = arg_c;
691 1.1 christos break;
692 1.1 christos
693 1.1 christos case arg_icr: /* Case $0x18(r1). */
694 1.1 christos operandS++;
695 1.1 christos case arg_cr: /* Case 0x18(r1). */
696 1.1 christos /* Set displacement constant. */
697 1.1 christos while (*operandE != '(')
698 1.1 christos operandE++;
699 1.1 christos *operandE = '\0';
700 1.1 christos process_label_constant (operandS, crx_ins);
701 1.3 christos operandS = operandE;
702 1.6 christos /* Fall through. */
703 1.1 christos case arg_rbase: /* Case (r1). */
704 1.1 christos operandS++;
705 1.1 christos /* Set register base. */
706 1.1 christos while (*operandE != ')')
707 1.1 christos operandE++;
708 1.1 christos *operandE = '\0';
709 1.1 christos if ((cur_arg->r = get_register (operandS)) == nullregister)
710 1.6 christos as_bad (_("Illegal register `%s' in instruction `%s'"),
711 1.1 christos operandS, ins_parse);
712 1.1 christos
713 1.1 christos if (cur_arg->type != arg_rbase)
714 1.1 christos cur_arg->type = arg_cr;
715 1.1 christos break;
716 1.1 christos
717 1.1 christos case arg_idxr:
718 1.1 christos /* Set displacement constant. */
719 1.1 christos while (*operandE != '(')
720 1.1 christos operandE++;
721 1.1 christos *operandE = '\0';
722 1.1 christos process_label_constant (operandS, crx_ins);
723 1.1 christos operandS = ++operandE;
724 1.3 christos
725 1.1 christos /* Set register base. */
726 1.1 christos while ((*operandE != ',') && (! ISSPACE (*operandE)))
727 1.1 christos operandE++;
728 1.1 christos *operandE++ = '\0';
729 1.1 christos if ((cur_arg->r = get_register (operandS)) == nullregister)
730 1.6 christos as_bad (_("Illegal register `%s' in instruction `%s'"),
731 1.1 christos operandS, ins_parse);
732 1.1 christos
733 1.1 christos /* Skip leading white space. */
734 1.1 christos while (ISSPACE (*operandE))
735 1.1 christos operandE++;
736 1.1 christos operandS = operandE;
737 1.1 christos
738 1.1 christos /* Set register index. */
739 1.1 christos while ((*operandE != ')') && (*operandE != ','))
740 1.1 christos operandE++;
741 1.1 christos c = *operandE;
742 1.1 christos *operandE++ = '\0';
743 1.1 christos
744 1.1 christos if ((cur_arg->i_r = get_register (operandS)) == nullregister)
745 1.6 christos as_bad (_("Illegal register `%s' in instruction `%s'"),
746 1.1 christos operandS, ins_parse);
747 1.1 christos
748 1.1 christos /* Skip leading white space. */
749 1.1 christos while (ISSPACE (*operandE))
750 1.1 christos operandE++;
751 1.1 christos operandS = operandE;
752 1.1 christos
753 1.1 christos /* Set the scale. */
754 1.1 christos if (c == ')')
755 1.1 christos cur_arg->scale = 0;
756 1.1 christos else
757 1.8 christos {
758 1.1 christos while (*operandE != ')')
759 1.1 christos operandE++;
760 1.1 christos *operandE = '\0';
761 1.1 christos
762 1.1 christos /* Preprocess the scale string. */
763 1.1 christos input_save = input_line_pointer;
764 1.1 christos input_line_pointer = operandS;
765 1.1 christos expression (&scale);
766 1.1 christos input_line_pointer = input_save;
767 1.1 christos
768 1.1 christos scale_val = scale.X_add_number;
769 1.1 christos
770 1.1 christos /* Check if the scale value is legal. */
771 1.8 christos if (scale_val != 1 && scale_val != 2
772 1.8 christos && scale_val != 4 && scale_val != 8)
773 1.1 christos as_bad (_("Illegal Scale - `%d'"), scale_val);
774 1.1 christos
775 1.1 christos cur_arg->scale = exponent2scale (scale_val);
776 1.8 christos }
777 1.1 christos break;
778 1.1 christos
779 1.1 christos default:
780 1.1 christos break;
781 1.1 christos }
782 1.1 christos }
783 1.1 christos
784 1.1 christos /* Parse a single operand.
785 1.1 christos operand - Current operand to parse.
786 1.1 christos crx_ins - Current assembled instruction. */
787 1.1 christos
788 1.1 christos static void
789 1.1 christos parse_operand (char *operand, ins * crx_ins)
790 1.1 christos {
791 1.1 christos int ret_val;
792 1.1 christos argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
793 1.1 christos
794 1.1 christos /* Initialize the type to NULL before parsing. */
795 1.1 christos cur_arg->type = nullargs;
796 1.1 christos
797 1.1 christos /* Check whether this is a general processor register. */
798 1.1 christos if ((ret_val = get_register (operand)) != nullregister)
799 1.1 christos {
800 1.1 christos cur_arg->type = arg_r;
801 1.1 christos cur_arg->r = ret_val;
802 1.1 christos cur_arg->X_op = O_register;
803 1.1 christos return;
804 1.1 christos }
805 1.1 christos
806 1.1 christos /* Check whether this is a core [special] coprocessor register. */
807 1.1 christos if ((ret_val = get_copregister (operand)) != nullcopregister)
808 1.1 christos {
809 1.1 christos cur_arg->type = arg_copr;
810 1.1 christos if (ret_val >= cs0)
811 1.1 christos cur_arg->type = arg_copsr;
812 1.1 christos cur_arg->cr = ret_val;
813 1.1 christos cur_arg->X_op = O_register;
814 1.1 christos return;
815 1.1 christos }
816 1.1 christos
817 1.1 christos /* Deal with special characters. */
818 1.1 christos switch (operand[0])
819 1.1 christos {
820 1.1 christos case '$':
821 1.1 christos if (strchr (operand, '(') != NULL)
822 1.1 christos cur_arg->type = arg_icr;
823 1.1 christos else
824 1.8 christos cur_arg->type = arg_ic;
825 1.1 christos goto set_params;
826 1.1 christos break;
827 1.1 christos
828 1.1 christos case '*':
829 1.1 christos cur_arg->type = arg_sc;
830 1.1 christos goto set_params;
831 1.1 christos break;
832 1.1 christos
833 1.1 christos case '(':
834 1.1 christos cur_arg->type = arg_rbase;
835 1.1 christos goto set_params;
836 1.1 christos break;
837 1.1 christos
838 1.1 christos default:
839 1.8 christos break;
840 1.1 christos }
841 1.3 christos
842 1.1 christos if (strchr (operand, '(') != NULL)
843 1.1 christos {
844 1.1 christos if (strchr (operand, ',') != NULL
845 1.8 christos && (strchr (operand, ',') > strchr (operand, '(')))
846 1.8 christos cur_arg->type = arg_idxr;
847 1.1 christos else
848 1.1 christos cur_arg->type = arg_cr;
849 1.1 christos }
850 1.1 christos else
851 1.1 christos cur_arg->type = arg_c;
852 1.1 christos goto set_params;
853 1.1 christos
854 1.8 christos /* Parse an operand according to its type. */
855 1.8 christos set_params:
856 1.1 christos cur_arg->constant = 0;
857 1.1 christos set_operand (operand, crx_ins);
858 1.1 christos }
859 1.1 christos
860 1.3 christos /* Parse the various operands. Each operand is then analyzed to fillup
861 1.1 christos the fields in the crx_ins data structure. */
862 1.1 christos
863 1.1 christos static void
864 1.1 christos parse_operands (ins * crx_ins, char *operands)
865 1.1 christos {
866 1.1 christos char *operandS; /* Operands string. */
867 1.1 christos char *operandH, *operandT; /* Single operand head/tail pointers. */
868 1.1 christos int allocated = 0; /* Indicates a new operands string was allocated. */
869 1.1 christos char *operand[MAX_OPERANDS]; /* Separating the operands. */
870 1.1 christos int op_num = 0; /* Current operand number we are parsing. */
871 1.1 christos int bracket_flag = 0; /* Indicates a bracket '(' was found. */
872 1.1 christos int sq_bracket_flag = 0; /* Indicates a square bracket '[' was found. */
873 1.1 christos
874 1.1 christos /* Preprocess the list of registers, if necessary. */
875 1.1 christos operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
876 1.1 christos preprocess_reglist (operands, &allocated) : operands;
877 1.1 christos
878 1.1 christos while (*operandT != '\0')
879 1.1 christos {
880 1.1 christos if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
881 1.8 christos {
882 1.1 christos *operandT++ = '\0';
883 1.1 christos operand[op_num++] = strdup (operandH);
884 1.8 christos operandH = operandT;
885 1.8 christos continue;
886 1.8 christos }
887 1.1 christos
888 1.1 christos if (*operandT == ' ')
889 1.1 christos as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
890 1.1 christos
891 1.1 christos if (*operandT == '(')
892 1.1 christos bracket_flag = 1;
893 1.1 christos else if (*operandT == '[')
894 1.1 christos sq_bracket_flag = 1;
895 1.1 christos
896 1.1 christos if (*operandT == ')')
897 1.1 christos {
898 1.1 christos if (bracket_flag)
899 1.1 christos bracket_flag = 0;
900 1.1 christos else
901 1.1 christos as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
902 1.1 christos }
903 1.1 christos else if (*operandT == ']')
904 1.1 christos {
905 1.1 christos if (sq_bracket_flag)
906 1.1 christos sq_bracket_flag = 0;
907 1.1 christos else
908 1.1 christos as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
909 1.1 christos }
910 1.1 christos
911 1.1 christos if (bracket_flag == 1 && *operandT == ')')
912 1.1 christos bracket_flag = 0;
913 1.1 christos else if (sq_bracket_flag == 1 && *operandT == ']')
914 1.1 christos sq_bracket_flag = 0;
915 1.1 christos
916 1.1 christos operandT++;
917 1.1 christos }
918 1.1 christos
919 1.1 christos /* Adding the last operand. */
920 1.1 christos operand[op_num++] = strdup (operandH);
921 1.1 christos crx_ins->nargs = op_num;
922 1.1 christos
923 1.1 christos /* Verifying correct syntax of operands (all brackets should be closed). */
924 1.1 christos if (bracket_flag || sq_bracket_flag)
925 1.1 christos as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
926 1.1 christos
927 1.1 christos /* Now we parse each operand separately. */
928 1.1 christos for (op_num = 0; op_num < crx_ins->nargs; op_num++)
929 1.1 christos {
930 1.1 christos cur_arg_num = op_num;
931 1.1 christos parse_operand (operand[op_num], crx_ins);
932 1.1 christos free (operand[op_num]);
933 1.1 christos }
934 1.1 christos
935 1.1 christos if (allocated)
936 1.1 christos free (operandS);
937 1.1 christos }
938 1.1 christos
939 1.1 christos /* Get the trap index in dispatch table, given its name.
940 1.1 christos This routine is used by assembling the 'excp' instruction. */
941 1.1 christos
942 1.1 christos static int
943 1.1 christos gettrap (const char *s)
944 1.1 christos {
945 1.1 christos const trap_entry *trap;
946 1.1 christos
947 1.1 christos for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
948 1.1 christos if (strcasecmp (trap->name, s) == 0)
949 1.1 christos return trap->entry;
950 1.1 christos
951 1.1 christos as_bad (_("Unknown exception: `%s'"), s);
952 1.1 christos return 0;
953 1.1 christos }
954 1.1 christos
955 1.3 christos /* Post-Increment instructions, as well as Store-Immediate instructions, are a
956 1.3 christos sub-group within load/stor instruction groups.
957 1.3 christos Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
958 1.3 christos advance the instruction pointer to the start of that sub-group (that is, up
959 1.1 christos to the first instruction of that type).
960 1.1 christos Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS. */
961 1.1 christos
962 1.1 christos static void
963 1.1 christos handle_LoadStor (const char *operands)
964 1.1 christos {
965 1.3 christos /* Post-Increment instructions precede Store-Immediate instructions in
966 1.3 christos CRX instruction table, hence they are handled before.
967 1.1 christos This synchronization should be kept. */
968 1.1 christos
969 1.1 christos /* Assuming Post-Increment insn has the following format :
970 1.1 christos 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
971 1.1 christos LD_STOR_INS_INC are the only store insns containing a plus sign (+). */
972 1.1 christos if (strstr (operands, ")+") != NULL)
973 1.1 christos {
974 1.1 christos while (! IS_INSN_TYPE (LD_STOR_INS_INC))
975 1.1 christos instruction++;
976 1.1 christos return;
977 1.1 christos }
978 1.1 christos
979 1.1 christos /* Assuming Store-Immediate insn has the following format :
980 1.1 christos 'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
981 1.1 christos STOR_IMM_INS are the only store insns containing a dollar sign ($). */
982 1.1 christos if (strstr (operands, "$") != NULL)
983 1.1 christos while (! IS_INSN_TYPE (STOR_IMM_INS))
984 1.1 christos instruction++;
985 1.1 christos }
986 1.1 christos
987 1.1 christos /* Top level module where instruction parsing starts.
988 1.1 christos crx_ins - data structure holds some information.
989 1.1 christos operands - holds the operands part of the whole instruction. */
990 1.1 christos
991 1.1 christos static void
992 1.1 christos parse_insn (ins *insn, char *operands)
993 1.1 christos {
994 1.1 christos int i;
995 1.1 christos
996 1.1 christos /* Handle instructions with no operands. */
997 1.6 christos for (i = 0; crx_no_op_insn[i] != NULL; i++)
998 1.1 christos {
999 1.6 christos if (streq (crx_no_op_insn[i], instruction->mnemonic))
1000 1.1 christos {
1001 1.1 christos insn->nargs = 0;
1002 1.1 christos return;
1003 1.1 christos }
1004 1.1 christos }
1005 1.1 christos
1006 1.1 christos /* Handle 'excp'/'cinv' instructions. */
1007 1.1 christos if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1008 1.1 christos {
1009 1.1 christos insn->nargs = 1;
1010 1.1 christos insn->arg[0].type = arg_ic;
1011 1.1 christos insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1012 1.1 christos gettrap (operands) : get_cinv_parameters (operands);
1013 1.1 christos insn->arg[0].X_op = O_constant;
1014 1.1 christos return;
1015 1.1 christos }
1016 1.1 christos
1017 1.1 christos /* Handle load/stor unique instructions before parsing. */
1018 1.1 christos if (IS_INSN_TYPE (LD_STOR_INS))
1019 1.1 christos handle_LoadStor (operands);
1020 1.1 christos
1021 1.1 christos if (operands != NULL)
1022 1.1 christos parse_operands (insn, operands);
1023 1.1 christos }
1024 1.1 christos
1025 1.1 christos /* Cinv instruction requires special handling. */
1026 1.1 christos
1027 1.1 christos static int
1028 1.1 christos get_cinv_parameters (const char *operand)
1029 1.1 christos {
1030 1.1 christos const char *p = operand;
1031 1.1 christos int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
1032 1.1 christos
1033 1.1 christos while (*++p != ']')
1034 1.1 christos {
1035 1.1 christos if (*p == ',' || *p == ' ')
1036 1.1 christos continue;
1037 1.1 christos
1038 1.1 christos if (*p == 'd')
1039 1.1 christos d_used = 1;
1040 1.1 christos else if (*p == 'i')
1041 1.1 christos i_used = 1;
1042 1.1 christos else if (*p == 'u')
1043 1.1 christos u_used = 1;
1044 1.1 christos else if (*p == 'b')
1045 1.1 christos b_used = 1;
1046 1.1 christos else
1047 1.1 christos as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1048 1.1 christos }
1049 1.1 christos
1050 1.1 christos return ((b_used ? 8 : 0)
1051 1.1 christos + (d_used ? 4 : 0)
1052 1.1 christos + (i_used ? 2 : 0)
1053 1.1 christos + (u_used ? 1 : 0));
1054 1.1 christos }
1055 1.1 christos
1056 1.1 christos /* Retrieve the opcode image of a given register.
1057 1.1 christos If the register is illegal for the current instruction,
1058 1.1 christos issue an error. */
1059 1.1 christos
1060 1.1 christos static int
1061 1.8 christos getreg_image (int r)
1062 1.1 christos {
1063 1.1 christos const reg_entry *rreg;
1064 1.1 christos char *reg_name;
1065 1.1 christos int is_procreg = 0; /* Nonzero means argument should be processor reg. */
1066 1.1 christos
1067 1.1 christos if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num == 1))
1068 1.1 christos || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num == 0)) )
1069 1.1 christos is_procreg = 1;
1070 1.1 christos
1071 1.1 christos /* Check whether the register is in registers table. */
1072 1.1 christos if (r < MAX_REG)
1073 1.1 christos rreg = &crx_regtab[r];
1074 1.1 christos /* Check whether the register is in coprocessor registers table. */
1075 1.1 christos else if (r < (int) MAX_COPREG)
1076 1.1 christos rreg = &crx_copregtab[r-MAX_REG];
1077 1.1 christos /* Register not found. */
1078 1.1 christos else
1079 1.1 christos {
1080 1.1 christos as_bad (_("Unknown register: `%d'"), r);
1081 1.1 christos return 0;
1082 1.1 christos }
1083 1.1 christos
1084 1.1 christos reg_name = rreg->name;
1085 1.1 christos
1086 1.1 christos /* Issue a error message when register is illegal. */
1087 1.1 christos #define IMAGE_ERR \
1088 1.6 christos as_bad (_("Illegal register (`%s') in instruction: `%s'"), \
1089 1.6 christos reg_name, ins_parse);
1090 1.1 christos
1091 1.1 christos switch (rreg->type)
1092 1.1 christos {
1093 1.1 christos case CRX_U_REGTYPE:
1094 1.1 christos if (is_procreg || (instruction->flags & USER_REG))
1095 1.1 christos return rreg->image;
1096 1.1 christos else
1097 1.1 christos IMAGE_ERR;
1098 1.6 christos break;
1099 1.1 christos
1100 1.1 christos case CRX_CFG_REGTYPE:
1101 1.1 christos if (is_procreg)
1102 1.1 christos return rreg->image;
1103 1.1 christos else
1104 1.1 christos IMAGE_ERR;
1105 1.6 christos break;
1106 1.1 christos
1107 1.1 christos case CRX_R_REGTYPE:
1108 1.1 christos if (! is_procreg)
1109 1.1 christos return rreg->image;
1110 1.1 christos else
1111 1.1 christos IMAGE_ERR;
1112 1.6 christos break;
1113 1.1 christos
1114 1.1 christos case CRX_C_REGTYPE:
1115 1.1 christos case CRX_CS_REGTYPE:
1116 1.1 christos return rreg->image;
1117 1.1 christos break;
1118 1.1 christos
1119 1.1 christos default:
1120 1.1 christos IMAGE_ERR;
1121 1.6 christos break;
1122 1.1 christos }
1123 1.1 christos
1124 1.1 christos return 0;
1125 1.1 christos }
1126 1.1 christos
1127 1.1 christos /* Routine used to represent integer X using NBITS bits. */
1128 1.1 christos
1129 1.1 christos static long
1130 1.1 christos getconstant (long x, int nbits)
1131 1.1 christos {
1132 1.1 christos return x & ((((1U << (nbits - 1)) - 1) << 1) | 1);
1133 1.1 christos }
1134 1.1 christos
1135 1.1 christos /* Print a constant value to 'output_opcode':
1136 1.1 christos ARG holds the operand's type and value.
1137 1.1 christos SHIFT represents the location of the operand to be print into.
1138 1.1 christos NBITS determines the size (in bits) of the constant. */
1139 1.1 christos
1140 1.1 christos static void
1141 1.1 christos print_constant (int nbits, int shift, argument *arg)
1142 1.1 christos {
1143 1.1 christos unsigned long mask = 0;
1144 1.8 christos unsigned long constant = getconstant (arg->constant, nbits);
1145 1.1 christos
1146 1.1 christos switch (nbits)
1147 1.1 christos {
1148 1.1 christos case 32:
1149 1.1 christos case 28:
1150 1.1 christos case 24:
1151 1.1 christos case 22:
1152 1.1 christos /* mask the upper part of the constant, that is, the bits
1153 1.1 christos going to the lowest byte of output_opcode[0].
1154 1.1 christos The upper part of output_opcode[1] is always filled,
1155 1.1 christos therefore it is always masked with 0xFFFF. */
1156 1.1 christos mask = (1 << (nbits - 16)) - 1;
1157 1.1 christos /* Divide the constant between two consecutive words :
1158 1.1 christos 0 1 2 3
1159 1.1 christos +---------+---------+---------+---------+
1160 1.1 christos | | X X X X | X X X X | |
1161 1.1 christos +---------+---------+---------+---------+
1162 1.1 christos output_opcode[0] output_opcode[1] */
1163 1.1 christos
1164 1.1 christos CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1165 1.8 christos CRX_PRINT (1, constant & 0xFFFF, WORD_SHIFT);
1166 1.1 christos break;
1167 1.1 christos
1168 1.1 christos case 16:
1169 1.1 christos case 12:
1170 1.1 christos /* Special case - in arg_cr, the SHIFT represents the location
1171 1.1 christos of the REGISTER, not the constant, which is itself not shifted. */
1172 1.1 christos if (arg->type == arg_cr)
1173 1.1 christos {
1174 1.1 christos CRX_PRINT (0, constant, 0);
1175 1.1 christos break;
1176 1.1 christos }
1177 1.1 christos
1178 1.3 christos /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1179 1.3 christos always filling the upper part of output_opcode[1]. If we mistakenly
1180 1.1 christos write it to output_opcode[0], the constant prefix (that is, 'match')
1181 1.1 christos will be overridden.
1182 1.1 christos 0 1 2 3
1183 1.1 christos +---------+---------+---------+---------+
1184 1.1 christos | 'match' | | X X X X | |
1185 1.1 christos +---------+---------+---------+---------+
1186 1.1 christos output_opcode[0] output_opcode[1] */
1187 1.1 christos
1188 1.1 christos if ((instruction->size > 2) && (shift == WORD_SHIFT))
1189 1.1 christos CRX_PRINT (1, constant, WORD_SHIFT);
1190 1.1 christos else
1191 1.1 christos CRX_PRINT (0, constant, shift);
1192 1.1 christos break;
1193 1.1 christos
1194 1.1 christos default:
1195 1.1 christos CRX_PRINT (0, constant, shift);
1196 1.1 christos break;
1197 1.1 christos }
1198 1.1 christos }
1199 1.1 christos
1200 1.1 christos /* Print an operand to 'output_opcode', which later on will be
1201 1.1 christos printed to the object file:
1202 1.1 christos ARG holds the operand's type, size and value.
1203 1.1 christos SHIFT represents the printing location of operand.
1204 1.1 christos NBITS determines the size (in bits) of a constant operand. */
1205 1.1 christos
1206 1.1 christos static void
1207 1.1 christos print_operand (int nbits, int shift, argument *arg)
1208 1.1 christos {
1209 1.1 christos switch (arg->type)
1210 1.1 christos {
1211 1.1 christos case arg_r:
1212 1.1 christos CRX_PRINT (0, getreg_image (arg->r), shift);
1213 1.1 christos break;
1214 1.1 christos
1215 1.1 christos case arg_copr:
1216 1.1 christos if (arg->cr < c0 || arg->cr > c15)
1217 1.6 christos as_bad (_("Illegal co-processor register in instruction `%s'"),
1218 1.1 christos ins_parse);
1219 1.1 christos CRX_PRINT (0, getreg_image (arg->cr), shift);
1220 1.1 christos break;
1221 1.1 christos
1222 1.1 christos case arg_copsr:
1223 1.1 christos if (arg->cr < cs0 || arg->cr > cs15)
1224 1.6 christos as_bad (_("Illegal co-processor special register in instruction `%s'"),
1225 1.1 christos ins_parse);
1226 1.1 christos CRX_PRINT (0, getreg_image (arg->cr), shift);
1227 1.1 christos break;
1228 1.1 christos
1229 1.1 christos case arg_idxr:
1230 1.1 christos /* 16 12 8 6 0
1231 1.1 christos +--------------------------------+
1232 1.1 christos | r_base | r_idx | scl| disp |
1233 1.1 christos +--------------------------------+ */
1234 1.1 christos CRX_PRINT (0, getreg_image (arg->r), 12);
1235 1.1 christos CRX_PRINT (0, getreg_image (arg->i_r), 8);
1236 1.1 christos CRX_PRINT (0, arg->scale, 6);
1237 1.6 christos /* Fall through. */
1238 1.1 christos case arg_ic:
1239 1.1 christos case arg_c:
1240 1.1 christos print_constant (nbits, shift, arg);
1241 1.1 christos break;
1242 1.1 christos
1243 1.1 christos case arg_rbase:
1244 1.1 christos CRX_PRINT (0, getreg_image (arg->r), shift);
1245 1.1 christos break;
1246 1.1 christos
1247 1.1 christos case arg_cr:
1248 1.1 christos /* case base_cst4. */
1249 1.1 christos if (instruction->flags & DISPU4MAP)
1250 1.1 christos print_constant (nbits, shift + REG_SIZE, arg);
1251 1.1 christos else
1252 1.1 christos /* rbase_disps<NN> and other such cases. */
1253 1.1 christos print_constant (nbits, shift, arg);
1254 1.1 christos /* Add the register argument to the output_opcode. */
1255 1.1 christos CRX_PRINT (0, getreg_image (arg->r), shift);
1256 1.1 christos break;
1257 1.1 christos
1258 1.1 christos default:
1259 1.1 christos break;
1260 1.1 christos }
1261 1.1 christos }
1262 1.1 christos
1263 1.1 christos /* Retrieve the number of operands for the current assembled instruction. */
1264 1.1 christos
1265 1.1 christos static int
1266 1.1 christos get_number_of_operands (void)
1267 1.1 christos {
1268 1.1 christos int i;
1269 1.1 christos
1270 1.1 christos for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1271 1.1 christos ;
1272 1.1 christos return i;
1273 1.1 christos }
1274 1.1 christos
1275 1.3 christos /* Verify that the number NUM can be represented in BITS bits (that is,
1276 1.3 christos within its permitted range), based on the instruction's FLAGS.
1277 1.1 christos If UPDATE is nonzero, update the value of NUM if necessary.
1278 1.1 christos Return OP_LEGAL upon success, actual error type upon failure. */
1279 1.1 christos
1280 1.1 christos static op_err
1281 1.1 christos check_range (long *num, int bits, int unsigned flags, int update)
1282 1.1 christos {
1283 1.1 christos uint32_t max;
1284 1.5 christos op_err retval = OP_LEGAL;
1285 1.1 christos int bin;
1286 1.1 christos uint32_t upper_64kb = 0xffff0000;
1287 1.1 christos uint32_t value = *num;
1288 1.1 christos
1289 1.1 christos /* Verify operand value is even. */
1290 1.1 christos if (flags & OP_EVEN)
1291 1.1 christos {
1292 1.1 christos if (value % 2)
1293 1.1 christos return OP_NOT_EVEN;
1294 1.1 christos }
1295 1.1 christos
1296 1.1 christos if (flags & OP_UPPER_64KB)
1297 1.1 christos {
1298 1.1 christos /* Check if value is to be mapped to upper 64 KB memory area. */
1299 1.1 christos if ((value & upper_64kb) == upper_64kb)
1300 1.1 christos {
1301 1.1 christos value -= upper_64kb;
1302 1.1 christos if (update)
1303 1.1 christos *num = value;
1304 1.1 christos }
1305 1.1 christos else
1306 1.1 christos return OP_NOT_UPPER_64KB;
1307 1.1 christos }
1308 1.1 christos
1309 1.1 christos if (flags & OP_SHIFT)
1310 1.1 christos {
1311 1.1 christos /* All OP_SHIFT args are also OP_SIGNED, so we want to keep the
1312 1.1 christos sign. However, right shift of a signed type with a negative
1313 1.1 christos value is implementation defined. See ISO C 6.5.7. So we use
1314 1.1 christos an unsigned type and sign extend afterwards. */
1315 1.1 christos value >>= 1;
1316 1.1 christos value = (value ^ 0x40000000) - 0x40000000;
1317 1.1 christos if (update)
1318 1.1 christos *num = value;
1319 1.1 christos }
1320 1.1 christos else if (flags & OP_SHIFT_DEC)
1321 1.1 christos {
1322 1.1 christos value = (value >> 1) - 1;
1323 1.1 christos if (update)
1324 1.1 christos *num = value;
1325 1.1 christos }
1326 1.1 christos
1327 1.1 christos if (flags & OP_ESC)
1328 1.1 christos {
1329 1.1 christos /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
1330 1.1 christos if (value == 0x7e || value == 0x7f)
1331 1.1 christos return OP_OUT_OF_RANGE;
1332 1.1 christos }
1333 1.1 christos
1334 1.1 christos if (flags & OP_DISPU4)
1335 1.1 christos {
1336 1.1 christos int is_dispu4 = 0;
1337 1.1 christos
1338 1.3 christos uint32_t mul = (instruction->flags & DISPUB4 ? 1
1339 1.1 christos : instruction->flags & DISPUW4 ? 2
1340 1.1 christos : instruction->flags & DISPUD4 ? 4
1341 1.1 christos : 0);
1342 1.3 christos
1343 1.6 christos for (bin = 0; bin < crx_cst4_maps; bin++)
1344 1.1 christos {
1345 1.1 christos if (value == mul * bin)
1346 1.1 christos {
1347 1.1 christos is_dispu4 = 1;
1348 1.1 christos if (update)
1349 1.1 christos *num = bin;
1350 1.1 christos break;
1351 1.1 christos }
1352 1.1 christos }
1353 1.1 christos if (!is_dispu4)
1354 1.1 christos retval = OP_ILLEGAL_DISPU4;
1355 1.1 christos }
1356 1.1 christos else if (flags & OP_CST4)
1357 1.1 christos {
1358 1.1 christos int is_cst4 = 0;
1359 1.1 christos
1360 1.6 christos for (bin = 0; bin < crx_cst4_maps; bin++)
1361 1.1 christos {
1362 1.6 christos if (value == (uint32_t) crx_cst4_map[bin])
1363 1.1 christos {
1364 1.1 christos is_cst4 = 1;
1365 1.1 christos if (update)
1366 1.1 christos *num = bin;
1367 1.1 christos break;
1368 1.1 christos }
1369 1.1 christos }
1370 1.1 christos if (!is_cst4)
1371 1.1 christos retval = OP_ILLEGAL_CST4;
1372 1.1 christos }
1373 1.1 christos else if (flags & OP_SIGNED)
1374 1.1 christos {
1375 1.1 christos max = 1;
1376 1.1 christos max = max << (bits - 1);
1377 1.1 christos value += max;
1378 1.1 christos max = ((max - 1) << 1) | 1;
1379 1.1 christos if (value > max)
1380 1.1 christos retval = OP_OUT_OF_RANGE;
1381 1.1 christos }
1382 1.1 christos else if (flags & OP_UNSIGNED)
1383 1.1 christos {
1384 1.1 christos max = 1;
1385 1.1 christos max = max << (bits - 1);
1386 1.1 christos max = ((max - 1) << 1) | 1;
1387 1.1 christos if (value > max)
1388 1.1 christos retval = OP_OUT_OF_RANGE;
1389 1.1 christos }
1390 1.1 christos return retval;
1391 1.1 christos }
1392 1.1 christos
1393 1.1 christos /* Assemble a single instruction:
1394 1.1 christos INSN is already parsed (that is, all operand values and types are set).
1395 1.3 christos For instruction to be assembled, we need to find an appropriate template in
1396 1.1 christos the instruction table, meeting the following conditions:
1397 1.1 christos 1: Has the same number of operands.
1398 1.1 christos 2: Has the same operand types.
1399 1.1 christos 3: Each operand size is sufficient to represent the instruction's values.
1400 1.1 christos Returns 1 upon success, 0 upon failure. */
1401 1.1 christos
1402 1.1 christos static int
1403 1.1 christos assemble_insn (char *mnemonic, ins *insn)
1404 1.1 christos {
1405 1.1 christos /* Type of each operand in the current template. */
1406 1.1 christos argtype cur_type[MAX_OPERANDS];
1407 1.1 christos /* Size (in bits) of each operand in the current template. */
1408 1.1 christos unsigned int cur_size[MAX_OPERANDS];
1409 1.1 christos /* Flags of each operand in the current template. */
1410 1.1 christos unsigned int cur_flags[MAX_OPERANDS];
1411 1.1 christos /* Instruction type to match. */
1412 1.1 christos unsigned int ins_type;
1413 1.1 christos /* Boolean flag to mark whether a match was found. */
1414 1.1 christos int match = 0;
1415 1.1 christos int i;
1416 1.1 christos /* Nonzero if an instruction with same number of operands was found. */
1417 1.1 christos int found_same_number_of_operands = 0;
1418 1.1 christos /* Nonzero if an instruction with same argument types was found. */
1419 1.1 christos int found_same_argument_types = 0;
1420 1.1 christos /* Nonzero if a constant was found within the required range. */
1421 1.1 christos int found_const_within_range = 0;
1422 1.1 christos /* Argument number of an operand with invalid type. */
1423 1.1 christos int invalid_optype = -1;
1424 1.1 christos /* Argument number of an operand with invalid constant value. */
1425 1.1 christos int invalid_const = -1;
1426 1.1 christos /* Operand error (used for issuing various constant error messages). */
1427 1.1 christos op_err op_error, const_err = OP_LEGAL;
1428 1.1 christos
1429 1.8 christos /* Retrieve data (based on FUNC) for each operand of a given instruction. */
1430 1.8 christos #define GET_CURRENT_DATA(FUNC, ARRAY) \
1431 1.8 christos for (i = 0; i < insn->nargs; i++) \
1432 1.1 christos ARRAY[i] = FUNC (instruction->operands[i].op_type)
1433 1.1 christos
1434 1.1 christos #define GET_CURRENT_TYPE GET_CURRENT_DATA(get_optype, cur_type)
1435 1.1 christos #define GET_CURRENT_SIZE GET_CURRENT_DATA(get_opbits, cur_size)
1436 1.1 christos #define GET_CURRENT_FLAGS GET_CURRENT_DATA(get_opflags, cur_flags)
1437 1.1 christos
1438 1.1 christos /* Instruction has no operands -> only copy the constant opcode. */
1439 1.1 christos if (insn->nargs == 0)
1440 1.1 christos {
1441 1.1 christos output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1442 1.1 christos return 1;
1443 1.1 christos }
1444 1.1 christos
1445 1.1 christos /* In some case, same mnemonic can appear with different instruction types.
1446 1.1 christos For example, 'storb' is supported with 3 different types :
1447 1.1 christos LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
1448 1.3 christos We assume that when reaching this point, the instruction type was
1449 1.1 christos pre-determined. We need to make sure that the type stays the same
1450 1.1 christos during a search for matching instruction. */
1451 1.1 christos ins_type = CRX_INS_TYPE(instruction->flags);
1452 1.1 christos
1453 1.1 christos while (/* Check that match is still not found. */
1454 1.1 christos match != 1
1455 1.1 christos /* Check we didn't get to end of table. */
1456 1.1 christos && instruction->mnemonic != NULL
1457 1.1 christos /* Check that the actual mnemonic is still available. */
1458 1.1 christos && IS_INSN_MNEMONIC (mnemonic)
1459 1.1 christos /* Check that the instruction type wasn't changed. */
1460 1.1 christos && IS_INSN_TYPE(ins_type))
1461 1.1 christos {
1462 1.1 christos /* Check whether number of arguments is legal. */
1463 1.1 christos if (get_number_of_operands () != insn->nargs)
1464 1.1 christos goto next_insn;
1465 1.1 christos found_same_number_of_operands = 1;
1466 1.1 christos
1467 1.1 christos /* Initialize arrays with data of each operand in current template. */
1468 1.1 christos GET_CURRENT_TYPE;
1469 1.1 christos GET_CURRENT_SIZE;
1470 1.1 christos GET_CURRENT_FLAGS;
1471 1.1 christos
1472 1.1 christos /* Check for type compatibility. */
1473 1.1 christos for (i = 0; i < insn->nargs; i++)
1474 1.8 christos {
1475 1.1 christos if (cur_type[i] != insn->arg[i].type)
1476 1.1 christos {
1477 1.1 christos if (invalid_optype == -1)
1478 1.1 christos invalid_optype = i + 1;
1479 1.1 christos goto next_insn;
1480 1.1 christos }
1481 1.1 christos }
1482 1.1 christos found_same_argument_types = 1;
1483 1.1 christos
1484 1.1 christos for (i = 0; i < insn->nargs; i++)
1485 1.1 christos {
1486 1.1 christos /* Reverse the operand indices for certain opcodes:
1487 1.1 christos Index 0 -->> 1
1488 1.3 christos Index 1 -->> 0
1489 1.1 christos Other index -->> stays the same. */
1490 1.8 christos int j = (instruction->flags & REVERSE_MATCH) && i <= 1 ? 1 - i : i;
1491 1.1 christos
1492 1.3 christos /* Only check range - don't update the constant's value, since the
1493 1.3 christos current instruction may not be the last we try to match.
1494 1.3 christos The constant's value will be updated later, right before printing
1495 1.1 christos it to the object file. */
1496 1.8 christos if ((insn->arg[j].X_op == O_constant)
1497 1.8 christos && (op_error = check_range (&insn->arg[j].constant, cur_size[j],
1498 1.8 christos cur_flags[j], 0)))
1499 1.8 christos {
1500 1.1 christos if (invalid_const == -1)
1501 1.8 christos {
1502 1.8 christos invalid_const = j + 1;
1503 1.8 christos const_err = op_error;
1504 1.8 christos }
1505 1.1 christos goto next_insn;
1506 1.1 christos }
1507 1.3 christos /* For symbols, we make sure the relocation size (which was already
1508 1.1 christos determined) is sufficient. */
1509 1.1 christos else if ((insn->arg[j].X_op == O_symbol)
1510 1.8 christos && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
1511 1.8 christos > cur_size[j]))
1512 1.8 christos goto next_insn;
1513 1.1 christos }
1514 1.1 christos found_const_within_range = 1;
1515 1.1 christos
1516 1.1 christos /* If we got till here -> Full match is found. */
1517 1.1 christos match = 1;
1518 1.1 christos break;
1519 1.1 christos
1520 1.8 christos /* Try again with next instruction. */
1521 1.8 christos next_insn:
1522 1.1 christos instruction++;
1523 1.1 christos }
1524 1.1 christos
1525 1.1 christos if (!match)
1526 1.1 christos {
1527 1.1 christos /* We haven't found a match - instruction can't be assembled. */
1528 1.1 christos if (!found_same_number_of_operands)
1529 1.1 christos as_bad (_("Incorrect number of operands"));
1530 1.1 christos else if (!found_same_argument_types)
1531 1.1 christos as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
1532 1.1 christos else if (!found_const_within_range)
1533 1.1 christos {
1534 1.8 christos switch (const_err)
1535 1.8 christos {
1536 1.8 christos case OP_OUT_OF_RANGE:
1537 1.8 christos as_bad (_("Operand out of range (arg %d)"), invalid_const);
1538 1.8 christos break;
1539 1.8 christos case OP_NOT_EVEN:
1540 1.8 christos as_bad (_("Operand has odd displacement (arg %d)"),
1541 1.8 christos invalid_const);
1542 1.8 christos break;
1543 1.8 christos case OP_ILLEGAL_DISPU4:
1544 1.8 christos as_bad (_("Invalid DISPU4 operand value (arg %d)"),
1545 1.8 christos invalid_const);
1546 1.8 christos break;
1547 1.8 christos case OP_ILLEGAL_CST4:
1548 1.8 christos as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const);
1549 1.8 christos break;
1550 1.8 christos case OP_NOT_UPPER_64KB:
1551 1.8 christos as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1552 1.8 christos invalid_const);
1553 1.8 christos break;
1554 1.8 christos default:
1555 1.8 christos as_bad (_("Illegal operand (arg %d)"), invalid_const);
1556 1.8 christos break;
1557 1.8 christos }
1558 1.1 christos }
1559 1.3 christos
1560 1.1 christos return 0;
1561 1.1 christos }
1562 1.1 christos else
1563 1.1 christos /* Full match - print the encoding to output file. */
1564 1.1 christos {
1565 1.6 christos /* Make further checking (such that couldn't be made earlier).
1566 1.1 christos Warn the user if necessary. */
1567 1.1 christos warn_if_needed (insn);
1568 1.3 christos
1569 1.1 christos /* Check whether we need to adjust the instruction pointer. */
1570 1.1 christos if (adjust_if_needed (insn))
1571 1.3 christos /* If instruction pointer was adjusted, we need to update
1572 1.1 christos the size of the current template operands. */
1573 1.1 christos GET_CURRENT_SIZE;
1574 1.1 christos
1575 1.1 christos for (i = 0; i < insn->nargs; i++)
1576 1.8 christos {
1577 1.8 christos int j = (instruction->flags & REVERSE_MATCH) && i <= 1 ? 1 - i : i;
1578 1.1 christos
1579 1.1 christos /* This time, update constant value before printing it. */
1580 1.8 christos if ((insn->arg[j].X_op == O_constant)
1581 1.8 christos && (check_range (&insn->arg[j].constant, cur_size[j],
1582 1.8 christos cur_flags[j], 1) != OP_LEGAL))
1583 1.8 christos as_fatal (_("Illegal operand (arg %d)"), j+1);
1584 1.1 christos }
1585 1.1 christos
1586 1.1 christos /* First, copy the instruction's opcode. */
1587 1.1 christos output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1588 1.1 christos
1589 1.1 christos for (i = 0; i < insn->nargs; i++)
1590 1.8 christos {
1591 1.1 christos cur_arg_num = i;
1592 1.8 christos print_operand (cur_size[i], instruction->operands[i].shift,
1593 1.1 christos &insn->arg[i]);
1594 1.8 christos }
1595 1.1 christos }
1596 1.1 christos
1597 1.1 christos return 1;
1598 1.1 christos }
1599 1.1 christos
1600 1.6 christos /* Bunch of error checking.
1601 1.1 christos The checks are made after a matching instruction was found. */
1602 1.1 christos
1603 1.1 christos void
1604 1.1 christos warn_if_needed (ins *insn)
1605 1.1 christos {
1606 1.3 christos /* If the post-increment address mode is used and the load/store
1607 1.3 christos source register is the same as rbase, the result of the
1608 1.1 christos instruction is undefined. */
1609 1.1 christos if (IS_INSN_TYPE (LD_STOR_INS_INC))
1610 1.1 christos {
1611 1.1 christos /* Enough to verify that one of the arguments is a simple reg. */
1612 1.1 christos if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
1613 1.1 christos if (insn->arg[0].r == insn->arg[1].r)
1614 1.3 christos as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1615 1.1 christos insn->arg[0].r);
1616 1.1 christos }
1617 1.1 christos
1618 1.1 christos /* Some instruction assume the stack pointer as rptr operand.
1619 1.1 christos Issue an error when the register to be loaded is also SP. */
1620 1.1 christos if (instruction->flags & NO_SP)
1621 1.1 christos {
1622 1.1 christos if (getreg_image (insn->arg[0].r) == getreg_image (sp))
1623 1.1 christos as_bad (_("`%s' has undefined result"), ins_parse);
1624 1.1 christos }
1625 1.1 christos
1626 1.3 christos /* If the rptr register is specified as one of the registers to be loaded,
1627 1.1 christos the final contents of rptr are undefined. Thus, we issue an error. */
1628 1.1 christos if (instruction->flags & NO_RPTR)
1629 1.1 christos {
1630 1.1 christos if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
1631 1.3 christos as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1632 1.1 christos getreg_image (insn->arg[0].r));
1633 1.1 christos }
1634 1.1 christos }
1635 1.1 christos
1636 1.3 christos /* In some cases, we need to adjust the instruction pointer although a
1637 1.1 christos match was already found. Here, we gather all these cases.
1638 1.1 christos Returns 1 if instruction pointer was adjusted, otherwise 0. */
1639 1.1 christos
1640 1.1 christos int
1641 1.1 christos adjust_if_needed (ins *insn)
1642 1.1 christos {
1643 1.1 christos int ret_value = 0;
1644 1.1 christos
1645 1.1 christos /* Special check for 'addub $0, r0' instruction -
1646 1.1 christos The opcode '0000 0000 0000 0000' is not allowed. */
1647 1.1 christos if (IS_INSN_MNEMONIC ("addub"))
1648 1.1 christos {
1649 1.1 christos if ((instruction->operands[0].op_type == cst4)
1650 1.1 christos && instruction->operands[1].op_type == regr)
1651 1.8 christos {
1652 1.8 christos if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
1653 1.1 christos {
1654 1.1 christos instruction++;
1655 1.1 christos ret_value = 1;
1656 1.1 christos }
1657 1.8 christos }
1658 1.1 christos }
1659 1.1 christos
1660 1.3 christos /* Optimization: Omit a zero displacement in bit operations,
1661 1.1 christos saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)'). */
1662 1.1 christos if (IS_INSN_TYPE (CSTBIT_INS))
1663 1.1 christos {
1664 1.1 christos if ((instruction->operands[1].op_type == rbase_disps12)
1665 1.8 christos && (insn->arg[1].X_op == O_constant)
1666 1.8 christos && (insn->arg[1].constant == 0))
1667 1.8 christos {
1668 1.8 christos instruction--;
1669 1.8 christos ret_value = 1;
1670 1.8 christos }
1671 1.1 christos }
1672 1.1 christos
1673 1.1 christos return ret_value;
1674 1.1 christos }
1675 1.1 christos
1676 1.1 christos /* Set the appropriate bit for register 'r' in 'mask'.
1677 1.1 christos This indicates that this register is loaded or stored by
1678 1.1 christos the instruction. */
1679 1.1 christos
1680 1.1 christos static void
1681 1.1 christos mask_reg (int r, unsigned short int *mask)
1682 1.1 christos {
1683 1.1 christos if ((reg)r > (reg)sp)
1684 1.1 christos {
1685 1.6 christos as_bad (_("Invalid register in register list"));
1686 1.1 christos return;
1687 1.1 christos }
1688 1.1 christos
1689 1.1 christos *mask |= (1 << r);
1690 1.1 christos }
1691 1.1 christos
1692 1.1 christos /* Preprocess register list - create a 16-bit mask with one bit for each
1693 1.1 christos of the 16 general purpose registers. If a bit is set, it indicates
1694 1.1 christos that this register is loaded or stored by the instruction. */
1695 1.1 christos
1696 1.1 christos static char *
1697 1.1 christos preprocess_reglist (char *param, int *allocated)
1698 1.1 christos {
1699 1.1 christos char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name. */
1700 1.1 christos char *regP; /* Pointer to 'reg_name' string. */
1701 1.1 christos int reg_counter = 0; /* Count number of parsed registers. */
1702 1.1 christos unsigned short int mask = 0; /* Mask for 16 general purpose registers. */
1703 1.1 christos char *new_param; /* New created operands string. */
1704 1.6 christos char *paramP = param; /* Pointer to original operands string. */
1705 1.1 christos char maskstring[10]; /* Array to print the mask as a string. */
1706 1.1 christos int hi_found = 0, lo_found = 0; /* Boolean flags for hi/lo registers. */
1707 1.1 christos reg r;
1708 1.1 christos copreg cr;
1709 1.1 christos
1710 1.1 christos /* If 'param' is already in form of a number, no need to preprocess. */
1711 1.1 christos if (strchr (paramP, '{') == NULL)
1712 1.1 christos return param;
1713 1.1 christos
1714 1.1 christos /* Verifying correct syntax of operand. */
1715 1.1 christos if (strchr (paramP, '}') == NULL)
1716 1.1 christos as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1717 1.1 christos
1718 1.1 christos while (*paramP++ != '{');
1719 1.1 christos
1720 1.5 christos new_param = XCNEWVEC (char, MAX_INST_LEN);
1721 1.1 christos *allocated = 1;
1722 1.1 christos strncpy (new_param, param, paramP - param - 1);
1723 1.1 christos
1724 1.1 christos while (*paramP != '}')
1725 1.1 christos {
1726 1.1 christos regP = paramP;
1727 1.1 christos memset (®_name, '\0', sizeof (reg_name));
1728 1.1 christos
1729 1.1 christos while (ISALNUM (*paramP))
1730 1.1 christos paramP++;
1731 1.1 christos
1732 1.1 christos strncpy (reg_name, regP, paramP - regP);
1733 1.1 christos
1734 1.1 christos /* Coprocessor register c<N>. */
1735 1.1 christos if (IS_INSN_TYPE (COP_REG_INS))
1736 1.8 christos {
1737 1.8 christos if (((cr = get_copregister (reg_name)) == nullcopregister)
1738 1.1 christos || (crx_copregtab[cr-MAX_REG].type != CRX_C_REGTYPE))
1739 1.1 christos as_fatal (_("Illegal register `%s' in cop-register list"), reg_name);
1740 1.1 christos mask_reg (getreg_image (cr - c0), &mask);
1741 1.8 christos }
1742 1.1 christos /* Coprocessor Special register cs<N>. */
1743 1.1 christos else if (IS_INSN_TYPE (COPS_REG_INS))
1744 1.8 christos {
1745 1.8 christos if (((cr = get_copregister (reg_name)) == nullcopregister)
1746 1.1 christos || (crx_copregtab[cr-MAX_REG].type != CRX_CS_REGTYPE))
1747 1.3 christos as_fatal (_("Illegal register `%s' in cop-special-register list"),
1748 1.1 christos reg_name);
1749 1.1 christos mask_reg (getreg_image (cr - cs0), &mask);
1750 1.8 christos }
1751 1.1 christos /* User register u<N>. */
1752 1.1 christos else if (instruction->flags & USER_REG)
1753 1.1 christos {
1754 1.1 christos if (streq(reg_name, "uhi"))
1755 1.1 christos {
1756 1.1 christos hi_found = 1;
1757 1.1 christos goto next_inst;
1758 1.1 christos }
1759 1.1 christos else if (streq(reg_name, "ulo"))
1760 1.1 christos {
1761 1.1 christos lo_found = 1;
1762 1.1 christos goto next_inst;
1763 1.1 christos }
1764 1.8 christos else if (((r = get_register (reg_name)) == nullregister)
1765 1.8 christos || (crx_regtab[r].type != CRX_U_REGTYPE))
1766 1.1 christos as_fatal (_("Illegal register `%s' in user register list"), reg_name);
1767 1.3 christos
1768 1.3 christos mask_reg (getreg_image (r - u0), &mask);
1769 1.1 christos }
1770 1.1 christos /* General purpose register r<N>. */
1771 1.1 christos else
1772 1.8 christos {
1773 1.1 christos if (streq(reg_name, "hi"))
1774 1.1 christos {
1775 1.1 christos hi_found = 1;
1776 1.1 christos goto next_inst;
1777 1.1 christos }
1778 1.1 christos else if (streq(reg_name, "lo"))
1779 1.1 christos {
1780 1.1 christos lo_found = 1;
1781 1.1 christos goto next_inst;
1782 1.1 christos }
1783 1.8 christos else if (((r = get_register (reg_name)) == nullregister)
1784 1.8 christos || (crx_regtab[r].type != CRX_R_REGTYPE))
1785 1.1 christos as_fatal (_("Illegal register `%s' in register list"), reg_name);
1786 1.1 christos
1787 1.1 christos mask_reg (getreg_image (r - r0), &mask);
1788 1.8 christos }
1789 1.1 christos
1790 1.1 christos if (++reg_counter > MAX_REGS_IN_MASK16)
1791 1.1 christos as_bad (_("Maximum %d bits may be set in `mask16' operand"),
1792 1.1 christos MAX_REGS_IN_MASK16);
1793 1.1 christos
1794 1.8 christos next_inst:
1795 1.1 christos while (!ISALNUM (*paramP) && *paramP != '}')
1796 1.8 christos paramP++;
1797 1.1 christos }
1798 1.1 christos
1799 1.1 christos if (*++paramP != '\0')
1800 1.1 christos as_warn (_("rest of line ignored; first ignored character is `%c'"),
1801 1.1 christos *paramP);
1802 1.1 christos
1803 1.1 christos switch (hi_found + lo_found)
1804 1.1 christos {
1805 1.1 christos case 0:
1806 1.1 christos /* At least one register should be specified. */
1807 1.1 christos if (mask == 0)
1808 1.1 christos as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1809 1.1 christos ins_parse);
1810 1.1 christos break;
1811 1.1 christos
1812 1.1 christos case 1:
1813 1.1 christos /* HI can't be specified without LO (and vise-versa). */
1814 1.1 christos as_bad (_("HI/LO registers should be specified together"));
1815 1.1 christos break;
1816 1.1 christos
1817 1.1 christos case 2:
1818 1.1 christos /* HI/LO registers mustn't be masked with additional registers. */
1819 1.1 christos if (mask != 0)
1820 1.1 christos as_bad (_("HI/LO registers should be specified without additional registers"));
1821 1.1 christos
1822 1.1 christos default:
1823 1.1 christos break;
1824 1.1 christos }
1825 1.1 christos
1826 1.1 christos sprintf (maskstring, "$0x%x", mask);
1827 1.1 christos strcat (new_param, maskstring);
1828 1.1 christos return new_param;
1829 1.1 christos }
1830 1.1 christos
1831 1.1 christos /* Print the instruction.
1832 1.1 christos Handle also cases where the instruction is relaxable/relocatable. */
1833 1.1 christos
1834 1.8 christos static void
1835 1.1 christos print_insn (ins *insn)
1836 1.1 christos {
1837 1.1 christos unsigned int i, j, insn_size;
1838 1.1 christos char *this_frag;
1839 1.1 christos unsigned short words[4];
1840 1.1 christos int addr_mod;
1841 1.1 christos
1842 1.1 christos /* Arrange the insn encodings in a WORD size array. */
1843 1.1 christos for (i = 0, j = 0; i < 2; i++)
1844 1.1 christos {
1845 1.1 christos words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
1846 1.1 christos words[j++] = output_opcode[i] & 0xFFFF;
1847 1.1 christos }
1848 1.1 christos
1849 1.6 christos /* Handle relaxation. */
1850 1.1 christos if ((instruction->flags & RELAXABLE) && relocatable)
1851 1.1 christos {
1852 1.1 christos int relax_subtype;
1853 1.1 christos
1854 1.1 christos /* Write the maximal instruction size supported. */
1855 1.1 christos insn_size = INSN_MAX_SIZE;
1856 1.1 christos
1857 1.1 christos /* bCC */
1858 1.1 christos if (IS_INSN_TYPE (BRANCH_INS))
1859 1.1 christos relax_subtype = 0;
1860 1.1 christos /* bal */
1861 1.1 christos else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
1862 1.1 christos relax_subtype = 3;
1863 1.1 christos /* cmpbr/bcop */
1864 1.1 christos else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1865 1.1 christos relax_subtype = 5;
1866 1.1 christos else
1867 1.1 christos abort ();
1868 1.1 christos
1869 1.1 christos this_frag = frag_var (rs_machine_dependent, insn_size * 2,
1870 1.1 christos 4, relax_subtype,
1871 1.1 christos insn->exp.X_add_symbol,
1872 1.1 christos insn->exp.X_add_number,
1873 1.1 christos 0);
1874 1.1 christos }
1875 1.1 christos else
1876 1.1 christos {
1877 1.1 christos insn_size = instruction->size;
1878 1.1 christos this_frag = frag_more (insn_size * 2);
1879 1.1 christos
1880 1.1 christos /* Handle relocation. */
1881 1.1 christos if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
1882 1.1 christos {
1883 1.1 christos reloc_howto_type *reloc_howto;
1884 1.1 christos int size;
1885 1.1 christos
1886 1.1 christos reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
1887 1.1 christos
1888 1.1 christos if (!reloc_howto)
1889 1.1 christos abort ();
1890 1.1 christos
1891 1.1 christos size = bfd_get_reloc_size (reloc_howto);
1892 1.1 christos
1893 1.1 christos if (size < 1 || size > 4)
1894 1.1 christos abort ();
1895 1.1 christos
1896 1.1 christos fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
1897 1.1 christos size, &insn->exp, reloc_howto->pc_relative,
1898 1.1 christos insn->rtype);
1899 1.1 christos }
1900 1.1 christos }
1901 1.1 christos
1902 1.1 christos /* Verify a 2-byte code alignment. */
1903 1.1 christos addr_mod = frag_now_fix () & 1;
1904 1.1 christos if (frag_now->has_code && frag_now->insn_addr != addr_mod)
1905 1.1 christos as_bad (_("instruction address is not a multiple of 2"));
1906 1.1 christos frag_now->insn_addr = addr_mod;
1907 1.1 christos frag_now->has_code = 1;
1908 1.1 christos
1909 1.1 christos /* Write the instruction encoding to frag. */
1910 1.1 christos for (i = 0; i < insn_size; i++)
1911 1.1 christos {
1912 1.1 christos md_number_to_chars (this_frag, (valueT) words[i], 2);
1913 1.1 christos this_frag += 2;
1914 1.1 christos }
1915 1.1 christos }
1916 1.1 christos
1917 1.1 christos /* This is the guts of the machine-dependent assembler. OP points to a
1918 1.1 christos machine dependent instruction. This function is supposed to emit
1919 1.1 christos the frags/bytes it assembles to. */
1920 1.1 christos
1921 1.1 christos void
1922 1.1 christos md_assemble (char *op)
1923 1.1 christos {
1924 1.1 christos ins crx_ins;
1925 1.1 christos char *param;
1926 1.1 christos char c;
1927 1.1 christos
1928 1.1 christos /* Reset global variables for a new instruction. */
1929 1.1 christos reset_vars (op);
1930 1.1 christos
1931 1.1 christos /* Strip the mnemonic. */
1932 1.1 christos for (param = op; *param != 0 && !ISSPACE (*param); param++)
1933 1.1 christos ;
1934 1.1 christos c = *param;
1935 1.1 christos *param++ = '\0';
1936 1.1 christos
1937 1.1 christos /* Find the instruction. */
1938 1.8 christos instruction = (const inst *) str_hash_find (crx_inst_hash, op);
1939 1.1 christos if (instruction == NULL)
1940 1.1 christos {
1941 1.1 christos as_bad (_("Unknown opcode: `%s'"), op);
1942 1.1 christos param[-1] = c;
1943 1.1 christos return;
1944 1.1 christos }
1945 1.1 christos
1946 1.1 christos /* Tie dwarf2 debug info to the address at the start of the insn. */
1947 1.1 christos dwarf2_emit_insn (0);
1948 1.1 christos
1949 1.1 christos /* Parse the instruction's operands. */
1950 1.1 christos parse_insn (&crx_ins, param);
1951 1.1 christos
1952 1.1 christos /* Assemble the instruction - return upon failure. */
1953 1.1 christos if (assemble_insn (op, &crx_ins) == 0)
1954 1.1 christos {
1955 1.1 christos param[-1] = c;
1956 1.1 christos return;
1957 1.1 christos }
1958 1.1 christos
1959 1.1 christos /* Print the instruction. */
1960 1.1 christos param[-1] = c;
1961 1.1 christos print_insn (&crx_ins);
1962 1.1 christos }
1963