]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
* some support for funny-endian 16/32-bit insn sets
authorFrank Ch. Eigler <fche@redhat.com>
Thu, 12 Jul 2001 02:32:25 +0000 (02:32 +0000)
committerFrank Ch. Eigler <fche@redhat.com>
Thu, 12 Jul 2001 02:32:25 +0000 (02:32 +0000)
[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.

include/opcode/ChangeLog
include/opcode/cgen.h
opcodes/ChangeLog
opcodes/cgen-dis.in
opcodes/cgen-opc.c

index 8ab1f704f145662f3608c8430cbc1f4086c8550f..a027c8df7d1b212667f17db38913df65c9c2e797 100644 (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.
index c13c4d9e8ae99211396b45f086f7ce3f9fbe650d..c01b5c2a25410962f1ff36249f5d71a12bee6cab 100644 (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;
 \f
 /* 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.  */
index 2953237b6c7b17bb7360f3002c34c037359f2b6f..4adba8a416c9ffb916f81e2491695338ec5b335c 100644 (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.
index b2372fd56d7b3dc8c1eae5b75b43549a0c0d53ab..2c4ce7feed9fbbea398388eff3bd810ef903c664 100644 (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
index 188a157f3a193bc1123525affce32d5ff2044144..9dfc16e9e51ce2bc8ada0c395483b801bb02e8d3 100644 (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);
+    }
 }
 \f
 /* Look up instruction INSN_*_VALUE and extract its fields.