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