re PR target/11965 (invalid assembler code for a shift << 32 operation)
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 10 Sep 2003 12:59:36 +0000 (12:59 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 10 Sep 2003 12:59:36 +0000 (12:59 +0000)
PR target/11965
* config/sparc/sparc.c (sparc_v8plus_shift): Protect against
constants greater than 63.
* config/sparc/sparc.md (ashlsi3, ashrsi3, lshrsi3): Protect
against constants greater than 31.
(*ashldi3_sp64, *ashrdi3_sp64, *lshrdi3_sp64): Protect against
constants greater than 63.

From-SVN: r71266

gcc/ChangeLog
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ultrasp10.c [new file with mode: 0644]

index 2b099c1008683f8cf321df9fe7c09371534f0a80..bac59f1963f6a250e7a8d0f1e4e8a95838074b38 100644 (file)
@@ -1,3 +1,13 @@
+2003-09-10  Martin Husemann  <martin@duskware.de>
+
+       PR target/11965
+       * config/sparc/sparc.c (sparc_v8plus_shift): Protect against
+       constants greater than 63.
+       * config/sparc/sparc.md (ashlsi3, ashrsi3, lshrsi3): Protect
+       against constants greater than 31.
+       (*ashldi3_sp64, *ashrdi3_sp64, *lshrdi3_sp64): Protect against
+       constants greater than 63.
+
 2003-09-09  Richard Henderson  <rth@redhat.com>
 
        * cgraphunit.c (cgraph_finalize_function): Remove unused argument.
index 9e651365632d1adbf326dc46d7e91d02d0fbe3b3..4c4ea63325ad78b3af3c4b303d1c9f9b0f93d191 100644 (file)
@@ -8302,6 +8302,10 @@ sparc_v8plus_shift (rtx *operands, rtx insn, const char *opcode)
   if (which_alternative != 2)
     operands[3] = operands[0];
 
+  /* We can only shift by constants <= 63. */
+  if (GET_CODE (operands[2]) == CONST_INT)
+    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
+
   if (GET_CODE (operands[1]) == CONST_INT)
     {
       output_asm_insn ("mov\t%1, %3", operands);
index 954e89dc2b6c8ff8404e98dc18d7b0965b9a0179..a987041af81ceab369229d469f0b42b83f762c06 100644 (file)
 {
   if (operands[2] == const1_rtx)
     return "add\t%1, %1, %0";
+  if (GET_CODE (operands[2]) == CONST_INT)
+    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
   return "sll\t%1, %2, %0";
 }
   [(set (attr "type")
 {
   if (operands[2] == const1_rtx)
     return "add\t%1, %1, %0";
+  if (GET_CODE (operands[2]) == CONST_INT)
+    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
   return "sllx\t%1, %2, %0";
 }
   [(set (attr "type")
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
                     (match_operand:SI 2 "arith_operand" "rI")))]
   ""
-  "sra\t%1, %2, %0"
+  {
+     if (GET_CODE (operands[2]) == CONST_INT)
+       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
+     return "sra\t%1, %2, %0";
+  }
   [(set_attr "type" "shift")])
 
 (define_insn "*ashrsi3_extend"
     }
 })
 
-(define_insn ""
+(define_insn "*ashrdi3_sp64"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
                     (match_operand:SI 2 "arith_operand" "rI")))]
   "TARGET_ARCH64"
-  "srax\t%1, %2, %0"
+  
+  {
+    if (GET_CODE (operands[2]) == CONST_INT)
+      operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
+    return "srax\t%1, %2, %0";
+  }
   [(set_attr "type" "shift")])
 
 ;; XXX
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
                     (match_operand:SI 2 "arith_operand" "rI")))]
   ""
-  "srl\t%1, %2, %0"
+  {
+    if (GET_CODE (operands[2]) == CONST_INT)
+      operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
+    return "srl\t%1, %2, %0";
+  }
   [(set_attr "type" "shift")])
 
 ;; This handles the case where
     }
 })
 
-(define_insn ""
+(define_insn "*lshrdi3_sp64"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
                     (match_operand:SI 2 "arith_operand" "rI")))]
   "TARGET_ARCH64"
-  "srlx\t%1, %2, %0"
+  {
+    if (GET_CODE (operands[2]) == CONST_INT)
+      operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
+    return "srlx\t%1, %2, %0";
+  }
   [(set_attr "type" "shift")])
 
 ;; XXX
index 05cf7b3a99c6081b8c2e1bd7e815b17740c34094..db6cc0d371de27e43abbe8e5b54ae00f1c29fcb4 100644 (file)
@@ -1,3 +1,6 @@
+2003-09-10  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       * gcc.dg/ultrasp10.c: New test.
 
 2003-09-09  Devang Patel  <dpatel@apple.com>
 
diff --git a/gcc/testsuite/gcc.dg/ultrasp10.c b/gcc/testsuite/gcc.dg/ultrasp10.c
new file mode 100644 (file)
index 0000000..ffa3229
--- /dev/null
@@ -0,0 +1,25 @@
+/* PR target/11965 */
+/* Originator: <jk@tools.de> */
+/* { dg-do run { target sparc*-*-* } } */
+/* { dg-options "-O -mcpu=ultrasparc" } */
+
+/* This used to fail on 32-bit Ultrasparc because GCC emitted
+   an invalid shift instruction.  */
+
+
+static inline unsigned int shift(int n, unsigned int value)
+{
+  return value << n;
+}
+
+unsigned int val = 1;
+
+int main(void)
+{
+  int i;
+
+  for (i = 0; i < 4; i++)
+    val = shift(32, val);
+
+  return 0;
+}