* 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:
parent
3bbfbb92b3
commit
81f6038f98
|
@ -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.
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue