From 4904231323789b7d5a0f6fa70fe7f55ee6fba109 Mon Sep 17 00:00:00 2001 From: Mingjie Xing Date: Fri, 3 Sep 2010 09:29:19 +0000 Subject: [PATCH] Fix shift count truncate problem for loongson. From-SVN: r163799 --- gcc/ChangeLog | 6 ++++ gcc/config/mips/mips.c | 17 +++++++++ gcc/config/mips/mips.h | 7 ++-- gcc/testsuite/ChangeLog | 4 +++ .../mips/loongson-shift-count-truncated-1.c | 35 +++++++++++++++++++ 5 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/mips/loongson-shift-count-truncated-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 44c1da8e25b..dc4f9a0bf61 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-09-03 Mingjie Xing + + * config/mips/mips.h (SHIFT_COUNT_TRUNCATED): Change the definition. + * config/mips/mips.c (mips_shift_truncation_mask): New function. + (TARGET_SHIFT_TRUNCATION_MASK): Define. + 2010-09-02 Richard Henderson * configure.ac (gcc_cv_as_cfi_advance_working): Use objdump diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 052e8051d25..3fe7f8b5961 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -16338,6 +16338,20 @@ void mips_function_profiler (FILE *file) fprintf (file, "\tmove\t%s,%s\n", reg_names[STATIC_CHAIN_REGNUM], reg_names[2]); } + +/* Implement TARGET_SHIFT_TRUNCATION_MASK. We want to keep the default + behaviour of TARGET_SHIFT_TRUNCATION_MASK for non-vector modes even + when TARGET_LOONGSON_2EF is true. */ + +static unsigned HOST_WIDE_INT +mips_shift_truncation_mask (enum machine_mode mode) +{ + if (TARGET_LOONGSON_2EF && VECTOR_MODE_P (mode)) + return 0; + + return GET_MODE_BITSIZE (mode) - 1; +} + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP @@ -16546,6 +16560,9 @@ void mips_function_profiler (FILE *file) #undef TARGET_ASM_OUTPUT_SOURCE_FILENAME #define TARGET_ASM_OUTPUT_SOURCE_FILENAME mips_output_filename +#undef TARGET_SHIFT_TRUNCATION_MASK +#define TARGET_SHIFT_TRUNCATION_MASK mips_shift_truncation_mask + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-mips.h" diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 4dd86d4495c..74bf3d25c4c 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -2423,9 +2423,10 @@ typedef struct mips_args { (often extended) would be needed for byte accesses. */ #define SLOW_BYTE_ACCESS (!TARGET_MIPS16) -/* Define this to be nonzero if shift instructions ignore all but the low-order - few bits. */ -#define SHIFT_COUNT_TRUNCATED 1 +/* Standard MIPS integer shifts truncate the shift amount to the + width of the shifted operand. However, Loongson vector shifts + do not truncate the shift amount at all. */ +#define SHIFT_COUNT_TRUNCATED (!TARGET_LOONGSON_2EF) /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits is done just by pretending it is already truncated. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 015ce4c4408..0a15006ba07 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-09-03 Mingjie Xing + + * gcc.target/mips/loongson-shift-count-truncated-1.c: New. + 2010-09-03 Daniel Kraft PR fortran/44602 diff --git a/gcc/testsuite/gcc.target/mips/loongson-shift-count-truncated-1.c b/gcc/testsuite/gcc.target/mips/loongson-shift-count-truncated-1.c new file mode 100644 index 00000000000..be52cf7dedc --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/loongson-shift-count-truncated-1.c @@ -0,0 +1,35 @@ +/* Test case for SHIFT_COUNT_TRUNCATED on Loongson. */ + +/* { dg-do run } */ +/* loongson.h does not handle or check for MIPS16ness. There doesn't + seem any good reason for it to, given that the Loongson processors + do not support MIPS16. */ +/* { dg-options "isa=loongson -mhard-float -mno-mips16 -O1" } */ + +#include "loongson.h" +#include + +typedef union { int32x2_t v; int32_t a[2]; } int32x2_encap_t; + +void +main1 (int shift) +{ + int32x2_encap_t s; + int32x2_encap_t r; + + s.a[0] = 0xffffffff; + s.a[1] = 0xffffffff; + /* Loongson SIMD use low-order 7 bits to specify the shift amount. + Thus V2SI << 0x40 == 0. The below expression 'shift & 0x3f' will be + mis-optimized as 'shift', if SHIFT_COUNT_TRUNCATED is nonzero. */ + r.v = psllw_s (s.v, (shift & 0x3f)); + assert (r.a[0] == 0xffffffff); + assert (r.a[1] == 0xffffffff); +} + +int +main (void) +{ + main1 (0x40); + return 0; +} -- 2.30.2