From 1c8b4e29cc037130c30a057b0f2b8e92d933276b Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 10 Sep 2003 12:59:36 +0000 Subject: [PATCH] re PR target/11965 (invalid assembler code for a shift << 32 operation) 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 | 10 ++++++++++ gcc/config/sparc/sparc.c | 4 ++++ gcc/config/sparc/sparc.md | 33 ++++++++++++++++++++++++++------ gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.dg/ultrasp10.c | 25 ++++++++++++++++++++++++ 5 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ultrasp10.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2b099c10086..bac59f1963f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2003-09-10 Martin Husemann + + 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 * cgraphunit.c (cgraph_finalize_function): Remove unused argument. diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 9e651365632..4c4ea63325a 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -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); diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 954e89dc2b6..a987041af81 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -6908,6 +6908,8 @@ { 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") @@ -6937,6 +6939,8 @@ { 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") @@ -6996,7 +7000,11 @@ (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" @@ -7043,12 +7051,17 @@ } }) -(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 @@ -7067,7 +7080,11 @@ (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 @@ -7124,12 +7141,16 @@ } }) -(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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 05cf7b3a99c..db6cc0d371d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,6 @@ +2003-09-10 Eric Botcazou + + * gcc.dg/ultrasp10.c: New test. 2003-09-09 Devang Patel diff --git a/gcc/testsuite/gcc.dg/ultrasp10.c b/gcc/testsuite/gcc.dg/ultrasp10.c new file mode 100644 index 00000000000..ffa3229fa4f --- /dev/null +++ b/gcc/testsuite/gcc.dg/ultrasp10.c @@ -0,0 +1,25 @@ +/* PR target/11965 */ +/* Originator: */ +/* { 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; +} -- 2.30.2