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