This is the mail archive of the cgen@sources.redhat.com mailing list for the CGEN project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

patch for insn size > word size


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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]