* m32r-asm.c: Regenerate.
[deliverable/binutils-gdb.git] / opcodes / m32r-asm.c
1 /* Assembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
3
4 THIS FILE IS USED TO GENERATE m32r-asm.c.
5
6 Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
7
8 This file is part of the GNU Binutils and GDB, the GNU debugger.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software Foundation, Inc.,
22 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23
24 #include "sysdep.h"
25 #include <ctype.h>
26 #include <stdio.h>
27 #include "ansidecl.h"
28 #include "bfd.h"
29 #include "symcat.h"
30 #include "m32r-opc.h"
31 #include "opintl.h"
32
33 #undef min
34 #define min(a,b) ((a) < (b) ? (a) : (b))
35 #undef max
36 #define max(a,b) ((a) > (b) ? (a) : (b))
37
38 #undef INLINE
39 #ifdef __GNUC__
40 #define INLINE __inline__
41 #else
42 #define INLINE
43 #endif
44
45 static const char * insert_normal
46 PARAMS ((CGEN_OPCODE_DESC, long, unsigned int, int, int, int,
47 CGEN_INSN_BYTES_PTR));
48 static const char * parse_insn_normal
49 PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *,
50 const char **, CGEN_FIELDS *));
51 static const char * insert_insn_normal
52 PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *,
53 CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
54 \f
55 /* -- assembler routines inserted here */
56 /* -- asm.c */
57
58 /* Handle '#' prefixes (i.e. skip over them). */
59
60 static const char *
61 parse_hash (od, strp, opindex, valuep)
62 CGEN_OPCODE_DESC od;
63 const char **strp;
64 int opindex;
65 unsigned long *valuep;
66 {
67 if (**strp == '#')
68 ++*strp;
69 return NULL;
70 }
71
72 /* Handle shigh(), high(). */
73
74 static const char *
75 parse_hi16 (od, strp, opindex, valuep)
76 CGEN_OPCODE_DESC od;
77 const char **strp;
78 int opindex;
79 unsigned long *valuep;
80 {
81 const char *errmsg;
82 enum cgen_parse_operand_result result_type;
83 bfd_vma value;
84
85 if (**strp == '#')
86 ++*strp;
87
88 if (strncasecmp (*strp, "high(", 5) == 0)
89 {
90 *strp += 5;
91 errmsg = cgen_parse_address (od, strp, opindex, BFD_RELOC_M32R_HI16_ULO,
92 &result_type, &value);
93 if (**strp != ')')
94 return "missing `)'";
95 ++*strp;
96 if (errmsg == NULL
97 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
98 value >>= 16;
99 *valuep = value;
100 return errmsg;
101 }
102 else if (strncasecmp (*strp, "shigh(", 6) == 0)
103 {
104 *strp += 6;
105 errmsg = cgen_parse_address (od, strp, opindex, BFD_RELOC_M32R_HI16_SLO,
106 &result_type, &value);
107 if (**strp != ')')
108 return "missing `)'";
109 ++*strp;
110 if (errmsg == NULL
111 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
112 value = (value >> 16) + (value & 0x8000 ? 1 : 0);
113 *valuep = value;
114 return errmsg;
115 }
116
117 return cgen_parse_unsigned_integer (od, strp, opindex, valuep);
118 }
119
120 /* Handle low() in a signed context. Also handle sda().
121 The signedness of the value doesn't matter to low(), but this also
122 handles the case where low() isn't present. */
123
124 static const char *
125 parse_slo16 (od, strp, opindex, valuep)
126 CGEN_OPCODE_DESC od;
127 const char **strp;
128 int opindex;
129 long *valuep;
130 {
131 const char *errmsg;
132 enum cgen_parse_operand_result result_type;
133 bfd_vma value;
134
135 if (**strp == '#')
136 ++*strp;
137
138 if (strncasecmp (*strp, "low(", 4) == 0)
139 {
140 *strp += 4;
141 errmsg = cgen_parse_address (od, strp, opindex, BFD_RELOC_M32R_LO16,
142 &result_type, &value);
143 if (**strp != ')')
144 return "missing `)'";
145 ++*strp;
146 if (errmsg == NULL
147 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
148 value &= 0xffff;
149 *valuep = value;
150 return errmsg;
151 }
152
153 if (strncasecmp (*strp, "sda(", 4) == 0)
154 {
155 *strp += 4;
156 errmsg = cgen_parse_address (od, strp, opindex, BFD_RELOC_M32R_SDA16,
157 NULL, &value);
158 if (**strp != ')')
159 return "missing `)'";
160 ++*strp;
161 *valuep = value;
162 return errmsg;
163 }
164
165 return cgen_parse_signed_integer (od, strp, opindex, valuep);
166 }
167
168 /* Handle low() in an unsigned context.
169 The signedness of the value doesn't matter to low(), but this also
170 handles the case where low() isn't present. */
171
172 static const char *
173 parse_ulo16 (od, strp, opindex, valuep)
174 CGEN_OPCODE_DESC od;
175 const char **strp;
176 int opindex;
177 unsigned long *valuep;
178 {
179 const char *errmsg;
180 enum cgen_parse_operand_result result_type;
181 bfd_vma value;
182
183 if (**strp == '#')
184 ++*strp;
185
186 if (strncasecmp (*strp, "low(", 4) == 0)
187 {
188 *strp += 4;
189 errmsg = cgen_parse_address (od, strp, opindex, BFD_RELOC_M32R_LO16,
190 &result_type, &value);
191 if (**strp != ')')
192 return "missing `)'";
193 ++*strp;
194 if (errmsg == NULL
195 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
196 value &= 0xffff;
197 *valuep = value;
198 return errmsg;
199 }
200
201 return cgen_parse_unsigned_integer (od, strp, opindex, valuep);
202 }
203
204 /* -- */
205
206 /* Main entry point for operand parsing.
207
208 This function is basically just a big switch statement. Earlier versions
209 used tables to look up the function to use, but
210 - if the table contains both assembler and disassembler functions then
211 the disassembler contains much of the assembler and vice-versa,
212 - there's a lot of inlining possibilities as things grow,
213 - using a switch statement avoids the function call overhead.
214
215 This function could be moved into `parse_insn_normal', but keeping it
216 separate makes clear the interface between `parse_insn_normal' and each of
217 the handlers.
218 */
219
220 const char *
221 m32r_cgen_parse_operand (od, opindex, strp, fields)
222 CGEN_OPCODE_DESC od;
223 int opindex;
224 const char ** strp;
225 CGEN_FIELDS * fields;
226 {
227 const char * errmsg;
228
229 switch (opindex)
230 {
231 case M32R_OPERAND_SR :
232 errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_gr, & fields->f_r2);
233 break;
234 case M32R_OPERAND_DR :
235 errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_gr, & fields->f_r1);
236 break;
237 case M32R_OPERAND_SRC1 :
238 errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_gr, & fields->f_r1);
239 break;
240 case M32R_OPERAND_SRC2 :
241 errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_gr, & fields->f_r2);
242 break;
243 case M32R_OPERAND_SCR :
244 errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_cr, & fields->f_r2);
245 break;
246 case M32R_OPERAND_DCR :
247 errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_cr, & fields->f_r1);
248 break;
249 case M32R_OPERAND_SIMM8 :
250 errmsg = cgen_parse_signed_integer (od, strp, M32R_OPERAND_SIMM8, &fields->f_simm8);
251 break;
252 case M32R_OPERAND_SIMM16 :
253 errmsg = cgen_parse_signed_integer (od, strp, M32R_OPERAND_SIMM16, &fields->f_simm16);
254 break;
255 case M32R_OPERAND_UIMM4 :
256 errmsg = cgen_parse_unsigned_integer (od, strp, M32R_OPERAND_UIMM4, &fields->f_uimm4);
257 break;
258 case M32R_OPERAND_UIMM5 :
259 errmsg = cgen_parse_unsigned_integer (od, strp, M32R_OPERAND_UIMM5, &fields->f_uimm5);
260 break;
261 case M32R_OPERAND_UIMM16 :
262 errmsg = cgen_parse_unsigned_integer (od, strp, M32R_OPERAND_UIMM16, &fields->f_uimm16);
263 break;
264 /* start-sanitize-m32rx */
265 case M32R_OPERAND_IMM1 :
266 errmsg = cgen_parse_unsigned_integer (od, strp, M32R_OPERAND_IMM1, &fields->f_imm1);
267 break;
268 /* end-sanitize-m32rx */
269 /* start-sanitize-m32rx */
270 case M32R_OPERAND_ACCD :
271 errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_accums, & fields->f_accd);
272 break;
273 /* end-sanitize-m32rx */
274 /* start-sanitize-m32rx */
275 case M32R_OPERAND_ACCS :
276 errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_accums, & fields->f_accs);
277 break;
278 /* end-sanitize-m32rx */
279 /* start-sanitize-m32rx */
280 case M32R_OPERAND_ACC :
281 errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_accums, & fields->f_acc);
282 break;
283 /* end-sanitize-m32rx */
284 case M32R_OPERAND_HASH :
285 errmsg = parse_hash (od, strp, M32R_OPERAND_HASH, &fields->f_nil);
286 break;
287 case M32R_OPERAND_HI16 :
288 errmsg = parse_hi16 (od, strp, M32R_OPERAND_HI16, &fields->f_hi16);
289 break;
290 case M32R_OPERAND_SLO16 :
291 errmsg = parse_slo16 (od, strp, M32R_OPERAND_SLO16, &fields->f_simm16);
292 break;
293 case M32R_OPERAND_ULO16 :
294 errmsg = parse_ulo16 (od, strp, M32R_OPERAND_ULO16, &fields->f_uimm16);
295 break;
296 case M32R_OPERAND_UIMM24 :
297 {
298 bfd_vma value;
299 errmsg = cgen_parse_address (od, strp, M32R_OPERAND_UIMM24, 0, NULL, & value);
300 fields->f_uimm24 = value;
301 }
302 break;
303 case M32R_OPERAND_DISP8 :
304 {
305 bfd_vma value;
306 errmsg = cgen_parse_address (od, strp, M32R_OPERAND_DISP8, 0, NULL, & value);
307 fields->f_disp8 = value;
308 }
309 break;
310 case M32R_OPERAND_DISP16 :
311 {
312 bfd_vma value;
313 errmsg = cgen_parse_address (od, strp, M32R_OPERAND_DISP16, 0, NULL, & value);
314 fields->f_disp16 = value;
315 }
316 break;
317 case M32R_OPERAND_DISP24 :
318 {
319 bfd_vma value;
320 errmsg = cgen_parse_address (od, strp, M32R_OPERAND_DISP24, 0, NULL, & value);
321 fields->f_disp24 = value;
322 }
323 break;
324
325 default :
326 /* xgettext:c-format */
327 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
328 abort ();
329 }
330
331 return errmsg;
332 }
333
334 /* Main entry point for operand insertion.
335
336 This function is basically just a big switch statement. Earlier versions
337 used tables to look up the function to use, but
338 - if the table contains both assembler and disassembler functions then
339 the disassembler contains much of the assembler and vice-versa,
340 - there's a lot of inlining possibilities as things grow,
341 - using a switch statement avoids the function call overhead.
342
343 This function could be moved into `parse_insn_normal', but keeping it
344 separate makes clear the interface between `parse_insn_normal' and each of
345 the handlers. It's also needed by GAS to insert operands that couldn't be
346 resolved during parsing.
347 */
348
349 const char *
350 m32r_cgen_insert_operand (od, opindex, fields, buffer, pc)
351 CGEN_OPCODE_DESC od;
352 int opindex;
353 CGEN_FIELDS * fields;
354 CGEN_INSN_BYTES_PTR buffer;
355 bfd_vma pc;
356 {
357 const char * errmsg;
358
359 switch (opindex)
360 {
361 case M32R_OPERAND_SR :
362 errmsg = insert_normal (od, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
363 break;
364 case M32R_OPERAND_DR :
365 errmsg = insert_normal (od, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
366 break;
367 case M32R_OPERAND_SRC1 :
368 errmsg = insert_normal (od, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
369 break;
370 case M32R_OPERAND_SRC2 :
371 errmsg = insert_normal (od, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
372 break;
373 case M32R_OPERAND_SCR :
374 errmsg = insert_normal (od, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
375 break;
376 case M32R_OPERAND_DCR :
377 errmsg = insert_normal (od, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
378 break;
379 case M32R_OPERAND_SIMM8 :
380 errmsg = insert_normal (od, fields->f_simm8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
381 break;
382 case M32R_OPERAND_SIMM16 :
383 errmsg = insert_normal (od, fields->f_simm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
384 break;
385 case M32R_OPERAND_UIMM4 :
386 errmsg = insert_normal (od, fields->f_uimm4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
387 break;
388 case M32R_OPERAND_UIMM5 :
389 errmsg = insert_normal (od, fields->f_uimm5, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 11, 5, CGEN_FIELDS_BITSIZE (fields), buffer);
390 break;
391 case M32R_OPERAND_UIMM16 :
392 errmsg = insert_normal (od, fields->f_uimm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
393 break;
394 /* start-sanitize-m32rx */
395 case M32R_OPERAND_IMM1 :
396 {
397 long value = fields->f_imm1;
398 value = ((value) - (1));
399 errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 15, 1, CGEN_FIELDS_BITSIZE (fields), buffer);
400 }
401 break;
402 /* end-sanitize-m32rx */
403 /* start-sanitize-m32rx */
404 case M32R_OPERAND_ACCD :
405 errmsg = insert_normal (od, fields->f_accd, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 2, CGEN_FIELDS_BITSIZE (fields), buffer);
406 break;
407 /* end-sanitize-m32rx */
408 /* start-sanitize-m32rx */
409 case M32R_OPERAND_ACCS :
410 errmsg = insert_normal (od, fields->f_accs, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 2, CGEN_FIELDS_BITSIZE (fields), buffer);
411 break;
412 /* end-sanitize-m32rx */
413 /* start-sanitize-m32rx */
414 case M32R_OPERAND_ACC :
415 errmsg = insert_normal (od, fields->f_acc, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 1, CGEN_FIELDS_BITSIZE (fields), buffer);
416 break;
417 /* end-sanitize-m32rx */
418 case M32R_OPERAND_HASH :
419 errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
420 break;
421 case M32R_OPERAND_HI16 :
422 errmsg = insert_normal (od, fields->f_hi16, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
423 break;
424 case M32R_OPERAND_SLO16 :
425 errmsg = insert_normal (od, fields->f_simm16, 0, 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
426 break;
427 case M32R_OPERAND_ULO16 :
428 errmsg = insert_normal (od, fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
429 break;
430 case M32R_OPERAND_UIMM24 :
431 errmsg = insert_normal (od, fields->f_uimm24, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), 8, 24, CGEN_FIELDS_BITSIZE (fields), buffer);
432 break;
433 case M32R_OPERAND_DISP8 :
434 {
435 long value = fields->f_disp8;
436 value = ((int) (((value) - (((pc) & (-4))))) >> (2));
437 errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
438 }
439 break;
440 case M32R_OPERAND_DISP16 :
441 {
442 long value = fields->f_disp16;
443 value = ((int) (((value) - (pc))) >> (2));
444 errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
445 }
446 break;
447 case M32R_OPERAND_DISP24 :
448 {
449 long value = fields->f_disp24;
450 value = ((int) (((value) - (pc))) >> (2));
451 errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 24, CGEN_FIELDS_BITSIZE (fields), buffer);
452 }
453 break;
454
455 default :
456 /* xgettext:c-format */
457 fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
458 opindex);
459 abort ();
460 }
461
462 return errmsg;
463 }
464
465 cgen_parse_fn * const m32r_cgen_parse_handlers[] =
466 {
467 0, /* default */
468 parse_insn_normal,
469 };
470
471 cgen_insert_fn * const m32r_cgen_insert_handlers[] =
472 {
473 0, /* default */
474 insert_insn_normal,
475 };
476
477 void
478 m32r_cgen_init_asm (od)
479 CGEN_OPCODE_DESC od;
480 {
481 }
482
483 \f
484 #if ! CGEN_INT_INSN_P
485
486 /* Subroutine of insert_normal. */
487
488 static INLINE void
489 insert_1 (od, value, start, length, word_length, bufp)
490 CGEN_OPCODE_DESC od;
491 unsigned long value;
492 int start,length,word_length;
493 unsigned char *bufp;
494 {
495 unsigned long x,mask;
496 int shift;
497 int big_p = CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG;
498
499 switch (word_length)
500 {
501 case 8:
502 x = *bufp;
503 break;
504 case 16:
505 if (big_p)
506 x = bfd_getb16 (bufp);
507 else
508 x = bfd_getl16 (bufp);
509 break;
510 case 24:
511 /* ??? This may need reworking as these cases don't necessarily
512 want the first byte and the last two bytes handled like this. */
513 if (big_p)
514 x = (bfd_getb8 (bufp) << 16) | bfd_getb16 (bufp + 1);
515 else
516 x = bfd_getl16 (bufp) | (bfd_getb8 (bufp + 2) << 16);
517 break;
518 case 32:
519 if (big_p)
520 x = bfd_getb32 (bufp);
521 else
522 x = bfd_getl32 (bufp);
523 break;
524 default :
525 abort ();
526 }
527
528 /* Written this way to avoid undefined behaviour. */
529 mask = (((1L << (length - 1)) - 1) << 1) | 1;
530 if (CGEN_INSN_LSB0_P)
531 shift = start;
532 else
533 shift = (word_length - (start + length));
534 x = (x & ~(mask << shift)) | ((value & mask) << shift);
535
536 switch (word_length)
537 {
538 case 8:
539 *bufp = x;
540 break;
541 case 16:
542 if (big_p)
543 bfd_putb16 (x, bufp);
544 else
545 bfd_putl16 (x, bufp);
546 break;
547 case 24:
548 /* ??? This may need reworking as these cases don't necessarily
549 want the first byte and the last two bytes handled like this. */
550 if (big_p)
551 {
552 bfd_putb8 (x >> 16, bufp);
553 bfd_putb16 (x, bufp + 1);
554 }
555 else
556 {
557 bfd_putl16 (x, bufp);
558 bfd_putb8 (x >> 16, bufp + 2);
559 }
560 break;
561 case 32:
562 if (big_p)
563 bfd_putb32 (x, bufp);
564 else
565 bfd_putl32 (x, bufp);
566 break;
567 default :
568 abort ();
569 }
570 }
571
572 #endif /* ! CGEN_INT_INSN_P */
573
574 /* Default insertion routine.
575
576 ATTRS is a mask of the boolean attributes.
577 START is the starting bit number, architecture origin.
578 LENGTH is the length of VALUE in bits.
579 TOTAL_LENGTH is the total length of the insn.
580
581 The result is an error message or NULL if success. */
582
583 /* ??? May need to know word length in order to properly place values as
584 an insn may be made of multiple words and the current bit number handling
585 may be insufficient. Word length is an architectural attribute and thus
586 methinks the way to go [if needed] is to fetch this value from OD or
587 define a macro in <arch>-opc.h rather than adding an extra argument -
588 after all that's how endianness is handled. */
589 /* ??? This duplicates functionality with bfd's howto table and
590 bfd_install_relocation. */
591 /* ??? For architectures where insns can be representable as ints,
592 store insn in `field' struct and add registers, etc. while parsing? */
593 /* ??? This doesn't handle bfd_vma's. Create another function when
594 necessary. */
595
596 static const char *
597 insert_normal (od, value, attrs, start, length, total_length, buffer)
598 CGEN_OPCODE_DESC od;
599 long value;
600 unsigned int attrs;
601 int start;
602 int length;
603 int total_length;
604 CGEN_INSN_BYTES_PTR buffer;
605 {
606 static char errbuf[100];
607 /* Written this way to avoid undefined behaviour. */
608 unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
609
610 /* If LENGTH is zero, this operand doesn't contribute to the value. */
611 if (length == 0)
612 return NULL;
613
614 /* Ensure VALUE will fit. */
615 if ((attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED)) != 0)
616 {
617 unsigned long maxval = mask;
618 if ((unsigned long) value > maxval)
619 {
620 /* xgettext:c-format */
621 sprintf (errbuf,
622 _("operand out of range (%lu not between 0 and %lu)"),
623 value, maxval);
624 return errbuf;
625 }
626 }
627 else
628 {
629 long minval = - (1L << (length - 1));
630 long maxval = (1L << (length - 1)) - 1;
631 if (value < minval || value > maxval)
632 {
633 sprintf
634 /* xgettext:c-format */
635 (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
636 value, minval, maxval);
637 return errbuf;
638 }
639 }
640
641 #if CGEN_INT_INSN_P
642
643 if (total_length > 32)
644 abort ();
645 {
646 int shift;
647
648 if (CGEN_INSN_LSB0_P)
649 shift = start;
650 else
651 shift = total_length - (start + length);
652 *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
653 }
654
655 #else
656
657 /* FIXME: unfinished and untested */
658
659 /* ??? To be defined in <arch>-opc.h as necessary. */
660 #ifndef CGEN_WORD_ENDIAN
661 #define CGEN_WORD_ENDIAN(od) CGEN_OPCODE_ENDIAN (od)
662 #endif
663 #ifndef CGEN_INSN_WORD_ENDIAN
664 #define CGEN_INSN_WORD_ENDIAN(od) CGEN_WORD_ENDIAN (od)
665 #endif
666
667 /* The hard case is probably too slow for the normal cases.
668 It's certainly more difficult to understand than the normal case.
669 Thus this is split into two. Keep it that way. The hard case is defined
670 to be when a field straddles a (loosely defined) word boundary
671 (??? which may require target specific help to determine). */
672
673 #if 0 /*wip*/
674
675 #define HARD_CASE_P 0 /* FIXME:wip */
676
677 if (HARD_CASE_P)
678 {
679 unsigned char *bufp = (unsigned char *) buffer;
680 int insn_length_left = total_length;
681
682 if (CGEN_INSN_LSB0_P)
683 {
684 int word_offset = (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG
685 ? ...
686 : start / CGEN_BASE_INSN_BITSIZE);
687 bufp += word_offset * (CGEN_BASE_INSN_BITSIZE / 8);
688 if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
689 else
690 start -= word_offset * CGEN_BASE_INSN_BITSIZE;
691 }
692 else
693 {
694 int word_offset = (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG
695 ? start / CGEN_BASE_INSN_BITSIZE
696 : ...);
697 bufp += word_offset * (CGEN_BASE_INSN_BITSIZE / 8);
698 if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
699 start -= word_offset * CGEN_BASE_INSN_BITSIZE;
700 else
701 }
702
703 /* Loop so we handle a field straddling an insn word boundary
704 (remember, "insn word boundary" is loosely defined here). */
705
706 while (length > 0)
707 {
708 int this_pass_length = length;
709 int this_pass_start = start;
710 int this_pass_word_length = min (insn_length_left,
711 (CGEN_BASE_INSN_BITSIZE == 8
712 ? 32
713 : CGEN_BASE_INSN_BITSIZE));
714
715 insert_1 (od, value, attrs,
716 this_pass_start, this_pass_length, this_pass_word_length,
717 bufp);
718
719 length -= this_pass_length;
720 insn_length_left -= this_pass_word_length;
721 if (???)
722 {
723 value >>= ???;
724 start += ???;
725 }
726 else
727 {
728 value >>= ???;
729 start += ???;
730 }
731 bufp += this_pass_word_length / 8;
732 }
733 }
734 else
735 #endif /* 0 */
736 {
737 unsigned char *bufp = (unsigned char *) buffer;
738
739 if (length > 32)
740 abort ();
741
742 /* Adjust start,total_length,bufp to point to the pseudo-word that holds
743 the value. For example in a 48 bit insn where the value to insert
744 (say an immediate value) is the last 16 bits then word_length here
745 would be 16. To handle a 24 bit insn with an 18 bit immediate,
746 insert_1 handles 24 bits (using a combination of bfd_get8,16). */
747
748 if (total_length > 32)
749 {
750 int needed_width = start % 8 + length;
751 int fetch_length = (needed_width <= 8 ? 8
752 : needed_width <= 16 ? 16
753 : 32);
754
755 if (CGEN_INSN_LSB0_P)
756 {
757 if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
758 {
759 abort (); /* wip */
760 }
761 else
762 {
763 int offset = start & ~7;
764
765 bufp += offset / 8;
766 start -= offset;
767 total_length -= offset;
768 }
769 }
770 else
771 {
772 if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
773 {
774 int offset = start & ~7;
775
776 bufp += offset / 8;
777 start -= offset;
778 total_length -= offset;
779 }
780 else
781 {
782 abort (); /* wip */
783 }
784 }
785 }
786
787 insert_1 (od, value, start, length, total_length, bufp);
788 }
789
790 #endif /* ! CGEN_INT_INSN_P */
791
792 return NULL;
793 }
794 \f
795 /* Default insn parser.
796
797 The syntax string is scanned and operands are parsed and stored in FIELDS.
798 Relocs are queued as we go via other callbacks.
799
800 ??? Note that this is currently an all-or-nothing parser. If we fail to
801 parse the instruction, we return 0 and the caller will start over from
802 the beginning. Backtracking will be necessary in parsing subexpressions,
803 but that can be handled there. Not handling backtracking here may get
804 expensive in the case of the m68k. Deal with later.
805
806 Returns NULL for success, an error message for failure.
807 */
808
809 static const char *
810 parse_insn_normal (od, insn, strp, fields)
811 CGEN_OPCODE_DESC od;
812 const CGEN_INSN * insn;
813 const char ** strp;
814 CGEN_FIELDS * fields;
815 {
816 const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
817 const char * str = *strp;
818 const char * errmsg;
819 const char * p;
820 const unsigned char * syn;
821 #ifdef CGEN_MNEMONIC_OPERANDS
822 /* FIXME: wip */
823 int past_opcode_p;
824 #endif
825
826 /* For now we assume the mnemonic is first (there are no leading operands).
827 We can parse it without needing to set up operand parsing.
828 GAS's input scrubber will ensure mnemonics are lowercase, but we may
829 not be called from GAS. */
830 p = CGEN_INSN_MNEMONIC (insn);
831 while (*p && tolower (*p) == tolower (*str))
832 ++p, ++str;
833
834 if (* p || (* str && !isspace (* str)))
835 return _("unrecognized instruction");
836
837 CGEN_INIT_PARSE (od);
838 cgen_init_parse_operand (od);
839 #ifdef CGEN_MNEMONIC_OPERANDS
840 past_opcode_p = 0;
841 #endif
842
843 /* We don't check for (*str != '\0') here because we want to parse
844 any trailing fake arguments in the syntax string. */
845 syn = CGEN_SYNTAX_STRING (syntax);
846
847 /* Mnemonics come first for now, ensure valid string. */
848 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
849 abort ();
850
851 ++syn;
852
853 while (* syn != 0)
854 {
855 /* Non operand chars must match exactly. */
856 if (CGEN_SYNTAX_CHAR_P (* syn))
857 {
858 if (*str == CGEN_SYNTAX_CHAR (* syn))
859 {
860 #ifdef CGEN_MNEMONIC_OPERANDS
861 if (* syn == ' ')
862 past_opcode_p = 1;
863 #endif
864 ++ syn;
865 ++ str;
866 }
867 else
868 {
869 /* Syntax char didn't match. Can't be this insn. */
870 /* FIXME: would like to return something like
871 "expected char `c'" */
872 return _("syntax error");
873 }
874 continue;
875 }
876
877 /* We have an operand of some sort. */
878 errmsg = m32r_cgen_parse_operand (od, CGEN_SYNTAX_FIELD (*syn),
879 &str, fields);
880 if (errmsg)
881 return errmsg;
882
883 /* Done with this operand, continue with next one. */
884 ++ syn;
885 }
886
887 /* If we're at the end of the syntax string, we're done. */
888 if (* syn == '\0')
889 {
890 /* FIXME: For the moment we assume a valid `str' can only contain
891 blanks now. IE: We needn't try again with a longer version of
892 the insn and it is assumed that longer versions of insns appear
893 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
894 while (isspace (* str))
895 ++ str;
896
897 if (* str != '\0')
898 return _("junk at end of line"); /* FIXME: would like to include `str' */
899
900 return NULL;
901 }
902
903 /* We couldn't parse it. */
904 return _("unrecognized instruction");
905 }
906
907 /* Default insn builder (insert handler).
908 The instruction is recorded in CGEN_INT_INSN_P byte order
909 (meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
910 recorded in host byte order, otherwise BUFFER is an array of bytes and the
911 value is recorded in target byte order).
912 The result is an error message or NULL if success. */
913
914 static const char *
915 insert_insn_normal (od, insn, fields, buffer, pc)
916 CGEN_OPCODE_DESC od;
917 const CGEN_INSN * insn;
918 CGEN_FIELDS * fields;
919 CGEN_INSN_BYTES_PTR buffer;
920 bfd_vma pc;
921 {
922 const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
923 unsigned long value;
924 const unsigned char * syn;
925
926 CGEN_INIT_INSERT (od);
927 value = CGEN_INSN_VALUE (insn);
928
929 /* If we're recording insns as numbers (rather than a string of bytes),
930 target byte order handling is deferred until later. */
931
932 #if CGEN_INT_INSN_P
933
934 *buffer = value;
935
936 #else
937
938 cgen_insn_put_value (od, buffer, min (CGEN_BASE_INSN_BITSIZE,
939 CGEN_FIELDS_BITSIZE (fields)),
940 value);
941
942 #endif /* ! CGEN_INT_INSN_P */
943
944 /* ??? Rather than scanning the syntax string again, we could store
945 in `fields' a null terminated list of the fields that are present. */
946
947 for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
948 {
949 const char *errmsg;
950
951 if (CGEN_SYNTAX_CHAR_P (* syn))
952 continue;
953
954 errmsg = m32r_cgen_insert_operand (od, CGEN_SYNTAX_FIELD (*syn),
955 fields, buffer, pc);
956 if (errmsg)
957 return errmsg;
958 }
959
960 return NULL;
961 }
962 \f
963 /* Main entry point.
964 This routine is called for each instruction to be assembled.
965 STR points to the insn to be assembled.
966 We assume all necessary tables have been initialized.
967 The assembled instruction, less any fixups, is stored in BUF.
968 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
969 still needs to be converted to target byte order, otherwise BUF is an array
970 of bytes in target byte order.
971 The result is a pointer to the insn's entry in the opcode table,
972 or NULL if an error occured (an error message will have already been
973 printed).
974
975 Note that when processing (non-alias) macro-insns,
976 this function recurses. */
977
978 const CGEN_INSN *
979 m32r_cgen_assemble_insn (od, str, fields, buf, errmsg)
980 CGEN_OPCODE_DESC od;
981 const char * str;
982 CGEN_FIELDS * fields;
983 CGEN_INSN_BYTES_PTR buf;
984 char ** errmsg;
985 {
986 const char * start;
987 CGEN_INSN_LIST * ilist;
988
989 /* Skip leading white space. */
990 while (isspace (* str))
991 ++ str;
992
993 /* The instructions are stored in hashed lists.
994 Get the first in the list. */
995 ilist = CGEN_ASM_LOOKUP_INSN (od, str);
996
997 /* Keep looking until we find a match. */
998
999 start = str;
1000 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
1001 {
1002 const CGEN_INSN *insn = ilist->insn;
1003
1004 #if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */
1005 /* Is this insn supported by the selected cpu? */
1006 if (! m32r_cgen_insn_supported (od, insn))
1007 continue;
1008 #endif
1009
1010 /* If the RELAX attribute is set, this is an insn that shouldn't be
1011 chosen immediately. Instead, it is used during assembler/linker
1012 relaxation if possible. */
1013 if (CGEN_INSN_ATTR (insn, CGEN_INSN_RELAX) != 0)
1014 continue;
1015
1016 str = start;
1017
1018 /* Record a default length for the insn. This will get set to the
1019 correct value while parsing. */
1020 /* FIXME: wip */
1021 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
1022
1023 if (! CGEN_PARSE_FN (insn) (od, insn, & str, fields))
1024 {
1025 /* ??? 0 is passed for `pc' */
1026 if (CGEN_INSERT_FN (insn) (od, insn, fields, buf, (bfd_vma) 0) != NULL)
1027 continue;
1028 /* It is up to the caller to actually output the insn and any
1029 queued relocs. */
1030 return insn;
1031 }
1032
1033 /* Try the next entry. */
1034 }
1035
1036 /* FIXME: We can return a better error message than this.
1037 Need to track why it failed and pick the right one. */
1038 {
1039 static char errbuf[100];
1040 if (strlen (start) > 50)
1041 /* xgettext:c-format */
1042 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1043 else
1044 /* xgettext:c-format */
1045 sprintf (errbuf, _("bad instruction `%.50s'"), start);
1046
1047 *errmsg = errbuf;
1048 return NULL;
1049 }
1050 }
1051 \f
1052 #if 0 /* This calls back to GAS which we can't do without care. */
1053
1054 /* Record each member of OPVALS in the assembler's symbol table.
1055 This lets GAS parse registers for us.
1056 ??? Interesting idea but not currently used. */
1057
1058 /* Record each member of OPVALS in the assembler's symbol table.
1059 FIXME: Not currently used. */
1060
1061 void
1062 m32r_cgen_asm_hash_keywords (od, opvals)
1063 CGEN_OPCODE_DESC od;
1064 CGEN_KEYWORD * opvals;
1065 {
1066 CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
1067 const CGEN_KEYWORD_ENTRY * ke;
1068
1069 while ((ke = cgen_keyword_search_next (& search)) != NULL)
1070 {
1071 #if 0 /* Unnecessary, should be done in the search routine. */
1072 if (! m32r_cgen_opval_supported (ke))
1073 continue;
1074 #endif
1075 cgen_asm_record_register (od, ke->name, ke->value);
1076 }
1077 }
1078
1079 #endif /* 0 */
This page took 0.105535 seconds and 5 git commands to generate.