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