tc-cr16.c revision 1.10 1 1.1 christos /* tc-cr16.c -- Assembler code for the CR16 CPU core.
2 1.10 christos Copyright (C) 2007-2025 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos Contributed by M R Swami Reddy <MR.Swami.Reddy (at) nsc.com>
5 1.1 christos
6 1.1 christos This file is part of GAS, the GNU Assembler.
7 1.1 christos
8 1.1 christos GAS is free software; you can redistribute it and/or modify
9 1.1 christos it under the terms of the GNU General Public License as published by
10 1.1 christos the Free Software Foundation; either version 3, or (at your option)
11 1.1 christos any later version.
12 1.1 christos
13 1.1 christos GAS is distributed in the hope that it will be useful,
14 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
15 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 1.1 christos GNU General Public License for more details.
17 1.1 christos
18 1.1 christos You should have received a copy of the GNU General Public License
19 1.1 christos along with GAS; see the file COPYING. If not, write to the
20 1.1 christos Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
21 1.1 christos MA 02110-1301, USA. */
22 1.1 christos
23 1.1 christos #include "as.h"
24 1.1 christos #include "safe-ctype.h"
25 1.1 christos #include "dwarf2dbg.h"
26 1.1 christos #include "opcode/cr16.h"
27 1.1 christos #include "elf/cr16.h"
28 1.1 christos
29 1.8 christos #include <limits.h>
30 1.8 christos #ifndef CHAR_BIT
31 1.8 christos #define CHAR_BIT 8
32 1.8 christos #endif
33 1.1 christos
34 1.1 christos /* Word is considered here as a 16-bit unsigned short int. */
35 1.1 christos #define WORD_SHIFT 16
36 1.1 christos
37 1.1 christos /* Register is 2-byte size. */
38 1.1 christos #define REG_SIZE 2
39 1.1 christos
40 1.1 christos /* Maximum size of a single instruction (in words). */
41 1.1 christos #define INSN_MAX_SIZE 3
42 1.1 christos
43 1.1 christos /* Maximum bits which may be set in a `mask16' operand. */
44 1.1 christos #define MAX_REGS_IN_MASK16 8
45 1.1 christos
46 1.1 christos /* Assign a number NUM, shifted by SHIFT bytes, into a location
47 1.1 christos pointed by index BYTE of array 'output_opcode'. */
48 1.8 christos #define CR16_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM) << (SHIFT)
49 1.1 christos
50 1.1 christos /* Operand errors. */
51 1.1 christos typedef enum
52 1.1 christos {
53 1.1 christos OP_LEGAL = 0, /* Legal operand. */
54 1.1 christos OP_OUT_OF_RANGE, /* Operand not within permitted range. */
55 1.1 christos OP_NOT_EVEN /* Operand is Odd number, should be even. */
56 1.1 christos }
57 1.1 christos op_err;
58 1.1 christos
59 1.1 christos /* Opcode mnemonics hash table. */
60 1.8 christos static htab_t cr16_inst_hash;
61 1.1 christos /* CR16 registers hash table. */
62 1.8 christos static htab_t reg_hash;
63 1.1 christos /* CR16 register pair hash table. */
64 1.8 christos static htab_t regp_hash;
65 1.1 christos /* CR16 processor registers hash table. */
66 1.8 christos static htab_t preg_hash;
67 1.1 christos /* CR16 processor registers 32 bit hash table. */
68 1.8 christos static htab_t pregp_hash;
69 1.1 christos /* Current instruction we're assembling. */
70 1.1 christos const inst *instruction;
71 1.1 christos
72 1.1 christos
73 1.1 christos static int code_label = 0;
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 #ifdef OBJ_ELF
107 1.1 christos /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
108 1.1 christos symbolS * GOT_symbol;
109 1.1 christos #endif
110 1.1 christos
111 1.1 christos /* Target-specific multicharacter options, not const-declared at usage. */
112 1.10 christos const char md_shortopts[] = "";
113 1.10 christos const struct option md_longopts[] =
114 1.1 christos {
115 1.1 christos {NULL, no_argument, NULL, 0}
116 1.1 christos };
117 1.10 christos const size_t md_longopts_size = sizeof (md_longopts);
118 1.1 christos
119 1.1 christos static void
120 1.1 christos l_cons (int nbytes)
121 1.1 christos {
122 1.1 christos int c;
123 1.1 christos expressionS exp;
124 1.1 christos
125 1.1 christos #ifdef md_flush_pending_output
126 1.8 christos md_flush_pending_output ();
127 1.1 christos #endif
128 1.1 christos
129 1.1 christos if (is_it_end_of_statement ())
130 1.1 christos {
131 1.1 christos demand_empty_rest_of_line ();
132 1.1 christos return;
133 1.1 christos }
134 1.1 christos
135 1.1 christos #ifdef TC_ADDRESS_BYTES
136 1.1 christos if (nbytes == 0)
137 1.1 christos nbytes = TC_ADDRESS_BYTES ();
138 1.1 christos #endif
139 1.1 christos
140 1.1 christos #ifdef md_cons_align
141 1.1 christos md_cons_align (nbytes);
142 1.1 christos #endif
143 1.1 christos
144 1.1 christos c = 0;
145 1.1 christos do
146 1.1 christos {
147 1.1 christos unsigned int bits_available = BITS_PER_CHAR * nbytes;
148 1.1 christos char *hold = input_line_pointer;
149 1.1 christos
150 1.1 christos expression (&exp);
151 1.1 christos
152 1.1 christos if (*input_line_pointer == ':')
153 1.8 christos {
154 1.8 christos /* Bitfields. */
155 1.8 christos long value = 0;
156 1.8 christos
157 1.8 christos for (;;)
158 1.8 christos {
159 1.8 christos unsigned long width;
160 1.8 christos
161 1.8 christos if (*input_line_pointer != ':')
162 1.8 christos {
163 1.8 christos input_line_pointer = hold;
164 1.8 christos break;
165 1.8 christos }
166 1.8 christos if (exp.X_op == O_absent)
167 1.8 christos {
168 1.8 christos as_warn (_("using a bit field width of zero"));
169 1.8 christos exp.X_add_number = 0;
170 1.8 christos exp.X_op = O_constant;
171 1.8 christos }
172 1.8 christos
173 1.8 christos if (exp.X_op != O_constant)
174 1.8 christos {
175 1.8 christos *input_line_pointer = '\0';
176 1.8 christos as_bad (_("field width \"%s\" too complex for a bitfield"),
177 1.8 christos hold);
178 1.8 christos *input_line_pointer = ':';
179 1.8 christos demand_empty_rest_of_line ();
180 1.8 christos return;
181 1.8 christos }
182 1.8 christos
183 1.8 christos if ((width = exp.X_add_number) >
184 1.8 christos (unsigned int)(BITS_PER_CHAR * nbytes))
185 1.8 christos {
186 1.6 christos as_warn (ngettext ("field width %lu too big to fit in %d"
187 1.6 christos " byte: truncated to %d bits",
188 1.6 christos "field width %lu too big to fit in %d"
189 1.6 christos " bytes: truncated to %d bits",
190 1.6 christos nbytes),
191 1.6 christos width, nbytes, (BITS_PER_CHAR * nbytes));
192 1.8 christos width = BITS_PER_CHAR * nbytes;
193 1.8 christos }
194 1.8 christos
195 1.8 christos if (width > bits_available)
196 1.8 christos {
197 1.8 christos /* FIXME-SOMEDAY: backing up and reparsing is wasteful. */
198 1.8 christos input_line_pointer = hold;
199 1.8 christos exp.X_add_number = value;
200 1.8 christos break;
201 1.8 christos }
202 1.8 christos
203 1.8 christos /* Skip ':'. */
204 1.8 christos hold = ++input_line_pointer;
205 1.8 christos
206 1.8 christos expression (&exp);
207 1.8 christos if (exp.X_op != O_constant)
208 1.8 christos {
209 1.8 christos char cache = *input_line_pointer;
210 1.8 christos
211 1.8 christos *input_line_pointer = '\0';
212 1.8 christos as_bad (_("field value \"%s\" too complex for a bitfield"),
213 1.8 christos hold);
214 1.8 christos *input_line_pointer = cache;
215 1.8 christos demand_empty_rest_of_line ();
216 1.8 christos return;
217 1.8 christos }
218 1.8 christos
219 1.8 christos value |= ((~(-(1 << width)) & exp.X_add_number)
220 1.8 christos << ((BITS_PER_CHAR * nbytes) - bits_available));
221 1.8 christos
222 1.8 christos if ((bits_available -= width) == 0
223 1.8 christos || is_it_end_of_statement ()
224 1.8 christos || *input_line_pointer != ',')
225 1.8 christos break;
226 1.1 christos
227 1.8 christos hold = ++input_line_pointer;
228 1.8 christos expression (&exp);
229 1.8 christos }
230 1.1 christos
231 1.8 christos exp.X_add_number = value;
232 1.8 christos exp.X_op = O_constant;
233 1.8 christos exp.X_unsigned = 1;
234 1.8 christos }
235 1.1 christos
236 1.1 christos if ((*(input_line_pointer) == '@') && (*(input_line_pointer +1) == 'c'))
237 1.8 christos code_label = 1;
238 1.10 christos emit_expr (&exp, nbytes);
239 1.1 christos ++c;
240 1.1 christos if ((*(input_line_pointer) == '@') && (*(input_line_pointer +1) == 'c'))
241 1.8 christos {
242 1.8 christos input_line_pointer +=3;
243 1.8 christos break;
244 1.8 christos }
245 1.1 christos }
246 1.1 christos while ((*input_line_pointer++ == ','));
247 1.1 christos
248 1.1 christos /* Put terminator back into stream. */
249 1.1 christos input_line_pointer--;
250 1.1 christos
251 1.1 christos demand_empty_rest_of_line ();
252 1.1 christos }
253 1.1 christos
254 1.1 christos /* This table describes all the machine specific pseudo-ops
255 1.1 christos the assembler has to support. The fields are:
256 1.1 christos *** Pseudo-op name without dot.
257 1.1 christos *** Function to call to execute this pseudo-op.
258 1.1 christos *** Integer arg to pass to the function. */
259 1.1 christos
260 1.1 christos const pseudo_typeS md_pseudo_table[] =
261 1.1 christos {
262 1.1 christos /* In CR16 machine, align is in bytes (not a ptwo boundary). */
263 1.1 christos {"align", s_align_bytes, 0},
264 1.1 christos {"long", l_cons, 4 },
265 1.1 christos {"4byte", l_cons, 4 },
266 1.1 christos {0, 0, 0}
267 1.1 christos };
268 1.1 christos
269 1.1 christos /* CR16 relaxation table. */
270 1.1 christos const relax_typeS md_relax_table[] =
271 1.1 christos {
272 1.1 christos /* bCC */
273 1.1 christos {0x7f, -0x80, 2, 1}, /* 8 */
274 1.1 christos {0xfffe, -0x10000, 4, 2}, /* 16 */
275 1.1 christos {0xfffffe, -0x1000000, 6, 0}, /* 24 */
276 1.1 christos };
277 1.1 christos
278 1.1 christos /* Return the bit size for a given operand. */
279 1.1 christos
280 1.1 christos static int
281 1.1 christos get_opbits (operand_type op)
282 1.1 christos {
283 1.1 christos if (op < MAX_OPRD)
284 1.1 christos return cr16_optab[op].bit_size;
285 1.1 christos
286 1.1 christos return 0;
287 1.1 christos }
288 1.1 christos
289 1.1 christos /* Return the argument type of a given operand. */
290 1.1 christos
291 1.1 christos static argtype
292 1.1 christos get_optype (operand_type op)
293 1.1 christos {
294 1.1 christos if (op < MAX_OPRD)
295 1.1 christos return cr16_optab[op].arg_type;
296 1.1 christos else
297 1.1 christos return nullargs;
298 1.1 christos }
299 1.1 christos
300 1.1 christos /* Return the flags of a given operand. */
301 1.1 christos
302 1.1 christos static int
303 1.1 christos get_opflags (operand_type op)
304 1.1 christos {
305 1.1 christos if (op < MAX_OPRD)
306 1.1 christos return cr16_optab[op].flags;
307 1.1 christos
308 1.1 christos return 0;
309 1.1 christos }
310 1.1 christos
311 1.1 christos /* Get the cc code. */
312 1.1 christos
313 1.1 christos static int
314 1.1 christos get_cc (char *cc_name)
315 1.1 christos {
316 1.1 christos unsigned int i;
317 1.1 christos
318 1.1 christos for (i = 0; i < cr16_num_cc; i++)
319 1.1 christos if (strcmp (cc_name, cr16_b_cond_tab[i]) == 0)
320 1.1 christos return i;
321 1.1 christos
322 1.1 christos return -1;
323 1.1 christos }
324 1.1 christos
325 1.1 christos /* Get the core processor register 'reg_name'. */
326 1.1 christos
327 1.1 christos static reg
328 1.1 christos get_register (char *reg_name)
329 1.1 christos {
330 1.1 christos const reg_entry *rreg;
331 1.1 christos
332 1.10 christos rreg = str_hash_find (reg_hash, reg_name);
333 1.1 christos
334 1.1 christos if (rreg != NULL)
335 1.1 christos return rreg->value.reg_val;
336 1.1 christos
337 1.1 christos return nullregister;
338 1.1 christos }
339 1.1 christos /* Get the core processor register-pair 'reg_name'. */
340 1.1 christos
341 1.1 christos static reg
342 1.1 christos get_register_pair (char *reg_name)
343 1.1 christos {
344 1.1 christos const reg_entry *rreg;
345 1.1 christos char tmp_rp[16]="\0";
346 1.1 christos
347 1.6 christos /* Add '(' and ')' to the reg pair, if it's not present. */
348 1.3 christos if (reg_name[0] != '(')
349 1.1 christos {
350 1.1 christos tmp_rp[0] = '(';
351 1.1 christos strcat (tmp_rp, reg_name);
352 1.1 christos strcat (tmp_rp,")");
353 1.10 christos rreg = str_hash_find (regp_hash, tmp_rp);
354 1.1 christos }
355 1.1 christos else
356 1.10 christos rreg = str_hash_find (regp_hash, reg_name);
357 1.1 christos
358 1.1 christos if (rreg != NULL)
359 1.1 christos return rreg->value.reg_val;
360 1.1 christos
361 1.1 christos return nullregister;
362 1.3 christos }
363 1.1 christos
364 1.1 christos /* Get the index register 'reg_name'. */
365 1.1 christos
366 1.1 christos static reg
367 1.1 christos get_index_register (char *reg_name)
368 1.1 christos {
369 1.1 christos const reg_entry *rreg;
370 1.1 christos
371 1.10 christos rreg = str_hash_find (reg_hash, reg_name);
372 1.1 christos
373 1.1 christos if ((rreg != NULL)
374 1.1 christos && ((rreg->value.reg_val == 12) || (rreg->value.reg_val == 13)))
375 1.1 christos return rreg->value.reg_val;
376 1.1 christos
377 1.1 christos return nullregister;
378 1.1 christos }
379 1.1 christos /* Get the core processor index register-pair 'reg_name'. */
380 1.1 christos
381 1.1 christos static reg
382 1.1 christos get_index_register_pair (char *reg_name)
383 1.1 christos {
384 1.1 christos const reg_entry *rreg;
385 1.1 christos
386 1.10 christos rreg = str_hash_find (regp_hash, reg_name);
387 1.1 christos
388 1.1 christos if (rreg != NULL)
389 1.1 christos {
390 1.1 christos if ((rreg->value.reg_val != 1) || (rreg->value.reg_val != 7)
391 1.8 christos || (rreg->value.reg_val != 9) || (rreg->value.reg_val > 10))
392 1.8 christos return rreg->value.reg_val;
393 1.1 christos
394 1.1 christos as_bad (_("Unknown register pair - index relative mode: `%d'"), rreg->value.reg_val);
395 1.1 christos }
396 1.1 christos
397 1.1 christos return nullregister;
398 1.1 christos }
399 1.1 christos
400 1.1 christos /* Get the processor register 'preg_name'. */
401 1.1 christos
402 1.1 christos static preg
403 1.1 christos get_pregister (char *preg_name)
404 1.1 christos {
405 1.1 christos const reg_entry *prreg;
406 1.1 christos
407 1.10 christos prreg = str_hash_find (preg_hash, preg_name);
408 1.1 christos
409 1.1 christos if (prreg != NULL)
410 1.1 christos return prreg->value.preg_val;
411 1.1 christos
412 1.1 christos return nullpregister;
413 1.1 christos }
414 1.1 christos
415 1.1 christos /* Get the processor register 'preg_name 32 bit'. */
416 1.1 christos
417 1.1 christos static preg
418 1.1 christos get_pregisterp (char *preg_name)
419 1.1 christos {
420 1.1 christos const reg_entry *prreg;
421 1.1 christos
422 1.10 christos prreg = str_hash_find (pregp_hash, preg_name);
423 1.1 christos
424 1.1 christos if (prreg != NULL)
425 1.1 christos return prreg->value.preg_val;
426 1.1 christos
427 1.1 christos return nullpregister;
428 1.1 christos }
429 1.1 christos
430 1.1 christos
431 1.1 christos /* Round up a section size to the appropriate boundary. */
432 1.1 christos
433 1.1 christos valueT
434 1.1 christos md_section_align (segT seg, valueT val)
435 1.1 christos {
436 1.1 christos /* Round .text section to a multiple of 2. */
437 1.1 christos if (seg == text_section)
438 1.1 christos return (val + 1) & ~1;
439 1.1 christos return val;
440 1.1 christos }
441 1.1 christos
442 1.1 christos /* Parse an operand that is machine-specific (remove '*'). */
443 1.1 christos
444 1.1 christos void
445 1.1 christos md_operand (expressionS * exp)
446 1.1 christos {
447 1.1 christos char c = *input_line_pointer;
448 1.1 christos
449 1.1 christos switch (c)
450 1.1 christos {
451 1.1 christos case '*':
452 1.1 christos input_line_pointer++;
453 1.1 christos expression (exp);
454 1.1 christos break;
455 1.1 christos default:
456 1.1 christos break;
457 1.1 christos }
458 1.1 christos }
459 1.1 christos
460 1.1 christos /* Reset global variables before parsing a new instruction. */
461 1.1 christos
462 1.1 christos static void
463 1.1 christos reset_vars (char *op)
464 1.1 christos {
465 1.1 christos cur_arg_num = relocatable = 0;
466 1.1 christos memset (& output_opcode, '\0', sizeof (output_opcode));
467 1.1 christos
468 1.1 christos /* Save a copy of the original OP (used in error messages). */
469 1.1 christos strncpy (ins_parse, op, sizeof ins_parse - 1);
470 1.1 christos ins_parse [sizeof ins_parse - 1] = 0;
471 1.1 christos }
472 1.1 christos
473 1.1 christos /* This macro decides whether a particular reloc is an entry in a
474 1.1 christos switch table. It is used when relaxing, because the linker needs
475 1.1 christos to know about all such entries so that it can adjust them if
476 1.1 christos necessary. */
477 1.1 christos
478 1.8 christos #define SWITCH_TABLE(fix) \
479 1.8 christos ((fix)->fx_addsy != NULL \
480 1.8 christos && (fix)->fx_subsy != NULL \
481 1.8 christos && ((fix)->fx_r_type == BFD_RELOC_CR16_NUM8 \
482 1.8 christos || (fix)->fx_r_type == BFD_RELOC_CR16_NUM16 \
483 1.8 christos || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32 \
484 1.8 christos || (fix)->fx_r_type == BFD_RELOC_CR16_NUM32a) \
485 1.8 christos && S_GET_SEGMENT ((fix)->fx_addsy) != undefined_section \
486 1.8 christos && S_GET_SEGMENT ((fix)->fx_addsy) == S_GET_SEGMENT ((fix)->fx_subsy))
487 1.1 christos
488 1.1 christos /* See whether we need to force a relocation into the output file.
489 1.1 christos This is used to force out switch and PC relative relocations when
490 1.1 christos relaxing. */
491 1.1 christos
492 1.1 christos int
493 1.1 christos cr16_force_relocation (fixS *fix)
494 1.1 christos {
495 1.1 christos if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
496 1.1 christos return 1;
497 1.1 christos
498 1.1 christos return 0;
499 1.1 christos }
500 1.1 christos
501 1.1 christos /* Record a fixup for a cons expression. */
502 1.1 christos
503 1.1 christos void
504 1.3 christos cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp,
505 1.3 christos bfd_reloc_code_real_type rtype)
506 1.1 christos {
507 1.1 christos switch (len)
508 1.1 christos {
509 1.1 christos default: rtype = BFD_RELOC_NONE; break;
510 1.1 christos case 1: rtype = BFD_RELOC_CR16_NUM8 ; break;
511 1.1 christos case 2: rtype = BFD_RELOC_CR16_NUM16; break;
512 1.1 christos case 4:
513 1.1 christos if (code_label)
514 1.8 christos {
515 1.8 christos rtype = BFD_RELOC_CR16_NUM32a;
516 1.8 christos code_label = 0;
517 1.8 christos }
518 1.1 christos else
519 1.8 christos rtype = BFD_RELOC_CR16_NUM32;
520 1.1 christos break;
521 1.1 christos }
522 1.1 christos
523 1.1 christos fix_new_exp (frag, offset, len, exp, 0, rtype);
524 1.1 christos }
525 1.1 christos
526 1.1 christos /* Generate a relocation entry for a fixup. */
527 1.1 christos
528 1.1 christos arelent *
529 1.1 christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
530 1.1 christos {
531 1.1 christos arelent * reloc;
532 1.1 christos
533 1.1 christos /* If symbols are local and resolved, then no relocation needed. */
534 1.3 christos if ( ((fixP->fx_addsy)
535 1.8 christos && (S_GET_SEGMENT (fixP->fx_addsy) == absolute_section))
536 1.3 christos || ((fixP->fx_subsy)
537 1.1 christos && (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)))
538 1.8 christos return NULL;
539 1.1 christos
540 1.10 christos reloc = notes_alloc (sizeof (arelent));
541 1.10 christos reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
542 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
543 1.1 christos reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
544 1.1 christos reloc->addend = fixP->fx_offset;
545 1.1 christos
546 1.1 christos if (fixP->fx_subsy != NULL)
547 1.1 christos {
548 1.1 christos if (SWITCH_TABLE (fixP))
549 1.8 christos {
550 1.8 christos /* Keep the current difference in the addend. */
551 1.8 christos reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
552 1.8 christos - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
553 1.8 christos
554 1.8 christos switch (fixP->fx_r_type)
555 1.8 christos {
556 1.8 christos case BFD_RELOC_CR16_NUM8:
557 1.8 christos fixP->fx_r_type = BFD_RELOC_CR16_SWITCH8;
558 1.8 christos break;
559 1.8 christos case BFD_RELOC_CR16_NUM16:
560 1.8 christos fixP->fx_r_type = BFD_RELOC_CR16_SWITCH16;
561 1.8 christos break;
562 1.8 christos case BFD_RELOC_CR16_NUM32:
563 1.8 christos fixP->fx_r_type = BFD_RELOC_CR16_SWITCH32;
564 1.8 christos break;
565 1.8 christos case BFD_RELOC_CR16_NUM32a:
566 1.8 christos fixP->fx_r_type = BFD_RELOC_CR16_NUM32a;
567 1.8 christos break;
568 1.8 christos default:
569 1.8 christos abort ();
570 1.8 christos break;
571 1.8 christos }
572 1.8 christos }
573 1.1 christos else
574 1.8 christos {
575 1.8 christos /* We only resolve difference expressions in the same section. */
576 1.8 christos as_bad_subtract (fixP);
577 1.8 christos return NULL;
578 1.8 christos }
579 1.1 christos }
580 1.1 christos #ifdef OBJ_ELF
581 1.8 christos if ((fixP->fx_r_type == BFD_RELOC_CR16_GOT_REGREL20)
582 1.8 christos && GOT_symbol
583 1.8 christos && fixP->fx_addsy == GOT_symbol)
584 1.8 christos {
585 1.8 christos reloc->addend = fixP->fx_offset = reloc->address;
586 1.8 christos }
587 1.8 christos else if ((fixP->fx_r_type == BFD_RELOC_CR16_GOTC_REGREL20)
588 1.8 christos && GOT_symbol
589 1.1 christos && fixP->fx_addsy == GOT_symbol)
590 1.8 christos {
591 1.8 christos reloc->addend = fixP->fx_offset = reloc->address;
592 1.8 christos }
593 1.1 christos #endif
594 1.1 christos
595 1.1 christos gas_assert ((int) fixP->fx_r_type > 0);
596 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
597 1.1 christos
598 1.1 christos if (reloc->howto == NULL)
599 1.1 christos {
600 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
601 1.8 christos _("internal error: reloc %d (`%s') not supported by object file format"),
602 1.8 christos fixP->fx_r_type,
603 1.8 christos bfd_get_reloc_code_name (fixP->fx_r_type));
604 1.1 christos return NULL;
605 1.1 christos }
606 1.1 christos gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
607 1.1 christos
608 1.1 christos return reloc;
609 1.1 christos }
610 1.1 christos
611 1.1 christos /* Prepare machine-dependent frags for relaxation. */
612 1.1 christos
613 1.1 christos int
614 1.1 christos md_estimate_size_before_relax (fragS *fragp, asection *seg)
615 1.1 christos {
616 1.1 christos /* If symbol is undefined or located in a different section,
617 1.1 christos select the largest supported relocation. */
618 1.1 christos relax_substateT subtype;
619 1.1 christos relax_substateT rlx_state[] = {0, 2};
620 1.1 christos
621 1.1 christos for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
622 1.1 christos {
623 1.1 christos if (fragp->fr_subtype == rlx_state[subtype]
624 1.8 christos && (!S_IS_DEFINED (fragp->fr_symbol)
625 1.8 christos || seg != S_GET_SEGMENT (fragp->fr_symbol)))
626 1.8 christos {
627 1.8 christos fragp->fr_subtype = rlx_state[subtype + 1];
628 1.8 christos break;
629 1.8 christos }
630 1.1 christos }
631 1.1 christos
632 1.1 christos if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
633 1.1 christos abort ();
634 1.1 christos
635 1.1 christos return md_relax_table[fragp->fr_subtype].rlx_length;
636 1.1 christos }
637 1.1 christos
638 1.1 christos void
639 1.10 christos md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
640 1.10 christos asection *sec ATTRIBUTE_UNUSED,
641 1.10 christos fragS *fragP)
642 1.1 christos {
643 1.1 christos /* 'opcode' points to the start of the instruction, whether
644 1.1 christos we need to change the instruction's fixed encoding. */
645 1.8 christos char *opcode = &fragP->fr_literal[0] + fragP->fr_fix;
646 1.1 christos bfd_reloc_code_real_type reloc;
647 1.1 christos
648 1.1 christos switch (fragP->fr_subtype)
649 1.1 christos {
650 1.1 christos case 0:
651 1.1 christos reloc = BFD_RELOC_CR16_DISP8;
652 1.1 christos break;
653 1.1 christos case 1:
654 1.1 christos /* If the subtype is not changed due to :m operand qualifier,
655 1.8 christos then no need to update the opcode value. */
656 1.1 christos if ((int)opcode[1] != 0x18)
657 1.8 christos {
658 1.8 christos opcode[0] = (opcode[0] & 0xf0);
659 1.8 christos opcode[1] = 0x18;
660 1.8 christos }
661 1.1 christos reloc = BFD_RELOC_CR16_DISP16;
662 1.1 christos break;
663 1.1 christos case 2:
664 1.1 christos /* If the subtype is not changed due to :l operand qualifier,
665 1.8 christos then no need to update the opcode value. */
666 1.1 christos if ((int)opcode[1] != 0)
667 1.8 christos {
668 1.8 christos opcode[2] = opcode[0];
669 1.8 christos opcode[0] = opcode[1];
670 1.8 christos opcode[1] = 0x0;
671 1.8 christos }
672 1.1 christos reloc = BFD_RELOC_CR16_DISP24;
673 1.1 christos break;
674 1.1 christos default:
675 1.1 christos abort();
676 1.1 christos }
677 1.1 christos
678 1.1 christos fix_new (fragP, fragP->fr_fix,
679 1.8 christos bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
680 1.8 christos fragP->fr_symbol, fragP->fr_offset, 1, reloc);
681 1.1 christos fragP->fr_var = 0;
682 1.1 christos fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
683 1.1 christos }
684 1.1 christos
685 1.1 christos symbolS *
686 1.1 christos md_undefined_symbol (char *name)
687 1.1 christos {
688 1.1 christos if (*name == '_' && *(name + 1) == 'G'
689 1.1 christos && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
690 1.8 christos {
691 1.8 christos if (!GOT_symbol)
692 1.8 christos {
693 1.8 christos if (symbol_find (name))
694 1.8 christos as_bad (_("GOT already in symbol table"));
695 1.8 christos GOT_symbol = symbol_new (name, undefined_section,
696 1.8 christos &zero_address_frag, 0);
697 1.8 christos }
698 1.8 christos return GOT_symbol;
699 1.8 christos }
700 1.1 christos return 0;
701 1.1 christos }
702 1.1 christos
703 1.1 christos /* Process machine-dependent command line options. Called once for
704 1.1 christos each option on the command line that the machine-independent part of
705 1.1 christos GAS does not understand. */
706 1.1 christos
707 1.1 christos int
708 1.5 christos md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
709 1.1 christos {
710 1.1 christos return 0;
711 1.1 christos }
712 1.1 christos
713 1.1 christos /* Machine-dependent usage-output. */
714 1.1 christos
715 1.1 christos void
716 1.1 christos md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
717 1.1 christos {
718 1.1 christos return;
719 1.1 christos }
720 1.1 christos
721 1.5 christos const char *
722 1.1 christos md_atof (int type, char *litP, int *sizeP)
723 1.1 christos {
724 1.1 christos return ieee_md_atof (type, litP, sizeP, target_big_endian);
725 1.1 christos }
726 1.1 christos
727 1.1 christos /* Apply a fixS (fixup of an instruction or data that we didn't have
728 1.1 christos enough info to complete immediately) to the data in a frag.
729 1.1 christos Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
730 1.1 christos relaxation of debug sections, this function is called only when
731 1.1 christos fixuping relocations of debug sections. */
732 1.1 christos
733 1.1 christos void
734 1.1 christos md_apply_fix (fixS *fixP, valueT *valP, segT seg)
735 1.1 christos {
736 1.1 christos valueT val = * valP;
737 1.1 christos
738 1.1 christos if (fixP->fx_addsy == NULL
739 1.1 christos && fixP->fx_pcrel == 0)
740 1.1 christos fixP->fx_done = 1;
741 1.1 christos else if (fixP->fx_pcrel == 1
742 1.1 christos && fixP->fx_addsy != NULL
743 1.1 christos && S_GET_SEGMENT (fixP->fx_addsy) == seg)
744 1.1 christos fixP->fx_done = 1;
745 1.1 christos else
746 1.1 christos fixP->fx_done = 0;
747 1.1 christos
748 1.1 christos if (fixP->fx_addsy != NULL && !fixP->fx_pcrel)
749 1.1 christos {
750 1.1 christos val = fixP->fx_offset;
751 1.1 christos fixP->fx_done = 1;
752 1.1 christos }
753 1.1 christos
754 1.1 christos if (fixP->fx_done)
755 1.1 christos {
756 1.1 christos char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
757 1.1 christos
758 1.1 christos fixP->fx_offset = 0;
759 1.1 christos
760 1.1 christos switch (fixP->fx_r_type)
761 1.1 christos {
762 1.1 christos case BFD_RELOC_CR16_NUM8:
763 1.10 christos bfd_put_8 (stdoutput, val, buf);
764 1.1 christos break;
765 1.1 christos case BFD_RELOC_CR16_NUM16:
766 1.1 christos bfd_put_16 (stdoutput, val, buf);
767 1.1 christos break;
768 1.1 christos case BFD_RELOC_CR16_NUM32:
769 1.1 christos bfd_put_32 (stdoutput, val, buf);
770 1.1 christos break;
771 1.1 christos case BFD_RELOC_CR16_NUM32a:
772 1.1 christos bfd_put_32 (stdoutput, val, buf);
773 1.1 christos break;
774 1.1 christos default:
775 1.1 christos /* We shouldn't ever get here because linkrelax is nonzero. */
776 1.1 christos abort ();
777 1.1 christos break;
778 1.1 christos }
779 1.1 christos fixP->fx_done = 0;
780 1.1 christos }
781 1.1 christos else
782 1.1 christos fixP->fx_offset = * valP;
783 1.1 christos }
784 1.1 christos
785 1.1 christos /* The location from which a PC relative jump should be calculated,
786 1.1 christos given a PC relative reloc. */
787 1.1 christos
788 1.1 christos long
789 1.1 christos md_pcrel_from (fixS *fixp)
790 1.1 christos {
791 1.1 christos return fixp->fx_frag->fr_address + fixp->fx_where;
792 1.1 christos }
793 1.1 christos
794 1.1 christos static void
795 1.8 christos initialise_reg_hash_table (htab_t *hash_table,
796 1.8 christos const reg_entry *register_table,
797 1.8 christos const unsigned int num_entries)
798 1.1 christos {
799 1.8 christos const reg_entry *rreg;
800 1.1 christos
801 1.8 christos *hash_table = str_htab_create ();
802 1.1 christos
803 1.1 christos for (rreg = register_table;
804 1.1 christos rreg < (register_table + num_entries);
805 1.1 christos rreg++)
806 1.8 christos if (str_hash_insert (*hash_table, rreg->name, rreg, 0) != NULL)
807 1.8 christos as_fatal (_("duplicate %s"), rreg->name);
808 1.1 christos }
809 1.1 christos
810 1.1 christos /* This function is called once, at assembler startup time. This should
811 1.1 christos set up all the tables, etc that the MD part of the assembler needs. */
812 1.1 christos
813 1.1 christos void
814 1.1 christos md_begin (void)
815 1.1 christos {
816 1.1 christos int i = 0;
817 1.1 christos
818 1.1 christos /* Set up a hash table for the instructions. */
819 1.8 christos cr16_inst_hash = str_htab_create ();
820 1.1 christos
821 1.1 christos while (cr16_instruction[i].mnemonic != NULL)
822 1.1 christos {
823 1.1 christos const char *mnemonic = cr16_instruction[i].mnemonic;
824 1.1 christos
825 1.8 christos if (str_hash_insert (cr16_inst_hash, mnemonic, cr16_instruction + i, 0))
826 1.8 christos as_fatal (_("duplicate %s"), mnemonic);
827 1.1 christos
828 1.1 christos /* Insert unique names into hash table. The CR16 instruction set
829 1.8 christos has many identical opcode names that have different opcodes based
830 1.8 christos on the operands. This hash table then provides a quick index to
831 1.8 christos the first opcode with a particular name in the opcode table. */
832 1.1 christos do
833 1.8 christos {
834 1.8 christos ++i;
835 1.8 christos }
836 1.1 christos while (cr16_instruction[i].mnemonic != NULL
837 1.8 christos && streq (cr16_instruction[i].mnemonic, mnemonic));
838 1.1 christos }
839 1.1 christos
840 1.1 christos /* Initialize reg_hash hash table. */
841 1.1 christos initialise_reg_hash_table (& reg_hash, cr16_regtab, NUMREGS);
842 1.1 christos /* Initialize regp_hash hash table. */
843 1.1 christos initialise_reg_hash_table (& regp_hash, cr16_regptab, NUMREGPS);
844 1.1 christos /* Initialize preg_hash hash table. */
845 1.1 christos initialise_reg_hash_table (& preg_hash, cr16_pregtab, NUMPREGS);
846 1.1 christos /* Initialize pregp_hash hash table. */
847 1.1 christos initialise_reg_hash_table (& pregp_hash, cr16_pregptab, NUMPREGPS);
848 1.1 christos
849 1.1 christos /* Set linkrelax here to avoid fixups in most sections. */
850 1.1 christos linkrelax = 1;
851 1.1 christos }
852 1.1 christos
853 1.1 christos /* Process constants (immediate/absolute)
854 1.1 christos and labels (jump targets/Memory locations). */
855 1.1 christos
856 1.1 christos static void
857 1.1 christos process_label_constant (char *str, ins * cr16_ins)
858 1.1 christos {
859 1.1 christos char *saved_input_line_pointer;
860 1.1 christos int symbol_with_at = 0;
861 1.1 christos int symbol_with_s = 0;
862 1.1 christos int symbol_with_m = 0;
863 1.1 christos int symbol_with_l = 0;
864 1.1 christos int symbol_with_at_got = 0;
865 1.1 christos int symbol_with_at_gotc = 0;
866 1.1 christos argument *cur_arg = cr16_ins->arg + cur_arg_num; /* Current argument. */
867 1.1 christos
868 1.1 christos saved_input_line_pointer = input_line_pointer;
869 1.1 christos input_line_pointer = str;
870 1.1 christos
871 1.1 christos expression (&cr16_ins->exp);
872 1.1 christos
873 1.1 christos switch (cr16_ins->exp.X_op)
874 1.1 christos {
875 1.1 christos case O_big:
876 1.1 christos case O_absent:
877 1.1 christos /* Missing or bad expr becomes absolute 0. */
878 1.1 christos as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
879 1.8 christos str);
880 1.1 christos cr16_ins->exp.X_op = O_constant;
881 1.1 christos cr16_ins->exp.X_add_number = 0;
882 1.1 christos cr16_ins->exp.X_add_symbol = NULL;
883 1.1 christos cr16_ins->exp.X_op_symbol = NULL;
884 1.1 christos /* Fall through. */
885 1.1 christos
886 1.1 christos case O_constant:
887 1.1 christos cur_arg->X_op = O_constant;
888 1.1 christos cur_arg->constant = cr16_ins->exp.X_add_number;
889 1.1 christos break;
890 1.1 christos
891 1.1 christos case O_symbol:
892 1.1 christos case O_subtract:
893 1.1 christos case O_add:
894 1.1 christos cur_arg->X_op = O_symbol;
895 1.1 christos cur_arg->constant = cr16_ins->exp.X_add_number;
896 1.1 christos cr16_ins->exp.X_add_number = 0;
897 1.1 christos cr16_ins->rtype = BFD_RELOC_NONE;
898 1.1 christos relocatable = 1;
899 1.1 christos
900 1.8 christos if (startswith (input_line_pointer, "@c"))
901 1.8 christos symbol_with_at = 1;
902 1.1 christos
903 1.8 christos if (startswith (input_line_pointer, "@l")
904 1.8 christos || startswith (input_line_pointer, ":l"))
905 1.8 christos symbol_with_l = 1;
906 1.8 christos
907 1.8 christos if (startswith (input_line_pointer, "@m")
908 1.8 christos || startswith (input_line_pointer, ":m"))
909 1.8 christos symbol_with_m = 1;
910 1.8 christos
911 1.8 christos if (startswith (input_line_pointer, "@s")
912 1.8 christos || startswith (input_line_pointer, ":s"))
913 1.8 christos symbol_with_s = 1;
914 1.1 christos
915 1.8 christos if (startswith (input_line_pointer, "@cGOT")
916 1.8 christos || startswith (input_line_pointer, "@cgot"))
917 1.1 christos {
918 1.1 christos if (GOT_symbol == NULL)
919 1.8 christos GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
920 1.1 christos
921 1.8 christos symbol_with_at_gotc = 1;
922 1.1 christos }
923 1.8 christos else if (startswith (input_line_pointer, "@GOT")
924 1.8 christos || startswith (input_line_pointer, "@got"))
925 1.1 christos {
926 1.8 christos if ((startswith (input_line_pointer, "+"))
927 1.8 christos || (startswith (input_line_pointer, "-")))
928 1.8 christos as_warn (_("GOT bad expression with %s."), input_line_pointer);
929 1.1 christos
930 1.1 christos if (GOT_symbol == NULL)
931 1.8 christos GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME);
932 1.1 christos
933 1.8 christos symbol_with_at_got = 1;
934 1.1 christos }
935 1.1 christos
936 1.1 christos switch (cur_arg->type)
937 1.8 christos {
938 1.8 christos case arg_cr:
939 1.8 christos if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
940 1.8 christos {
941 1.1 christos if (symbol_with_at_got)
942 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
943 1.1 christos else if (symbol_with_at_gotc)
944 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
945 1.1 christos else if (cur_arg->size == 20)
946 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
947 1.8 christos else
948 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a;
949 1.1 christos }
950 1.8 christos break;
951 1.8 christos
952 1.8 christos case arg_crp:
953 1.8 christos if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
954 1.8 christos {
955 1.8 christos if (symbol_with_at_got)
956 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
957 1.8 christos else if (symbol_with_at_gotc)
958 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
959 1.8 christos } else {
960 1.8 christos switch (instruction->size)
961 1.8 christos {
962 1.8 christos case 1:
963 1.8 christos switch (cur_arg->size)
964 1.8 christos {
965 1.8 christos case 0:
966 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL0;
967 1.8 christos break;
968 1.8 christos case 4:
969 1.8 christos if (IS_INSN_MNEMONIC ("loadb") || IS_INSN_MNEMONIC ("storb"))
970 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL4;
971 1.8 christos else
972 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL4a;
973 1.8 christos break;
974 1.8 christos default: break;
975 1.8 christos }
976 1.8 christos break;
977 1.8 christos case 2:
978 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL16;
979 1.8 christos break;
980 1.8 christos case 3:
981 1.8 christos if (cur_arg->size == 20)
982 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
983 1.8 christos else
984 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL20a;
985 1.8 christos break;
986 1.8 christos default:
987 1.8 christos break;
988 1.8 christos }
989 1.8 christos }
990 1.8 christos break;
991 1.1 christos
992 1.8 christos case arg_idxr:
993 1.8 christos if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
994 1.1 christos {
995 1.1 christos if (symbol_with_at_got)
996 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
997 1.1 christos else if (symbol_with_at_gotc)
998 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
999 1.1 christos else
1000 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_REGREL20;
1001 1.1 christos }
1002 1.8 christos break;
1003 1.1 christos
1004 1.8 christos case arg_idxrp:
1005 1.8 christos if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
1006 1.1 christos {
1007 1.8 christos if (symbol_with_at_got)
1008 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
1009 1.8 christos else if (symbol_with_at_gotc)
1010 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
1011 1.8 christos else {
1012 1.8 christos switch (instruction->size)
1013 1.8 christos {
1014 1.8 christos case 1: cr16_ins->rtype = BFD_RELOC_CR16_REGREL0; break;
1015 1.8 christos case 2: cr16_ins->rtype = BFD_RELOC_CR16_REGREL14; break;
1016 1.8 christos case 3: cr16_ins->rtype = BFD_RELOC_CR16_REGREL20; break;
1017 1.8 christos default: break;
1018 1.8 christos }
1019 1.8 christos }
1020 1.1 christos }
1021 1.8 christos break;
1022 1.1 christos
1023 1.8 christos case arg_c:
1024 1.8 christos if (IS_INSN_MNEMONIC ("bal"))
1025 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_DISP24;
1026 1.8 christos else if (IS_INSN_TYPE (BRANCH_INS))
1027 1.8 christos {
1028 1.8 christos if (symbol_with_l)
1029 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_DISP24;
1030 1.8 christos else if (symbol_with_m)
1031 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_DISP16;
1032 1.8 christos else
1033 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_DISP8;
1034 1.8 christos }
1035 1.8 christos else if (IS_INSN_TYPE (STOR_IMM_INS) || IS_INSN_TYPE (LD_STOR_INS)
1036 1.8 christos || IS_INSN_TYPE (CSTBIT_INS))
1037 1.8 christos {
1038 1.1 christos if (symbol_with_s)
1039 1.8 christos as_bad (_("operand %d: illegal use expression: `%s`"), cur_arg_num + 1, str);
1040 1.1 christos if (symbol_with_at_got)
1041 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
1042 1.1 christos else if (symbol_with_at_gotc)
1043 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
1044 1.1 christos else if (symbol_with_m)
1045 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_ABS20;
1046 1.8 christos else /* Default to (symbol_with_l) */
1047 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_ABS24;
1048 1.8 christos }
1049 1.8 christos else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1050 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_DISP4;
1051 1.8 christos break;
1052 1.8 christos
1053 1.8 christos case arg_ic:
1054 1.8 christos if (IS_INSN_TYPE (ARITH_INS))
1055 1.8 christos {
1056 1.1 christos if (symbol_with_at_got)
1057 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOT_REGREL20;
1058 1.1 christos else if (symbol_with_at_gotc)
1059 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_GOTC_REGREL20;
1060 1.1 christos else if (symbol_with_s)
1061 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_IMM4;
1062 1.8 christos else if (symbol_with_m)
1063 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_IMM20;
1064 1.8 christos else if (symbol_with_at)
1065 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_IMM32a;
1066 1.8 christos else /* Default to (symbol_with_l) */
1067 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_IMM32;
1068 1.8 christos }
1069 1.8 christos else if (IS_INSN_TYPE (ARITH_BYTE_INS))
1070 1.8 christos {
1071 1.8 christos cr16_ins->rtype = BFD_RELOC_CR16_IMM16;
1072 1.8 christos }
1073 1.8 christos break;
1074 1.8 christos default:
1075 1.8 christos break;
1076 1.8 christos }
1077 1.1 christos break;
1078 1.1 christos
1079 1.1 christos default:
1080 1.1 christos cur_arg->X_op = cr16_ins->exp.X_op;
1081 1.1 christos break;
1082 1.1 christos }
1083 1.1 christos
1084 1.1 christos input_line_pointer = saved_input_line_pointer;
1085 1.1 christos return;
1086 1.1 christos }
1087 1.1 christos
1088 1.1 christos /* Retrieve the opcode image of a given register.
1089 1.1 christos If the register is illegal for the current instruction,
1090 1.1 christos issue an error. */
1091 1.1 christos
1092 1.1 christos static int
1093 1.1 christos getreg_image (reg r)
1094 1.1 christos {
1095 1.1 christos const reg_entry *rreg;
1096 1.1 christos char *reg_name;
1097 1.1 christos int is_procreg = 0; /* Nonzero means argument should be processor reg. */
1098 1.1 christos
1099 1.1 christos /* Check whether the register is in registers table. */
1100 1.1 christos if (r < MAX_REG)
1101 1.1 christos rreg = cr16_regtab + r;
1102 1.1 christos else /* Register not found. */
1103 1.1 christos {
1104 1.1 christos as_bad (_("Unknown register: `%d'"), r);
1105 1.1 christos return 0;
1106 1.1 christos }
1107 1.1 christos
1108 1.1 christos reg_name = rreg->name;
1109 1.1 christos
1110 1.8 christos /* Issue a error message when register is illegal. */
1111 1.8 christos #define IMAGE_ERR \
1112 1.8 christos as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1113 1.6 christos reg_name, ins_parse);
1114 1.1 christos
1115 1.1 christos switch (rreg->type)
1116 1.1 christos {
1117 1.1 christos case CR16_R_REGTYPE:
1118 1.1 christos if (! is_procreg)
1119 1.8 christos return rreg->image;
1120 1.1 christos else
1121 1.8 christos IMAGE_ERR;
1122 1.6 christos break;
1123 1.1 christos
1124 1.1 christos case CR16_P_REGTYPE:
1125 1.1 christos return rreg->image;
1126 1.1 christos break;
1127 1.1 christos
1128 1.1 christos default:
1129 1.1 christos IMAGE_ERR;
1130 1.6 christos break;
1131 1.1 christos }
1132 1.1 christos
1133 1.1 christos return 0;
1134 1.1 christos }
1135 1.1 christos
1136 1.1 christos /* Parsing different types of operands
1137 1.1 christos -> constants Immediate/Absolute/Relative numbers
1138 1.1 christos -> Labels Relocatable symbols
1139 1.1 christos -> (reg pair base) Register pair base
1140 1.1 christos -> (rbase) Register base
1141 1.1 christos -> disp(rbase) Register relative
1142 1.1 christos -> [rinx]disp(reg pair) Register index with reg pair mode
1143 1.1 christos -> disp(rbase,ridx,scl) Register index mode. */
1144 1.1 christos
1145 1.1 christos static void
1146 1.1 christos set_operand (char *operand, ins * cr16_ins)
1147 1.1 christos {
1148 1.6 christos char *operandS; /* Pointer to start of sub-operand. */
1149 1.6 christos char *operandE; /* Pointer to end of sub-operand. */
1150 1.1 christos
1151 1.1 christos argument *cur_arg = &cr16_ins->arg[cur_arg_num]; /* Current argument. */
1152 1.1 christos
1153 1.1 christos /* Initialize pointers. */
1154 1.1 christos operandS = operandE = operand;
1155 1.1 christos
1156 1.1 christos switch (cur_arg->type)
1157 1.1 christos {
1158 1.1 christos case arg_ic: /* Case $0x18. */
1159 1.1 christos operandS++;
1160 1.6 christos /* Fall through. */
1161 1.1 christos case arg_c: /* Case 0x18. */
1162 1.1 christos /* Set constant. */
1163 1.1 christos process_label_constant (operandS, cr16_ins);
1164 1.1 christos
1165 1.1 christos if (cur_arg->type != arg_ic)
1166 1.8 christos cur_arg->type = arg_c;
1167 1.1 christos break;
1168 1.1 christos
1169 1.1 christos case arg_icr: /* Case $0x18(r1). */
1170 1.1 christos operandS++;
1171 1.1 christos case arg_cr: /* Case 0x18(r1). */
1172 1.1 christos /* Set displacement constant. */
1173 1.1 christos while (*operandE != '(')
1174 1.8 christos operandE++;
1175 1.1 christos *operandE = '\0';
1176 1.1 christos process_label_constant (operandS, cr16_ins);
1177 1.1 christos operandS = operandE;
1178 1.6 christos /* Fall through. */
1179 1.1 christos case arg_rbase: /* Case (r1) or (r1,r0). */
1180 1.1 christos operandS++;
1181 1.1 christos /* Set register base. */
1182 1.1 christos while (*operandE != ')')
1183 1.8 christos operandE++;
1184 1.1 christos *operandE = '\0';
1185 1.1 christos if ((cur_arg->r = get_register (operandS)) == nullregister)
1186 1.8 christos as_bad (_("Illegal register `%s' in Instruction `%s'"),
1187 1.8 christos operandS, ins_parse);
1188 1.1 christos
1189 1.1 christos /* set the arg->rp, if reg is "r12" or "r13" or "14" or "15" */
1190 1.1 christos if ((cur_arg->type != arg_rbase)
1191 1.8 christos && ((getreg_image (cur_arg->r) == 12)
1192 1.8 christos || (getreg_image (cur_arg->r) == 13)
1193 1.8 christos || (getreg_image (cur_arg->r) == 14)
1194 1.8 christos || (getreg_image (cur_arg->r) == 15)))
1195 1.8 christos {
1196 1.8 christos cur_arg->type = arg_crp;
1197 1.8 christos cur_arg->rp = cur_arg->r;
1198 1.8 christos }
1199 1.1 christos break;
1200 1.1 christos
1201 1.1 christos case arg_crp: /* Case 0x18(r1,r0). */
1202 1.1 christos /* Set displacement constant. */
1203 1.1 christos while (*operandE != '(')
1204 1.8 christos operandE++;
1205 1.1 christos *operandE = '\0';
1206 1.1 christos process_label_constant (operandS, cr16_ins);
1207 1.1 christos operandS = operandE;
1208 1.1 christos operandS++;
1209 1.1 christos /* Set register pair base. */
1210 1.1 christos while (*operandE != ')')
1211 1.8 christos operandE++;
1212 1.1 christos *operandE = '\0';
1213 1.1 christos if ((cur_arg->rp = get_register_pair (operandS)) == nullregister)
1214 1.8 christos as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
1215 1.8 christos operandS, ins_parse);
1216 1.1 christos break;
1217 1.1 christos
1218 1.1 christos case arg_idxr:
1219 1.1 christos /* Set register pair base. */
1220 1.1 christos if ((strchr (operandS,'(') != NULL))
1221 1.8 christos {
1222 1.10 christos while ((*operandE != '(') && (! is_whitespace (*operandE)))
1223 1.8 christos operandE++;
1224 1.8 christos if ((cur_arg->rp = get_index_register_pair (operandE)) == nullregister)
1225 1.8 christos as_bad (_("Illegal register pair `%s' in Instruction `%s'"),
1226 1.8 christos operandS, ins_parse);
1227 1.8 christos *operandE++ = '\0';
1228 1.8 christos cur_arg->type = arg_idxrp;
1229 1.8 christos }
1230 1.1 christos else
1231 1.8 christos cur_arg->rp = -1;
1232 1.1 christos
1233 1.8 christos operandE = operandS;
1234 1.1 christos /* Set displacement constant. */
1235 1.1 christos while (*operandE != ']')
1236 1.8 christos operandE++;
1237 1.1 christos process_label_constant (++operandE, cr16_ins);
1238 1.1 christos *operandE++ = '\0';
1239 1.1 christos operandE = operandS;
1240 1.1 christos
1241 1.1 christos /* Set index register . */
1242 1.1 christos operandS = strchr (operandE,'[');
1243 1.1 christos if (operandS != NULL)
1244 1.8 christos { /* Eliminate '[', detach from rest of operand. */
1245 1.8 christos *operandS++ = '\0';
1246 1.1 christos
1247 1.8 christos operandE = strchr (operandS, ']');
1248 1.1 christos
1249 1.8 christos if (operandE == NULL)
1250 1.8 christos as_bad (_("unmatched '['"));
1251 1.8 christos else
1252 1.8 christos { /* Eliminate ']' and make sure it was the last thing
1253 1.8 christos in the string. */
1254 1.8 christos *operandE = '\0';
1255 1.8 christos if (*(operandE + 1) != '\0')
1256 1.8 christos as_bad (_("garbage after index spec ignored"));
1257 1.8 christos }
1258 1.8 christos }
1259 1.1 christos
1260 1.1 christos if ((cur_arg->i_r = get_index_register (operandS)) == nullregister)
1261 1.8 christos as_bad (_("Illegal register `%s' in Instruction `%s'"),
1262 1.8 christos operandS, ins_parse);
1263 1.1 christos *operandE = '\0';
1264 1.1 christos *operandS = '\0';
1265 1.1 christos break;
1266 1.1 christos
1267 1.1 christos default:
1268 1.1 christos break;
1269 1.1 christos }
1270 1.1 christos }
1271 1.1 christos
1272 1.1 christos /* Parse a single operand.
1273 1.1 christos operand - Current operand to parse.
1274 1.1 christos cr16_ins - Current assembled instruction. */
1275 1.1 christos
1276 1.1 christos static void
1277 1.1 christos parse_operand (char *operand, ins * cr16_ins)
1278 1.1 christos {
1279 1.1 christos int ret_val;
1280 1.1 christos argument *cur_arg = cr16_ins->arg + cur_arg_num; /* Current argument. */
1281 1.1 christos
1282 1.1 christos /* Initialize the type to NULL before parsing. */
1283 1.1 christos cur_arg->type = nullargs;
1284 1.1 christos
1285 1.1 christos /* Check whether this is a condition code . */
1286 1.1 christos if ((IS_INSN_MNEMONIC ("b")) && ((ret_val = get_cc (operand)) != -1))
1287 1.1 christos {
1288 1.1 christos cur_arg->type = arg_cc;
1289 1.1 christos cur_arg->cc = ret_val;
1290 1.1 christos cur_arg->X_op = O_register;
1291 1.1 christos return;
1292 1.1 christos }
1293 1.1 christos
1294 1.1 christos /* Check whether this is a general processor register. */
1295 1.1 christos if ((ret_val = get_register (operand)) != nullregister)
1296 1.1 christos {
1297 1.1 christos cur_arg->type = arg_r;
1298 1.1 christos cur_arg->r = ret_val;
1299 1.1 christos cur_arg->X_op = 0;
1300 1.1 christos return;
1301 1.1 christos }
1302 1.1 christos
1303 1.1 christos /* Check whether this is a general processor register pair. */
1304 1.1 christos if ((operand[0] == '(')
1305 1.1 christos && ((ret_val = get_register_pair (operand)) != nullregister))
1306 1.1 christos {
1307 1.1 christos cur_arg->type = arg_rp;
1308 1.1 christos cur_arg->rp = ret_val;
1309 1.1 christos cur_arg->X_op = O_register;
1310 1.1 christos return;
1311 1.1 christos }
1312 1.1 christos
1313 1.1 christos /* Check whether the operand is a processor register.
1314 1.1 christos For "lprd" and "sprd" instruction, only 32 bit
1315 1.1 christos processor registers used. */
1316 1.1 christos if (!(IS_INSN_MNEMONIC ("lprd") || (IS_INSN_MNEMONIC ("sprd")))
1317 1.1 christos && ((ret_val = get_pregister (operand)) != nullpregister))
1318 1.1 christos {
1319 1.1 christos cur_arg->type = arg_pr;
1320 1.1 christos cur_arg->pr = ret_val;
1321 1.1 christos cur_arg->X_op = O_register;
1322 1.1 christos return;
1323 1.1 christos }
1324 1.1 christos
1325 1.1 christos /* Check whether this is a processor register - 32 bit. */
1326 1.1 christos if ((ret_val = get_pregisterp (operand)) != nullpregister)
1327 1.1 christos {
1328 1.1 christos cur_arg->type = arg_prp;
1329 1.1 christos cur_arg->prp = ret_val;
1330 1.1 christos cur_arg->X_op = O_register;
1331 1.1 christos return;
1332 1.1 christos }
1333 1.1 christos
1334 1.1 christos /* Deal with special characters. */
1335 1.1 christos switch (operand[0])
1336 1.1 christos {
1337 1.1 christos case '$':
1338 1.1 christos if (strchr (operand, '(') != NULL)
1339 1.8 christos cur_arg->type = arg_icr;
1340 1.1 christos else
1341 1.8 christos cur_arg->type = arg_ic;
1342 1.1 christos goto set_params;
1343 1.1 christos break;
1344 1.1 christos
1345 1.1 christos case '(':
1346 1.1 christos cur_arg->type = arg_rbase;
1347 1.1 christos goto set_params;
1348 1.1 christos break;
1349 1.1 christos
1350 1.1 christos case '[':
1351 1.1 christos cur_arg->type = arg_idxr;
1352 1.1 christos goto set_params;
1353 1.1 christos break;
1354 1.1 christos
1355 1.1 christos default:
1356 1.1 christos break;
1357 1.1 christos }
1358 1.1 christos
1359 1.1 christos if (strchr (operand, '(') != NULL)
1360 1.1 christos {
1361 1.1 christos if (strchr (operand, ',') != NULL
1362 1.8 christos && (strchr (operand, ',') > strchr (operand, '(')))
1363 1.8 christos cur_arg->type = arg_crp;
1364 1.1 christos else
1365 1.8 christos cur_arg->type = arg_cr;
1366 1.1 christos }
1367 1.1 christos else
1368 1.1 christos cur_arg->type = arg_c;
1369 1.1 christos
1370 1.8 christos /* Parse an operand according to its type. */
1371 1.1 christos set_params:
1372 1.1 christos cur_arg->constant = 0;
1373 1.1 christos set_operand (operand, cr16_ins);
1374 1.1 christos }
1375 1.1 christos
1376 1.1 christos /* Parse the various operands. Each operand is then analyzed to fillup
1377 1.1 christos the fields in the cr16_ins data structure. */
1378 1.1 christos
1379 1.1 christos static void
1380 1.1 christos parse_operands (ins * cr16_ins, char *operands)
1381 1.1 christos {
1382 1.1 christos char *operandS; /* Operands string. */
1383 1.1 christos char *operandH, *operandT; /* Single operand head/tail pointers. */
1384 1.1 christos int allocated = 0; /* Indicates a new operands string was allocated.*/
1385 1.1 christos char *operand[MAX_OPERANDS];/* Separating the operands. */
1386 1.1 christos int op_num = 0; /* Current operand number we are parsing. */
1387 1.1 christos int bracket_flag = 0; /* Indicates a bracket '(' was found. */
1388 1.1 christos int sq_bracket_flag = 0; /* Indicates a square bracket '[' was found. */
1389 1.1 christos
1390 1.1 christos /* Preprocess the list of registers, if necessary. */
1391 1.1 christos operandS = operandH = operandT = operands;
1392 1.1 christos
1393 1.1 christos while (*operandT != '\0')
1394 1.1 christos {
1395 1.1 christos if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
1396 1.8 christos {
1397 1.8 christos *operandT++ = '\0';
1398 1.8 christos operand[op_num++] = strdup (operandH);
1399 1.8 christos operandH = operandT;
1400 1.8 christos continue;
1401 1.8 christos }
1402 1.1 christos
1403 1.10 christos if (is_whitespace (*operandT))
1404 1.8 christos as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
1405 1.1 christos
1406 1.1 christos if (*operandT == '(')
1407 1.8 christos bracket_flag = 1;
1408 1.1 christos else if (*operandT == '[')
1409 1.8 christos sq_bracket_flag = 1;
1410 1.1 christos
1411 1.1 christos if (*operandT == ')')
1412 1.8 christos {
1413 1.8 christos if (bracket_flag)
1414 1.8 christos bracket_flag = 0;
1415 1.8 christos else
1416 1.8 christos as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1417 1.8 christos }
1418 1.1 christos else if (*operandT == ']')
1419 1.8 christos {
1420 1.8 christos if (sq_bracket_flag)
1421 1.8 christos sq_bracket_flag = 0;
1422 1.8 christos else
1423 1.8 christos as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1424 1.8 christos }
1425 1.1 christos
1426 1.1 christos if (bracket_flag == 1 && *operandT == ')')
1427 1.8 christos bracket_flag = 0;
1428 1.1 christos else if (sq_bracket_flag == 1 && *operandT == ']')
1429 1.8 christos sq_bracket_flag = 0;
1430 1.1 christos
1431 1.1 christos operandT++;
1432 1.1 christos }
1433 1.1 christos
1434 1.1 christos /* Adding the last operand. */
1435 1.1 christos operand[op_num++] = strdup (operandH);
1436 1.1 christos cr16_ins->nargs = op_num;
1437 1.1 christos
1438 1.1 christos /* Verifying correct syntax of operands (all brackets should be closed). */
1439 1.1 christos if (bracket_flag || sq_bracket_flag)
1440 1.1 christos as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1441 1.1 christos
1442 1.1 christos /* Now we parse each operand separately. */
1443 1.1 christos for (op_num = 0; op_num < cr16_ins->nargs; op_num++)
1444 1.1 christos {
1445 1.1 christos cur_arg_num = op_num;
1446 1.1 christos parse_operand (operand[op_num], cr16_ins);
1447 1.1 christos free (operand[op_num]);
1448 1.1 christos }
1449 1.1 christos
1450 1.1 christos if (allocated)
1451 1.1 christos free (operandS);
1452 1.1 christos }
1453 1.1 christos
1454 1.1 christos /* Get the trap index in dispatch table, given its name.
1455 1.1 christos This routine is used by assembling the 'excp' instruction. */
1456 1.1 christos
1457 1.1 christos static int
1458 1.1 christos gettrap (char *s)
1459 1.1 christos {
1460 1.1 christos const trap_entry *trap;
1461 1.1 christos
1462 1.1 christos for (trap = cr16_traps; trap < (cr16_traps + NUMTRAPS); trap++)
1463 1.1 christos if (strcasecmp (trap->name, s) == 0)
1464 1.1 christos return trap->entry;
1465 1.1 christos
1466 1.6 christos /* To make compatible with CR16 4.1 tools, the below 3-lines of
1467 1.1 christos * code added. Refer: Development Tracker item #123 */
1468 1.1 christos for (trap = cr16_traps; trap < (cr16_traps + NUMTRAPS); trap++)
1469 1.1 christos if (trap->entry == (unsigned int) atoi (s))
1470 1.1 christos return trap->entry;
1471 1.1 christos
1472 1.1 christos as_bad (_("Unknown exception: `%s'"), s);
1473 1.1 christos return 0;
1474 1.1 christos }
1475 1.1 christos
1476 1.1 christos /* Top level module where instruction parsing starts.
1477 1.1 christos cr16_ins - data structure holds some information.
1478 1.1 christos operands - holds the operands part of the whole instruction. */
1479 1.1 christos
1480 1.1 christos static void
1481 1.1 christos parse_insn (ins *insn, char *operands)
1482 1.1 christos {
1483 1.1 christos int i;
1484 1.1 christos
1485 1.1 christos /* Handle instructions with no operands. */
1486 1.1 christos for (i = 0; cr16_no_op_insn[i] != NULL; i++)
1487 1.1 christos {
1488 1.1 christos if (streq (cr16_no_op_insn[i], instruction->mnemonic))
1489 1.1 christos {
1490 1.1 christos insn->nargs = 0;
1491 1.1 christos return;
1492 1.1 christos }
1493 1.1 christos }
1494 1.1 christos
1495 1.1 christos /* Handle 'excp' instructions. */
1496 1.1 christos if (IS_INSN_MNEMONIC ("excp"))
1497 1.1 christos {
1498 1.1 christos insn->nargs = 1;
1499 1.1 christos insn->arg[0].type = arg_ic;
1500 1.1 christos insn->arg[0].constant = gettrap (operands);
1501 1.1 christos insn->arg[0].X_op = O_constant;
1502 1.1 christos return;
1503 1.1 christos }
1504 1.1 christos
1505 1.1 christos if (operands != NULL)
1506 1.1 christos parse_operands (insn, operands);
1507 1.1 christos }
1508 1.1 christos
1509 1.1 christos /* bCC instruction requires special handling. */
1510 1.1 christos static char *
1511 1.1 christos get_b_cc (char * op)
1512 1.1 christos {
1513 1.1 christos unsigned int i;
1514 1.1 christos
1515 1.8 christos if (op[1] == 0 || (op[2] != 0 && op[3] != 0))
1516 1.8 christos return NULL;
1517 1.1 christos
1518 1.1 christos for (i = 0; i < cr16_num_cc ; i++)
1519 1.8 christos if (streq (op + 1, cr16_b_cond_tab[i]))
1520 1.1 christos return (char *) cr16_b_cond_tab[i];
1521 1.1 christos
1522 1.1 christos return NULL;
1523 1.1 christos }
1524 1.1 christos
1525 1.1 christos /* bCC instruction requires special handling. */
1526 1.1 christos static int
1527 1.1 christos is_bcc_insn (char * op)
1528 1.1 christos {
1529 1.1 christos if (!(streq (op, "bal") || streq (op, "beq0b") || streq (op, "bnq0b")
1530 1.8 christos || streq (op, "beq0w") || streq (op, "bnq0w")))
1531 1.1 christos if ((op[0] == 'b') && (get_b_cc (op) != NULL))
1532 1.1 christos return 1;
1533 1.1 christos return 0;
1534 1.1 christos }
1535 1.1 christos
1536 1.1 christos /* Cinv instruction requires special handling. */
1537 1.1 christos
1538 1.1 christos static void
1539 1.1 christos check_cinv_options (char * operand)
1540 1.1 christos {
1541 1.1 christos char *p = operand;
1542 1.1 christos
1543 1.1 christos while (*++p != ']')
1544 1.1 christos {
1545 1.1 christos switch (*p)
1546 1.1 christos {
1547 1.1 christos case ',':
1548 1.1 christos case 'i':
1549 1.1 christos case 'u':
1550 1.1 christos case 'd':
1551 1.1 christos break;
1552 1.1 christos default:
1553 1.10 christos if (is_whitespace (*p))
1554 1.10 christos break;
1555 1.1 christos as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1556 1.1 christos }
1557 1.1 christos }
1558 1.1 christos }
1559 1.1 christos
1560 1.1 christos /* Retrieve the opcode image of a given register pair.
1561 1.1 christos If the register is illegal for the current instruction,
1562 1.1 christos issue an error. */
1563 1.1 christos
1564 1.1 christos static int
1565 1.1 christos getregp_image (reg r)
1566 1.1 christos {
1567 1.1 christos const reg_entry *rreg;
1568 1.1 christos char *reg_name;
1569 1.1 christos
1570 1.1 christos /* Check whether the register is in registers table. */
1571 1.1 christos if (r < MAX_REG)
1572 1.1 christos rreg = cr16_regptab + r;
1573 1.1 christos /* Register not found. */
1574 1.1 christos else
1575 1.1 christos {
1576 1.1 christos as_bad (_("Unknown register pair: `%d'"), r);
1577 1.1 christos return 0;
1578 1.1 christos }
1579 1.1 christos
1580 1.1 christos reg_name = rreg->name;
1581 1.1 christos
1582 1.8 christos /* Issue a error message when register pair is illegal. */
1583 1.8 christos #define RPAIR_IMAGE_ERR \
1584 1.8 christos as_bad (_("Illegal register pair (`%s') in Instruction: `%s'"), \
1585 1.8 christos reg_name, ins_parse); \
1586 1.1 christos break;
1587 1.1 christos
1588 1.1 christos switch (rreg->type)
1589 1.1 christos {
1590 1.1 christos case CR16_RP_REGTYPE:
1591 1.1 christos return rreg->image;
1592 1.1 christos default:
1593 1.1 christos RPAIR_IMAGE_ERR;
1594 1.1 christos }
1595 1.1 christos
1596 1.1 christos return 0;
1597 1.1 christos }
1598 1.1 christos
1599 1.1 christos /* Retrieve the opcode image of a given index register pair.
1600 1.1 christos If the register is illegal for the current instruction,
1601 1.1 christos issue an error. */
1602 1.1 christos
1603 1.1 christos static int
1604 1.1 christos getidxregp_image (reg r)
1605 1.1 christos {
1606 1.1 christos const reg_entry *rreg;
1607 1.1 christos char *reg_name;
1608 1.1 christos
1609 1.1 christos /* Check whether the register is in registers table. */
1610 1.1 christos if (r < MAX_REG)
1611 1.1 christos rreg = cr16_regptab + r;
1612 1.1 christos /* Register not found. */
1613 1.1 christos else
1614 1.1 christos {
1615 1.1 christos as_bad (_("Unknown register pair: `%d'"), r);
1616 1.1 christos return 0;
1617 1.1 christos }
1618 1.1 christos
1619 1.1 christos reg_name = rreg->name;
1620 1.1 christos
1621 1.8 christos /* Issue a error message when register pair is illegal. */
1622 1.8 christos #define IDX_RPAIR_IMAGE_ERR \
1623 1.1 christos as_bad (_("Illegal index register pair (`%s') in Instruction: `%s'"), \
1624 1.8 christos reg_name, ins_parse); \
1625 1.1 christos
1626 1.1 christos if (rreg->type == CR16_RP_REGTYPE)
1627 1.1 christos {
1628 1.1 christos switch (rreg->image)
1629 1.8 christos {
1630 1.8 christos case 0: return 0; break;
1631 1.8 christos case 2: return 1; break;
1632 1.8 christos case 4: return 2; break;
1633 1.8 christos case 6: return 3; break;
1634 1.8 christos case 8: return 4; break;
1635 1.8 christos case 10: return 5; break;
1636 1.8 christos case 3: return 6; break;
1637 1.8 christos case 5: return 7; break;
1638 1.8 christos default:
1639 1.8 christos break;
1640 1.8 christos }
1641 1.1 christos }
1642 1.1 christos
1643 1.1 christos IDX_RPAIR_IMAGE_ERR;
1644 1.1 christos return 0;
1645 1.1 christos }
1646 1.1 christos
1647 1.6 christos /* Retrieve the opcode image of a given processor register.
1648 1.1 christos If the register is illegal for the current instruction,
1649 1.1 christos issue an error. */
1650 1.1 christos static int
1651 1.1 christos getprocreg_image (int r)
1652 1.1 christos {
1653 1.1 christos const reg_entry *rreg;
1654 1.1 christos char *reg_name;
1655 1.1 christos
1656 1.1 christos /* Check whether the register is in registers table. */
1657 1.1 christos if (r >= MAX_REG && r < MAX_PREG)
1658 1.1 christos rreg = &cr16_pregtab[r - MAX_REG];
1659 1.1 christos /* Register not found. */
1660 1.1 christos else
1661 1.1 christos {
1662 1.1 christos as_bad (_("Unknown processor register : `%d'"), r);
1663 1.1 christos return 0;
1664 1.1 christos }
1665 1.1 christos
1666 1.1 christos reg_name = rreg->name;
1667 1.1 christos
1668 1.8 christos /* Issue a error message when register pair is illegal. */
1669 1.8 christos #define PROCREG_IMAGE_ERR \
1670 1.8 christos as_bad (_("Illegal processor register (`%s') in Instruction: `%s'"), \
1671 1.8 christos reg_name, ins_parse); \
1672 1.1 christos break;
1673 1.1 christos
1674 1.1 christos switch (rreg->type)
1675 1.1 christos {
1676 1.1 christos case CR16_P_REGTYPE:
1677 1.1 christos return rreg->image;
1678 1.1 christos default:
1679 1.1 christos PROCREG_IMAGE_ERR;
1680 1.1 christos }
1681 1.1 christos
1682 1.1 christos return 0;
1683 1.1 christos }
1684 1.1 christos
1685 1.6 christos /* Retrieve the opcode image of a given processor register.
1686 1.1 christos If the register is illegal for the current instruction,
1687 1.1 christos issue an error. */
1688 1.1 christos static int
1689 1.1 christos getprocregp_image (int r)
1690 1.1 christos {
1691 1.1 christos const reg_entry *rreg;
1692 1.1 christos char *reg_name;
1693 1.1 christos int pregptab_disp = 0;
1694 1.1 christos
1695 1.1 christos /* Check whether the register is in registers table. */
1696 1.1 christos if (r >= MAX_REG && r < MAX_PREG)
1697 1.1 christos {
1698 1.1 christos r = r - MAX_REG;
1699 1.1 christos switch (r)
1700 1.8 christos {
1701 1.8 christos case 4: pregptab_disp = 1; break;
1702 1.8 christos case 6: pregptab_disp = 2; break;
1703 1.8 christos case 8:
1704 1.8 christos case 9:
1705 1.8 christos case 10:
1706 1.8 christos pregptab_disp = 3; break;
1707 1.8 christos case 12:
1708 1.8 christos pregptab_disp = 4; break;
1709 1.8 christos case 14:
1710 1.8 christos pregptab_disp = 5; break;
1711 1.8 christos default: break;
1712 1.8 christos }
1713 1.1 christos rreg = &cr16_pregptab[r - pregptab_disp];
1714 1.1 christos }
1715 1.1 christos /* Register not found. */
1716 1.1 christos else
1717 1.1 christos {
1718 1.1 christos as_bad (_("Unknown processor register (32 bit) : `%d'"), r);
1719 1.1 christos return 0;
1720 1.1 christos }
1721 1.1 christos
1722 1.1 christos reg_name = rreg->name;
1723 1.1 christos
1724 1.8 christos /* Issue a error message when register pair is illegal. */
1725 1.8 christos #define PROCREGP_IMAGE_ERR \
1726 1.8 christos as_bad (_("Illegal 32 bit - processor register (`%s') in Instruction: `%s'"), \
1727 1.8 christos reg_name, ins_parse); \
1728 1.1 christos break;
1729 1.1 christos
1730 1.1 christos switch (rreg->type)
1731 1.1 christos {
1732 1.1 christos case CR16_P_REGTYPE:
1733 1.1 christos return rreg->image;
1734 1.1 christos default:
1735 1.1 christos PROCREGP_IMAGE_ERR;
1736 1.1 christos }
1737 1.1 christos
1738 1.1 christos return 0;
1739 1.1 christos }
1740 1.1 christos
1741 1.1 christos /* Routine used to represent integer X using NBITS bits. */
1742 1.1 christos
1743 1.1 christos static long
1744 1.1 christos getconstant (long x, int nbits)
1745 1.1 christos {
1746 1.8 christos if ((unsigned) nbits >= sizeof (x) * CHAR_BIT)
1747 1.8 christos return x;
1748 1.8 christos return x & ((1UL << nbits) - 1);
1749 1.1 christos }
1750 1.1 christos
1751 1.1 christos /* Print a constant value to 'output_opcode':
1752 1.1 christos ARG holds the operand's type and value.
1753 1.1 christos SHIFT represents the location of the operand to be print into.
1754 1.1 christos NBITS determines the size (in bits) of the constant. */
1755 1.1 christos
1756 1.1 christos static void
1757 1.1 christos print_constant (int nbits, int shift, argument *arg)
1758 1.1 christos {
1759 1.1 christos unsigned long mask = 0;
1760 1.8 christos unsigned long constant = getconstant (arg->constant, nbits);
1761 1.1 christos
1762 1.1 christos switch (nbits)
1763 1.1 christos {
1764 1.1 christos case 32:
1765 1.1 christos case 28:
1766 1.1 christos /* mask the upper part of the constant, that is, the bits
1767 1.8 christos going to the lowest byte of output_opcode[0].
1768 1.8 christos The upper part of output_opcode[1] is always filled,
1769 1.8 christos therefore it is always masked with 0xFFFF. */
1770 1.1 christos mask = (1 << (nbits - 16)) - 1;
1771 1.1 christos /* Divide the constant between two consecutive words :
1772 1.8 christos 0 1 2 3
1773 1.8 christos +---------+---------+---------+---------+
1774 1.8 christos | | X X X X | x X x X | |
1775 1.8 christos +---------+---------+---------+---------+
1776 1.8 christos output_opcode[0] output_opcode[1] */
1777 1.1 christos
1778 1.1 christos CR16_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1779 1.8 christos CR16_PRINT (1, constant & 0xFFFF, WORD_SHIFT);
1780 1.1 christos break;
1781 1.1 christos
1782 1.1 christos case 21:
1783 1.6 christos if ((nbits == 21) && (IS_INSN_TYPE (LD_STOR_INS)))
1784 1.6 christos nbits = 20;
1785 1.6 christos /* Fall through. */
1786 1.1 christos case 24:
1787 1.1 christos case 22:
1788 1.1 christos case 20:
1789 1.1 christos /* mask the upper part of the constant, that is, the bits
1790 1.8 christos going to the lowest byte of output_opcode[0].
1791 1.8 christos The upper part of output_opcode[1] is always filled,
1792 1.8 christos therefore it is always masked with 0xFFFF. */
1793 1.1 christos mask = (1 << (nbits - 16)) - 1;
1794 1.1 christos /* Divide the constant between two consecutive words :
1795 1.8 christos 0 1 2 3
1796 1.8 christos +---------+---------+---------+---------+
1797 1.8 christos | | X X X X | - X - X | |
1798 1.8 christos +---------+---------+---------+---------+
1799 1.8 christos output_opcode[0] output_opcode[1] */
1800 1.8 christos
1801 1.8 christos if (instruction->size > 2 && shift == WORD_SHIFT)
1802 1.8 christos {
1803 1.8 christos if (arg->type == arg_idxrp)
1804 1.8 christos {
1805 1.8 christos CR16_PRINT (0, ((constant >> WORD_SHIFT) & mask) << 8, 0);
1806 1.8 christos CR16_PRINT (1, constant & 0xFFFF, WORD_SHIFT);
1807 1.8 christos }
1808 1.8 christos else
1809 1.8 christos {
1810 1.8 christos CR16_PRINT (0,
1811 1.8 christos ((((constant >> WORD_SHIFT) & mask & 0xf) << 8)
1812 1.8 christos | (((constant >> WORD_SHIFT) & mask & 0xf0) >> 4)),
1813 1.8 christos 0);
1814 1.8 christos CR16_PRINT (1, constant & 0xFFFF, WORD_SHIFT);
1815 1.8 christos }
1816 1.8 christos }
1817 1.1 christos else
1818 1.8 christos CR16_PRINT (0, constant, shift);
1819 1.1 christos break;
1820 1.1 christos
1821 1.1 christos case 14:
1822 1.1 christos if (arg->type == arg_idxrp)
1823 1.8 christos {
1824 1.8 christos if (instruction->size == 2)
1825 1.8 christos {
1826 1.8 christos CR16_PRINT (0, (constant) & 0xf, shift); /* 0-3 bits. */
1827 1.8 christos CR16_PRINT (0, (constant >> 4) & 0x3, shift + 20); /* 4-5 bits. */
1828 1.8 christos CR16_PRINT (0, (constant >> 6) & 0x3, shift + 14); /* 6-7 bits. */
1829 1.8 christos CR16_PRINT (0, (constant >> 8) & 0x3f, shift + 8); /* 8-13 bits. */
1830 1.8 christos }
1831 1.8 christos else
1832 1.8 christos CR16_PRINT (0, constant, shift);
1833 1.8 christos }
1834 1.1 christos break;
1835 1.1 christos
1836 1.1 christos case 16:
1837 1.1 christos case 12:
1838 1.1 christos /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1839 1.8 christos always filling the upper part of output_opcode[1]. If we mistakenly
1840 1.8 christos write it to output_opcode[0], the constant prefix (that is, 'match')
1841 1.8 christos will be overridden.
1842 1.8 christos 0 1 2 3
1843 1.8 christos +---------+---------+---------+---------+
1844 1.8 christos | 'match' | | X X X X | |
1845 1.8 christos +---------+---------+---------+---------+
1846 1.8 christos output_opcode[0] output_opcode[1] */
1847 1.1 christos
1848 1.8 christos if (instruction->size > 2 && shift == WORD_SHIFT)
1849 1.8 christos CR16_PRINT (1, constant, WORD_SHIFT);
1850 1.1 christos else
1851 1.8 christos CR16_PRINT (0, constant, shift);
1852 1.1 christos break;
1853 1.1 christos
1854 1.1 christos case 8:
1855 1.8 christos CR16_PRINT (0, (constant / 2) & 0xf, shift);
1856 1.8 christos CR16_PRINT (0, (constant / 2) >> 4, shift + 8);
1857 1.1 christos break;
1858 1.1 christos
1859 1.1 christos default:
1860 1.8 christos CR16_PRINT (0, constant, shift);
1861 1.1 christos break;
1862 1.1 christos }
1863 1.1 christos }
1864 1.1 christos
1865 1.1 christos /* Print an operand to 'output_opcode', which later on will be
1866 1.1 christos printed to the object file:
1867 1.1 christos ARG holds the operand's type, size and value.
1868 1.1 christos SHIFT represents the printing location of operand.
1869 1.1 christos NBITS determines the size (in bits) of a constant operand. */
1870 1.1 christos
1871 1.1 christos static void
1872 1.1 christos print_operand (int nbits, int shift, argument *arg)
1873 1.1 christos {
1874 1.1 christos switch (arg->type)
1875 1.1 christos {
1876 1.1 christos case arg_cc:
1877 1.1 christos CR16_PRINT (0, arg->cc, shift);
1878 1.1 christos break;
1879 1.1 christos
1880 1.1 christos case arg_r:
1881 1.1 christos CR16_PRINT (0, getreg_image (arg->r), shift);
1882 1.1 christos break;
1883 1.1 christos
1884 1.1 christos case arg_rp:
1885 1.1 christos CR16_PRINT (0, getregp_image (arg->rp), shift);
1886 1.1 christos break;
1887 1.1 christos
1888 1.1 christos case arg_pr:
1889 1.1 christos CR16_PRINT (0, getprocreg_image (arg->pr), shift);
1890 1.1 christos break;
1891 1.1 christos
1892 1.1 christos case arg_prp:
1893 1.1 christos CR16_PRINT (0, getprocregp_image (arg->prp), shift);
1894 1.1 christos break;
1895 1.1 christos
1896 1.1 christos case arg_idxrp:
1897 1.1 christos /* 16 12 8 6 0
1898 1.8 christos +-----------------------------+
1899 1.8 christos | r_index | disp | rp_base |
1900 1.8 christos +-----------------------------+ */
1901 1.1 christos
1902 1.1 christos if (instruction->size == 3)
1903 1.8 christos {
1904 1.8 christos CR16_PRINT (0, getidxregp_image (arg->rp), 0);
1905 1.8 christos CR16_PRINT (0, getreg_image (arg->i_r) & 1, 3);
1906 1.8 christos }
1907 1.1 christos else
1908 1.8 christos {
1909 1.8 christos CR16_PRINT (0, getidxregp_image (arg->rp), 16);
1910 1.8 christos CR16_PRINT (0, getreg_image (arg->i_r) & 1, 19);
1911 1.8 christos }
1912 1.1 christos print_constant (nbits, shift, arg);
1913 1.1 christos break;
1914 1.1 christos
1915 1.1 christos case arg_idxr:
1916 1.8 christos CR16_PRINT (0, getreg_image (arg->i_r) & 1,
1917 1.8 christos (IS_INSN_TYPE (CSTBIT_INS)
1918 1.8 christos && instruction->mnemonic[4] == 'b') ? 23 : 24);
1919 1.1 christos print_constant (nbits, shift, arg);
1920 1.1 christos break;
1921 1.1 christos
1922 1.1 christos case arg_ic:
1923 1.1 christos case arg_c:
1924 1.1 christos print_constant (nbits, shift, arg);
1925 1.1 christos break;
1926 1.1 christos
1927 1.1 christos case arg_rbase:
1928 1.1 christos CR16_PRINT (0, getreg_image (arg->r), shift);
1929 1.1 christos break;
1930 1.1 christos
1931 1.1 christos case arg_cr:
1932 1.8 christos print_constant (nbits, shift, arg);
1933 1.1 christos /* Add the register argument to the output_opcode. */
1934 1.8 christos CR16_PRINT (0, getreg_image (arg->r), shift - 16);
1935 1.1 christos break;
1936 1.1 christos
1937 1.1 christos case arg_crp:
1938 1.8 christos print_constant (nbits, shift, arg);
1939 1.8 christos if ((IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (CSTBIT_INS))
1940 1.8 christos && instruction->size == 1)
1941 1.8 christos CR16_PRINT (0, getregp_image (arg->rp), 16);
1942 1.8 christos else if (instruction->size > 1)
1943 1.8 christos CR16_PRINT (0, getregp_image (arg->rp), (shift + 16) & 31);
1944 1.1 christos else
1945 1.8 christos CR16_PRINT (0, getregp_image (arg->rp), shift);
1946 1.1 christos break;
1947 1.1 christos
1948 1.1 christos default:
1949 1.1 christos break;
1950 1.1 christos }
1951 1.1 christos }
1952 1.1 christos
1953 1.1 christos /* Retrieve the number of operands for the current assembled instruction. */
1954 1.1 christos
1955 1.1 christos static int
1956 1.1 christos get_number_of_operands (void)
1957 1.1 christos {
1958 1.1 christos int i;
1959 1.1 christos
1960 1.1 christos for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1961 1.1 christos ;
1962 1.1 christos return i;
1963 1.1 christos }
1964 1.1 christos
1965 1.1 christos /* Verify that the number NUM can be represented in BITS bits (that is,
1966 1.1 christos within its permitted range), based on the instruction's FLAGS.
1967 1.1 christos If UPDATE is nonzero, update the value of NUM if necessary.
1968 1.1 christos Return OP_LEGAL upon success, actual error type upon failure. */
1969 1.1 christos
1970 1.1 christos static op_err
1971 1.1 christos check_range (long *num, int bits, int unsigned flags, int update)
1972 1.1 christos {
1973 1.8 christos int32_t min, max;
1974 1.5 christos op_err retval = OP_LEGAL;
1975 1.8 christos int32_t value = *num;
1976 1.1 christos
1977 1.1 christos /* Verify operand value is even. */
1978 1.1 christos if (flags & OP_EVEN)
1979 1.1 christos {
1980 1.1 christos if (value % 2)
1981 1.8 christos return OP_NOT_EVEN;
1982 1.1 christos }
1983 1.1 christos
1984 1.1 christos if (flags & OP_DEC)
1985 1.1 christos {
1986 1.1 christos value -= 1;
1987 1.1 christos if (update)
1988 1.8 christos *num = value;
1989 1.1 christos }
1990 1.1 christos
1991 1.1 christos if (flags & OP_SHIFT)
1992 1.1 christos {
1993 1.1 christos value >>= 1;
1994 1.1 christos if (update)
1995 1.8 christos *num = value;
1996 1.1 christos }
1997 1.1 christos else if (flags & OP_SHIFT_DEC)
1998 1.1 christos {
1999 1.1 christos value = (value >> 1) - 1;
2000 1.1 christos if (update)
2001 1.8 christos *num = value;
2002 1.1 christos }
2003 1.1 christos
2004 1.1 christos if (flags & OP_ABS20)
2005 1.1 christos {
2006 1.1 christos if (value > 0xEFFFF)
2007 1.8 christos return OP_OUT_OF_RANGE;
2008 1.1 christos }
2009 1.1 christos
2010 1.1 christos if (flags & OP_ESC)
2011 1.1 christos {
2012 1.1 christos if (value == 0xB || value == 0x9)
2013 1.8 christos return OP_OUT_OF_RANGE;
2014 1.1 christos else if (value == -1)
2015 1.8 christos {
2016 1.8 christos if (update)
2017 1.8 christos *num = 9;
2018 1.8 christos return retval;
2019 1.8 christos }
2020 1.1 christos }
2021 1.1 christos
2022 1.1 christos if (flags & OP_ESC1)
2023 1.1 christos {
2024 1.1 christos if (value > 13)
2025 1.8 christos return OP_OUT_OF_RANGE;
2026 1.1 christos }
2027 1.1 christos
2028 1.8 christos if (bits == 0)
2029 1.8 christos {
2030 1.8 christos if (value != 0)
2031 1.8 christos retval = OP_OUT_OF_RANGE;
2032 1.8 christos return retval;
2033 1.8 christos }
2034 1.8 christos
2035 1.8 christos if (flags & OP_SIGNED)
2036 1.8 christos {
2037 1.8 christos max = (1U << (bits - 1)) - 1;
2038 1.8 christos min = - (1U << (bits - 1));
2039 1.8 christos if (value > max || value < min)
2040 1.8 christos retval = OP_OUT_OF_RANGE;
2041 1.8 christos }
2042 1.8 christos else if (flags & OP_UNSIGNED)
2043 1.8 christos {
2044 1.8 christos max = (1U << (bits - 1) << 1) - 1;
2045 1.8 christos if ((uint32_t) value > (uint32_t) max)
2046 1.8 christos retval = OP_OUT_OF_RANGE;
2047 1.8 christos }
2048 1.8 christos else if (flags & OP_NEG)
2049 1.8 christos {
2050 1.8 christos min = - ((1U << (bits - 1)) - 1);
2051 1.8 christos if (value < min)
2052 1.8 christos retval = OP_OUT_OF_RANGE;
2053 1.8 christos }
2054 1.8 christos return retval;
2055 1.1 christos }
2056 1.1 christos
2057 1.6 christos /* Bunch of error checking.
2058 1.1 christos The checks are made after a matching instruction was found. */
2059 1.1 christos
2060 1.1 christos static void
2061 1.1 christos warn_if_needed (ins *insn)
2062 1.1 christos {
2063 1.1 christos /* If the post-increment address mode is used and the load/store
2064 1.1 christos source register is the same as rbase, the result of the
2065 1.1 christos instruction is undefined. */
2066 1.1 christos if (IS_INSN_TYPE (LD_STOR_INS_INC))
2067 1.1 christos {
2068 1.1 christos /* Enough to verify that one of the arguments is a simple reg. */
2069 1.1 christos if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
2070 1.8 christos if (insn->arg[0].r == insn->arg[1].r)
2071 1.8 christos as_bad (_("Same src/dest register is used (`r%d'), "
2072 1.8 christos "result is undefined"), insn->arg[0].r);
2073 1.1 christos }
2074 1.1 christos
2075 1.1 christos if (IS_INSN_MNEMONIC ("pop")
2076 1.1 christos || IS_INSN_MNEMONIC ("push")
2077 1.1 christos || IS_INSN_MNEMONIC ("popret"))
2078 1.1 christos {
2079 1.1 christos unsigned int count = insn->arg[0].constant, reg_val;
2080 1.1 christos
2081 1.6 christos /* Check if count operand caused to save/retrieve the RA twice
2082 1.8 christos to generate warning message. */
2083 1.8 christos if (insn->nargs > 2)
2084 1.8 christos {
2085 1.8 christos reg_val = getreg_image (insn->arg[1].r);
2086 1.8 christos
2087 1.8 christos if ( ((reg_val == 9) && (count > 7))
2088 1.8 christos || ((reg_val == 10) && (count > 6))
2089 1.8 christos || ((reg_val == 11) && (count > 5))
2090 1.8 christos || ((reg_val == 12) && (count > 4))
2091 1.8 christos || ((reg_val == 13) && (count > 2))
2092 1.8 christos || ((reg_val == 14) && (count > 0)))
2093 1.8 christos as_warn (_("RA register is saved twice."));
2094 1.8 christos
2095 1.8 christos /* Check if the third operand is "RA" or "ra" */
2096 1.8 christos if (!(((insn->arg[2].r) == ra) || ((insn->arg[2].r) == RA)))
2097 1.8 christos as_bad (_("`%s' Illegal use of registers."), ins_parse);
2098 1.8 christos }
2099 1.1 christos
2100 1.1 christos if (insn->nargs > 1)
2101 1.8 christos {
2102 1.8 christos reg_val = getreg_image (insn->arg[1].r);
2103 1.1 christos
2104 1.8 christos /* If register is a register pair ie r12/r13/r14 in operand1, then
2105 1.8 christos the count constant should be validated. */
2106 1.8 christos if (((reg_val == 11) && (count > 7))
2107 1.8 christos || ((reg_val == 12) && (count > 6))
2108 1.8 christos || ((reg_val == 13) && (count > 4))
2109 1.8 christos || ((reg_val == 14) && (count > 2))
2110 1.8 christos || ((reg_val == 15) && (count > 0)))
2111 1.8 christos as_bad (_("`%s' Illegal count-register combination."), ins_parse);
2112 1.8 christos }
2113 1.8 christos else
2114 1.8 christos {
2115 1.8 christos /* Check if the operand is "RA" or "ra" */
2116 1.8 christos if (!(((insn->arg[0].r) == ra) || ((insn->arg[0].r) == RA)))
2117 1.8 christos as_bad (_("`%s' Illegal use of register."), ins_parse);
2118 1.8 christos }
2119 1.1 christos }
2120 1.1 christos
2121 1.1 christos /* Some instruction assume the stack pointer as rptr operand.
2122 1.1 christos Issue an error when the register to be loaded is also SP. */
2123 1.1 christos if (instruction->flags & NO_SP)
2124 1.1 christos {
2125 1.1 christos if (getreg_image (insn->arg[1].r) == getreg_image (sp))
2126 1.8 christos as_bad (_("`%s' has undefined result"), ins_parse);
2127 1.1 christos }
2128 1.1 christos
2129 1.1 christos /* If the rptr register is specified as one of the registers to be loaded,
2130 1.1 christos the final contents of rptr are undefined. Thus, we issue an error. */
2131 1.1 christos if (instruction->flags & NO_RPTR)
2132 1.1 christos {
2133 1.1 christos if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
2134 1.8 christos as_bad (_("Same src/dest register is used (`r%d'),result is undefined"),
2135 1.8 christos getreg_image (insn->arg[0].r));
2136 1.1 christos }
2137 1.1 christos }
2138 1.1 christos
2139 1.1 christos /* In some cases, we need to adjust the instruction pointer although a
2140 1.1 christos match was already found. Here, we gather all these cases.
2141 1.1 christos Returns 1 if instruction pointer was adjusted, otherwise 0. */
2142 1.1 christos
2143 1.1 christos static int
2144 1.1 christos adjust_if_needed (ins *insn ATTRIBUTE_UNUSED)
2145 1.1 christos {
2146 1.1 christos int ret_value = 0;
2147 1.1 christos
2148 1.1 christos if ((IS_INSN_TYPE (CSTBIT_INS)) || (IS_INSN_TYPE (LD_STOR_INS)))
2149 1.1 christos {
2150 1.1 christos if ((instruction->operands[0].op_type == abs24)
2151 1.8 christos && ((insn->arg[0].constant) > 0xF00000))
2152 1.8 christos {
2153 1.8 christos insn->arg[0].constant &= 0xFFFFF;
2154 1.8 christos instruction--;
2155 1.8 christos ret_value = 1;
2156 1.8 christos }
2157 1.1 christos }
2158 1.1 christos
2159 1.1 christos return ret_value;
2160 1.1 christos }
2161 1.1 christos
2162 1.1 christos /* Assemble a single instruction:
2163 1.1 christos INSN is already parsed (that is, all operand values and types are set).
2164 1.1 christos For instruction to be assembled, we need to find an appropriate template in
2165 1.1 christos the instruction table, meeting the following conditions:
2166 1.1 christos 1: Has the same number of operands.
2167 1.1 christos 2: Has the same operand types.
2168 1.1 christos 3: Each operand size is sufficient to represent the instruction's values.
2169 1.1 christos Returns 1 upon success, 0 upon failure. */
2170 1.1 christos
2171 1.1 christos static int
2172 1.5 christos assemble_insn (const char *mnemonic, ins *insn)
2173 1.1 christos {
2174 1.1 christos /* Type of each operand in the current template. */
2175 1.1 christos argtype cur_type[MAX_OPERANDS];
2176 1.1 christos /* Size (in bits) of each operand in the current template. */
2177 1.1 christos unsigned int cur_size[MAX_OPERANDS];
2178 1.1 christos /* Flags of each operand in the current template. */
2179 1.1 christos unsigned int cur_flags[MAX_OPERANDS];
2180 1.1 christos /* Instruction type to match. */
2181 1.1 christos unsigned int ins_type;
2182 1.1 christos /* Boolean flag to mark whether a match was found. */
2183 1.1 christos int match = 0;
2184 1.1 christos int i;
2185 1.1 christos /* Nonzero if an instruction with same number of operands was found. */
2186 1.1 christos int found_same_number_of_operands = 0;
2187 1.1 christos /* Nonzero if an instruction with same argument types was found. */
2188 1.1 christos int found_same_argument_types = 0;
2189 1.1 christos /* Nonzero if a constant was found within the required range. */
2190 1.1 christos int found_const_within_range = 0;
2191 1.1 christos /* Argument number of an operand with invalid type. */
2192 1.1 christos int invalid_optype = -1;
2193 1.1 christos /* Argument number of an operand with invalid constant value. */
2194 1.1 christos int invalid_const = -1;
2195 1.1 christos /* Operand error (used for issuing various constant error messages). */
2196 1.1 christos op_err op_error, const_err = OP_LEGAL;
2197 1.1 christos
2198 1.8 christos /* Retrieve data (based on FUNC) for each operand of a given instruction. */
2199 1.8 christos #define GET_CURRENT_DATA(FUNC, ARRAY) \
2200 1.8 christos for (i = 0; i < insn->nargs; i++) \
2201 1.1 christos ARRAY[i] = FUNC (instruction->operands[i].op_type)
2202 1.1 christos
2203 1.1 christos #define GET_CURRENT_TYPE GET_CURRENT_DATA (get_optype, cur_type)
2204 1.1 christos #define GET_CURRENT_SIZE GET_CURRENT_DATA (get_opbits, cur_size)
2205 1.1 christos #define GET_CURRENT_FLAGS GET_CURRENT_DATA (get_opflags, cur_flags)
2206 1.1 christos
2207 1.1 christos /* Instruction has no operands -> only copy the constant opcode. */
2208 1.1 christos if (insn->nargs == 0)
2209 1.1 christos {
2210 1.1 christos output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2211 1.1 christos return 1;
2212 1.1 christos }
2213 1.1 christos
2214 1.1 christos /* In some case, same mnemonic can appear with different instruction types.
2215 1.1 christos For example, 'storb' is supported with 3 different types :
2216 1.1 christos LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
2217 1.1 christos We assume that when reaching this point, the instruction type was
2218 1.1 christos pre-determined. We need to make sure that the type stays the same
2219 1.1 christos during a search for matching instruction. */
2220 1.1 christos ins_type = CR16_INS_TYPE (instruction->flags);
2221 1.1 christos
2222 1.1 christos while (/* Check that match is still not found. */
2223 1.8 christos match != 1
2224 1.8 christos /* Check we didn't get to end of table. */
2225 1.8 christos && instruction->mnemonic != NULL
2226 1.8 christos /* Check that the actual mnemonic is still available. */
2227 1.8 christos && IS_INSN_MNEMONIC (mnemonic)
2228 1.8 christos /* Check that the instruction type wasn't changed. */
2229 1.8 christos && IS_INSN_TYPE (ins_type))
2230 1.1 christos {
2231 1.1 christos /* Check whether number of arguments is legal. */
2232 1.1 christos if (get_number_of_operands () != insn->nargs)
2233 1.8 christos goto next_insn;
2234 1.1 christos found_same_number_of_operands = 1;
2235 1.1 christos
2236 1.1 christos /* Initialize arrays with data of each operand in current template. */
2237 1.1 christos GET_CURRENT_TYPE;
2238 1.1 christos GET_CURRENT_SIZE;
2239 1.1 christos GET_CURRENT_FLAGS;
2240 1.1 christos
2241 1.1 christos /* Check for type compatibility. */
2242 1.1 christos for (i = 0; i < insn->nargs; i++)
2243 1.8 christos {
2244 1.8 christos if (cur_type[i] != insn->arg[i].type)
2245 1.8 christos {
2246 1.8 christos if (invalid_optype == -1)
2247 1.8 christos invalid_optype = i + 1;
2248 1.8 christos goto next_insn;
2249 1.8 christos }
2250 1.8 christos }
2251 1.1 christos found_same_argument_types = 1;
2252 1.1 christos
2253 1.1 christos for (i = 0; i < insn->nargs; i++)
2254 1.8 christos {
2255 1.8 christos /* If 'bal' instruction size is '2' and reg operand is not 'ra'
2256 1.8 christos then goto next instruction. */
2257 1.8 christos if (IS_INSN_MNEMONIC ("bal") && (i == 0)
2258 1.8 christos && (instruction->size == 2) && (insn->arg[i].rp != 14))
2259 1.8 christos goto next_insn;
2260 1.8 christos
2261 1.8 christos /* If 'storb' instruction with 'sp' reg and 16-bit disp of
2262 1.8 christos * reg-pair, leads to undefined trap, so this should use
2263 1.8 christos * 20-bit disp of reg-pair. */
2264 1.8 christos if (IS_INSN_MNEMONIC ("storb") && (instruction->size == 2)
2265 1.8 christos && (insn->arg[i].r == 15) && (insn->arg[i + 1].type == arg_crp))
2266 1.8 christos goto next_insn;
2267 1.8 christos
2268 1.8 christos /* Only check range - don't update the constant's value, since the
2269 1.8 christos current instruction may not be the last we try to match.
2270 1.8 christos The constant's value will be updated later, right before printing
2271 1.8 christos it to the object file. */
2272 1.8 christos if ((insn->arg[i].X_op == O_constant)
2273 1.8 christos && (op_error = check_range (&insn->arg[i].constant, cur_size[i],
2274 1.8 christos cur_flags[i], 0)))
2275 1.8 christos {
2276 1.8 christos if (invalid_const == -1)
2277 1.8 christos {
2278 1.8 christos invalid_const = i + 1;
2279 1.8 christos const_err = op_error;
2280 1.8 christos }
2281 1.8 christos goto next_insn;
2282 1.8 christos }
2283 1.8 christos /* For symbols, we make sure the relocation size (which was already
2284 1.8 christos determined) is sufficient. */
2285 1.8 christos else if ((insn->arg[i].X_op == O_symbol)
2286 1.8 christos && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
2287 1.8 christos > cur_size[i]))
2288 1.8 christos goto next_insn;
2289 1.8 christos }
2290 1.1 christos found_const_within_range = 1;
2291 1.1 christos
2292 1.1 christos /* If we got till here -> Full match is found. */
2293 1.1 christos match = 1;
2294 1.1 christos break;
2295 1.1 christos
2296 1.8 christos /* Try again with next instruction. */
2297 1.8 christos next_insn:
2298 1.1 christos instruction++;
2299 1.1 christos }
2300 1.1 christos
2301 1.1 christos if (!match)
2302 1.1 christos {
2303 1.1 christos /* We haven't found a match - instruction can't be assembled. */
2304 1.1 christos if (!found_same_number_of_operands)
2305 1.8 christos as_bad (_("Incorrect number of operands"));
2306 1.1 christos else if (!found_same_argument_types)
2307 1.8 christos as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
2308 1.1 christos else if (!found_const_within_range)
2309 1.8 christos {
2310 1.8 christos switch (const_err)
2311 1.8 christos {
2312 1.8 christos case OP_OUT_OF_RANGE:
2313 1.8 christos as_bad (_("Operand out of range (arg %d)"), invalid_const);
2314 1.8 christos break;
2315 1.8 christos case OP_NOT_EVEN:
2316 1.8 christos as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
2317 1.8 christos break;
2318 1.8 christos default:
2319 1.8 christos as_bad (_("Illegal operand (arg %d)"), invalid_const);
2320 1.8 christos break;
2321 1.8 christos }
2322 1.8 christos }
2323 1.1 christos
2324 1.8 christos return 0;
2325 1.1 christos }
2326 1.1 christos else
2327 1.1 christos /* Full match - print the encoding to output file. */
2328 1.1 christos {
2329 1.6 christos /* Make further checking (such that couldn't be made earlier).
2330 1.8 christos Warn the user if necessary. */
2331 1.1 christos warn_if_needed (insn);
2332 1.1 christos
2333 1.1 christos /* Check whether we need to adjust the instruction pointer. */
2334 1.1 christos if (adjust_if_needed (insn))
2335 1.8 christos /* If instruction pointer was adjusted, we need to update
2336 1.8 christos the size of the current template operands. */
2337 1.8 christos GET_CURRENT_SIZE;
2338 1.1 christos
2339 1.1 christos for (i = 0; i < insn->nargs; i++)
2340 1.8 christos {
2341 1.8 christos int j = instruction->flags & REVERSE_MATCH ?
2342 1.8 christos i == 0 ? 1 :
2343 1.8 christos i == 1 ? 0 : i :
2344 1.8 christos i;
2345 1.8 christos
2346 1.8 christos /* This time, update constant value before printing it. */
2347 1.8 christos if ((insn->arg[j].X_op == O_constant)
2348 1.8 christos && (check_range (&insn->arg[j].constant, cur_size[j],
2349 1.8 christos cur_flags[j], 1) != OP_LEGAL))
2350 1.8 christos as_fatal (_("Illegal operand (arg %d)"), j+1);
2351 1.8 christos }
2352 1.1 christos
2353 1.1 christos /* First, copy the instruction's opcode. */
2354 1.1 christos output_opcode[0] = BIN (instruction->match, instruction->match_bits);
2355 1.1 christos
2356 1.1 christos for (i = 0; i < insn->nargs; i++)
2357 1.8 christos {
2358 1.8 christos /* For BAL (ra),disp17 instruction only. And also set the
2359 1.8 christos DISP24a relocation type. */
2360 1.8 christos if (IS_INSN_MNEMONIC ("bal") && (instruction->size == 2) && i == 0)
2361 1.8 christos {
2362 1.8 christos insn->rtype = BFD_RELOC_CR16_DISP24a;
2363 1.8 christos continue;
2364 1.8 christos }
2365 1.8 christos cur_arg_num = i;
2366 1.8 christos print_operand (cur_size[i], instruction->operands[i].shift,
2367 1.8 christos &insn->arg[i]);
2368 1.8 christos }
2369 1.1 christos }
2370 1.1 christos
2371 1.1 christos return 1;
2372 1.1 christos }
2373 1.1 christos
2374 1.1 christos /* Print the instruction.
2375 1.1 christos Handle also cases where the instruction is relaxable/relocatable. */
2376 1.1 christos
2377 1.1 christos static void
2378 1.1 christos print_insn (ins *insn)
2379 1.1 christos {
2380 1.1 christos unsigned int i, j, insn_size;
2381 1.1 christos char *this_frag;
2382 1.1 christos unsigned short words[4];
2383 1.1 christos int addr_mod;
2384 1.1 christos
2385 1.1 christos /* Arrange the insn encodings in a WORD size array. */
2386 1.1 christos for (i = 0, j = 0; i < 2; i++)
2387 1.1 christos {
2388 1.1 christos words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
2389 1.1 christos words[j++] = output_opcode[i] & 0xFFFF;
2390 1.1 christos }
2391 1.1 christos
2392 1.8 christos /* Handle relocation. */
2393 1.8 christos if ((instruction->flags & RELAXABLE) && relocatable)
2394 1.8 christos {
2395 1.8 christos int relax_subtype;
2396 1.8 christos /* Write the maximal instruction size supported. */
2397 1.8 christos insn_size = INSN_MAX_SIZE;
2398 1.8 christos
2399 1.8 christos if (IS_INSN_TYPE (BRANCH_INS))
2400 1.8 christos {
2401 1.8 christos switch (insn->rtype)
2402 1.8 christos {
2403 1.8 christos case BFD_RELOC_CR16_DISP24:
2404 1.8 christos relax_subtype = 2;
2405 1.8 christos break;
2406 1.8 christos case BFD_RELOC_CR16_DISP16:
2407 1.8 christos relax_subtype = 1;
2408 1.8 christos break;
2409 1.8 christos default:
2410 1.8 christos relax_subtype = 0;
2411 1.8 christos break;
2412 1.8 christos }
2413 1.8 christos }
2414 1.8 christos else
2415 1.8 christos abort ();
2416 1.8 christos
2417 1.8 christos this_frag = frag_var (rs_machine_dependent, insn_size *2,
2418 1.8 christos 4, relax_subtype,
2419 1.8 christos insn->exp.X_add_symbol,
2420 1.8 christos 0,
2421 1.8 christos 0);
2422 1.8 christos }
2423 1.8 christos else
2424 1.8 christos {
2425 1.8 christos insn_size = instruction->size;
2426 1.8 christos this_frag = frag_more (insn_size * 2);
2427 1.8 christos
2428 1.8 christos if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
2429 1.8 christos {
2430 1.8 christos reloc_howto_type *reloc_howto;
2431 1.8 christos int size;
2432 1.8 christos
2433 1.8 christos reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
2434 1.8 christos
2435 1.8 christos if (!reloc_howto)
2436 1.8 christos abort ();
2437 1.8 christos
2438 1.8 christos size = bfd_get_reloc_size (reloc_howto);
2439 1.8 christos
2440 1.8 christos if (size < 1 || size > 4)
2441 1.8 christos abort ();
2442 1.8 christos
2443 1.8 christos fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
2444 1.8 christos size, &insn->exp, reloc_howto->pc_relative,
2445 1.8 christos insn->rtype);
2446 1.8 christos }
2447 1.8 christos }
2448 1.1 christos
2449 1.1 christos /* Verify a 2-byte code alignment. */
2450 1.1 christos addr_mod = frag_now_fix () & 1;
2451 1.1 christos if (frag_now->has_code && frag_now->insn_addr != addr_mod)
2452 1.1 christos as_bad (_("instruction address is not a multiple of 2"));
2453 1.1 christos frag_now->insn_addr = addr_mod;
2454 1.1 christos frag_now->has_code = 1;
2455 1.1 christos
2456 1.1 christos /* Write the instruction encoding to frag. */
2457 1.1 christos for (i = 0; i < insn_size; i++)
2458 1.1 christos {
2459 1.10 christos md_number_to_chars (this_frag, words[i], 2);
2460 1.1 christos this_frag += 2;
2461 1.1 christos }
2462 1.1 christos }
2463 1.1 christos
2464 1.5 christos /* Actually assemble an instruction. */
2465 1.5 christos
2466 1.5 christos static void
2467 1.5 christos cr16_assemble (const char *op, char *param)
2468 1.5 christos {
2469 1.5 christos ins cr16_ins;
2470 1.5 christos
2471 1.5 christos /* Find the instruction. */
2472 1.10 christos instruction = str_hash_find (cr16_inst_hash, op);
2473 1.5 christos if (instruction == NULL)
2474 1.5 christos {
2475 1.5 christos as_bad (_("Unknown opcode: `%s'"), op);
2476 1.5 christos return;
2477 1.5 christos }
2478 1.5 christos
2479 1.5 christos /* Tie dwarf2 debug info to the address at the start of the insn. */
2480 1.5 christos dwarf2_emit_insn (0);
2481 1.5 christos
2482 1.5 christos /* Parse the instruction's operands. */
2483 1.5 christos parse_insn (&cr16_ins, param);
2484 1.5 christos
2485 1.5 christos /* Assemble the instruction - return upon failure. */
2486 1.5 christos if (assemble_insn (op, &cr16_ins) == 0)
2487 1.5 christos return;
2488 1.5 christos
2489 1.5 christos /* Print the instruction. */
2490 1.5 christos print_insn (&cr16_ins);
2491 1.5 christos }
2492 1.5 christos
2493 1.1 christos /* This is the guts of the machine-dependent assembler. OP points to a
2494 1.1 christos machine dependent instruction. This function is supposed to emit
2495 1.1 christos the frags/bytes it assembles to. */
2496 1.1 christos
2497 1.1 christos void
2498 1.1 christos md_assemble (char *op)
2499 1.1 christos {
2500 1.1 christos ins cr16_ins;
2501 1.1 christos char *param, param1[32];
2502 1.1 christos
2503 1.1 christos /* Reset global variables for a new instruction. */
2504 1.1 christos reset_vars (op);
2505 1.1 christos
2506 1.1 christos /* Strip the mnemonic. */
2507 1.10 christos for (param = op; *param != 0 && !is_whitespace (*param); param++)
2508 1.1 christos ;
2509 1.1 christos *param++ = '\0';
2510 1.1 christos
2511 1.6 christos /* bCC instructions and adjust the mnemonic by adding extra white spaces. */
2512 1.1 christos if (is_bcc_insn (op))
2513 1.1 christos {
2514 1.1 christos strcpy (param1, get_b_cc (op));
2515 1.1 christos strcat (param1,",");
2516 1.1 christos strcat (param1, param);
2517 1.10 christos param = param1;
2518 1.5 christos cr16_assemble ("b", param);
2519 1.5 christos return;
2520 1.1 christos }
2521 1.1 christos
2522 1.1 christos /* Checking the cinv options and adjust the mnemonic by removing the
2523 1.1 christos extra white spaces. */
2524 1.1 christos if (streq ("cinv", op))
2525 1.1 christos {
2526 1.8 christos /* Validate the cinv options. */
2527 1.8 christos unsigned int op_len, param_len;
2528 1.1 christos check_cinv_options (param);
2529 1.8 christos op_len = strlen (op);
2530 1.8 christos param_len = strlen (param) + 1;
2531 1.8 christos memmove (op + op_len, param, param_len);
2532 1.1 christos }
2533 1.1 christos
2534 1.1 christos /* MAPPING - SHIFT INSN, if imm4/imm16 positive values
2535 1.1 christos lsh[b/w] imm4/imm6, reg ==> ashu[b/w] imm4/imm16, reg
2536 1.6 christos as CR16 core doesn't support lsh[b/w] right shift operations. */
2537 1.1 christos if ((streq ("lshb", op) || streq ("lshw", op) || streq ("lshd", op))
2538 1.1 christos && (param [0] == '$'))
2539 1.1 christos {
2540 1.1 christos strcpy (param1, param);
2541 1.1 christos /* Find the instruction. */
2542 1.10 christos instruction = str_hash_find (cr16_inst_hash, op);
2543 1.8 christos parse_operands (&cr16_ins, param1);
2544 1.1 christos if (((&cr16_ins)->arg[0].type == arg_ic)
2545 1.8 christos && ((&cr16_ins)->arg[0].constant >= 0))
2546 1.8 christos {
2547 1.8 christos if (streq ("lshb", op))
2548 1.8 christos cr16_assemble ("ashub", param);
2549 1.8 christos else if (streq ("lshd", op))
2550 1.8 christos cr16_assemble ("ashud", param);
2551 1.8 christos else
2552 1.8 christos cr16_assemble ("ashuw", param);
2553 1.8 christos return;
2554 1.8 christos }
2555 1.1 christos }
2556 1.1 christos
2557 1.5 christos cr16_assemble (op, param);
2558 1.1 christos }
2559