* some support for funny-endian 16/32-bit insn sets

[cgen/ChangeLog]
2001-07-11  Frank Ch. Eigler  <fche@redhat.com>

        * desc-cpu.scm (-gen-mach-table-defns): Emit fourth field: the
        mach->cpu insn-chunk-bitsize.
        (-gen-cpu-open): In @arch@_cgen_rebuild_tables, process above new
        field toward CGEN_CPU_TABLE->insn_chunk_bitsize.
        * mach.scm (<cpu>): New field insn-chunk-bitsize.
        (-cpu-parse, -cpu-read): Parse/initialize it.
        * doc/rtl.texi (define-cpu): Document it.

[opcodes/ChangeLog]
2001-07-11  Frank Ch. Eigler  <fche@redhat.com>

        * cgen-dis.in (print_insn): Use cgen_get_insn_value instead of
        bfd_get_bits.
        * cgen-opc.c (cgen_get_insn_value, cgen_put_insn_value): Respect
        non-zero CGEN_CPU_DESC->insn_chunk_bitsize.

[include/opcode/ChangeLog]
2001-07-11  Frank Ch. Eigler  <fche@redhat.com>

        * cgen.h (CGEN_MACH): Add insn_chunk_bitsize field.
        (cgen_cpu_desc): Ditto.
This commit is contained in:
Frank Ch. Eigler 2001-07-12 02:32:25 +00:00
parent 3bbfbb92b3
commit 81f6038f98
5 changed files with 74 additions and 5 deletions

View File

@ -1,3 +1,8 @@
2001-07-11 Frank Ch. Eigler <fche@redhat.com>
* cgen.h (CGEN_MACH): Add insn_chunk_bitsize field.
(cgen_cpu_desc): Ditto.
2001-07-07 Ben Elliston <bje@redhat.com>
* m88k.h: Clean up and reformat. Remove unused code.

View File

@ -199,6 +199,8 @@ typedef struct {
const char *bfd_name;
/* one of enum mach_attr */
int num;
/* parameter from mach->cpu */
unsigned int insn_chunk_bitsize;
} CGEN_MACH;
/* Parse result (also extraction result).
@ -1166,6 +1168,10 @@ typedef struct cgen_cpu_desc
lazily fetch the data from there. */
unsigned int word_bitsize;
/* Instruction chunk size (in bits), for purposes of endianness
conversion. */
unsigned int insn_chunk_bitsize;
/* Indicator if sizes are unknown.
This is used by default_insn_bitsize,base_insn_bitsize if there is a
difference between the selected isa's. */

View File

@ -1,3 +1,10 @@
2001-07-11 Frank Ch. Eigler <fche@redhat.com>
* cgen-dis.in (print_insn): Use cgen_get_insn_value instead of
bfd_get_bits.
* cgen-opc.c (cgen_get_insn_value, cgen_put_insn_value): Respect
non-zero CGEN_CPU_DESC->insn_chunk_bitsize.
2001-07-09 Andreas Jaeger <aj@suse.de>, Karsten Keil <kkeil@suse.de>
* i386-dis.c (set_op): Handle 64 bit and 32 bit mode.

View File

@ -229,12 +229,12 @@ print_insn (cd, pc, info, buf, buflen)
char *buf;
int buflen;
{
unsigned long insn_value;
CGEN_INSN_INT insn_value;
const CGEN_INSN_LIST *insn_list;
CGEN_EXTRACT_INFO ex_info;
/* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
insn_value = cgen_get_insn_value (cd, buf, buflen * 8);
/* Fill in ex_info fields like read_insn would. Don't actually call
read_insn, since the incoming buffer is already read (and possibly

View File

@ -391,7 +391,35 @@ cgen_get_insn_value (cd, buf, length)
unsigned char *buf;
int length;
{
return bfd_get_bits (buf, length, cd->insn_endian == CGEN_ENDIAN_BIG);
int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
int insn_chunk_bitsize = cd->insn_chunk_bitsize;
CGEN_INSN_INT value = 0;
if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
{
/* We need to divide up the incoming value into insn_chunk_bitsize-length
segments, and endian-convert them, one at a time. */
int i;
/* Enforce divisibility. */
if ((length % insn_chunk_bitsize) != 0)
abort ();
for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
{
int index;
bfd_vma this_value;
index = i; /* NB: not dependent on endianness; opposite of cgen_put_insn_value! */
this_value = bfd_get_bits (& buf[index / 8], insn_chunk_bitsize, big_p);
value = (value << insn_chunk_bitsize) | this_value;
}
}
else
{
value = bfd_get_bits (buf, length, cd->insn_endian == CGEN_ENDIAN_BIG);
}
return value;
}
/* Cover function to store an insn value properly byteswapped. */
@ -403,8 +431,31 @@ cgen_put_insn_value (cd, buf, length, value)
int length;
CGEN_INSN_INT value;
{
bfd_put_bits ((bfd_vma) value, buf, length,
cd->insn_endian == CGEN_ENDIAN_BIG);
int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG);
int insn_chunk_bitsize = cd->insn_chunk_bitsize;
if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length)
{
/* We need to divide up the incoming value into insn_chunk_bitsize-length
segments, and endian-convert them, one at a time. */
int i;
/* Enforce divisibility. */
if ((length % insn_chunk_bitsize) != 0)
abort ();
for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */
{
int index;
index = (length - insn_chunk_bitsize - i); /* NB: not dependent on endianness! */
bfd_put_bits ((bfd_vma) value, & buf[index / 8], insn_chunk_bitsize, big_p);
value >>= insn_chunk_bitsize;
}
}
else
{
bfd_put_bits ((bfd_vma) value, buf, length, big_p);
}
}
/* Look up instruction INSN_*_VALUE and extract its fields.