]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
mn10300.c (const_8bit_operand): New function.
authorJeffrey A Law <law@cygnus.com>
Thu, 30 Oct 1997 20:34:59 +0000 (20:34 +0000)
committerJeff Law <law@gcc.gnu.org>
Thu, 30 Oct 1997 20:34:59 +0000 (13:34 -0700)
        * mn10300.c (const_8bit_operand): New function.
        (mask_ok_for_mem_btst): New funtion.
        * mn10300.md (btst patterns with mem operands): Use new functions
        to avoid creating btst instructions with invalid operands.

From-SVN: r16236

gcc/ChangeLog
gcc/config/mn10300/mn10300.c
gcc/config/mn10300/mn10300.md

index 3dd3e2b6404605fd3ca1656fa580f006c119e640..4af977e8f9ec3ca8805cbf28bf2b2b7fe957b862 100644 (file)
@@ -1,3 +1,10 @@
+Thu Oct 30 13:26:12 1997  Jeffrey A Law  (law@cygnus.com)
+
+       * mn10300.c (const_8bit_operand): New function.
+       (mask_ok_for_mem_btst): New funtion.
+       * mn10300.md (btst patterns with mem operands): Use new functions
+       to avoid creating btst instructions with invalid operands.
+
 Wed Oct 29 16:57:19 1997  Michael Meissner  <meissner@cygnus.com>
 
        * rs6000/xm-sysv4.h: Include xm-linux.h instead of xm-svr4.h if we
index 158cb2b34cdd93463f4f169b37960e951d9f3c66..201b51d1df22037e0661007a8ca2f7366aa7a12e 100644 (file)
@@ -990,6 +990,42 @@ impossible_plus_operand (op, mode)
   return 0;
 }
 
+/* Return 1 if X is a CONST_INT that is only 8 bits wide.  This is used
+   for the btst insn which may examine memory or a register (the memory
+   variant only allows an unsigned 8 bit integer).  */
+int
+const_8bit_operand (op, mode)
+    register rtx op;
+    enum machine_mode mode;
+{
+  return (GET_CODE (op) == CONST_INT
+         && INTVAL (op) >= 0
+         && INTVAL (op) < 256);
+}
+
+/* Similarly, but when using a zero_extract pattern for a btst where
+   the source operand might end up in memory.  */
+int
+mask_ok_for_mem_btst (len, bit)
+     int len;
+     int bit;
+{
+  int mask = 0;
+
+  while (len > 0)
+    {
+      mask |= (1 << bit);
+      bit++;
+      len--;
+    }
+
+  /* MASK must bit into an 8bit value.  */
+  return (((mask & 0xff) == mask)
+         || ((mask & 0xff00) == mask)
+         || ((mask & 0xff0000) == mask)
+         || ((mask & 0xff000000) == mask));
+}
+
 /* Return 1 if X contains a symbolic expression.  We know these
    expressions will have one of a few well defined forms, so
    we need only check those forms.  */
index f023478fe14f6abeaa1b31f5aceda6af02453d4c..1547ad01323d4a059e9a1c86f985d3c79b161e42 100644 (file)
      (zero_extract:SI (match_operand:QI 0 "general_operand" "R,d")
                      (match_operand 1 "const_int_operand" "")
                      (match_operand 2 "const_int_operand" "")))]
-  "INTVAL (operands[1]) <= 8 && INTVAL (operands[2]) <= 7"
+  "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
   "*
 {
   int len = INTVAL (operands[1]);
       len--;
     }
 
+  /* If the source operand is not a reg (ie it is memory), then extract the
+     bits from mask that we actually want to test.  Note that the mask will
+     never cross a byte boundary.  */
+  if (!REG_P (operands[0]))
+    {
+      if (mask & 0xff)
+       mask = mask & 0xff;
+      else if (mask & 0xff00)
+       mask = (mask >> 8) & 0xff;
+      else if (mask & 0xff0000)
+       mask = (mask >> 16) & 0xff;
+      else if (mask & 0xff000000)
+       mask = (mask >> 24) & 0xff;
+    }
+  
   xoperands[0] = operands[0];
   xoperands[1] = GEN_INT (mask);
   if (GET_CODE (operands[0]) == REG)
   [(set (cc0)
      (and:SI
        (subreg:SI (match_operand:QI 0 "general_operand" "R,d") 0)
-       (match_operand:SI 1 "const_int_operand" "")))]
+       (match_operand:SI 1 "const_8bit_operand" "")))]
   ""
   "@
   btst %1,%A0