From a73911a7677e707677b21b7b0e90343f99f4594a Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Thu, 3 Dec 1998 08:14:46 +0000 Subject: * fr30-asm.c,fr30-dis.c,fr30-opc.c,fr30-opc.h: Regenerate. --- opcodes/fr30-asm.c | 298 ++++++++++++++++++++--------------------------------- 1 file changed, 110 insertions(+), 188 deletions(-) (limited to 'opcodes/fr30-asm.c') diff --git a/opcodes/fr30-asm.c b/opcodes/fr30-asm.c index 292946a..32b47a3 100644 --- a/opcodes/fr30-asm.c +++ b/opcodes/fr30-asm.c @@ -42,9 +42,12 @@ along with this program; if not, write to the Free Software Foundation, Inc., #define INLINE #endif +/* Used by the ifield rtx function. */ +#define FLD(f) (fields->f) + static const char * insert_normal - PARAMS ((CGEN_OPCODE_DESC, long, unsigned int, int, int, int, - CGEN_INSN_BYTES_PTR)); + PARAMS ((CGEN_OPCODE_DESC, long, unsigned int, unsigned int, unsigned int, + unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR)); static const char * parse_insn_normal PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *)); @@ -184,6 +187,16 @@ fr30_cgen_parse_operand (od, opindex, strp, fields) case FR30_OPERAND_I32 : errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_I32, &fields->f_i32); break; + case FR30_OPERAND_I20 : + errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_I20, &fields->f_i20); + break; + case FR30_OPERAND_LABEL9 : + { + bfd_vma value; + errmsg = cgen_parse_address (od, strp, FR30_OPERAND_LABEL9, 0, NULL, & value); + fields->f_rel9 = value; + } + break; case FR30_OPERAND_DIR8 : errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_DIR8, &fields->f_dir8); break; @@ -193,11 +206,12 @@ fr30_cgen_parse_operand (od, opindex, strp, fields) case FR30_OPERAND_DIR10 : errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_DIR10, &fields->f_dir10); break; - case FR30_OPERAND_LABEL9 : - errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_LABEL9, &fields->f_rel9); - break; case FR30_OPERAND_LABEL12 : - errmsg = cgen_parse_signed_integer (od, strp, FR30_OPERAND_LABEL12, &fields->f_rel12); + { + bfd_vma value; + errmsg = cgen_parse_address (od, strp, FR30_OPERAND_LABEL12, 0, NULL, & value); + fields->f_rel12 = value; + } break; case FR30_OPERAND_REGLIST_LOW : errmsg = parse_low_register_list (od, strp, FR30_OPERAND_REGLIST_LOW, &fields->f_reglist_low); @@ -245,147 +259,162 @@ fr30_cgen_insert_operand (od, opindex, fields, buffer, pc) bfd_vma pc; { const char * errmsg; + unsigned int total_length = CGEN_FIELDS_BITSIZE (fields); switch (opindex) { case FR30_OPERAND_RI : - errmsg = insert_normal (od, fields->f_Ri, 0|(1<f_Ri, 0|(1<f_Rj, 0|(1<f_Rj, 0|(1<f_Ric, 0|(1<f_Ric, 0|(1<f_Rjc, 0|(1<f_Rjc, 0|(1<f_CRi, 0|(1<f_CRi, 0|(1<f_CRj, 0|(1<f_CRj, 0|(1<f_Rs1, 0|(1<f_Rs1, 0|(1<f_Rs2, 0|(1<f_Rs2, 0|(1<f_nil, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), buffer); + errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer); break; case FR30_OPERAND_R14 : - errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), buffer); + errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer); break; case FR30_OPERAND_R15 : - errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), buffer); + errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer); break; case FR30_OPERAND_PS : - errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), buffer); + errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer); break; case FR30_OPERAND_U4 : - errmsg = insert_normal (od, fields->f_u4, 0|(1<f_u4, 0|(1<f_u4c, 0|(1<f_u4c, 0|(1<f_m4; value = ((value) & (15)); - errmsg = insert_normal (od, value, 0|(1<f_u8, 0|(1<f_u8, 0|(1<f_i8, 0|(1<f_i8, 0|(1<f_udisp6; value = ((unsigned int) (value) >> (2)); - errmsg = insert_normal (od, value, 0|(1<f_disp8, 0|(1<f_disp8, 0|(1<f_disp9; value = ((int) (value) >> (1)); - errmsg = insert_normal (od, value, 0|(1<f_disp10; value = ((int) (value) >> (2)); - errmsg = insert_normal (od, value, 0|(1<f_s10; value = ((int) (value) >> (2)); - errmsg = insert_normal (od, value, 0|(1<f_u10; value = ((unsigned int) (value) >> (2)); - errmsg = insert_normal (od, value, 0|(1<f_i32, 0|(1<f_i32, 0|(1<> (16)); + FLD (f_i20_16) = ((FLD (f_i20)) & (65535)); +} while (0); + errmsg = insert_normal (od, fields->f_i20_4, 0|(1<f_i20_16, 0|(1<f_rel9; + value = ((int) (((value) - (((pc) + (2))))) >> (1)); + errmsg = insert_normal (od, value, 0|(1<f_dir8, 0|(1<f_dir8, 0|(1<f_dir9; value = ((unsigned int) (value) >> (1)); - errmsg = insert_normal (od, value, 0|(1<f_dir10; value = ((unsigned int) (value) >> (2)); - errmsg = insert_normal (od, value, 0|(1<f_rel9; - value = ((int) (((value) - (((pc) + (2))))) >> (1)); - errmsg = insert_normal (od, value, 0|(1<f_rel12; value = ((int) (((value) - (((pc) & (-2))))) >> (1)); - errmsg = insert_normal (od, value, 0|(1<f_reglist_low, 0|(1<f_reglist_low, 0|(1<f_reglist_hi, 0|(1<f_reglist_hi, 0|(1<f_cc, 0|(1<f_cc, 0|(1<f_ccc, 0|(1<f_ccc, 0|(1< 32) + abort (); + + /* For architectures with insns smaller than the insn-base-bitsize, + word_length may be too big. */ +#if CGEN_MIN_INSN_BITSIZE < CGEN_BASE_INSN_BITSIZE + if (word_offset == 0 + && word_length > total_length) + word_length = total_length; +#endif + /* Ensure VALUE will fit. */ if ((attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED)) != 0) { @@ -570,144 +613,23 @@ insert_normal (od, value, attrs, start, length, total_length, buffer) #if CGEN_INT_INSN_P - if (total_length > 32) /* 32 bits in a portable host int */ - abort (); { int shift; if (CGEN_INSN_LSB0_P) - shift = start; + shift = (start + 1) - length; else - shift = total_length - (start + length); + shift = word_length - (start + length); *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift); } -#else - - /* FIXME: unfinished and untested */ - - /* The hard case is probably too slow for the normal cases. - It's certainly more difficult to understand than the normal case. - Thus this is split into two. The hard case is defined - to be when a field straddles a (loosely defined) word boundary - (??? which may require target specific help to determine). */ - -#if 0 /*wip*/ - -#define HARD_CASE_P 0 /* FIXME:wip */ +#else /* ! CGEN_INT_INSN_P */ - if (HARD_CASE_P) - { - unsigned char *bufp = (unsigned char *) buffer; - int insn_length_left = total_length; - - if (CGEN_INSN_LSB0_P) - { - int word_offset = (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG - ? ... - : start / CGEN_BASE_INSN_BITSIZE); - bufp += word_offset * (CGEN_BASE_INSN_BITSIZE / 8); - if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG) - else - start -= word_offset * CGEN_BASE_INSN_BITSIZE; - } - else - { - int word_offset = (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG - ? start / CGEN_BASE_INSN_BITSIZE - : ...); - bufp += word_offset * (CGEN_BASE_INSN_BITSIZE / 8); - if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG) - start -= word_offset * CGEN_BASE_INSN_BITSIZE; - else - } - - /* Loop so we handle a field straddling an insn word boundary - (remember, "insn word boundary" is loosely defined here). */ - - while (length > 0) - { - int this_pass_length = length; - int this_pass_start = start; - int this_pass_word_length = min (insn_length_left, - (CGEN_BASE_INSN_BITSIZE == 8 - ? 32 - : CGEN_BASE_INSN_BITSIZE)); - - insert_1 (od, value, attrs, - this_pass_start, this_pass_length, this_pass_word_length, - bufp); - - length -= this_pass_length; - insn_length_left -= this_pass_word_length; - if (???) - { - value >>= ???; - start += ???; - } - else - { - value >>= ???; - start += ???; - } - bufp += this_pass_word_length / 8; - } - } - else -#endif /* 0 */ - { - unsigned char *bufp = (unsigned char *) buffer; - - if (length > 32) - abort (); - - /* Adjust start,total_length,bufp to point to the pseudo-word that holds - the value. For example in a 48 bit insn where the value to insert - (say an immediate value) is the last 16 bits then fetch_length here - would be 16. To handle a 24 bit insn with an 18 bit immediate, - insert_1 handles 24 bits. */ - - if (total_length > 32) - { - int needed_width = start % 8 + length; - int fetch_length = (needed_width <= 8 ? 8 - : needed_width <= 16 ? 16 - : 32); - - if (CGEN_INSN_LSB0_P) - { - if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG) - { - abort (); /* wip */ - } - else - { - int offset = start & ~7; - - bufp += offset / 8; - start -= offset; - total_length = fetch_length; - } - } - else - { - if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG) - { - int offset = start & ~7; - - bufp += offset / 8; - start -= offset; - total_length = fetch_length; - } - else - { - abort (); /* wip */ - } - } - } + { + unsigned char *bufp = (unsigned char *) buffer + word_offset / 8; - insert_1 (od, value, start, length, total_length, bufp); - } + insert_1 (od, value, start, length, word_length, bufp); + } #endif /* ! CGEN_INT_INSN_P */ @@ -846,7 +768,7 @@ insert_insn_normal (od, insn, fields, buffer, pc) const unsigned char * syn; CGEN_INIT_INSERT (od); - value = CGEN_INSN_VALUE (insn); + value = CGEN_INSN_BASE_VALUE (insn); /* If we're recording insns as numbers (rather than a string of bytes), target byte order handling is deferred until later. */ @@ -863,8 +785,10 @@ insert_insn_normal (od, insn, fields, buffer, pc) #endif /* ! CGEN_INT_INSN_P */ - /* ??? Rather than scanning the syntax string again, we could store - in `fields' a null terminated list of the fields that are present. */ + /* ??? It would be better to scan the format's fields. + Still need to be able to insert a value based on the operand though; + e.g. storing a branch displacement that got resolved later. + Needs more thought first. */ for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn) { @@ -937,9 +861,7 @@ fr30_cgen_assemble_insn (od, str, fields, buf, errmsg) str = start; - /* Record a default length for the insn. This will get set to the - correct value while parsing. */ - /* FIXME: wip */ + /* Allow parse/insert handlers to obtain length of insn. */ CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); if (! CGEN_PARSE_FN (insn) (od, insn, & str, fields)) -- cgit v1.1