From aed80daedfb2895a386538f2e25bd6e00fb7935c Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Tue, 2 Jan 2001 16:34:07 +0000 Subject: * generalization 2001-01-02 Richard Sandiford * cgen-dis.c (hash_insn_array): Use bfd_put_bits(). (hash_insn_list): Likewise * cgen-ibld.in (insert_1): Use bfd_put_bits() and bfd_get_bits(). (extract_1): Use bfd_get_bits(). (extract_normal): Apply sign extension to both extraction methods. * cgen-opc.c (cgen_get_insn_value): Use bfd_get_bits() (cgen_put_insn_value): Use bfd_put_bits() --- opcodes/cgen-ibld.in | 118 +++++++-------------------------------------------- 1 file changed, 15 insertions(+), 103 deletions(-) (limited to 'opcodes/cgen-ibld.in') diff --git a/opcodes/cgen-ibld.in b/opcodes/cgen-ibld.in index 51032934a7a..f5107a1fc71 100644 --- a/opcodes/cgen-ibld.in +++ b/opcodes/cgen-ibld.in @@ -78,34 +78,7 @@ insert_1 (cd, value, start, length, word_length, bufp) int shift; int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG; - switch (word_length) - { - case 8: - x = *bufp; - break; - case 16: - if (big_p) - x = bfd_getb16 (bufp); - else - x = bfd_getl16 (bufp); - break; - case 24: - /* ??? This may need reworking as these cases don't necessarily - want the first byte and the last two bytes handled like this. */ - if (big_p) - x = (bufp[0] << 16) | bfd_getb16 (bufp + 1); - else - x = bfd_getl16 (bufp) | (bufp[2] << 16); - break; - case 32: - if (big_p) - x = bfd_getb32 (bufp); - else - x = bfd_getl32 (bufp); - break; - default : - abort (); - } + x = bfd_get_bits (bufp, word_length, big_p); /* Written this way to avoid undefined behaviour. */ mask = (((1L << (length - 1)) - 1) << 1) | 1; @@ -115,40 +88,7 @@ insert_1 (cd, value, start, length, word_length, bufp) shift = (word_length - (start + length)); x = (x & ~(mask << shift)) | ((value & mask) << shift); - switch (word_length) - { - case 8: - *bufp = x; - break; - case 16: - if (big_p) - bfd_putb16 (x, bufp); - else - bfd_putl16 (x, bufp); - break; - case 24: - /* ??? This may need reworking as these cases don't necessarily - want the first byte and the last two bytes handled like this. */ - if (big_p) - { - bufp[0] = x >> 16; - bfd_putb16 (x, bufp + 1); - } - else - { - bfd_putl16 (x, bufp); - bufp[2] = x >> 16; - } - break; - case 32: - if (big_p) - bfd_putb32 (x, bufp); - else - bfd_putl32 (x, bufp); - break; - default : - abort (); - } + bfd_put_bits ((bfd_vma) x, bufp, word_length, big_p); } #endif /* ! CGEN_INT_INSN_P */ @@ -406,46 +346,17 @@ extract_1 (cd, ex_info, start, length, word_length, bufp, pc) unsigned char *bufp; bfd_vma pc; { - unsigned long x,mask; + unsigned long x; int shift; int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG; - switch (word_length) - { - case 8: - x = *bufp; - break; - case 16: - if (big_p) - x = bfd_getb16 (bufp); - else - x = bfd_getl16 (bufp); - break; - case 24: - /* ??? This may need reworking as these cases don't necessarily - want the first byte and the last two bytes handled like this. */ - if (big_p) - x = (bufp[0] << 16) | bfd_getb16 (bufp + 1); - else - x = bfd_getl16 (bufp) | (bufp[2] << 16); - break; - case 32: - if (big_p) - x = bfd_getb32 (bufp); - else - x = bfd_getl32 (bufp); - break; - default : - abort (); - } + x = bfd_get_bits (bufp, word_length, big_p); - /* Written this way to avoid undefined behaviour. */ - mask = (((1L << (length - 1)) - 1) << 1) | 1; if (CGEN_INSN_LSB0_P) shift = (start + 1) - length; else shift = (word_length - (start + length)); - return (x >> shift) & mask; + return x >> shift; } #endif /* ! CGEN_INT_INSN_P */ @@ -489,7 +400,7 @@ extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length, #endif long *valuep; { - CGEN_INSN_INT value; + CGEN_INSN_INT value, mask; /* If LENGTH is zero, this operand doesn't contribute to the value so give it a standard value of zero. */ @@ -521,18 +432,10 @@ extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length, if (CGEN_INT_INSN_P || word_offset == 0) { - /* Written this way to avoid undefined behaviour. */ - CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1; - if (CGEN_INSN_LSB0_P) value = insn_value >> ((word_offset + start + 1) - length); else value = insn_value >> (total_length - ( word_offset + start + length)); - value &= mask; - /* sign extend? */ - if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED) - && (value & (1L << (length - 1)))) - value |= ~mask; } #if ! CGEN_INT_INSN_P @@ -552,6 +455,15 @@ extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length, #endif /* ! CGEN_INT_INSN_P */ + /* Written this way to avoid undefined behaviour. */ + mask = (((1L << (length - 1)) - 1) << 1) | 1; + + value &= mask; + /* sign extend? */ + if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED) + && (value & (1L << (length - 1)))) + value |= ~mask; + *valuep = value; return 1; -- cgit v1.2.1