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 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
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
31 /* ??? The layout of this stuff is still work in progress.
32 For speed in assembly/disassembly, we use inline functions. That of course
33 will only work for GCC. When this stuff is finished, we can decide whether
34 to keep the inline functions (and only get the performance increase when
35 compiled with GCC), or switch to macros, or use something else.
38 static const char * parse_insn_normal
39 PARAMS ((const CGEN_INSN *, const char **, CGEN_FIELDS *));
40 static void insert_insn_normal
41 PARAMS ((const CGEN_INSN *, CGEN_FIELDS *, cgen_insn_t *));
43 /* Default insertion routine.
45 SHIFT is negative for left shifts, positive for right shifts.
46 All bits of VALUE to be inserted must be valid as we don't handle
47 signed vs unsigned shifts.
49 ATTRS is a mask of the boolean attributes. We don't need any at the
50 moment, but for consistency with extract_normal we have them. */
52 /* FIXME: This duplicates functionality with bfd's howto table and
53 bfd_install_relocation. */
54 /* FIXME: For architectures where insns can be representable as ints,
55 store insn in `field' struct and add registers, etc. while parsing. */
57 static CGEN_INLINE void
58 insert_normal (value, attrs, start, length, shift, total_length, buffer)
69 #if 0 /*def CGEN_INT_INSN*/
70 *buffer |= ((value & ((1 << length) - 1))
71 << (total_length - (start + length)));
76 x = * (unsigned char *) buffer;
79 if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
80 x = bfd_getb16 (buffer);
82 x = bfd_getl16 (buffer);
85 if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
86 x = bfd_getb32 (buffer);
88 x = bfd_getl32 (buffer);
99 x |= ((value & ((1 << length) - 1))
100 << (total_length - (start + length)));
102 switch (total_length)
108 if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
109 bfd_putb16 (x, buffer);
111 bfd_putl16 (x, buffer);
114 if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
115 bfd_putb32 (x, buffer);
117 bfd_putl32 (x, buffer);
125 /* -- assembler routines inserted here */
128 /* Handle shigh(), high(). */
131 parse_h_hi16 (strp, opindex, min, max, valuep)
134 unsigned long min, max;
135 unsigned long *valuep;
138 enum cgen_parse_operand_result result_type;
140 /* FIXME: Need # in assembler syntax (means '#' is optional). */
144 if (strncmp (*strp, "high(", 5) == 0)
147 errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_HI16_ULO,
148 &result_type, valuep);
150 return "missing `)'";
153 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
157 else if (strncmp (*strp, "shigh(", 6) == 0)
160 errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_HI16_SLO,
161 &result_type, valuep);
163 return "missing `)'";
166 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
167 *valuep = (*valuep >> 16) + ((*valuep) & 0x8000 ? 1 : 0);
171 return cgen_parse_unsigned_integer (strp, opindex, min, max, valuep);
174 /* Handle low() in a signed context. Also handle sda().
175 The signedness of the value doesn't matter to low(), but this also
176 handles the case where low() isn't present. */
179 parse_h_slo16 (strp, opindex, min, max, valuep)
186 enum cgen_parse_operand_result result_type;
188 /* FIXME: Need # in assembler syntax (means '#' is optional). */
192 if (strncmp (*strp, "low(", 4) == 0)
195 errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_LO16,
196 &result_type, valuep);
198 return "missing `)'";
203 if (strncmp (*strp, "sda(", 4) == 0)
206 errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_SDA16, NULL, valuep);
208 return "missing `)'";
213 return cgen_parse_signed_integer (strp, opindex, min, max, valuep);
216 /* Handle low() in an unsigned context.
217 The signedness of the value doesn't matter to low(), but this also
218 handles the case where low() isn't present. */
221 parse_h_ulo16 (strp, opindex, min, max, valuep)
224 unsigned long min, max;
225 unsigned long *valuep;
228 enum cgen_parse_operand_result result_type;
230 /* FIXME: Need # in assembler syntax (means '#' is optional). */
234 if (strncmp (*strp, "low(", 4) == 0)
237 errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_LO16,
238 &result_type, valuep);
240 return "missing `)'";
245 return cgen_parse_unsigned_integer (strp, opindex, min, max, valuep);
250 /* Main entry point for operand parsing.
252 This function is basically just a big switch statement. Earlier versions
253 used tables to look up the function to use, but
254 - if the table contains both assembler and disassembler functions then
255 the disassembler contains much of the assembler and vice-versa,
256 - there's a lot of inlining possibilities as things grow,
257 - using a switch statement avoids the function call overhead.
259 This function could be moved into `parse_insn_normal', but keeping it
260 separate makes clear the interface between `parse_insn_normal' and each of
264 CGEN_INLINE const char *
265 m32r_cgen_parse_operand (opindex, strp, fields)
268 CGEN_FIELDS * fields;
274 case M32R_OPERAND_SR :
275 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r2);
277 case M32R_OPERAND_DR :
278 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r1);
280 case M32R_OPERAND_SRC1 :
281 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r1);
283 case M32R_OPERAND_SRC2 :
284 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r2);
286 case M32R_OPERAND_SCR :
287 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_cr, & fields->f_r2);
289 case M32R_OPERAND_DCR :
290 errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_cr, & fields->f_r1);
292 case M32R_OPERAND_SIMM8 :
293 errmsg = cgen_parse_signed_integer (strp, 7, -128, 127, &fields->f_simm8);
295 case M32R_OPERAND_SIMM16 :
296 errmsg = cgen_parse_signed_integer (strp, 8, -32768, 32767, &fields->f_simm16);
298 case M32R_OPERAND_UIMM4 :
299 errmsg = cgen_parse_unsigned_integer (strp, 9, 0, 15, &fields->f_uimm4);
301 case M32R_OPERAND_UIMM5 :
302 errmsg = cgen_parse_unsigned_integer (strp, 10, 0, 31, &fields->f_uimm5);
304 case M32R_OPERAND_UIMM16 :
305 errmsg = cgen_parse_unsigned_integer (strp, 11, 0, 65535, &fields->f_uimm16);
307 case M32R_OPERAND_HI16 :
308 errmsg = parse_h_hi16 (strp, 12, 0, 65535, &fields->f_hi16);
310 case M32R_OPERAND_SLO16 :
311 errmsg = parse_h_slo16 (strp, 13, -32768, 32767, &fields->f_simm16);
313 case M32R_OPERAND_ULO16 :
314 errmsg = parse_h_ulo16 (strp, 14, 0, 65535, &fields->f_uimm16);
316 case M32R_OPERAND_UIMM24 :
317 errmsg = cgen_parse_address (strp, 15, 0, NULL, & fields->f_uimm24);
319 case M32R_OPERAND_DISP8 :
320 errmsg = cgen_parse_address (strp, 16, 0, NULL, & fields->f_disp8);
322 case M32R_OPERAND_DISP16 :
323 errmsg = cgen_parse_address (strp, 17, 0, NULL, & fields->f_disp16);
325 case M32R_OPERAND_DISP24 :
326 errmsg = cgen_parse_address (strp, 18, 0, NULL, & fields->f_disp24);
330 fprintf (stderr, "Unrecognized field %d while parsing.\n", opindex);
337 /* Main entry point for operand insertion.
339 This function is basically just a big switch statement. Earlier versions
340 used tables to look up the function to use, but
341 - if the table contains both assembler and disassembler functions then
342 the disassembler contains much of the assembler and vice-versa,
343 - there's a lot of inlining possibilities as things grow,
344 - using a switch statement avoids the function call overhead.
346 This function could be moved into `parse_insn_normal', but keeping it
347 separate makes clear the interface between `parse_insn_normal' and each of
348 the handlers. It's also needed by GAS to insert operands that couldn't be
349 resolved during parsing.
353 m32r_cgen_insert_operand (opindex, fields, buffer)
355 CGEN_FIELDS * fields;
356 cgen_insn_t * buffer;
360 case M32R_OPERAND_SR :
361 insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
363 case M32R_OPERAND_DR :
364 insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
366 case M32R_OPERAND_SRC1 :
367 insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
369 case M32R_OPERAND_SRC2 :
370 insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
372 case M32R_OPERAND_SCR :
373 insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
375 case M32R_OPERAND_DCR :
376 insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
378 case M32R_OPERAND_SIMM8 :
379 insert_normal (fields->f_simm8, 0, 8, 8, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
381 case M32R_OPERAND_SIMM16 :
382 insert_normal (fields->f_simm16, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
384 case M32R_OPERAND_UIMM4 :
385 insert_normal (fields->f_uimm4, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
387 case M32R_OPERAND_UIMM5 :
388 insert_normal (fields->f_uimm5, 0|(1<<CGEN_OPERAND_UNSIGNED), 11, 5, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
390 case M32R_OPERAND_UIMM16 :
391 insert_normal (fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
393 case M32R_OPERAND_HI16 :
394 insert_normal (fields->f_hi16, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
396 case M32R_OPERAND_SLO16 :
397 insert_normal (fields->f_simm16, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
399 case M32R_OPERAND_ULO16 :
400 insert_normal (fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
402 case M32R_OPERAND_UIMM24 :
403 insert_normal (fields->f_uimm24, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), 8, 24, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
405 case M32R_OPERAND_DISP8 :
406 insert_normal (fields->f_disp8, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 8, 2, CGEN_FIELDS_BITSIZE (fields), buffer);
408 case M32R_OPERAND_DISP16 :
409 insert_normal (fields->f_disp16, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 16, 16, 2, CGEN_FIELDS_BITSIZE (fields), buffer);
411 case M32R_OPERAND_DISP24 :
412 insert_normal (fields->f_disp24, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 24, 2, CGEN_FIELDS_BITSIZE (fields), buffer);
416 fprintf (stderr, "Unrecognized field %d while building insn.\n",
422 /* Main entry point for operand validation.
424 This function is called from GAS when it has fully resolved an operand
425 that couldn't be resolved during parsing.
427 The result is NULL for success or an error message (which may be
428 computed into a static buffer).
431 CGEN_INLINE const char *
432 m32r_cgen_validate_operand (opindex, fields)
434 const CGEN_FIELDS * fields;
436 const char * errmsg = NULL;
440 case M32R_OPERAND_SR :
443 case M32R_OPERAND_DR :
446 case M32R_OPERAND_SRC1 :
449 case M32R_OPERAND_SRC2 :
452 case M32R_OPERAND_SCR :
455 case M32R_OPERAND_DCR :
458 case M32R_OPERAND_SIMM8 :
459 errmsg = cgen_validate_signed_integer (fields->f_simm8, -128, 127);
461 case M32R_OPERAND_SIMM16 :
462 errmsg = cgen_validate_signed_integer (fields->f_simm16, -32768, 32767);
464 case M32R_OPERAND_UIMM4 :
465 errmsg = cgen_validate_unsigned_integer (fields->f_uimm4, 0, 15);
467 case M32R_OPERAND_UIMM5 :
468 errmsg = cgen_validate_unsigned_integer (fields->f_uimm5, 0, 31);
470 case M32R_OPERAND_UIMM16 :
471 errmsg = cgen_validate_unsigned_integer (fields->f_uimm16, 0, 65535);
473 case M32R_OPERAND_HI16 :
474 errmsg = cgen_validate_unsigned_integer (fields->f_hi16, 0, 65535);
476 case M32R_OPERAND_SLO16 :
477 errmsg = cgen_validate_signed_integer (fields->f_simm16, -32768, 32767);
479 case M32R_OPERAND_ULO16 :
480 errmsg = cgen_validate_unsigned_integer (fields->f_uimm16, 0, 65535);
482 case M32R_OPERAND_UIMM24 :
485 case M32R_OPERAND_DISP8 :
488 case M32R_OPERAND_DISP16 :
491 case M32R_OPERAND_DISP24 :
496 fprintf (stderr, "Unrecognized field %d while validating operand.\n",
504 cgen_parse_fn * m32r_cgen_parse_handlers[] =
509 cgen_insert_fn * m32r_cgen_insert_handlers[] =
515 m32r_cgen_init_asm (mach, endian)
517 enum cgen_endian endian;
519 m32r_cgen_init_tables (mach);
520 cgen_set_cpu (& m32r_cgen_opcode_data, mach, endian);
525 /* Default insn parser.
527 The syntax string is scanned and operands are parsed and stored in FIELDS.
528 Relocs are queued as we go via other callbacks.
530 ??? Note that this is currently an all-or-nothing parser. If we fail to
531 parse the instruction, we return 0 and the caller will start over from
532 the beginning. Backtracking will be necessary in parsing subexpressions,
533 but that can be handled there. Not handling backtracking here may get
534 expensive in the case of the m68k. Deal with later.
536 Returns NULL for success, an error message for failure.
540 parse_insn_normal (insn, strp, fields)
541 const CGEN_INSN * insn;
543 CGEN_FIELDS * fields;
545 const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
546 const char * str = *strp;
549 const unsigned char * syn;
550 #ifdef CGEN_MNEMONIC_OPERANDS
554 /* For now we assume the mnemonic is first (there are no leading operands).
555 We can parse it without needing to set up operand parsing. */
556 p = CGEN_INSN_MNEMONIC (insn);
557 while (* p && * p == * str)
559 if (* p || (* str && !isspace (* str)))
560 return "unrecognized instruction";
563 cgen_init_parse_operand ();
564 #ifdef CGEN_MNEMONIC_OPERANDS
568 /* We don't check for (*str != '\0') here because we want to parse
569 any trailing fake arguments in the syntax string. */
570 syn = CGEN_SYNTAX_STRING (CGEN_INSN_SYNTAX (insn));
572 /* Mnemonics come first for now, ensure valid string. */
573 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
580 /* Non operand chars must match exactly. */
581 /* FIXME: Need to better handle whitespace. */
582 if (CGEN_SYNTAX_CHAR_P (* syn))
584 if (*str == CGEN_SYNTAX_CHAR (* syn))
586 #ifdef CGEN_MNEMONIC_OPERANDS
595 /* Syntax char didn't match. Can't be this insn. */
596 /* FIXME: would like to return "expected char `c'" */
597 return "syntax error";
602 /* We have an operand of some sort. */
603 errmsg = m32r_cgen_parse_operand (CGEN_SYNTAX_FIELD (*syn),
608 /* Done with this operand, continue with next one. */
612 /* If we're at the end of the syntax string, we're done. */
615 /* FIXME: For the moment we assume a valid `str' can only contain
616 blanks now. IE: We needn't try again with a longer version of
617 the insn and it is assumed that longer versions of insns appear
618 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
619 while (isspace (* str))
623 return "junk at end of line"; /* FIXME: would like to include `str' */
628 /* We couldn't parse it. */
629 return "unrecognized instruction";
632 /* Default insn builder (insert handler).
633 The instruction is recorded in target byte order. */
636 insert_insn_normal (insn, fields, buffer)
637 const CGEN_INSN * insn;
638 CGEN_FIELDS * fields;
639 cgen_insn_t * buffer;
641 const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
643 const unsigned char * syn;
646 value = CGEN_INSN_VALUE (insn);
648 /* If we're recording insns as numbers (rather than a string of bytes),
649 target byte order handling is deferred until later. */
651 #define min(a,b) ((a) < (b) ? (a) : (b))
652 #if 0 /*def CGEN_INT_INSN*/
655 switch (min (CGEN_BASE_INSN_BITSIZE, CGEN_FIELDS_BITSIZE (fields)))
661 if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
662 bfd_putb16 (value, (char *) buffer);
664 bfd_putl16 (value, (char *) buffer);
667 if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
668 bfd_putb32 (value, (char *) buffer);
670 bfd_putl32 (value, (char *) buffer);
677 /* ??? Rather than scanning the syntax string again, we could store
678 in `fields' a null terminated list of the fields that are present. */
680 for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
682 if (CGEN_SYNTAX_CHAR_P (* syn))
685 m32r_cgen_insert_operand (CGEN_SYNTAX_FIELD (*syn), fields, buffer);
690 This routine is called for each instruction to be assembled.
691 STR points to the insn to be assembled.
692 We assume all necessary tables have been initialized.
693 The result is a pointer to the insn's entry in the opcode table,
694 or NULL if an error occured (an error message will have already been
698 m32r_cgen_assemble_insn (str, fields, buf, errmsg)
700 CGEN_FIELDS * fields;
705 CGEN_INSN_LIST * ilist;
707 /* Skip leading white space. */
708 while (isspace (* str))
711 /* The instructions are stored in hashed lists.
712 Get the first in the list. */
713 ilist = CGEN_ASM_LOOKUP_INSN (str);
715 /* Keep looking until we find a match. */
718 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
720 const CGEN_INSN *insn = ilist->insn;
722 #if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */
723 /* Is this insn supported by the selected cpu? */
724 if (! m32r_cgen_insn_supported (insn))
728 #if 1 /* FIXME: wip */
729 /* If the RELAX attribute is set, this is an insn that shouldn't be
730 chosen immediately. Instead, it is used during assembler/linker
731 relaxation if possible. */
732 if (CGEN_INSN_ATTR (insn, CGEN_INSN_RELAX) != 0)
738 /* Record a default length for the insn. This will get set to the
739 correct value while parsing. */
741 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
743 /* ??? The extent to which moving the parse and insert handlers into
744 this function (thus removing the function call) will speed things up
745 is unclear. The simplicity and flexibility of the current scheme is
746 appropriate for now. One could have the best of both worlds with
747 inline functions but of course that would only work for gcc. Since
748 we're machine generating some code we could do that here too. Maybe
750 if (! CGEN_PARSE_FN (insn) (insn, & str, fields))
752 CGEN_INSERT_FN (insn) (insn, fields, buf);
753 /* It is up to the caller to actually output the insn and any
758 /* Try the next entry. */
761 /* FIXME: We can return a better error message than this.
762 Need to track why it failed and pick the right one. */
764 static char errbuf[100];
765 sprintf (errbuf, "bad instruction `%.50s%s'",
766 start, strlen (start) > 50 ? "..." : "");
772 #if 0 /* This calls back to GAS which we can't do without care. */
774 /* Record each member of OPVALS in the assembler's symbol table.
775 This lets GAS parse registers for us.
776 ??? Interesting idea but not currently used. */
778 /* Record each member of OPVALS in the assembler's symbol table.
779 FIXME: Not currently used. */
782 m32r_cgen_asm_hash_keywords (opvals)
783 CGEN_KEYWORD * opvals;
785 CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
786 const CGEN_KEYWORD_ENTRY * ke;
788 while ((ke = cgen_keyword_search_next (& search)) != NULL)
790 #if 0 /* Unnecessary, should be done in the search routine. */
791 if (! m32r_cgen_opval_supported (ke))
794 cgen_asm_record_register (ke->name, ke->value);