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