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