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. */
33 /* ??? The layout of this stuff is still work in progress.
34 For speed in assembly/disassembly, we use inline functions. That of course
35 will only work for GCC. When this stuff is finished, we can decide whether
36 to keep the inline functions (and only get the performance increase when
37 compiled with GCC), or switch to macros, or use something else.
40 static const char * insert_normal
41 PARAMS ((long, unsigned int, int, int, int, char *));
42 static const char * parse_insn_normal
43 PARAMS ((const CGEN_INSN
*, const char **, CGEN_FIELDS
*));
44 static const char * insert_insn_normal
45 PARAMS ((const CGEN_INSN
*, CGEN_FIELDS
*, cgen_insn_t
*, bfd_vma
));
47 /* -- assembler routines inserted here */
50 /* Handle '#' prefixes (i.e. skip over them). */
53 parse_hash (strp
, opindex
, valuep
)
56 unsigned long *valuep
;
63 /* Handle shigh(), high(). */
66 parse_hi16 (strp
, opindex
, valuep
)
69 unsigned long *valuep
;
72 enum cgen_parse_operand_result result_type
;
77 if (strncasecmp (*strp
, "high(", 5) == 0)
80 errmsg
= cgen_parse_address (strp
, opindex
, BFD_RELOC_M32R_HI16_ULO
,
81 &result_type
, valuep
);
86 && result_type
== CGEN_PARSE_OPERAND_RESULT_NUMBER
)
90 else if (strncasecmp (*strp
, "shigh(", 6) == 0)
93 errmsg
= cgen_parse_address (strp
, opindex
, BFD_RELOC_M32R_HI16_SLO
,
94 &result_type
, valuep
);
99 && result_type
== CGEN_PARSE_OPERAND_RESULT_NUMBER
)
100 *valuep
= (*valuep
>> 16) + ((*valuep
) & 0x8000 ? 1 : 0);
104 return cgen_parse_unsigned_integer (strp
, opindex
, valuep
);
107 /* Handle low() in a signed context. Also handle sda().
108 The signedness of the value doesn't matter to low(), but this also
109 handles the case where low() isn't present. */
112 parse_slo16 (strp
, opindex
, valuep
)
118 enum cgen_parse_operand_result result_type
;
123 if (strncasecmp (*strp
, "low(", 4) == 0)
126 errmsg
= cgen_parse_address (strp
, opindex
, BFD_RELOC_M32R_LO16
,
127 &result_type
, valuep
);
129 return "missing `)'";
132 && result_type
== CGEN_PARSE_OPERAND_RESULT_NUMBER
)
137 if (strncasecmp (*strp
, "sda(", 4) == 0)
140 errmsg
= cgen_parse_address (strp
, opindex
, BFD_RELOC_M32R_SDA16
, NULL
, valuep
);
142 return "missing `)'";
147 return cgen_parse_signed_integer (strp
, opindex
, valuep
);
150 /* Handle low() in an unsigned context.
151 The signedness of the value doesn't matter to low(), but this also
152 handles the case where low() isn't present. */
155 parse_ulo16 (strp
, opindex
, valuep
)
158 unsigned long *valuep
;
161 enum cgen_parse_operand_result result_type
;
166 if (strncasecmp (*strp
, "low(", 4) == 0)
169 errmsg
= cgen_parse_address (strp
, opindex
, BFD_RELOC_M32R_LO16
,
170 &result_type
, valuep
);
172 return "missing `)'";
175 && result_type
== CGEN_PARSE_OPERAND_RESULT_NUMBER
)
180 return cgen_parse_unsigned_integer (strp
, opindex
, valuep
);
185 /* Main entry point for operand parsing.
187 This function is basically just a big switch statement. Earlier versions
188 used tables to look up the function to use, but
189 - if the table contains both assembler and disassembler functions then
190 the disassembler contains much of the assembler and vice-versa,
191 - there's a lot of inlining possibilities as things grow,
192 - using a switch statement avoids the function call overhead.
194 This function could be moved into `parse_insn_normal', but keeping it
195 separate makes clear the interface between `parse_insn_normal' and each of
200 m32r_cgen_parse_operand (opindex
, strp
, fields
)
203 CGEN_FIELDS
* fields
;
209 case M32R_OPERAND_SR
:
210 errmsg
= cgen_parse_keyword (strp
, & m32r_cgen_opval_h_gr
, & fields
->f_r2
);
212 case M32R_OPERAND_DR
:
213 errmsg
= cgen_parse_keyword (strp
, & m32r_cgen_opval_h_gr
, & fields
->f_r1
);
215 case M32R_OPERAND_SRC1
:
216 errmsg
= cgen_parse_keyword (strp
, & m32r_cgen_opval_h_gr
, & fields
->f_r1
);
218 case M32R_OPERAND_SRC2
:
219 errmsg
= cgen_parse_keyword (strp
, & m32r_cgen_opval_h_gr
, & fields
->f_r2
);
221 case M32R_OPERAND_SCR
:
222 errmsg
= cgen_parse_keyword (strp
, & m32r_cgen_opval_h_cr
, & fields
->f_r2
);
224 case M32R_OPERAND_DCR
:
225 errmsg
= cgen_parse_keyword (strp
, & m32r_cgen_opval_h_cr
, & fields
->f_r1
);
227 case M32R_OPERAND_SIMM8
:
228 errmsg
= cgen_parse_signed_integer (strp
, M32R_OPERAND_SIMM8
, &fields
->f_simm8
);
230 case M32R_OPERAND_SIMM16
:
231 errmsg
= cgen_parse_signed_integer (strp
, M32R_OPERAND_SIMM16
, &fields
->f_simm16
);
233 case M32R_OPERAND_UIMM4
:
234 errmsg
= cgen_parse_unsigned_integer (strp
, M32R_OPERAND_UIMM4
, &fields
->f_uimm4
);
236 case M32R_OPERAND_UIMM5
:
237 errmsg
= cgen_parse_unsigned_integer (strp
, M32R_OPERAND_UIMM5
, &fields
->f_uimm5
);
239 case M32R_OPERAND_UIMM16
:
240 errmsg
= cgen_parse_unsigned_integer (strp
, M32R_OPERAND_UIMM16
, &fields
->f_uimm16
);
242 /* start-sanitize-m32rx */
243 case M32R_OPERAND_IMM1
:
244 errmsg
= cgen_parse_unsigned_integer (strp
, M32R_OPERAND_IMM1
, &fields
->f_imm1
);
246 /* end-sanitize-m32rx */
247 /* start-sanitize-m32rx */
248 case M32R_OPERAND_ACCD
:
249 errmsg
= cgen_parse_keyword (strp
, & m32r_cgen_opval_h_accums
, & fields
->f_accd
);
251 /* end-sanitize-m32rx */
252 /* start-sanitize-m32rx */
253 case M32R_OPERAND_ACCS
:
254 errmsg
= cgen_parse_keyword (strp
, & m32r_cgen_opval_h_accums
, & fields
->f_accs
);
256 /* end-sanitize-m32rx */
257 /* start-sanitize-m32rx */
258 case M32R_OPERAND_ACC
:
259 errmsg
= cgen_parse_keyword (strp
, & m32r_cgen_opval_h_accums
, & fields
->f_acc
);
261 /* end-sanitize-m32rx */
262 case M32R_OPERAND_HASH
:
263 errmsg
= parse_hash (strp
, M32R_OPERAND_HASH
, &fields
->f_nil
);
265 case M32R_OPERAND_HI16
:
266 errmsg
= parse_hi16 (strp
, M32R_OPERAND_HI16
, &fields
->f_hi16
);
268 case M32R_OPERAND_SLO16
:
269 errmsg
= parse_slo16 (strp
, M32R_OPERAND_SLO16
, &fields
->f_simm16
);
271 case M32R_OPERAND_ULO16
:
272 errmsg
= parse_ulo16 (strp
, M32R_OPERAND_ULO16
, &fields
->f_uimm16
);
274 case M32R_OPERAND_UIMM24
:
275 errmsg
= cgen_parse_address (strp
, M32R_OPERAND_UIMM24
, 0, NULL
, & fields
->f_uimm24
);
277 case M32R_OPERAND_DISP8
:
278 errmsg
= cgen_parse_address (strp
, M32R_OPERAND_DISP8
, 0, NULL
, & fields
->f_disp8
);
280 case M32R_OPERAND_DISP16
:
281 errmsg
= cgen_parse_address (strp
, M32R_OPERAND_DISP16
, 0, NULL
, & fields
->f_disp16
);
283 case M32R_OPERAND_DISP24
:
284 errmsg
= cgen_parse_address (strp
, M32R_OPERAND_DISP24
, 0, NULL
, & fields
->f_disp24
);
288 /* xgettext:c-format */
289 fprintf (stderr
, _("Unrecognized field %d while parsing.\n"), opindex
);
296 /* Main entry point for operand insertion.
298 This function is basically just a big switch statement. Earlier versions
299 used tables to look up the function to use, but
300 - if the table contains both assembler and disassembler functions then
301 the disassembler contains much of the assembler and vice-versa,
302 - there's a lot of inlining possibilities as things grow,
303 - using a switch statement avoids the function call overhead.
305 This function could be moved into `parse_insn_normal', but keeping it
306 separate makes clear the interface between `parse_insn_normal' and each of
307 the handlers. It's also needed by GAS to insert operands that couldn't be
308 resolved during parsing.
312 m32r_cgen_insert_operand (opindex
, fields
, buffer
, pc
)
314 CGEN_FIELDS
* fields
;
322 case M32R_OPERAND_SR
:
323 errmsg
= insert_normal (fields
->f_r2
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 12, 4, CGEN_FIELDS_BITSIZE (fields
), buffer
);
325 case M32R_OPERAND_DR
:
326 errmsg
= insert_normal (fields
->f_r1
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 4, 4, CGEN_FIELDS_BITSIZE (fields
), buffer
);
328 case M32R_OPERAND_SRC1
:
329 errmsg
= insert_normal (fields
->f_r1
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 4, 4, CGEN_FIELDS_BITSIZE (fields
), buffer
);
331 case M32R_OPERAND_SRC2
:
332 errmsg
= insert_normal (fields
->f_r2
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 12, 4, CGEN_FIELDS_BITSIZE (fields
), buffer
);
334 case M32R_OPERAND_SCR
:
335 errmsg
= insert_normal (fields
->f_r2
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 12, 4, CGEN_FIELDS_BITSIZE (fields
), buffer
);
337 case M32R_OPERAND_DCR
:
338 errmsg
= insert_normal (fields
->f_r1
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 4, 4, CGEN_FIELDS_BITSIZE (fields
), buffer
);
340 case M32R_OPERAND_SIMM8
:
341 errmsg
= insert_normal (fields
->f_simm8
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
), 8, 8, CGEN_FIELDS_BITSIZE (fields
), buffer
);
343 case M32R_OPERAND_SIMM16
:
344 errmsg
= insert_normal (fields
->f_simm16
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
), 16, 16, CGEN_FIELDS_BITSIZE (fields
), buffer
);
346 case M32R_OPERAND_UIMM4
:
347 errmsg
= insert_normal (fields
->f_uimm4
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 12, 4, CGEN_FIELDS_BITSIZE (fields
), buffer
);
349 case M32R_OPERAND_UIMM5
:
350 errmsg
= insert_normal (fields
->f_uimm5
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 11, 5, CGEN_FIELDS_BITSIZE (fields
), buffer
);
352 case M32R_OPERAND_UIMM16
:
353 errmsg
= insert_normal (fields
->f_uimm16
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 16, 16, CGEN_FIELDS_BITSIZE (fields
), buffer
);
355 /* start-sanitize-m32rx */
356 case M32R_OPERAND_IMM1
:
358 long value
= fields
->f_imm1
;
359 value
= ((value
) - (1));
360 errmsg
= insert_normal (value
, 0|(1<<CGEN_OPERAND_HASH_PREFIX
)|(1<<CGEN_OPERAND_UNSIGNED
), 15, 1, CGEN_FIELDS_BITSIZE (fields
), buffer
);
363 /* end-sanitize-m32rx */
364 /* start-sanitize-m32rx */
365 case M32R_OPERAND_ACCD
:
366 errmsg
= insert_normal (fields
->f_accd
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 4, 2, CGEN_FIELDS_BITSIZE (fields
), buffer
);
368 /* end-sanitize-m32rx */
369 /* start-sanitize-m32rx */
370 case M32R_OPERAND_ACCS
:
371 errmsg
= insert_normal (fields
->f_accs
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 12, 2, CGEN_FIELDS_BITSIZE (fields
), buffer
);
373 /* end-sanitize-m32rx */
374 /* start-sanitize-m32rx */
375 case M32R_OPERAND_ACC
:
376 errmsg
= insert_normal (fields
->f_acc
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 8, 1, CGEN_FIELDS_BITSIZE (fields
), buffer
);
378 /* end-sanitize-m32rx */
379 case M32R_OPERAND_HASH
:
380 errmsg
= insert_normal (fields
->f_nil
, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields
), buffer
);
382 case M32R_OPERAND_HI16
:
383 errmsg
= insert_normal (fields
->f_hi16
, 0|(1<<CGEN_OPERAND_SIGN_OPT
)|(1<<CGEN_OPERAND_UNSIGNED
), 16, 16, CGEN_FIELDS_BITSIZE (fields
), buffer
);
385 case M32R_OPERAND_SLO16
:
386 errmsg
= insert_normal (fields
->f_simm16
, 0, 16, 16, CGEN_FIELDS_BITSIZE (fields
), buffer
);
388 case M32R_OPERAND_ULO16
:
389 errmsg
= insert_normal (fields
->f_uimm16
, 0|(1<<CGEN_OPERAND_UNSIGNED
), 16, 16, CGEN_FIELDS_BITSIZE (fields
), buffer
);
391 case M32R_OPERAND_UIMM24
:
392 errmsg
= insert_normal (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
);
394 case M32R_OPERAND_DISP8
:
396 long value
= fields
->f_disp8
;
397 value
= ((int) (((value
) - (((pc
) & (-4))))) >> (2));
398 errmsg
= insert_normal (value
, 0|(1<<CGEN_OPERAND_RELAX
)|(1<<CGEN_OPERAND_RELOC
)|(1<<CGEN_OPERAND_PCREL_ADDR
), 8, 8, CGEN_FIELDS_BITSIZE (fields
), buffer
);
401 case M32R_OPERAND_DISP16
:
403 long value
= fields
->f_disp16
;
404 value
= ((int) (((value
) - (pc
))) >> (2));
405 errmsg
= insert_normal (value
, 0|(1<<CGEN_OPERAND_RELOC
)|(1<<CGEN_OPERAND_PCREL_ADDR
), 16, 16, CGEN_FIELDS_BITSIZE (fields
), buffer
);
408 case M32R_OPERAND_DISP24
:
410 long value
= fields
->f_disp24
;
411 value
= ((int) (((value
) - (pc
))) >> (2));
412 errmsg
= insert_normal (value
, 0|(1<<CGEN_OPERAND_RELAX
)|(1<<CGEN_OPERAND_RELOC
)|(1<<CGEN_OPERAND_PCREL_ADDR
), 8, 24, CGEN_FIELDS_BITSIZE (fields
), buffer
);
417 /* xgettext:c-format */
418 fprintf (stderr
, _("Unrecognized field %d while building insn.\n"),
426 cgen_parse_fn
* m32r_cgen_parse_handlers
[] =
432 cgen_insert_fn
* m32r_cgen_insert_handlers
[] =
439 m32r_cgen_init_asm (mach
, endian
)
441 enum cgen_endian endian
;
443 m32r_cgen_init_tables (mach
);
444 cgen_set_cpu (& m32r_cgen_opcode_table
, mach
, endian
);
449 /* Default insertion routine.
451 ATTRS is a mask of the boolean attributes.
452 LENGTH is the length of VALUE in bits.
453 TOTAL_LENGTH is the total length of the insn (currently 8,16,32).
455 The result is an error message or NULL if success. */
457 /* ??? This duplicates functionality with bfd's howto table and
458 bfd_install_relocation. */
459 /* ??? For architectures where insns can be representable as ints,
460 store insn in `field' struct and add registers, etc. while parsing? */
463 insert_normal (value
, attrs
, start
, length
, total_length
, buffer
)
472 static char buf
[100];
473 /* Written this way to avoid undefined behaviour.
474 Yes, `long' will be bfd_vma but not yet. */
475 long mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
477 /* If LENGTH is zero, this operand doesn't contribute to the value. */
481 /* Ensure VALUE will fit. */
482 if ((attrs
& CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED
)) != 0)
484 unsigned long max
= mask
;
485 if ((unsigned long) value
> max
)
487 /* xgettext:c-format */
488 sprintf (buf
, _("operand out of range (%lu not between 0 and %lu)"),
495 long min
= - (1L << (length
- 1));
496 long max
= (1L << (length
- 1)) - 1;
497 if (value
< min
|| value
> max
)
500 /* xgettext:c-format */
501 (buf
, _("operand out of range (%ld not between %ld and %ld)"),
507 #if 0 /*def CGEN_INT_INSN*/
508 *buffer
|= (value
& mask
) << (total_length
- (start
+ length
));
510 switch (total_length
)
513 x
= * (unsigned char *) buffer
;
516 if (CGEN_CURRENT_ENDIAN
== CGEN_ENDIAN_BIG
)
517 x
= bfd_getb16 (buffer
);
519 x
= bfd_getl16 (buffer
);
522 if (CGEN_CURRENT_ENDIAN
== CGEN_ENDIAN_BIG
)
523 x
= bfd_getb32 (buffer
);
525 x
= bfd_getl32 (buffer
);
531 x
|= (value
& mask
) << (total_length
- (start
+ length
));
533 switch (total_length
)
539 if (CGEN_CURRENT_ENDIAN
== CGEN_ENDIAN_BIG
)
540 bfd_putb16 (x
, buffer
);
542 bfd_putl16 (x
, buffer
);
545 if (CGEN_CURRENT_ENDIAN
== CGEN_ENDIAN_BIG
)
546 bfd_putb32 (x
, buffer
);
548 bfd_putl32 (x
, buffer
);
558 /* Default insn parser.
560 The syntax string is scanned and operands are parsed and stored in FIELDS.
561 Relocs are queued as we go via other callbacks.
563 ??? Note that this is currently an all-or-nothing parser. If we fail to
564 parse the instruction, we return 0 and the caller will start over from
565 the beginning. Backtracking will be necessary in parsing subexpressions,
566 but that can be handled there. Not handling backtracking here may get
567 expensive in the case of the m68k. Deal with later.
569 Returns NULL for success, an error message for failure.
573 parse_insn_normal (insn
, strp
, fields
)
574 const CGEN_INSN
* insn
;
576 CGEN_FIELDS
* fields
;
578 const CGEN_SYNTAX
* syntax
= CGEN_INSN_SYNTAX (insn
);
579 const char * str
= *strp
;
582 const unsigned char * syn
;
583 #ifdef CGEN_MNEMONIC_OPERANDS
588 /* For now we assume the mnemonic is first (there are no leading operands).
589 We can parse it without needing to set up operand parsing. */
590 p
= CGEN_INSN_MNEMONIC (insn
);
591 while (* p
&& * p
== * str
)
594 if (* p
|| (* str
&& !isspace (* str
)))
595 return _("unrecognized instruction");
598 cgen_init_parse_operand ();
599 #ifdef CGEN_MNEMONIC_OPERANDS
603 /* We don't check for (*str != '\0') here because we want to parse
604 any trailing fake arguments in the syntax string. */
605 syn
= CGEN_SYNTAX_STRING (CGEN_INSN_SYNTAX (insn
));
607 /* Mnemonics come first for now, ensure valid string. */
608 if (! CGEN_SYNTAX_MNEMONIC_P (* syn
))
615 /* Non operand chars must match exactly. */
616 if (CGEN_SYNTAX_CHAR_P (* syn
))
618 if (*str
== CGEN_SYNTAX_CHAR (* syn
))
620 #ifdef CGEN_MNEMONIC_OPERANDS
629 /* Syntax char didn't match. Can't be this insn. */
630 /* FIXME: would like to return something like
631 "expected char `c'" */
632 return _("syntax error");
637 /* We have an operand of some sort. */
638 errmsg
= m32r_cgen_parse_operand (CGEN_SYNTAX_FIELD (*syn
),
643 /* Done with this operand, continue with next one. */
647 /* If we're at the end of the syntax string, we're done. */
650 /* FIXME: For the moment we assume a valid `str' can only contain
651 blanks now. IE: We needn't try again with a longer version of
652 the insn and it is assumed that longer versions of insns appear
653 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
654 while (isspace (* str
))
658 return _("junk at end of line"); /* FIXME: would like to include `str' */
663 /* We couldn't parse it. */
664 return "unrecognized instruction";
667 /* Default insn builder (insert handler).
668 The instruction is recorded in target byte order.
669 The result is an error message or NULL if success. */
670 /* FIXME: change buffer to char *? */
673 insert_insn_normal (insn
, fields
, buffer
, pc
)
674 const CGEN_INSN
* insn
;
675 CGEN_FIELDS
* fields
;
676 cgen_insn_t
* buffer
;
679 const CGEN_SYNTAX
* syntax
= CGEN_INSN_SYNTAX (insn
);
681 const unsigned char * syn
;
684 value
= CGEN_INSN_VALUE (insn
);
686 /* If we're recording insns as numbers (rather than a string of bytes),
687 target byte order handling is deferred until later. */
689 #define min(a,b) ((a) < (b) ? (a) : (b))
690 #if 0 /*def CGEN_INT_INSN*/
693 switch (min (CGEN_BASE_INSN_BITSIZE
, CGEN_FIELDS_BITSIZE (fields
)))
699 if (CGEN_CURRENT_ENDIAN
== CGEN_ENDIAN_BIG
)
700 bfd_putb16 (value
, (char *) buffer
);
702 bfd_putl16 (value
, (char *) buffer
);
705 if (CGEN_CURRENT_ENDIAN
== CGEN_ENDIAN_BIG
)
706 bfd_putb32 (value
, (char *) buffer
);
708 bfd_putl32 (value
, (char *) buffer
);
715 /* ??? Rather than scanning the syntax string again, we could store
716 in `fields' a null terminated list of the fields that are present. */
718 for (syn
= CGEN_SYNTAX_STRING (syntax
); * syn
!= '\0'; ++ syn
)
722 if (CGEN_SYNTAX_CHAR_P (* syn
))
725 errmsg
= m32r_cgen_insert_operand (CGEN_SYNTAX_FIELD (*syn
), fields
,
726 (char *) buffer
, pc
);
735 This routine is called for each instruction to be assembled.
736 STR points to the insn to be assembled.
737 We assume all necessary tables have been initialized.
738 The assembled instruction, less any fixups, is stored in buf.
739 [??? What byte order?]
740 The result is a pointer to the insn's entry in the opcode table,
741 or NULL if an error occured (an error message will have already been
744 Note that when processing (non-alias) macro-insns,
745 this function recurses. */
748 m32r_cgen_assemble_insn (str
, fields
, buf
, errmsg
)
750 CGEN_FIELDS
* fields
;
755 CGEN_INSN_LIST
* ilist
;
757 /* Skip leading white space. */
758 while (isspace (* str
))
761 /* The instructions are stored in hashed lists.
762 Get the first in the list. */
763 ilist
= CGEN_ASM_LOOKUP_INSN (str
);
765 /* Keep looking until we find a match. */
768 for ( ; ilist
!= NULL
; ilist
= CGEN_ASM_NEXT_INSN (ilist
))
770 const CGEN_INSN
*insn
= ilist
->insn
;
772 #if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */
773 /* Is this insn supported by the selected cpu? */
774 if (! m32r_cgen_insn_supported (insn
))
778 /* If the RELAX attribute is set, this is an insn that shouldn't be
779 chosen immediately. Instead, it is used during assembler/linker
780 relaxation if possible. */
781 if (CGEN_INSN_ATTR (insn
, CGEN_INSN_RELAX
) != 0)
786 /* Record a default length for the insn. This will get set to the
787 correct value while parsing. */
789 CGEN_FIELDS_BITSIZE (fields
) = CGEN_INSN_BITSIZE (insn
);
791 if (! CGEN_PARSE_FN (insn
) (insn
, & str
, fields
))
793 /* ??? 0 is passed for `pc' */
794 if (CGEN_INSERT_FN (insn
) (insn
, fields
, buf
, (bfd_vma
) 0) != NULL
)
796 /* It is up to the caller to actually output the insn and any
801 /* Try the next entry. */
804 /* FIXME: We can return a better error message than this.
805 Need to track why it failed and pick the right one. */
807 static char errbuf
[100];
808 if (strlen (start
) > 50)
809 /* xgettext:c-format */
810 sprintf (errbuf
, _("bad instruction `%.50s...'"), start
);
812 /* xgettext:c-format */
813 sprintf (errbuf
, _("bad instruction `%.50s'"), start
);
820 #if 0 /* This calls back to GAS which we can't do without care. */
822 /* Record each member of OPVALS in the assembler's symbol table.
823 This lets GAS parse registers for us.
824 ??? Interesting idea but not currently used. */
826 /* Record each member of OPVALS in the assembler's symbol table.
827 FIXME: Not currently used. */
830 m32r_cgen_asm_hash_keywords (opvals
)
831 CGEN_KEYWORD
* opvals
;
833 CGEN_KEYWORD_SEARCH search
= cgen_keyword_search_init (opvals
, NULL
);
834 const CGEN_KEYWORD_ENTRY
* ke
;
836 while ((ke
= cgen_keyword_search_next (& search
)) != NULL
)
838 #if 0 /* Unnecessary, should be done in the search routine. */
839 if (! m32r_cgen_opval_supported (ke
))
842 cgen_asm_record_register (ke
->name
, ke
->value
);