This is the mail archive of the
cgen@sources.redhat.com
mailing list for the CGEN project.
patch for insn size > word size
- To: cgen at sourceware dot cygnus dot com
- Subject: patch for insn size > word size
- From: Stan Cox <scox at redhat dot com>
- Date: Wed, 4 Apr 2001 12:05:24 -0400
This proposed patch adds support for architectures where the insn size
is larger than the word size. The cgen changes adds
CGEN_CPU_WORD_SIZE so it is easy to get this value from C code and
makes insn_value an array. The opcode changes read, print, and insert
each insn word individually. The code assumes if an insn is larger
than the word size, then it is twice as large. Other possibilities are:
1. check that insn size is twice word size
2. generalize for an insn that is any multiple of word size
(seems like it may not be worth the effort)
Also tested on an existing port where CGEN_INT_INSN_P is 0
2001-04-03 Stan Cox <scox@redhat.com>
* opc-ibld.scm (-gen-extract-switch): Change insn_value
to be pointer to CGEN_INSN_INT.
* desc-cpu.scm (-gen-hash-defines): Add CGEN_CPU_WORD_SIZE.
Index: desc-cpu.scm
===================================================================
RCS file: /cvs/cvsfiles/devo/cgen/desc-cpu.scm,v
retrieving revision 1.27
diff -u -2 -p -r1.27 desc-cpu.scm
--- desc-cpu.scm 2001/03/20 18:20:06 1.27
+++ desc-cpu.scm 2001/04/04 15:13:53
@@ -308,4 +308,8 @@ const CGEN_HW_ENTRY @arch@_cgen_hw_table
"#define CGEN_INSN_LSB0_P " (if (current-arch-insn-lsb0?) "1" "0")
"\n\n"
+ "/* Size of a word (in bytes). */\n"
+ "#define CGEN_CPU_WORD_SIZE "
+ (number->string (bits->bytes (cpu-word-bitsize (current-cpu))))
+ "\n\n"
"/* Minimum size of any insn (in bytes). */\n"
"#define CGEN_MIN_INSN_SIZE "
Index: opc-ibld.scm
===================================================================
RCS file: /cvs/cvsfiles/devo/cgen/opc-ibld.scm,v
retrieving revision 1.8
diff -u -2 -p -r1.8 opc-ibld.scm
--- opc-ibld.scm 2000/07/27 04:53:32 1.8
+++ opc-ibld.scm 2001/04/04 15:13:53
@@ -229,5 +229,5 @@ int
int opindex;
CGEN_EXTRACT_INFO *ex_info;
- CGEN_INSN_INT insn_value;
+ CGEN_INSN_INT *insn_value;
CGEN_FIELDS * fields;
bfd_vma pc;
2001-04-03 Stan Cox <scox@redhat.com>
* cgen-dis.in (read_insn, print_insn): Allow for insns which are one
word larger than the host word size.
* cgen-ibld.in (insert_1, insert_normal, extract_normal,
extract_insn_normal): Likewise.
Index: cgen-dis.in
===================================================================
RCS file: /cvs/cvsfiles/devo/opcodes/cgen-dis.in,v
retrieving revision 1.33
diff -u -2 -p -r1.33 cgen-dis.in
--- cgen-dis.in 2001/03/28 19:06:34 1.33
+++ cgen-dis.in 2001/04/04 15:13:10
@@ -212,5 +212,15 @@ read_insn (cd, pc, info, buf, buflen, ex
ex_info->insn_bytes = buf;
- *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
+ if (CGEN_CPU_WORD_SIZE < CGEN_MIN_INSN_SIZE)
+ {
+ *insn_value = bfd_get_bits (buf, CGEN_CPU_WORD_SIZE * 8,
+ info->endian == BFD_ENDIAN_BIG);
+ insn_value += 1;
+ *insn_value = bfd_get_bits (buf + 4, CGEN_CPU_WORD_SIZE * 8,
+ info->endian == BFD_ENDIAN_BIG);
+ }
+ else
+ *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
+
return 0;
}
@@ -230,5 +240,5 @@ print_insn (cd, pc, info, buf, buflen)
int buflen;
{
- unsigned long insn_value;
+ int insn_value[CGEN_MAX_INSN_SIZE / 4];
const CGEN_INSN_LIST *insn_list;
CGEN_EXTRACT_INFO ex_info;
@@ -261,5 +271,8 @@ print_insn (cd, pc, info, buf, buflen)
/* ??? May wish to allow target to defer this check until the extract
handler. */
- if ((insn_value & CGEN_INSN_BASE_MASK (insn))
+ if ((((CGEN_CPU_WORD_SIZE < CGEN_MIN_INSN_SIZE)
+ : insn_value[1]
+ ? insn_value[0])
+ & CGEN_INSN_BASE_MASK (insn))
== CGEN_INSN_BASE_VALUE (insn))
{
@@ -280,5 +293,5 @@ print_insn (cd, pc, info, buf, buflen)
return rc;
length = CGEN_EXTRACT_FN (cd, insn)
- (cd, insn, &ex_info, full_insn_value, &fields, pc);
+ (cd, insn, &ex_info, & full_insn_value, &fields, pc);
}
else
Index: cgen-ibld.in
===================================================================
RCS file: /cvs/cvsfiles/devo/opcodes/cgen-ibld.in,v
retrieving revision 1.13
diff -u -2 -p -r1.13 cgen-ibld.in
--- cgen-ibld.in 2001/03/27 21:33:55 1.13
+++ cgen-ibld.in 2001/04/04 15:13:11
@@ -52,10 +52,10 @@ static const char * insert_insn_normal
static int extract_normal
- PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
+ PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT *,
unsigned int, unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int, bfd_vma, long *));
static int extract_insn_normal
PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
- CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
+ CGEN_INSN_INT *, CGEN_FIELDS *, bfd_vma));
static void put_insn_int_value
PARAMS ((CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT));
@@ -78,6 +78,12 @@ insert_1 (cd, value, start, length, word
int shift;
int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
-
- x = bfd_get_bits (bufp, word_length, big_p);
+
+ if (CGEN_CPU_WORD_SIZE < CGEN_MIN_INSN_SIZE)
+ if (start < CGEN_CPU_WORD_SIZE * 8)
+ x = bfd_get_bits (bufp + 4, CGEN_CPU_WORD_SIZE * 8, big_p);
+ else
+ x = bfd_get_bits (bufp, CGEN_CPU_WORD_SIZE * 8, big_p);
+ else
+ x = bfd_get_bits (bufp, word_length, big_p);
/* Written this way to avoid undefined behaviour. */
@@ -89,5 +95,11 @@ insert_1 (cd, value, start, length, word
x = (x & ~(mask << shift)) | ((value & mask) << shift);
- bfd_put_bits ((bfd_vma) x, bufp, word_length, big_p);
+ if (CGEN_CPU_WORD_SIZE < CGEN_MIN_INSN_SIZE)
+ if (start < CGEN_CPU_WORD_SIZE * 8)
+ bfd_put_bits ((bfd_vma) x, bufp + 4, CGEN_CPU_WORD_SIZE * 8, big_p);
+ else
+ bfd_put_bits ((bfd_vma) x, bufp, CGEN_CPU_WORD_SIZE * 8, big_p);
+ else
+ bfd_put_bits ((bfd_vma) x, bufp, word_length, big_p);
}
@@ -133,6 +145,8 @@ insert_normal (cd, value, attrs, word_of
#endif
+#if 0
if (word_length > 32)
abort ();
+#endif
/* For architectures with insns smaller than the base-insn-bitsize,
@@ -391,5 +405,5 @@ extract_normal (cd, ex_info, insn_value,
CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED;
#endif
- CGEN_INSN_INT insn_value;
+ CGEN_INSN_INT *insn_value;
unsigned int attrs;
unsigned int word_offset, start, length, word_length, total_length;
@@ -417,6 +431,8 @@ extract_normal (cd, ex_info, insn_value,
#endif
+#if 0
if (word_length > 32)
abort ();
+#endif
/* For architectures with insns smaller than the insn-base-bitsize,
@@ -433,8 +449,28 @@ extract_normal (cd, ex_info, insn_value,
if (CGEN_INT_INSN_P || word_offset == 0)
{
+
if (CGEN_INSN_LSB0_P)
- value = insn_value >> ((word_offset + start + 1) - length);
+ {
+ if (CGEN_CPU_WORD_SIZE < CGEN_MIN_INSN_SIZE)
+ if (start < CGEN_CPU_WORD_SIZE * 8)
+ value = insn_value[1] >> ((word_offset + start + 1) - length);
+ else
+ value = insn_value[0] >> ((word_offset + start + 1) - length);
+ else
+ value = insn_value[0] >> ((word_offset + start + 1) - length);
+ }
else
- value = insn_value >> (total_length - ( word_offset + start + length));
+ {
+ if (CGEN_CPU_WORD_SIZE < CGEN_MIN_INSN_SIZE)
+ if (start < CGEN_CPU_WORD_SIZE)
+ value = insn_value[1] >>
+ (total_length - ( word_offset + start + length));
+ else
+ value = insn_value[0] >>
+ (total_length - ( word_offset + start + length));
+ else
+ value = insn_value[0] >>
+ (total_length - ( word_offset + start + length));
+ }
}
@@ -484,5 +520,5 @@ extract_insn_normal (cd, insn, ex_info,
const CGEN_INSN *insn;
CGEN_EXTRACT_INFO *ex_info;
- CGEN_INSN_INT insn_value;
+ CGEN_INSN_INT *insn_value;
CGEN_FIELDS *fields;
bfd_vma pc;