[PATCH][AArch64] Vector shift by 64 fix
gcc/ * config/aarch64/aarch64-simd-builtins.def (ashr): DI mode removed. (ashr_simd): New builtin handling DI mode. * config/aarch64/aarch64-simd.md (aarch64_ashr_simddi): New pattern. (aarch64_sshr_simddi): New match pattern. * config/aarch64/arm_neon.h (vshr_n_s32): Builtin call modified. (vshrd_n_s64): Likewise. * config/aarch64/predicates.md (aarch64_shift_imm64_di): New predicate. gcc/testsuite/ * gcc.target/aarch64/sshr64_1.c: New testcase. From-SVN: r206978
This commit is contained in:
parent
949ad9715a
commit
f9a4c9a613
@ -1,3 +1,13 @@
|
||||
2014-01-23 Alex Velenko <Alex.Velenko@arm.com>
|
||||
|
||||
* config/aarch64/aarch64-simd-builtins.def (ashr): DI mode removed.
|
||||
(ashr_simd): New builtin handling DI mode.
|
||||
* config/aarch64/aarch64-simd.md (aarch64_ashr_simddi): New pattern.
|
||||
(aarch64_sshr_simddi): New match pattern.
|
||||
* config/aarch64/arm_neon.h (vshr_n_s32): Builtin call modified.
|
||||
(vshrd_n_s64): Likewise.
|
||||
* config/aarch64/predicates.md (aarch64_shift_imm64_di): New predicate.
|
||||
|
||||
2014-01-23 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* config/msp430/msp430.h (ASM_SPEC): Pass the -mcpu as -mcpu.
|
||||
|
@ -190,7 +190,8 @@
|
||||
BUILTIN_VSDQ_I_DI (BINOP, srshl, 0)
|
||||
BUILTIN_VSDQ_I_DI (BINOP, urshl, 0)
|
||||
|
||||
BUILTIN_VSDQ_I_DI (SHIFTIMM, ashr, 3)
|
||||
BUILTIN_VDQ_I (SHIFTIMM, ashr, 3)
|
||||
VAR1 (SHIFTIMM, ashr_simd, 0, di)
|
||||
BUILTIN_VSDQ_I_DI (SHIFTIMM, lshr, 3)
|
||||
/* Implemented by aarch64_<sur>shr_n<mode>. */
|
||||
BUILTIN_VSDQ_I_DI (SHIFTIMM, srshr_n, 0)
|
||||
|
@ -685,6 +685,32 @@
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; DI vector shift
|
||||
(define_expand "aarch64_ashr_simddi"
|
||||
[(match_operand:DI 0 "register_operand" "=w")
|
||||
(match_operand:DI 1 "register_operand" "w")
|
||||
(match_operand:QI 2 "aarch64_shift_imm64_di" "")]
|
||||
"TARGET_SIMD"
|
||||
{
|
||||
if (INTVAL (operands[2]) == 64)
|
||||
emit_insn (gen_aarch64_sshr_simddi (operands[0], operands[1]));
|
||||
else
|
||||
emit_insn (gen_ashrdi3 (operands[0], operands[1], operands[2]));
|
||||
DONE;
|
||||
}
|
||||
)
|
||||
|
||||
;; SIMD shift by 64. This pattern is a special case as standard pattern does
|
||||
;; not handle NEON shifts by 64.
|
||||
(define_insn "aarch64_sshr_simddi"
|
||||
[(set (match_operand:DI 0 "register_operand" "=w")
|
||||
(unspec:DI
|
||||
[(match_operand:DI 1 "register_operand" "w")] UNSPEC_SSHR64))]
|
||||
"TARGET_SIMD"
|
||||
"sshr\t%d0, %d1, 64"
|
||||
[(set_attr "type" "neon_shift_imm")]
|
||||
)
|
||||
|
||||
(define_expand "vlshr<mode>3"
|
||||
[(match_operand:VQ_S 0 "register_operand" "")
|
||||
(match_operand:VQ_S 1 "register_operand" "")
|
||||
|
@ -93,6 +93,7 @@
|
||||
UNSPEC_SISD_SSHL
|
||||
UNSPEC_SISD_USHL
|
||||
UNSPEC_SSHL_2S
|
||||
UNSPEC_SSHR64
|
||||
UNSPEC_ST1
|
||||
UNSPEC_ST2
|
||||
UNSPEC_ST3
|
||||
|
@ -23340,7 +23340,7 @@ vshr_n_s32 (int32x2_t __a, const int __b)
|
||||
__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
|
||||
vshr_n_s64 (int64x1_t __a, const int __b)
|
||||
{
|
||||
return (int64x1_t) __builtin_aarch64_ashrdi (__a, __b);
|
||||
return (int64x1_t) __builtin_aarch64_ashr_simddi (__a, __b);
|
||||
}
|
||||
|
||||
__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
|
||||
@ -23418,7 +23418,7 @@ vshrq_n_u64 (uint64x2_t __a, const int __b)
|
||||
__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
|
||||
vshrd_n_s64 (int64x1_t __a, const int __b)
|
||||
{
|
||||
return (int64x1_t) __builtin_aarch64_ashrdi (__a, __b);
|
||||
return (int64x1_t) __builtin_aarch64_ashr_simddi (__a, __b);
|
||||
}
|
||||
|
||||
__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__))
|
||||
|
@ -86,6 +86,10 @@
|
||||
(and (match_code "const_int")
|
||||
(match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 64")))
|
||||
|
||||
(define_predicate "aarch64_shift_imm64_di"
|
||||
(and (match_code "const_int")
|
||||
(match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 64")))
|
||||
|
||||
(define_predicate "aarch64_reg_or_shift_imm_si"
|
||||
(ior (match_operand 0 "register_operand")
|
||||
(match_operand 0 "aarch64_shift_imm_si")))
|
||||
|
@ -1,3 +1,7 @@
|
||||
2014-01-23 Alex Velenko <Alex.Velenko@arm.com>
|
||||
|
||||
* gcc.target/aarch64/sshr64_1.c: New testcase.
|
||||
|
||||
2014-01-23 Balaji V. Iyer <balaji.v.iyer@intel.com>
|
||||
|
||||
* g++.dg/cilk-plus/cilk-plus.exp: Called the C/C++ common tests for
|
||||
|
115
gcc/testsuite/gcc.target/aarch64/sshr64_1.c
Normal file
115
gcc/testsuite/gcc.target/aarch64/sshr64_1.c
Normal file
@ -0,0 +1,115 @@
|
||||
/* Test SIMD shift works correctly. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-O3 --save-temps" } */
|
||||
|
||||
#include "arm_neon.h"
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
test_sshr64 ()
|
||||
{
|
||||
int64x1_t arg;
|
||||
int64x1_t result;
|
||||
int64_t got;
|
||||
int64_t exp;
|
||||
arg = vcreate_s64 (0x0000000080000000);
|
||||
result = vshr_n_s64 (arg, 64);
|
||||
got = vget_lane_s64 (result, 0);
|
||||
exp = 0;
|
||||
/* Expect: "result" = 0000000000000000. */
|
||||
if (exp != got)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
test_sshr64_neg ()
|
||||
{
|
||||
int64x1_t arg;
|
||||
int64x1_t result;
|
||||
int64_t got;
|
||||
int64_t exp;
|
||||
arg = vcreate_s64 (0xffffffff80000000);
|
||||
result = vshr_n_s64 (arg, 64);
|
||||
got = vget_lane_s64 (result, 0);
|
||||
exp = 0xffffffffffffffff;
|
||||
/* Expect: "result" = -1. */
|
||||
if (exp != got)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__attribute__ ((noinline))
|
||||
test_other ()
|
||||
{
|
||||
int64x1_t arg;
|
||||
int64x1_t result;
|
||||
int64_t got;
|
||||
int64_t exp;
|
||||
arg = vcreate_s64 (0x0000000080000000);
|
||||
result = vshr_n_s64 (arg, 4);
|
||||
got = vget_lane_s64 (result, 0);
|
||||
exp = 0x0000000008000000;
|
||||
/* Expect: "result" = 0x0000000008000000. */
|
||||
if (exp != got)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
test_other_neg ()
|
||||
{
|
||||
int64x1_t arg;
|
||||
int64x1_t result;
|
||||
int64_t got;
|
||||
int64_t exp;
|
||||
arg = vcreate_s64 (0xffffffff80000000);
|
||||
result = vshr_n_s64 (arg, 4);
|
||||
got = vget_lane_s64 (result, 0);
|
||||
exp = 0xfffffffff8000000;
|
||||
/* Expect: "result" = 0xfffffffff8000000. */
|
||||
if (exp != got)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __attribute__ ((noinline))
|
||||
test_no_sshr0 ()
|
||||
{
|
||||
int64x1_t arg;
|
||||
int64x1_t result;
|
||||
int64_t got;
|
||||
int64_t exp;
|
||||
arg = vcreate_s64 (0x0000000080000000);
|
||||
result = vshr_n_s64 (arg, 0);
|
||||
got = vget_lane_s64 (result, 0);
|
||||
exp = 0x0000000080000000;
|
||||
/* Expect: "result" = 0x0000000080000000. */
|
||||
if (exp != got)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "sshr\\td\[0-9\]+, d\[0-9\]+, 0" } } */
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (test_sshr64 ())
|
||||
abort ();
|
||||
if (test_other ())
|
||||
abort ();
|
||||
|
||||
if (test_sshr64_neg ())
|
||||
abort ();
|
||||
if (test_other_neg ())
|
||||
abort ();
|
||||
|
||||
if (test_no_sshr0 ())
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { cleanup-saved-temps } } */
|
Loading…
Reference in New Issue
Block a user