From a73911a7677e707677b21b7b0e90343f99f4594a Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Thu, 3 Dec 1998 08:14:46 +0000 Subject: [PATCH] * fr30-asm.c,fr30-dis.c,fr30-opc.c,fr30-opc.h: Regenerate. --- opcodes/ChangeLog | 6 + opcodes/fr30-asm.c | 298 +++++++++-------------- opcodes/fr30-dis.c | 236 ++++++++---------- opcodes/fr30-opc.c | 690 +++++++++++++++++++++++++++++++++++++---------------- opcodes/fr30-opc.h | 119 ++++++--- 5 files changed, 786 insertions(+), 563 deletions(-) diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index af34477..10c17b5 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,9 @@ +start-sanitize-fr30 +Thu Dec 3 00:09:17 1998 Doug Evans + + * fr30-asm.c,fr30-dis.c,fr30-opc.c,fr30-opc.h: Regenerate. + +end-sanitize-fr30 1998-11-30 Doug Evans * cgen-dis.c (hash_insn_array): CGEN_INSN_VALUE -> 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)) diff --git a/opcodes/fr30-dis.c b/opcodes/fr30-dis.c index 750e5ab..76ca095 100644 --- a/opcodes/fr30-dis.c +++ b/opcodes/fr30-dis.c @@ -40,9 +40,13 @@ along with this program; if not, write to the Free Software Foundation, Inc., /* Default text to print if an instruction isn't recognized. */ #define UNKNOWN_INSN_MSG _("*unknown*") +/* Used by the ifield rtx function. */ +#define FLD(f) (fields->f) + static int extract_normal PARAMS ((CGEN_OPCODE_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, - unsigned int, int, int, int, bfd_vma, long *)); + unsigned int, unsigned int, unsigned int, unsigned int, + unsigned int, unsigned int, bfd_vma, long *)); static void print_normal PARAMS ((CGEN_OPCODE_DESC, PTR, long, unsigned int, bfd_vma, int)); static void print_address @@ -108,19 +112,6 @@ print_low_register_list (od, dis_info, value, attrs, pc, length) print_register_list (dis_info, value, 0); } -static void -print_label9 (od, dis_info, value, attrs, pc, length) - CGEN_OPCODE_DESC od; - PTR dis_info; - long value; - unsigned int attrs; - bfd_vma pc; - int length; -{ - disassemble_info *info = (disassemble_info *) dis_info; - (*info->fprintf_func) (info->stream, "0x%lx", value); -} - /* -- */ /* Main entry point for operand extraction. @@ -147,80 +138,81 @@ fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc) bfd_vma pc; { int length; + unsigned int total_length = CGEN_FIELDS_BITSIZE (fields); switch (opindex) { case FR30_OPERAND_RI : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_Ri); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_Ri); break; case FR30_OPERAND_RJ : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_Rj); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_Rj); break; case FR30_OPERAND_RIC : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_Ric); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_Ric); break; case FR30_OPERAND_RJC : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_Rjc); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_Rjc); break; case FR30_OPERAND_CRI : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_CRi); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_CRi); break; case FR30_OPERAND_CRJ : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_CRj); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_CRj); break; case FR30_OPERAND_RS1 : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_Rs1); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_Rs1); break; case FR30_OPERAND_RS2 : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_Rs2); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_Rs2); break; case FR30_OPERAND_R13 : - length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil); + length = extract_normal (od, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil); break; case FR30_OPERAND_R14 : - length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil); + length = extract_normal (od, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil); break; case FR30_OPERAND_R15 : - length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil); + length = extract_normal (od, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil); break; case FR30_OPERAND_PS : - length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil); + length = extract_normal (od, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil); break; case FR30_OPERAND_U4 : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_u4); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_u4); break; case FR30_OPERAND_U4C : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_u4c); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_u4c); break; case FR30_OPERAND_M4 : { long value; - length = extract_normal (od, ex_info, insn_value, 0|(1<f_m4 = value; } break; case FR30_OPERAND_U8 : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_u8); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_u8); break; case FR30_OPERAND_I8 : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_i8); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_i8); break; case FR30_OPERAND_UDISP6 : { long value; - length = extract_normal (od, ex_info, insn_value, 0|(1<f_udisp6 = value; } break; case FR30_OPERAND_DISP8 : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_disp8); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_disp8); break; case FR30_OPERAND_DISP9 : { long value; - length = extract_normal (od, ex_info, insn_value, 0|(1<f_disp9 = value; } @@ -228,7 +220,7 @@ fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc) case FR30_OPERAND_DISP10 : { long value; - length = extract_normal (od, ex_info, insn_value, 0|(1<f_disp10 = value; } @@ -236,7 +228,7 @@ fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc) case FR30_OPERAND_S10 : { long value; - length = extract_normal (od, ex_info, insn_value, 0|(1<f_s10 = value; } @@ -244,21 +236,38 @@ fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc) case FR30_OPERAND_U10 : { long value; - length = extract_normal (od, ex_info, insn_value, 0|(1<f_u10 = value; } break; case FR30_OPERAND_I32 : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_i32); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_i32); + break; + case FR30_OPERAND_I20 : + { + length = extract_normal (od, ex_info, insn_value, 0|(1<f_i20_4); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_i20_16); +do { + FLD (f_i20) = ((((FLD (f_i20_4)) << (16))) | (FLD (f_i20_16))); +} while (0); + } + break; + case FR30_OPERAND_LABEL9 : + { + long value; + length = extract_normal (od, ex_info, insn_value, 0|(1<f_rel9 = value; + } break; case FR30_OPERAND_DIR8 : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_dir8); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_dir8); break; case FR30_OPERAND_DIR9 : { long value; - length = extract_normal (od, ex_info, insn_value, 0|(1<f_dir9 = value; } @@ -266,38 +275,30 @@ fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc) case FR30_OPERAND_DIR10 : { long value; - length = extract_normal (od, ex_info, insn_value, 0|(1<f_dir10 = value; } break; - case FR30_OPERAND_LABEL9 : - { - long value; - length = extract_normal (od, ex_info, insn_value, 0|(1<f_rel9 = value; - } - break; case FR30_OPERAND_LABEL12 : { long value; - length = extract_normal (od, ex_info, insn_value, 0|(1<f_rel12 = value; } break; case FR30_OPERAND_REGLIST_LOW : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_reglist_low); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_reglist_low); break; case FR30_OPERAND_REGLIST_HI : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_reglist_hi); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_reglist_hi); break; case FR30_OPERAND_CC : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_cc); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_cc); break; case FR30_OPERAND_CCC : - length = extract_normal (od, ex_info, insn_value, 0|(1<f_ccc); + length = extract_normal (od, ex_info, insn_value, 0|(1<f_ccc); break; default : @@ -408,6 +409,12 @@ fr30_cgen_print_operand (od, opindex, info, fields, attrs, pc, length) case FR30_OPERAND_I32 : print_normal (od, info, fields->f_i32, 0|(1<f_i20, 0|(1<f_rel9, 0|(1<f_dir8, 0|(1<f_dir10, 0|(1<f_rel9, 0|(1<f_rel12, 0|(1<f_rel12, 0|(1<f_reglist_low, 0|(1<> shift) & mask; @@ -571,26 +577,33 @@ extract_1 (od, ex_info, start, length, word_length, bufp, pc) INSN_VALUE is the first CGEN_BASE_INSN_SIZE bits of the insn in host order, or sometimes less for cases like the m32r where the base insn size is 32 but some insns are 16 bits. - ATTRS is a mask of the boolean attributes. We only need `unsigned', + ATTRS is a mask of the boolean attributes. We only need `UNSIGNED', but for generality we take a bitmask of all of them. - TOTAL_LENGTH is the length of the insn in bits. + WORD_OFFSET is the offset in bits from the start of the insn of the value. + WORD_LENGTH is the length of the word in bits in which the value resides. + START is the starting bit number in the word, architecture origin. + LENGTH is the length of VALUE in bits. + TOTAL_LENGTH is the total length of the insn in bits. Returns 1 for success, 0 for failure. */ +/* ??? The return code isn't properly used. wip. */ + /* ??? This doesn't handle bfd_vma's. Create another function when necessary. */ static int -extract_normal (od, ex_info, insn_value, attrs, start, length, total_length, pc, valuep) +extract_normal (od, ex_info, insn_value, attrs, word_offset, start, length, + word_length, total_length, pc, valuep) CGEN_OPCODE_DESC od; CGEN_EXTRACT_INFO *ex_info; CGEN_INSN_INT insn_value; unsigned int attrs; - int start, length, total_length; + unsigned int word_offset, start, length, word_length, total_length; bfd_vma pc; long *valuep; { - unsigned long value; + CGEN_INSN_INT value; /* If LENGTH is zero, this operand doesn't contribute to the value so give it a standard value of zero. */ @@ -601,17 +614,31 @@ extract_normal (od, ex_info, insn_value, attrs, start, length, total_length, pc, } if (CGEN_INT_INSN_P - || (CGEN_INSN_LSB0_P - ? ((total_length - start) <= CGEN_BASE_INSN_BITSIZE) - : ((start + length) <= CGEN_BASE_INSN_BITSIZE))) + && word_offset != 0) + abort (); + + if (word_length > 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 + + /* Does the value reside in INSN_VALUE? */ + + if (word_offset == 0) { /* Written this way to avoid undefined behaviour. */ - unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1; + CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1; if (CGEN_INSN_LSB0_P) - value = insn_value >> start; + value = insn_value >> ((start + 1) - length); else - value = insn_value >> (total_length - (start + length)); + value = insn_value >> (word_length - (start + length)); value &= mask; /* sign extend? */ if (! (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED)) @@ -621,75 +648,17 @@ extract_normal (od, ex_info, insn_value, attrs, start, length, total_length, pc, #if ! CGEN_INT_INSN_P - /* 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). */ - -#define HARD_CASE_P 0 /* FIXME:wip */ - - else if (HARD_CASE_P) - { - } - else { - unsigned char *bufp = ex_info->insn_bytes; - int offset = 0; + unsigned char *bufp = ex_info->insn_bytes + word_offset / 8; - if (length > 32) + if (word_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, - extract_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 - { - offset = start & ~7; - - bufp += offset / 8; - start -= offset; - total_length = fetch_length; - } - } - else - { - if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG) - { - offset = start & ~7; - - bufp += offset / 8; - start -= offset; - total_length = fetch_length; - } - else - { - abort (); /* wip */ - } - } - } - - if (fill_cache (od, ex_info, offset / 8, total_length / 8, pc) == 0) + if (fill_cache (od, ex_info, word_offset / 8, word_length / 8, pc) == 0) return 0; - value = extract_1 (od, ex_info, start, length, total_length, bufp, pc); + value = extract_1 (od, ex_info, start, length, word_length, bufp, pc); } #endif /* ! CGEN_INT_INSN_P */ @@ -912,7 +881,8 @@ print_insn (od, pc, info, buf, buflen) /* Basic bit mask must be correct. */ /* ??? May wish to allow target to defer this check until the extract handler. */ - if ((insn_value & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn)) + if ((insn_value & CGEN_INSN_BASE_MASK (insn)) + == CGEN_INSN_BASE_VALUE (insn)) { /* Printing is handled in two passes. The first pass parses the machine insn and extracts the fields. The second pass prints diff --git a/opcodes/fr30-opc.c b/opcodes/fr30-opc.c index 331d377..4539432 100644 --- a/opcodes/fr30-opc.c +++ b/opcodes/fr30-opc.c @@ -30,6 +30,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., #include "fr30-opc.h" #include "opintl.h" +/* Used by the ifield rtx function. */ +#define FLD(f) (fields->f) + /* The hash functions are recorded here to help keep assembler code out of the disassembler and vice versa. */ @@ -98,7 +101,8 @@ fr30_cgen_lookup_insn (od, insn, insn_value, length, fields, alias_p) /* Basic bit mask must be correct. */ /* ??? May wish to allow target to defer this check until the extract handler. */ - if ((base_insn & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn)) + if ((base_insn & CGEN_INSN_BASE_MASK (insn)) + == CGEN_INSN_BASE_VALUE (insn)) { /* ??? 0 is passed for `pc' */ int elength = (*CGEN_EXTRACT_FN (insn)) (od, insn, info, @@ -222,11 +226,11 @@ const CGEN_ATTR_TABLE fr30_cgen_operand_attr_table[] = { "NEGATIVE", NULL }, { "PCREL-ADDR", NULL }, { "RELAX", NULL }, - { "RELOC", NULL }, { "SEM-ONLY", NULL }, { "SIGN-OPT", NULL }, { "SIGNED", NULL }, { "UNSIGNED", NULL }, + { "VIRTUAL", NULL }, { 0, 0 } }; @@ -234,7 +238,9 @@ const CGEN_ATTR_TABLE fr30_cgen_insn_attr_table[] = { { "ALIAS", NULL }, { "COND-CTI", NULL }, + { "DELAY-SLOT", NULL }, { "NO-DIS", NULL }, + { "NOT-IN-DELAY-SLOT", NULL }, { "RELAX", NULL }, { "RELAXABLE", NULL }, { "SKIP-CTI", NULL }, @@ -386,6 +392,51 @@ static const CGEN_HW_ENTRY fr30_cgen_hw_entries[] = { 0 } }; +/* The instruction field table. */ + +static const CGEN_IFLD fr30_cgen_ifld_table[] = +{ + { FR30_F_NIL, "f-nil", 0, 0, 0, 0, { 0, 0, { 0 } } }, + { FR30_F_OP1, "f-op1", 0, 16, 0, 4, { 0, 0|(1<f_i32; break; + case FR30_OPERAND_I20 : + value = fields->f_i20; + break; + case FR30_OPERAND_LABEL9 : + value = fields->f_rel9; + break; case FR30_OPERAND_DIR8 : value = fields->f_dir8; break; @@ -2454,9 +2730,6 @@ fr30_cgen_get_int_operand (opindex, fields) case FR30_OPERAND_DIR10 : value = fields->f_dir10; break; - case FR30_OPERAND_LABEL9 : - value = fields->f_rel9; - break; case FR30_OPERAND_LABEL12 : value = fields->f_rel12; break; @@ -2564,6 +2837,12 @@ fr30_cgen_get_vma_operand (opindex, fields) case FR30_OPERAND_I32 : value = fields->f_i32; break; + case FR30_OPERAND_I20 : + value = fields->f_i20; + break; + case FR30_OPERAND_LABEL9 : + value = fields->f_rel9; + break; case FR30_OPERAND_DIR8 : value = fields->f_dir8; break; @@ -2573,9 +2852,6 @@ fr30_cgen_get_vma_operand (opindex, fields) case FR30_OPERAND_DIR10 : value = fields->f_dir10; break; - case FR30_OPERAND_LABEL9 : - value = fields->f_rel9; - break; case FR30_OPERAND_LABEL12 : value = fields->f_rel12; break; @@ -2687,6 +2963,12 @@ fr30_cgen_set_int_operand (opindex, fields, value) case FR30_OPERAND_I32 : fields->f_i32 = value; break; + case FR30_OPERAND_I20 : + fields->f_i20 = value; + break; + case FR30_OPERAND_LABEL9 : + fields->f_rel9 = value; + break; case FR30_OPERAND_DIR8 : fields->f_dir8 = value; break; @@ -2696,9 +2978,6 @@ fr30_cgen_set_int_operand (opindex, fields, value) case FR30_OPERAND_DIR10 : fields->f_dir10 = value; break; - case FR30_OPERAND_LABEL9 : - fields->f_rel9 = value; - break; case FR30_OPERAND_LABEL12 : fields->f_rel12 = value; break; @@ -2803,6 +3082,12 @@ fr30_cgen_set_vma_operand (opindex, fields, value) case FR30_OPERAND_I32 : fields->f_i32 = value; break; + case FR30_OPERAND_I20 : + fields->f_i20 = value; + break; + case FR30_OPERAND_LABEL9 : + fields->f_rel9 = value; + break; case FR30_OPERAND_DIR8 : fields->f_dir8 = value; break; @@ -2812,9 +3097,6 @@ fr30_cgen_set_vma_operand (opindex, fields, value) case FR30_OPERAND_DIR10 : fields->f_dir10 = value; break; - case FR30_OPERAND_LABEL9 : - fields->f_rel9 = value; - break; case FR30_OPERAND_LABEL12 : fields->f_rel12 = value; break; diff --git a/opcodes/fr30-opc.h b/opcodes/fr30-opc.h index 0eb8b1a..b268b3a 100644 --- a/opcodes/fr30-opc.h +++ b/opcodes/fr30-opc.h @@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define CGEN_ARCH fr30 -/* Given symbol S, return fr30_cgen_. */ +/* Given symbol S, return fr30_cgen_. */ #define CGEN_SYM(s) CONCAT3 (fr30,_cgen_,s) /* Selected cpu families. */ @@ -54,6 +54,9 @@ with this program; if not, write to the Free Software Foundation, Inc., /* Maximum number of operands any insn or macro-insn has. */ #define CGEN_MAX_INSN_OPERANDS 16 +/* Maximum number of fields in an instruction. */ +#define CGEN_MAX_IFMT_OPERANDS 7 + /* Enums. */ /* Enum declaration for insn op1 enums. */ @@ -149,11 +152,11 @@ typedef enum cgen_operand_type { , FR30_OPERAND_PS, FR30_OPERAND_U4, FR30_OPERAND_U4C, FR30_OPERAND_M4 , FR30_OPERAND_U8, FR30_OPERAND_I8, FR30_OPERAND_UDISP6, FR30_OPERAND_DISP8 , FR30_OPERAND_DISP9, FR30_OPERAND_DISP10, FR30_OPERAND_S10, FR30_OPERAND_U10 - , FR30_OPERAND_I32, FR30_OPERAND_DIR8, FR30_OPERAND_DIR9, FR30_OPERAND_DIR10 - , FR30_OPERAND_LABEL9, FR30_OPERAND_LABEL12, FR30_OPERAND_REGLIST_LOW, FR30_OPERAND_REGLIST_HI - , FR30_OPERAND_CC, FR30_OPERAND_CCC, FR30_OPERAND_NBIT, FR30_OPERAND_VBIT - , FR30_OPERAND_ZBIT, FR30_OPERAND_CBIT, FR30_OPERAND_IBIT, FR30_OPERAND_SBIT - , FR30_OPERAND_MAX + , FR30_OPERAND_I32, FR30_OPERAND_I20, FR30_OPERAND_LABEL9, FR30_OPERAND_DIR8 + , FR30_OPERAND_DIR9, FR30_OPERAND_DIR10, FR30_OPERAND_LABEL12, FR30_OPERAND_REGLIST_LOW + , FR30_OPERAND_REGLIST_HI, FR30_OPERAND_CC, FR30_OPERAND_CCC, FR30_OPERAND_NBIT + , FR30_OPERAND_VBIT, FR30_OPERAND_ZBIT, FR30_OPERAND_CBIT, FR30_OPERAND_IBIT + , FR30_OPERAND_SBIT, FR30_OPERAND_MAX } CGEN_OPERAND_TYPE; /* Non-boolean attributes. */ @@ -182,11 +185,38 @@ typedef enum cgen_hw_attr { /* Number of non-boolean elements in cgen_hw. */ #define CGEN_HW_NBOOL_ATTRS ((int) CGEN_HW_CACHE_ADDR) +/* Hardware, operand and instruction attribute indices. */ + +/* Enum declaration for cgen_ifld attrs. */ +typedef enum cgen_ifld_attr { + CGEN_IFLD_ABS_ADDR, CGEN_IFLD_PCREL_ADDR, CGEN_IFLD_RESERVED, CGEN_IFLD_SIGN_OPT + , CGEN_IFLD_SIGNED, CGEN_IFLD_UNSIGNED, CGEN_IFLD_VIRTUAL +} CGEN_IFLD_ATTR; + +/* Number of non-boolean elements in cgen_ifld. */ +#define CGEN_IFLD_NBOOL_ATTRS ((int) CGEN_IFLD_ABS_ADDR) + +/* Enum declaration for fr30 ifield types. */ +typedef enum ifield_type { + FR30_F_NIL, FR30_F_OP1, FR30_F_OP2, FR30_F_OP3 + , FR30_F_OP4, FR30_F_OP5, FR30_F_CC, FR30_F_CCC + , FR30_F_RJ, FR30_F_RI, FR30_F_RS1, FR30_F_RS2 + , FR30_F_RJC, FR30_F_RIC, FR30_F_CRJ, FR30_F_CRI + , FR30_F_U4, FR30_F_U4C, FR30_F_I4, FR30_F_M4 + , FR30_F_U8, FR30_F_I8, FR30_F_I20_4, FR30_F_I20_16 + , FR30_F_I20, FR30_F_I32, FR30_F_UDISP6, FR30_F_DISP8 + , FR30_F_DISP9, FR30_F_DISP10, FR30_F_S10, FR30_F_U10 + , FR30_F_REL9, FR30_F_DIR8, FR30_F_DIR9, FR30_F_DIR10 + , FR30_F_REL12, FR30_F_REGLIST_HI, FR30_F_REGLIST_LOW, FR30_F_MAX +} IFIELD_TYPE; + +#define MAX_IFLD ((int) FR30_F_MAX) + /* Enum declaration for cgen_operand attrs. */ typedef enum cgen_operand_attr { CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_HASH_PREFIX, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_PCREL_ADDR , CGEN_OPERAND_RELAX, CGEN_OPERAND_SEM_ONLY, CGEN_OPERAND_SIGN_OPT, CGEN_OPERAND_SIGNED - , CGEN_OPERAND_UNSIGNED + , CGEN_OPERAND_UNSIGNED, CGEN_OPERAND_VIRTUAL } CGEN_OPERAND_ATTR; /* Number of non-boolean elements in cgen_operand. */ @@ -194,8 +224,9 @@ typedef enum cgen_operand_attr { /* Enum declaration for cgen_insn attrs. */ typedef enum cgen_insn_attr { - CGEN_INSN_ALIAS, CGEN_INSN_COND_CTI, CGEN_INSN_NO_DIS, CGEN_INSN_RELAX - , CGEN_INSN_RELAXABLE, CGEN_INSN_SKIP_CTI, CGEN_INSN_UNCOND_CTI, CGEN_INSN_VIRTUAL + CGEN_INSN_ALIAS, CGEN_INSN_COND_CTI, CGEN_INSN_DELAY_SLOT, CGEN_INSN_NO_DIS + , CGEN_INSN_NOT_IN_DELAY_SLOT, CGEN_INSN_RELAX, CGEN_INSN_RELAXABLE, CGEN_INSN_SKIP_CTI + , CGEN_INSN_UNCOND_CTI, CGEN_INSN_VIRTUAL } CGEN_INSN_ATTR; /* Number of non-boolean elements in cgen_insn. */ @@ -216,35 +247,35 @@ typedef enum cgen_insn_type { , FR30_INSN_DIV1, FR30_INSN_DIV2, FR30_INSN_DIV3, FR30_INSN_DIV4S , FR30_INSN_LSL, FR30_INSN_LSLI, FR30_INSN_LSL2, FR30_INSN_LSR , FR30_INSN_LSRI, FR30_INSN_LSR2, FR30_INSN_ASR, FR30_INSN_ASRI - , FR30_INSN_ASR2, FR30_INSN_LDI_8, FR30_INSN_LDI32, FR30_INSN_LD - , FR30_INSN_LDUH, FR30_INSN_LDUB, FR30_INSN_LDR13, FR30_INSN_LDR13UH - , FR30_INSN_LDR13UB, FR30_INSN_LDR14, FR30_INSN_LDR14UH, FR30_INSN_LDR14UB - , FR30_INSN_LDR15, FR30_INSN_LDR15GR, FR30_INSN_LDR15DR, FR30_INSN_LDR15PS - , FR30_INSN_ST, FR30_INSN_STH, FR30_INSN_STB, FR30_INSN_STR13 - , FR30_INSN_STR13H, FR30_INSN_STR13B, FR30_INSN_STR14, FR30_INSN_STR14H - , FR30_INSN_STR14B, FR30_INSN_STR15, FR30_INSN_STR15GR, FR30_INSN_STR15DR - , FR30_INSN_STR15PS, FR30_INSN_MOV, FR30_INSN_MOVDR, FR30_INSN_MOVPS - , FR30_INSN_MOV2DR, FR30_INSN_MOV2PS, FR30_INSN_JMP, FR30_INSN_JMPD - , FR30_INSN_CALLR, FR30_INSN_CALLRD, FR30_INSN_CALL, FR30_INSN_CALLD - , FR30_INSN_RET, FR30_INSN_RETD, FR30_INSN_INT, FR30_INSN_INTE - , FR30_INSN_RETI, FR30_INSN_BRA, FR30_INSN_BNO, FR30_INSN_BEQ - , FR30_INSN_BNE, FR30_INSN_BC, FR30_INSN_BNC, FR30_INSN_BN - , FR30_INSN_BP, FR30_INSN_BV, FR30_INSN_BNV, FR30_INSN_BLT - , FR30_INSN_BGE, FR30_INSN_BLE, FR30_INSN_BGT, FR30_INSN_BLS - , FR30_INSN_BHI, FR30_INSN_BRAD, FR30_INSN_BNOD, FR30_INSN_BEQD - , FR30_INSN_BNED, FR30_INSN_BCD, FR30_INSN_BNCD, FR30_INSN_BND - , FR30_INSN_BPD, FR30_INSN_BVD, FR30_INSN_BNVD, FR30_INSN_BLTD - , FR30_INSN_BGED, FR30_INSN_BLED, FR30_INSN_BGTD, FR30_INSN_BLSD - , FR30_INSN_BHID, FR30_INSN_DMOVR13, FR30_INSN_DMOVR13H, FR30_INSN_DMOVR13B - , FR30_INSN_DMOVR13PI, FR30_INSN_DMOVR13PIH, FR30_INSN_DMOVR13PIB, FR30_INSN_DMOVR15PI - , FR30_INSN_DMOV2R13, FR30_INSN_DMOV2R13H, FR30_INSN_DMOV2R13B, FR30_INSN_DMOV2R13PI - , FR30_INSN_DMOV2R13PIH, FR30_INSN_DMOV2R13PIB, FR30_INSN_DMOV2R15PD, FR30_INSN_LDRES - , FR30_INSN_STRES, FR30_INSN_COPOP, FR30_INSN_COPLD, FR30_INSN_COPST - , FR30_INSN_COPSV, FR30_INSN_NOP, FR30_INSN_ANDCCR, FR30_INSN_ORCCR - , FR30_INSN_STILM, FR30_INSN_ADDSP, FR30_INSN_EXTSB, FR30_INSN_EXTUB - , FR30_INSN_EXTSH, FR30_INSN_EXTUH, FR30_INSN_LDM0, FR30_INSN_LDM1 - , FR30_INSN_STM0, FR30_INSN_STM1, FR30_INSN_ENTER, FR30_INSN_LEAVE - , FR30_INSN_XCHB, FR30_INSN_MAX + , FR30_INSN_ASR2, FR30_INSN_LDI8, FR30_INSN_LDI20, FR30_INSN_LDI32 + , FR30_INSN_LD, FR30_INSN_LDUH, FR30_INSN_LDUB, FR30_INSN_LDR13 + , FR30_INSN_LDR13UH, FR30_INSN_LDR13UB, FR30_INSN_LDR14, FR30_INSN_LDR14UH + , FR30_INSN_LDR14UB, FR30_INSN_LDR15, FR30_INSN_LDR15GR, FR30_INSN_LDR15DR + , FR30_INSN_LDR15PS, FR30_INSN_ST, FR30_INSN_STH, FR30_INSN_STB + , FR30_INSN_STR13, FR30_INSN_STR13H, FR30_INSN_STR13B, FR30_INSN_STR14 + , FR30_INSN_STR14H, FR30_INSN_STR14B, FR30_INSN_STR15, FR30_INSN_STR15GR + , FR30_INSN_STR15DR, FR30_INSN_STR15PS, FR30_INSN_MOV, FR30_INSN_MOVDR + , FR30_INSN_MOVPS, FR30_INSN_MOV2DR, FR30_INSN_MOV2PS, FR30_INSN_JMP + , FR30_INSN_JMPD, FR30_INSN_CALLR, FR30_INSN_CALLRD, FR30_INSN_CALL + , FR30_INSN_CALLD, FR30_INSN_RET, FR30_INSN_RETD, FR30_INSN_INT + , FR30_INSN_INTE, FR30_INSN_RETI, FR30_INSN_BRA, FR30_INSN_BNO + , FR30_INSN_BEQ, FR30_INSN_BNE, FR30_INSN_BC, FR30_INSN_BNC + , FR30_INSN_BN, FR30_INSN_BP, FR30_INSN_BV, FR30_INSN_BNV + , FR30_INSN_BLT, FR30_INSN_BGE, FR30_INSN_BLE, FR30_INSN_BGT + , FR30_INSN_BLS, FR30_INSN_BHI, FR30_INSN_BRAD, FR30_INSN_BNOD + , FR30_INSN_BEQD, FR30_INSN_BNED, FR30_INSN_BCD, FR30_INSN_BNCD + , FR30_INSN_BND, FR30_INSN_BPD, FR30_INSN_BVD, FR30_INSN_BNVD + , FR30_INSN_BLTD, FR30_INSN_BGED, FR30_INSN_BLED, FR30_INSN_BGTD + , FR30_INSN_BLSD, FR30_INSN_BHID, FR30_INSN_DMOVR13, FR30_INSN_DMOVR13H + , FR30_INSN_DMOVR13B, FR30_INSN_DMOVR13PI, FR30_INSN_DMOVR13PIH, FR30_INSN_DMOVR13PIB + , FR30_INSN_DMOVR15PI, FR30_INSN_DMOV2R13, FR30_INSN_DMOV2R13H, FR30_INSN_DMOV2R13B + , FR30_INSN_DMOV2R13PI, FR30_INSN_DMOV2R13PIH, FR30_INSN_DMOV2R13PIB, FR30_INSN_DMOV2R15PD + , FR30_INSN_LDRES, FR30_INSN_STRES, FR30_INSN_COPOP, FR30_INSN_COPLD + , FR30_INSN_COPST, FR30_INSN_COPSV, FR30_INSN_NOP, FR30_INSN_ANDCCR + , FR30_INSN_ORCCR, FR30_INSN_STILM, FR30_INSN_ADDSP, FR30_INSN_EXTSB + , FR30_INSN_EXTUB, FR30_INSN_EXTSH, FR30_INSN_EXTUH, FR30_INSN_LDM0 + , FR30_INSN_LDM1, FR30_INSN_STM0, FR30_INSN_STM1, FR30_INSN_ENTER + , FR30_INSN_LEAVE, FR30_INSN_XCHB, FR30_INSN_MAX } CGEN_INSN_TYPE; /* Index of `invalid' insn place holder. */ @@ -280,6 +311,9 @@ struct cgen_fields long f_m4; long f_u8; long f_i8; + long f_i20_4; + long f_i20_16; + long f_i20; long f_i32; long f_udisp6; long f_disp8; @@ -336,6 +370,15 @@ extern CGEN_KEYWORD fr30_cgen_opval_h_r15; {\ } +/* -- opc.h */ + +/* ??? This can be improved upon. */ +#undef CGEN_DIS_HASH_SIZE +#define CGEN_DIS_HASH_SIZE 16 +#undef CGEN_DIS_HASH +#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 4) + +/* -- */ #endif /* FR30_OPC_H */ -- 2.7.4