1 /* Assembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
4 THIS FILE IS USED TO GENERATE fr30-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 */
57 /* Main entry point for operand parsing.
59 This function is basically just a big switch statement. Earlier versions
60 used tables to look up the function to use, but
61 - if the table contains both assembler and disassembler functions then
62 the disassembler contains much of the assembler and vice-versa,
63 - there's a lot of inlining possibilities as things grow,
64 - using a switch statement avoids the function call overhead.
66 This function could be moved into `parse_insn_normal', but keeping it
67 separate makes clear the interface between `parse_insn_normal' and each of
72 fr30_cgen_parse_operand (od
, opindex
, strp
, fields
)
82 case FR30_OPERAND_RI
:
83 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_gr
, & fields
->f_Ri
);
85 case FR30_OPERAND_RJ
:
86 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_gr
, & fields
->f_Rj
);
88 case FR30_OPERAND_RS1
:
89 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_dr
, & fields
->f_Rs1
);
91 case FR30_OPERAND_RS2
:
92 errmsg
= cgen_parse_keyword (od
, strp
, & fr30_cgen_opval_h_dr
, & fields
->f_Rs2
);
94 case FR30_OPERAND_U4
:
95 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_U4
, &fields
->f_u4
);
97 case FR30_OPERAND_M4
:
98 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_M4
, &fields
->f_m4
);
100 case FR30_OPERAND_I8
:
101 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_I8
, &fields
->f_i8
);
103 case FR30_OPERAND_U8
:
104 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_U8
, &fields
->f_u8
);
106 case FR30_OPERAND_O8
:
107 errmsg
= cgen_parse_signed_integer (od
, strp
, FR30_OPERAND_O8
, &fields
->f_o8
);
109 case FR30_OPERAND_S10
:
110 errmsg
= cgen_parse_signed_integer (od
, strp
, FR30_OPERAND_S10
, &fields
->f_s10
);
112 case FR30_OPERAND_U10
:
113 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_U10
, &fields
->f_u10
);
115 case FR30_OPERAND_DIR8
:
116 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_DIR8
, &fields
->f_dir8
);
118 case FR30_OPERAND_DIR9
:
119 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_DIR9
, &fields
->f_dir9
);
121 case FR30_OPERAND_DIR10
:
122 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_DIR10
, &fields
->f_dir10
);
124 case FR30_OPERAND_LABEL9
:
125 errmsg
= cgen_parse_signed_integer (od
, strp
, FR30_OPERAND_LABEL9
, &fields
->f_rel8
);
127 case FR30_OPERAND_LABEL12
:
128 errmsg
= cgen_parse_signed_integer (od
, strp
, FR30_OPERAND_LABEL12
, &fields
->f_rel11
);
130 case FR30_OPERAND_CC
:
131 errmsg
= cgen_parse_unsigned_integer (od
, strp
, FR30_OPERAND_CC
, &fields
->f_cc
);
135 /* xgettext:c-format */
136 fprintf (stderr
, _("Unrecognized field %d while parsing.\n"), opindex
);
143 /* Main entry point for operand insertion.
145 This function is basically just a big switch statement. Earlier versions
146 used tables to look up the function to use, but
147 - if the table contains both assembler and disassembler functions then
148 the disassembler contains much of the assembler and vice-versa,
149 - there's a lot of inlining possibilities as things grow,
150 - using a switch statement avoids the function call overhead.
152 This function could be moved into `parse_insn_normal', but keeping it
153 separate makes clear the interface between `parse_insn_normal' and each of
154 the handlers. It's also needed by GAS to insert operands that couldn't be
155 resolved during parsing.
159 fr30_cgen_insert_operand (od
, opindex
, fields
, buffer
, pc
)
162 CGEN_FIELDS
* fields
;
163 CGEN_INSN_BYTES_PTR buffer
;
170 case FR30_OPERAND_RI
:
171 errmsg
= insert_normal (od
, fields
->f_Ri
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 12, 4, CGEN_FIELDS_BITSIZE (fields
), buffer
);
173 case FR30_OPERAND_RJ
:
174 errmsg
= insert_normal (od
, fields
->f_Rj
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 8, 4, CGEN_FIELDS_BITSIZE (fields
), buffer
);
176 case FR30_OPERAND_RS1
:
177 errmsg
= insert_normal (od
, fields
->f_Rs1
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 8, 4, CGEN_FIELDS_BITSIZE (fields
), buffer
);
179 case FR30_OPERAND_RS2
:
180 errmsg
= insert_normal (od
, fields
->f_Rs2
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 12, 4, CGEN_FIELDS_BITSIZE (fields
), buffer
);
182 case FR30_OPERAND_U4
:
183 errmsg
= insert_normal (od
, fields
->f_u4
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 8, 4, CGEN_FIELDS_BITSIZE (fields
), buffer
);
185 case FR30_OPERAND_M4
:
187 long value
= fields
->f_m4
;
188 value
= ((value
) & (15));
189 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 8, 4, CGEN_FIELDS_BITSIZE (fields
), buffer
);
192 case FR30_OPERAND_I8
:
193 errmsg
= insert_normal (od
, fields
->f_i8
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 4, 8, CGEN_FIELDS_BITSIZE (fields
), buffer
);
195 case FR30_OPERAND_U8
:
196 errmsg
= insert_normal (od
, fields
->f_u8
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 8, 8, CGEN_FIELDS_BITSIZE (fields
), buffer
);
198 case FR30_OPERAND_O8
:
199 errmsg
= insert_normal (od
, fields
->f_o8
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 4, 8, CGEN_FIELDS_BITSIZE (fields
), buffer
);
201 case FR30_OPERAND_S10
:
203 long value
= fields
->f_s10
;
204 value
= ((((unsigned int) (value
) >> (2))) & (255));
205 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_SIGNED
), 8, 8, CGEN_FIELDS_BITSIZE (fields
), buffer
);
208 case FR30_OPERAND_U10
:
210 long value
= fields
->f_u10
;
211 value
= ((((unsigned int) (value
) >> (2))) & (255));
212 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 8, 8, CGEN_FIELDS_BITSIZE (fields
), buffer
);
215 case FR30_OPERAND_DIR8
:
216 errmsg
= insert_normal (od
, fields
->f_dir8
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 8, 8, CGEN_FIELDS_BITSIZE (fields
), buffer
);
218 case FR30_OPERAND_DIR9
:
220 long value
= fields
->f_dir9
;
221 value
= ((((unsigned int) (value
) >> (1))) & (255));
222 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 8, 8, CGEN_FIELDS_BITSIZE (fields
), buffer
);
225 case FR30_OPERAND_DIR10
:
227 long value
= fields
->f_dir10
;
228 value
= ((((unsigned int) (value
) >> (2))) & (255));
229 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 8, 8, CGEN_FIELDS_BITSIZE (fields
), buffer
);
232 case FR30_OPERAND_LABEL9
:
234 long value
= fields
->f_rel8
;
235 value
= ((((unsigned int) (value
) >> (1))) & (255));
236 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_SIGNED
), 8, 8, CGEN_FIELDS_BITSIZE (fields
), buffer
);
239 case FR30_OPERAND_LABEL12
:
241 long value
= fields
->f_rel11
;
242 value
= ((((unsigned int) (value
) >> (1))) & (2047));
243 errmsg
= insert_normal (od
, value
, 0|(1<<CGEN_OPERAND_SIGNED
), 5, 11, CGEN_FIELDS_BITSIZE (fields
), buffer
);
246 case FR30_OPERAND_CC
:
247 errmsg
= insert_normal (od
, fields
->f_cc
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 4, 4, CGEN_FIELDS_BITSIZE (fields
), buffer
);
251 /* xgettext:c-format */
252 fprintf (stderr
, _("Unrecognized field %d while building insn.\n"),
260 cgen_parse_fn
* const fr30_cgen_parse_handlers
[] =
266 cgen_insert_fn
* const fr30_cgen_insert_handlers
[] =
273 fr30_cgen_init_asm (od
)
279 #if ! CGEN_INT_INSN_P
281 /* Subroutine of insert_normal. */
284 insert_1 (od
, value
, start
, length
, word_length
, bufp
)
287 int start
,length
,word_length
;
290 unsigned long x
,mask
;
292 int big_p
= CGEN_OPCODE_INSN_ENDIAN (od
) == CGEN_ENDIAN_BIG
;
301 x
= bfd_getb16 (bufp
);
303 x
= bfd_getl16 (bufp
);
306 /* ??? This may need reworking as these cases don't necessarily
307 want the first byte and the last two bytes handled like this. */
309 x
= (bfd_getb8 (bufp
) << 16) | bfd_getb16 (bufp
+ 1);
311 x
= bfd_getl16 (bufp
) | (bfd_getb8 (bufp
+ 2) << 16);
315 x
= bfd_getb32 (bufp
);
317 x
= bfd_getl32 (bufp
);
323 /* Written this way to avoid undefined behaviour. */
324 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
325 if (CGEN_INSN_LSB0_P
)
328 shift
= (word_length
- (start
+ length
));
329 x
= (x
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
338 bfd_putb16 (x
, bufp
);
340 bfd_putl16 (x
, bufp
);
343 /* ??? This may need reworking as these cases don't necessarily
344 want the first byte and the last two bytes handled like this. */
347 bfd_putb8 (x
>> 16, bufp
);
348 bfd_putb16 (x
, bufp
+ 1);
352 bfd_putl16 (x
, bufp
);
353 bfd_putb8 (x
>> 16, bufp
+ 2);
358 bfd_putb32 (x
, bufp
);
360 bfd_putl32 (x
, bufp
);
367 #endif /* ! CGEN_INT_INSN_P */
369 /* Default insertion routine.
371 ATTRS is a mask of the boolean attributes.
372 START is the starting bit number, architecture origin.
373 LENGTH is the length of VALUE in bits.
374 TOTAL_LENGTH is the total length of the insn.
376 The result is an error message or NULL if success. */
378 /* ??? May need to know word length in order to properly place values as
379 an insn may be made of multiple words and the current bit number handling
380 may be insufficient. Word length is an architectural attribute and thus
381 methinks the way to go [if needed] is to fetch this value from OD or
382 define a macro in <arch>-opc.h rather than adding an extra argument -
383 after all that's how endianness is handled. */
384 /* ??? This duplicates functionality with bfd's howto table and
385 bfd_install_relocation. */
386 /* ??? For architectures where insns can be representable as ints,
387 store insn in `field' struct and add registers, etc. while parsing? */
388 /* ??? This doesn't handle bfd_vma's. Create another function when
392 insert_normal (od
, value
, attrs
, start
, length
, total_length
, buffer
)
399 CGEN_INSN_BYTES_PTR buffer
;
401 static char errbuf
[100];
402 /* Written this way to avoid undefined behaviour. */
403 unsigned long mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
405 /* If LENGTH is zero, this operand doesn't contribute to the value. */
409 /* Ensure VALUE will fit. */
410 if ((attrs
& CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED
)) != 0)
412 unsigned long maxval
= mask
;
413 if ((unsigned long) value
> maxval
)
415 /* xgettext:c-format */
417 _("operand out of range (%lu not between 0 and %lu)"),
424 long minval
= - (1L << (length
- 1));
425 long maxval
= (1L << (length
- 1)) - 1;
426 if (value
< minval
|| value
> maxval
)
429 /* xgettext:c-format */
430 (errbuf
, _("operand out of range (%ld not between %ld and %ld)"),
431 value
, minval
, maxval
);
438 if (total_length
> 32)
443 if (CGEN_INSN_LSB0_P
)
446 shift
= total_length
- (start
+ length
);
447 *buffer
= (*buffer
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
452 /* FIXME: unfinished and untested */
454 /* ??? To be defined in <arch>-opc.h as necessary. */
455 #ifndef CGEN_WORD_ENDIAN
456 #define CGEN_WORD_ENDIAN(od) CGEN_OPCODE_ENDIAN (od)
458 #ifndef CGEN_INSN_WORD_ENDIAN
459 #define CGEN_INSN_WORD_ENDIAN(od) CGEN_WORD_ENDIAN (od)
462 /* The hard case is probably too slow for the normal cases.
463 It's certainly more difficult to understand than the normal case.
464 Thus this is split into two. Keep it that way. The hard case is defined
465 to be when a field straddles a (loosely defined) word boundary
466 (??? which may require target specific help to determine). */
470 #define HARD_CASE_P 0 /* FIXME:wip */
474 unsigned char *bufp
= (unsigned char *) buffer
;
475 int insn_length_left
= total_length
;
477 if (CGEN_INSN_LSB0_P
)
479 int word_offset
= (CGEN_INSN_WORD_ENDIAN (od
) == CGEN_ENDIAN_BIG
481 : start
/ CGEN_BASE_INSN_BITSIZE
);
482 bufp
+= word_offset
* (CGEN_BASE_INSN_BITSIZE
/ 8);
483 if (CGEN_INSN_WORD_ENDIAN (od
) == CGEN_ENDIAN_BIG
)
485 start
-= word_offset
* CGEN_BASE_INSN_BITSIZE
;
489 int word_offset
= (CGEN_INSN_WORD_ENDIAN (od
) == CGEN_ENDIAN_BIG
490 ? start
/ CGEN_BASE_INSN_BITSIZE
492 bufp
+= word_offset
* (CGEN_BASE_INSN_BITSIZE
/ 8);
493 if (CGEN_INSN_WORD_ENDIAN (od
) == CGEN_ENDIAN_BIG
)
494 start
-= word_offset
* CGEN_BASE_INSN_BITSIZE
;
498 /* Loop so we handle a field straddling an insn word boundary
499 (remember, "insn word boundary" is loosely defined here). */
503 int this_pass_length
= length
;
504 int this_pass_start
= start
;
505 int this_pass_word_length
= min (insn_length_left
,
506 (CGEN_BASE_INSN_BITSIZE
== 8
508 : CGEN_BASE_INSN_BITSIZE
));
510 insert_1 (od
, value
, attrs
,
511 this_pass_start
, this_pass_length
, this_pass_word_length
,
514 length
-= this_pass_length
;
515 insn_length_left
-= this_pass_word_length
;
526 bufp
+= this_pass_word_length
/ 8;
532 unsigned char *bufp
= (unsigned char *) buffer
;
537 /* Adjust start,total_length,bufp to point to the pseudo-word that holds
538 the value. For example in a 48 bit insn where the value to insert
539 (say an immediate value) is the last 16 bits then word_length here
540 would be 16. To handle a 24 bit insn with an 18 bit immediate,
541 insert_1 handles 24 bits (using a combination of bfd_get8,16). */
543 if (total_length
> 32)
545 int needed_width
= start
% 8 + length
;
546 int fetch_length
= (needed_width
<= 8 ? 8
547 : needed_width
<= 16 ? 16
550 if (CGEN_INSN_LSB0_P
)
552 if (CGEN_INSN_WORD_ENDIAN (od
) == CGEN_ENDIAN_BIG
)
558 int offset
= start
& ~7;
562 total_length
-= offset
;
567 if (CGEN_INSN_WORD_ENDIAN (od
) == CGEN_ENDIAN_BIG
)
569 int offset
= start
& ~7;
573 total_length
-= offset
;
582 insert_1 (od
, value
, start
, length
, total_length
, bufp
);
585 #endif /* ! CGEN_INT_INSN_P */
590 /* Default insn parser.
592 The syntax string is scanned and operands are parsed and stored in FIELDS.
593 Relocs are queued as we go via other callbacks.
595 ??? Note that this is currently an all-or-nothing parser. If we fail to
596 parse the instruction, we return 0 and the caller will start over from
597 the beginning. Backtracking will be necessary in parsing subexpressions,
598 but that can be handled there. Not handling backtracking here may get
599 expensive in the case of the m68k. Deal with later.
601 Returns NULL for success, an error message for failure.
605 parse_insn_normal (od
, insn
, strp
, fields
)
607 const CGEN_INSN
* insn
;
609 CGEN_FIELDS
* fields
;
611 const CGEN_SYNTAX
* syntax
= CGEN_INSN_SYNTAX (insn
);
612 const char * str
= *strp
;
615 const unsigned char * syn
;
616 #ifdef CGEN_MNEMONIC_OPERANDS
621 /* For now we assume the mnemonic is first (there are no leading operands).
622 We can parse it without needing to set up operand parsing.
623 GAS's input scrubber will ensure mnemonics are lowercase, but we may
624 not be called from GAS. */
625 p
= CGEN_INSN_MNEMONIC (insn
);
626 while (*p
&& tolower (*p
) == tolower (*str
))
629 if (* p
|| (* str
&& !isspace (* str
)))
630 return _("unrecognized instruction");
632 CGEN_INIT_PARSE (od
);
633 cgen_init_parse_operand (od
);
634 #ifdef CGEN_MNEMONIC_OPERANDS
638 /* We don't check for (*str != '\0') here because we want to parse
639 any trailing fake arguments in the syntax string. */
640 syn
= CGEN_SYNTAX_STRING (syntax
);
642 /* Mnemonics come first for now, ensure valid string. */
643 if (! CGEN_SYNTAX_MNEMONIC_P (* syn
))
650 /* Non operand chars must match exactly. */
651 if (CGEN_SYNTAX_CHAR_P (* syn
))
653 if (*str
== CGEN_SYNTAX_CHAR (* syn
))
655 #ifdef CGEN_MNEMONIC_OPERANDS
664 /* Syntax char didn't match. Can't be this insn. */
665 /* FIXME: would like to return something like
666 "expected char `c'" */
667 return _("syntax error");
672 /* We have an operand of some sort. */
673 errmsg
= fr30_cgen_parse_operand (od
, CGEN_SYNTAX_FIELD (*syn
),
678 /* Done with this operand, continue with next one. */
682 /* If we're at the end of the syntax string, we're done. */
685 /* FIXME: For the moment we assume a valid `str' can only contain
686 blanks now. IE: We needn't try again with a longer version of
687 the insn and it is assumed that longer versions of insns appear
688 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
689 while (isspace (* str
))
693 return _("junk at end of line"); /* FIXME: would like to include `str' */
698 /* We couldn't parse it. */
699 return _("unrecognized instruction");
702 /* Default insn builder (insert handler).
703 The instruction is recorded in CGEN_INT_INSN_P byte order
704 (meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
705 recorded in host byte order, otherwise BUFFER is an array of bytes and the
706 value is recorded in target byte order).
707 The result is an error message or NULL if success. */
710 insert_insn_normal (od
, insn
, fields
, buffer
, pc
)
712 const CGEN_INSN
* insn
;
713 CGEN_FIELDS
* fields
;
714 CGEN_INSN_BYTES_PTR buffer
;
717 const CGEN_SYNTAX
* syntax
= CGEN_INSN_SYNTAX (insn
);
719 const unsigned char * syn
;
721 CGEN_INIT_INSERT (od
);
722 value
= CGEN_INSN_VALUE (insn
);
724 /* If we're recording insns as numbers (rather than a string of bytes),
725 target byte order handling is deferred until later. */
733 cgen_insn_put_value (od
, buffer
, min (CGEN_BASE_INSN_BITSIZE
,
734 CGEN_FIELDS_BITSIZE (fields
)),
737 #endif /* ! CGEN_INT_INSN_P */
739 /* ??? Rather than scanning the syntax string again, we could store
740 in `fields' a null terminated list of the fields that are present. */
742 for (syn
= CGEN_SYNTAX_STRING (syntax
); * syn
!= '\0'; ++ syn
)
746 if (CGEN_SYNTAX_CHAR_P (* syn
))
749 errmsg
= fr30_cgen_insert_operand (od
, CGEN_SYNTAX_FIELD (*syn
),
759 This routine is called for each instruction to be assembled.
760 STR points to the insn to be assembled.
761 We assume all necessary tables have been initialized.
762 The assembled instruction, less any fixups, is stored in BUF.
763 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
764 still needs to be converted to target byte order, otherwise BUF is an array
765 of bytes in target byte order.
766 The result is a pointer to the insn's entry in the opcode table,
767 or NULL if an error occured (an error message will have already been
770 Note that when processing (non-alias) macro-insns,
771 this function recurses. */
774 fr30_cgen_assemble_insn (od
, str
, fields
, buf
, errmsg
)
777 CGEN_FIELDS
* fields
;
778 CGEN_INSN_BYTES_PTR buf
;
782 CGEN_INSN_LIST
* ilist
;
784 /* Skip leading white space. */
785 while (isspace (* str
))
788 /* The instructions are stored in hashed lists.
789 Get the first in the list. */
790 ilist
= CGEN_ASM_LOOKUP_INSN (od
, str
);
792 /* Keep looking until we find a match. */
795 for ( ; ilist
!= NULL
; ilist
= CGEN_ASM_NEXT_INSN (ilist
))
797 const CGEN_INSN
*insn
= ilist
->insn
;
799 #if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */
800 /* Is this insn supported by the selected cpu? */
801 if (! fr30_cgen_insn_supported (od
, insn
))
805 /* If the RELAX attribute is set, this is an insn that shouldn't be
806 chosen immediately. Instead, it is used during assembler/linker
807 relaxation if possible. */
808 if (CGEN_INSN_ATTR (insn
, CGEN_INSN_RELAX
) != 0)
813 /* Record a default length for the insn. This will get set to the
814 correct value while parsing. */
816 CGEN_FIELDS_BITSIZE (fields
) = CGEN_INSN_BITSIZE (insn
);
818 if (! CGEN_PARSE_FN (insn
) (od
, insn
, & str
, fields
))
820 /* ??? 0 is passed for `pc' */
821 if (CGEN_INSERT_FN (insn
) (od
, insn
, fields
, buf
, (bfd_vma
) 0) != NULL
)
823 /* It is up to the caller to actually output the insn and any
828 /* Try the next entry. */
831 /* FIXME: We can return a better error message than this.
832 Need to track why it failed and pick the right one. */
834 static char errbuf
[100];
835 if (strlen (start
) > 50)
836 /* xgettext:c-format */
837 sprintf (errbuf
, _("bad instruction `%.50s...'"), start
);
839 /* xgettext:c-format */
840 sprintf (errbuf
, _("bad instruction `%.50s'"), start
);
847 #if 0 /* This calls back to GAS which we can't do without care. */
849 /* Record each member of OPVALS in the assembler's symbol table.
850 This lets GAS parse registers for us.
851 ??? Interesting idea but not currently used. */
853 /* Record each member of OPVALS in the assembler's symbol table.
854 FIXME: Not currently used. */
857 fr30_cgen_asm_hash_keywords (od
, opvals
)
859 CGEN_KEYWORD
* opvals
;
861 CGEN_KEYWORD_SEARCH search
= cgen_keyword_search_init (opvals
, NULL
);
862 const CGEN_KEYWORD_ENTRY
* ke
;
864 while ((ke
= cgen_keyword_search_next (& search
)) != NULL
)
866 #if 0 /* Unnecessary, should be done in the search routine. */
867 if (! fr30_cgen_opval_supported (ke
))
870 cgen_asm_record_register (od
, ke
->name
, ke
->value
);