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