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