2000-08-28 Dave Brolley <brolley@redhat.com>
[deliverable/binutils-gdb.git] / opcodes / fr30-ibld.c
index 2aa44589cf2966c3c48def562ff44d1b53937e63..a29ce3e2f58182364238e110bb0304bd93afd7fe 100644 (file)
@@ -3,7 +3,7 @@
 THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
 - the resultant file is machine generated, cgen-ibld.in isn't
 
-Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
 
 This file is part of the GNU Binutils and GDB, the GNU debugger.
 
@@ -57,6 +57,9 @@ static int extract_normal
 static int extract_insn_normal
      PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
              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));
+
 \f
 /* Operand insertion.  */
 
@@ -183,9 +186,11 @@ insert_normal (cd, value, attrs, word_offset, start, length, word_length,
   if (length == 0)
     return NULL;
 
+#if 0
   if (CGEN_INT_INSN_P
       && word_offset != 0)
     abort ();
+#endif
 
   if (word_length > 32)
     abort ();
@@ -203,6 +208,7 @@ insert_normal (cd, value, attrs, word_offset, start, length, word_length,
   if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
     {
       unsigned long maxval = mask;
+      
       if ((unsigned long) value > maxval)
        {
          /* xgettext:c-format */
@@ -214,15 +220,19 @@ insert_normal (cd, value, attrs, word_offset, start, length, word_length,
     }
   else
     {
-      long minval = - (1L << (length - 1));
-      long maxval = (1L << (length - 1)) - 1;
-      if (value < minval || value > maxval)
+      if (! cgen_signed_overflow_ok_p (cd))
        {
-         sprintf
-           /* xgettext:c-format */
-           (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
-            value, minval, maxval);
-         return errbuf;
+         long minval = - (1L << (length - 1));
+         long maxval =   (1L << (length - 1)) - 1;
+         
+         if (value < minval || value > maxval)
+           {
+             sprintf
+               /* xgettext:c-format */
+               (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
+                value, minval, maxval);
+             return errbuf;
+           }
        }
     }
 
@@ -232,9 +242,9 @@ insert_normal (cd, value, attrs, word_offset, start, length, word_length,
     int shift;
 
     if (CGEN_INSN_LSB0_P)
-      shift = (start + 1) - length;
+      shift = (word_offset + start + 1) - length;
     else
-      shift = word_length - (start + length);
+      shift = total_length - (word_offset + start + length);
     *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
   }
 
@@ -278,7 +288,8 @@ insert_insn_normal (cd, insn, fields, buffer, pc)
 
 #if CGEN_INT_INSN_P
 
-  *buffer = value;
+  put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
+                     CGEN_FIELDS_BITSIZE (fields), value);
 
 #else
 
@@ -308,6 +319,30 @@ insert_insn_normal (cd, insn, fields, buffer, pc)
 
   return NULL;
 }
+
+/* Cover function to store an insn value into an integral insn.  Must go here
+ because it needs <prefix>-desc.h for CGEN_INT_INSN_P.  */
+
+static void
+put_insn_int_value (cd, buf, length, insn_length, value)
+     CGEN_CPU_DESC cd;
+     CGEN_INSN_BYTES_PTR buf;
+     int length;
+     int insn_length;
+     CGEN_INSN_INT value;
+{
+  /* For architectures with insns smaller than the base-insn-bitsize,
+     length may be too big.  */
+  if (length > insn_length)
+    *buf = value;
+  else
+    {
+      int shift = insn_length - length;
+      /* Written this way to avoid undefined behaviour.  */
+      CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
+      *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
+    }
+}
 \f
 /* Operand extraction.  */
 
@@ -439,11 +474,19 @@ static int
 extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
                word_length, total_length, pc, valuep)
      CGEN_CPU_DESC cd;
+#if ! CGEN_INT_INSN_P
      CGEN_EXTRACT_INFO *ex_info;
+#else
+     CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED;
+#endif
      CGEN_INSN_INT insn_value;
      unsigned int attrs;
      unsigned int word_offset, start, length, word_length, total_length;
+#if ! CGEN_INT_INSN_P
      bfd_vma pc;
+#else
+     bfd_vma pc ATTRIBUTE_UNUSED;
+#endif
      long *valuep;
 {
   CGEN_INSN_INT value;
@@ -456,9 +499,11 @@ extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
       return 1;
     }
 
+#if 0
   if (CGEN_INT_INSN_P
       && word_offset != 0)
     abort ();
+#endif
 
   if (word_length > 32)
     abort ();
@@ -474,15 +519,15 @@ extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
 
   /* Does the value reside in INSN_VALUE?  */
 
-  if (word_offset == 0)
+  if (CGEN_INT_INSN_P || word_offset == 0)
     {
       /* Written this way to avoid undefined behaviour.  */
       CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
 
       if (CGEN_INSN_LSB0_P)
-       value = insn_value >> ((start + 1) - length);
+       value = insn_value >> ((word_offset + start + 1) - length);
       else
-       value = insn_value >> (word_length - (start + length));
+       value = insn_value >> (total_length - ( word_offset + start + length));
       value &= mask;
       /* sign extend? */
       if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
@@ -858,7 +903,9 @@ fr30_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
     case FR30_OPERAND_I20 :
       {
         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_i20_4);
+        if (length <= 0) break;
         length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 16, 16, total_length, pc, & fields->f_i20_16);
+        if (length <= 0) break;
 {
   FLD (f_i20) = ((((FLD (f_i20_4)) << (16))) | (FLD (f_i20_16)));
 }
This page took 0.027256 seconds and 4 git commands to generate.