1 /* Assembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
4 THIS FILE IS USED TO GENERATE m32r-asm.c.
6 Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
8 This file is part of the GNU Binutils and GDB, the GNU debugger.
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)
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.
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. */
34 #define min(a,b) ((a) < (b) ? (a) : (b))
36 #define max(a,b) ((a) > (b) ? (a) : (b))
40 #define INLINE __inline__
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
));
55 /* -- assembler routines inserted here */
58 /* Handle '#' prefixes (i.e. skip over them). */
61 parse_hash (od
, strp
, opindex
, valuep
)
65 unsigned long *valuep
;
72 /* Handle shigh(), high(). */
75 parse_hi16 (od
, strp
, opindex
, valuep
)
79 unsigned long *valuep
;
82 enum cgen_parse_operand_result result_type
;
88 if (strncasecmp (*strp
, "high(", 5) == 0)
91 errmsg
= cgen_parse_address (od
, strp
, opindex
, BFD_RELOC_M32R_HI16_ULO
,
92 &result_type
, &value
);
97 && result_type
== CGEN_PARSE_OPERAND_RESULT_NUMBER
)
102 else if (strncasecmp (*strp
, "shigh(", 6) == 0)
105 errmsg
= cgen_parse_address (od
, strp
, opindex
, BFD_RELOC_M32R_HI16_SLO
,
106 &result_type
, &value
);
108 return "missing `)'";
111 && result_type
== CGEN_PARSE_OPERAND_RESULT_NUMBER
)
112 value
= (value
>> 16) + (value
& 0x8000 ? 1 : 0);
117 return cgen_parse_unsigned_integer (od
, strp
, opindex
, valuep
);
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. */
125 parse_slo16 (od
, strp
, opindex
, valuep
)
132 enum cgen_parse_operand_result result_type
;
138 if (strncasecmp (*strp
, "low(", 4) == 0)
141 errmsg
= cgen_parse_address (od
, strp
, opindex
, BFD_RELOC_M32R_LO16
,
142 &result_type
, &value
);
144 return "missing `)'";
147 && result_type
== CGEN_PARSE_OPERAND_RESULT_NUMBER
)
153 if (strncasecmp (*strp
, "sda(", 4) == 0)
156 errmsg
= cgen_parse_address (od
, strp
, opindex
, BFD_RELOC_M32R_SDA16
,
159 return "missing `)'";
165 return cgen_parse_signed_integer (od
, strp
, opindex
, valuep
);
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. */
173 parse_ulo16 (od
, strp
, opindex
, valuep
)
177 unsigned long *valuep
;
180 enum cgen_parse_operand_result result_type
;
186 if (strncasecmp (*strp
, "low(", 4) == 0)
189 errmsg
= cgen_parse_address (od
, strp
, opindex
, BFD_RELOC_M32R_LO16
,
190 &result_type
, &value
);
192 return "missing `)'";
195 && result_type
== CGEN_PARSE_OPERAND_RESULT_NUMBER
)
201 return cgen_parse_unsigned_integer (od
, strp
, opindex
, valuep
);
206 /* Main entry point for operand parsing.
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.
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
221 m32r_cgen_parse_operand (od
, opindex
, strp
, fields
)
225 CGEN_FIELDS
* fields
;
231 case M32R_OPERAND_SR
:
232 errmsg
= cgen_parse_keyword (od
, strp
, & m32r_cgen_opval_h_gr
, & fields
->f_r2
);
234 case M32R_OPERAND_DR
:
235 errmsg
= cgen_parse_keyword (od
, strp
, & m32r_cgen_opval_h_gr
, & fields
->f_r1
);
237 case M32R_OPERAND_SRC1
:
238 errmsg
= cgen_parse_keyword (od
, strp
, & m32r_cgen_opval_h_gr
, & fields
->f_r1
);
240 case M32R_OPERAND_SRC2
:
241 errmsg
= cgen_parse_keyword (od
, strp
, & m32r_cgen_opval_h_gr
, & fields
->f_r2
);
243 case M32R_OPERAND_SCR
:
244 errmsg
= cgen_parse_keyword (od
, strp
, & m32r_cgen_opval_h_cr
, & fields
->f_r2
);
246 case M32R_OPERAND_DCR
:
247 errmsg
= cgen_parse_keyword (od
, strp
, & m32r_cgen_opval_h_cr
, & fields
->f_r1
);
249 case M32R_OPERAND_SIMM8
:
250 errmsg
= cgen_parse_signed_integer (od
, strp
, M32R_OPERAND_SIMM8
, &fields
->f_simm8
);
252 case M32R_OPERAND_SIMM16
:
253 errmsg
= cgen_parse_signed_integer (od
, strp
, M32R_OPERAND_SIMM16
, &fields
->f_simm16
);
255 case M32R_OPERAND_UIMM4
:
256 errmsg
= cgen_parse_unsigned_integer (od
, strp
, M32R_OPERAND_UIMM4
, &fields
->f_uimm4
);
258 case M32R_OPERAND_UIMM5
:
259 errmsg
= cgen_parse_unsigned_integer (od
, strp
, M32R_OPERAND_UIMM5
, &fields
->f_uimm5
);
261 case M32R_OPERAND_UIMM16
:
262 errmsg
= cgen_parse_unsigned_integer (od
, strp
, M32R_OPERAND_UIMM16
, &fields
->f_uimm16
);
264 /* start-sanitize-m32rx */
265 case M32R_OPERAND_IMM1
:
266 errmsg
= cgen_parse_unsigned_integer (od
, strp
, M32R_OPERAND_IMM1
, &fields
->f_imm1
);
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
);
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
);
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
);
283 /* end-sanitize-m32rx */
284 case M32R_OPERAND_HASH
:
285 errmsg
= parse_hash (od
, strp
, M32R_OPERAND_HASH
, &fields
->f_nil
);
287 case M32R_OPERAND_HI16
:
288 errmsg
= parse_hi16 (od
, strp
, M32R_OPERAND_HI16
, &fields
->f_hi16
);
290 case M32R_OPERAND_SLO16
:
291 errmsg
= parse_slo16 (od
, strp
, M32R_OPERAND_SLO16
, &fields
->f_simm16
);
293 case M32R_OPERAND_ULO16
:
294 errmsg
= parse_ulo16 (od
, strp
, M32R_OPERAND_ULO16
, &fields
->f_uimm16
);
296 case M32R_OPERAND_UIMM24
:
299 errmsg
= cgen_parse_address (od
, strp
, M32R_OPERAND_UIMM24
, 0, NULL
, & value
);
300 fields
->f_uimm24
= value
;
303 case M32R_OPERAND_DISP8
:
306 errmsg
= cgen_parse_address (od
, strp
, M32R_OPERAND_DISP8
, 0, NULL
, & value
);
307 fields
->f_disp8
= value
;
310 case M32R_OPERAND_DISP16
:
313 errmsg
= cgen_parse_address (od
, strp
, M32R_OPERAND_DISP16
, 0, NULL
, & value
);
314 fields
->f_disp16
= value
;
317 case M32R_OPERAND_DISP24
:
320 errmsg
= cgen_parse_address (od
, strp
, M32R_OPERAND_DISP24
, 0, NULL
, & value
);
321 fields
->f_disp24
= value
;
326 /* xgettext:c-format */
327 fprintf (stderr
, _("Unrecognized field %d while parsing.\n"), opindex
);
334 /* Main entry point for operand insertion.
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.
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.
350 m32r_cgen_insert_operand (od
, opindex
, fields
, buffer
, pc
)
353 CGEN_FIELDS
* fields
;
354 CGEN_INSN_BYTES_PTR buffer
;
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
394 /* start-sanitize-m32rx */
395 case M32R_OPERAND_IMM1
:
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
);
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
);
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
);
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
);
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
);
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
);
424 case M32R_OPERAND_SLO16
:
425 errmsg
= insert_normal (od
, fields
->f_simm16
, 0, 16, 16, CGEN_FIELDS_BITSIZE (fields
), buffer
);
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
);
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
);
433 case M32R_OPERAND_DISP8
:
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
);
440 case M32R_OPERAND_DISP16
:
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
);
447 case M32R_OPERAND_DISP24
:
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
);
456 /* xgettext:c-format */
457 fprintf (stderr
, _("Unrecognized field %d while building insn.\n"),
465 cgen_parse_fn
* const m32r_cgen_parse_handlers
[] =
471 cgen_insert_fn
* const m32r_cgen_insert_handlers
[] =
478 m32r_cgen_init_asm (od
)
484 #if ! CGEN_INT_INSN_P
486 /* Subroutine of insert_normal. */
489 insert_1 (od
, value
, start
, length
, word_length
, bufp
)
492 int start
,length
,word_length
;
495 unsigned long x
,mask
;
497 int big_p
= CGEN_OPCODE_INSN_ENDIAN (od
) == CGEN_ENDIAN_BIG
;
506 x
= bfd_getb16 (bufp
);
508 x
= bfd_getl16 (bufp
);
511 /* ??? This may need reworking as these cases don't necessarily
512 want the first byte and the last two bytes handled like this. */
514 x
= (bfd_getb8 (bufp
) << 16) | bfd_getb16 (bufp
+ 1);
516 x
= bfd_getl16 (bufp
) | (bfd_getb8 (bufp
+ 2) << 16);
520 x
= bfd_getb32 (bufp
);
522 x
= bfd_getl32 (bufp
);
528 /* Written this way to avoid undefined behaviour. */
529 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
530 if (CGEN_INSN_LSB0_P
)
533 shift
= (word_length
- (start
+ length
));
534 x
= (x
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
543 bfd_putb16 (x
, bufp
);
545 bfd_putl16 (x
, bufp
);
548 /* ??? This may need reworking as these cases don't necessarily
549 want the first byte and the last two bytes handled like this. */
552 bfd_putb8 (x
>> 16, bufp
);
553 bfd_putb16 (x
, bufp
+ 1);
557 bfd_putl16 (x
, bufp
);
558 bfd_putb8 (x
>> 16, bufp
+ 2);
563 bfd_putb32 (x
, bufp
);
565 bfd_putl32 (x
, bufp
);
572 #endif /* ! CGEN_INT_INSN_P */
574 /* Default insertion routine.
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.
581 The result is an error message or NULL if success. */
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
597 insert_normal (od
, value
, attrs
, start
, length
, total_length
, buffer
)
604 CGEN_INSN_BYTES_PTR buffer
;
606 static char errbuf
[100];
607 /* Written this way to avoid undefined behaviour. */
608 unsigned long mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
610 /* If LENGTH is zero, this operand doesn't contribute to the value. */
614 /* Ensure VALUE will fit. */
615 if ((attrs
& CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED
)) != 0)
617 unsigned long maxval
= mask
;
618 if ((unsigned long) value
> maxval
)
620 /* xgettext:c-format */
622 _("operand out of range (%lu not between 0 and %lu)"),
629 long minval
= - (1L << (length
- 1));
630 long maxval
= (1L << (length
- 1)) - 1;
631 if (value
< minval
|| value
> maxval
)
634 /* xgettext:c-format */
635 (errbuf
, _("operand out of range (%ld not between %ld and %ld)"),
636 value
, minval
, maxval
);
643 if (total_length
> 32)
648 if (CGEN_INSN_LSB0_P
)
651 shift
= total_length
- (start
+ length
);
652 *buffer
= (*buffer
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
657 /* FIXME: unfinished and untested */
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)
663 #ifndef CGEN_INSN_WORD_ENDIAN
664 #define CGEN_INSN_WORD_ENDIAN(od) CGEN_WORD_ENDIAN (od)
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). */
675 #define HARD_CASE_P 0 /* FIXME:wip */
679 unsigned char *bufp
= (unsigned char *) buffer
;
680 int insn_length_left
= total_length
;
682 if (CGEN_INSN_LSB0_P
)
684 int word_offset
= (CGEN_INSN_WORD_ENDIAN (od
) == CGEN_ENDIAN_BIG
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
)
690 start
-= word_offset
* CGEN_BASE_INSN_BITSIZE
;
694 int word_offset
= (CGEN_INSN_WORD_ENDIAN (od
) == CGEN_ENDIAN_BIG
695 ? start
/ CGEN_BASE_INSN_BITSIZE
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
;
703 /* Loop so we handle a field straddling an insn word boundary
704 (remember, "insn word boundary" is loosely defined here). */
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
713 : CGEN_BASE_INSN_BITSIZE
));
715 insert_1 (od
, value
, attrs
,
716 this_pass_start
, this_pass_length
, this_pass_word_length
,
719 length
-= this_pass_length
;
720 insn_length_left
-= this_pass_word_length
;
731 bufp
+= this_pass_word_length
/ 8;
737 unsigned char *bufp
= (unsigned char *) buffer
;
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). */
748 if (total_length
> 32)
750 int needed_width
= start
% 8 + length
;
751 int fetch_length
= (needed_width
<= 8 ? 8
752 : needed_width
<= 16 ? 16
755 if (CGEN_INSN_LSB0_P
)
757 if (CGEN_INSN_WORD_ENDIAN (od
) == CGEN_ENDIAN_BIG
)
763 int offset
= start
& ~7;
767 total_length
-= offset
;
772 if (CGEN_INSN_WORD_ENDIAN (od
) == CGEN_ENDIAN_BIG
)
774 int offset
= start
& ~7;
778 total_length
-= offset
;
787 insert_1 (od
, value
, start
, length
, total_length
, bufp
);
790 #endif /* ! CGEN_INT_INSN_P */
795 /* Default insn parser.
797 The syntax string is scanned and operands are parsed and stored in FIELDS.
798 Relocs are queued as we go via other callbacks.
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.
806 Returns NULL for success, an error message for failure.
810 parse_insn_normal (od
, insn
, strp
, fields
)
812 const CGEN_INSN
* insn
;
814 CGEN_FIELDS
* fields
;
816 const CGEN_SYNTAX
* syntax
= CGEN_INSN_SYNTAX (insn
);
817 const char * str
= *strp
;
820 const unsigned char * syn
;
821 #ifdef CGEN_MNEMONIC_OPERANDS
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
))
834 if (* p
|| (* str
&& !isspace (* str
)))
835 return _("unrecognized instruction");
837 CGEN_INIT_PARSE (od
);
838 cgen_init_parse_operand (od
);
839 #ifdef CGEN_MNEMONIC_OPERANDS
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
);
847 /* Mnemonics come first for now, ensure valid string. */
848 if (! CGEN_SYNTAX_MNEMONIC_P (* syn
))
855 /* Non operand chars must match exactly. */
856 if (CGEN_SYNTAX_CHAR_P (* syn
))
858 if (*str
== CGEN_SYNTAX_CHAR (* syn
))
860 #ifdef CGEN_MNEMONIC_OPERANDS
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");
877 /* We have an operand of some sort. */
878 errmsg
= m32r_cgen_parse_operand (od
, CGEN_SYNTAX_FIELD (*syn
),
883 /* Done with this operand, continue with next one. */
887 /* If we're at the end of the syntax string, we're done. */
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
))
898 return _("junk at end of line"); /* FIXME: would like to include `str' */
903 /* We couldn't parse it. */
904 return _("unrecognized instruction");
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. */
915 insert_insn_normal (od
, insn
, fields
, buffer
, pc
)
917 const CGEN_INSN
* insn
;
918 CGEN_FIELDS
* fields
;
919 CGEN_INSN_BYTES_PTR buffer
;
922 const CGEN_SYNTAX
* syntax
= CGEN_INSN_SYNTAX (insn
);
924 const unsigned char * syn
;
926 CGEN_INIT_INSERT (od
);
927 value
= CGEN_INSN_VALUE (insn
);
929 /* If we're recording insns as numbers (rather than a string of bytes),
930 target byte order handling is deferred until later. */
938 cgen_insn_put_value (od
, buffer
, min (CGEN_BASE_INSN_BITSIZE
,
939 CGEN_FIELDS_BITSIZE (fields
)),
942 #endif /* ! CGEN_INT_INSN_P */
944 /* ??? Rather than scanning the syntax string again, we could store
945 in `fields' a null terminated list of the fields that are present. */
947 for (syn
= CGEN_SYNTAX_STRING (syntax
); * syn
!= '\0'; ++ syn
)
951 if (CGEN_SYNTAX_CHAR_P (* syn
))
954 errmsg
= m32r_cgen_insert_operand (od
, CGEN_SYNTAX_FIELD (*syn
),
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
975 Note that when processing (non-alias) macro-insns,
976 this function recurses. */
979 m32r_cgen_assemble_insn (od
, str
, fields
, buf
, errmsg
)
982 CGEN_FIELDS
* fields
;
983 CGEN_INSN_BYTES_PTR buf
;
987 CGEN_INSN_LIST
* ilist
;
989 /* Skip leading white space. */
990 while (isspace (* str
))
993 /* The instructions are stored in hashed lists.
994 Get the first in the list. */
995 ilist
= CGEN_ASM_LOOKUP_INSN (od
, str
);
997 /* Keep looking until we find a match. */
1000 for ( ; ilist
!= NULL
; ilist
= CGEN_ASM_NEXT_INSN (ilist
))
1002 const CGEN_INSN
*insn
= ilist
->insn
;
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
))
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)
1018 /* Record a default length for the insn. This will get set to the
1019 correct value while parsing. */
1021 CGEN_FIELDS_BITSIZE (fields
) = CGEN_INSN_BITSIZE (insn
);
1023 if (! CGEN_PARSE_FN (insn
) (od
, insn
, & str
, fields
))
1025 /* ??? 0 is passed for `pc' */
1026 if (CGEN_INSERT_FN (insn
) (od
, insn
, fields
, buf
, (bfd_vma
) 0) != NULL
)
1028 /* It is up to the caller to actually output the insn and any
1033 /* Try the next entry. */
1036 /* FIXME: We can return a better error message than this.
1037 Need to track why it failed and pick the right one. */
1039 static char errbuf
[100];
1040 if (strlen (start
) > 50)
1041 /* xgettext:c-format */
1042 sprintf (errbuf
, _("bad instruction `%.50s...'"), start
);
1044 /* xgettext:c-format */
1045 sprintf (errbuf
, _("bad instruction `%.50s'"), start
);
1052 #if 0 /* This calls back to GAS which we can't do without care. */
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. */
1058 /* Record each member of OPVALS in the assembler's symbol table.
1059 FIXME: Not currently used. */
1062 m32r_cgen_asm_hash_keywords (od
, opvals
)
1063 CGEN_OPCODE_DESC od
;
1064 CGEN_KEYWORD
* opvals
;
1066 CGEN_KEYWORD_SEARCH search
= cgen_keyword_search_init (opvals
, NULL
);
1067 const CGEN_KEYWORD_ENTRY
* ke
;
1069 while ((ke
= cgen_keyword_search_next (& search
)) != NULL
)
1071 #if 0 /* Unnecessary, should be done in the search routine. */
1072 if (! m32r_cgen_opval_supported (ke
))
1075 cgen_asm_record_register (od
, ke
->name
, ke
->value
);