aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/aarch64
diff options
context:
space:
mode:
authorprathamesh3492 <prathamesh3492@138bc75d-0d04-0410-961f-82ee72b054a4>2015-03-04 20:28:49 +0000
committerprathamesh3492 <prathamesh3492@138bc75d-0d04-0410-961f-82ee72b054a4>2015-03-04 20:28:49 +0000
commit932bf051566cf95f78ec715d54eb13a4d049d284 (patch)
tree58cad4784d72ab41007868efce15a283a8098c12 /gcc/config/aarch64
parent35c8f07809cbfcf53f744cad8d20c30516a8fc3f (diff)
Backport from trunk r215612.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@221194 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/aarch64')
-rw-r--r--gcc/config/aarch64/aarch64-protos.h1
-rw-r--r--gcc/config/aarch64/aarch64-simd.md46
-rw-r--r--gcc/config/aarch64/aarch64.c10
-rw-r--r--gcc/config/aarch64/iterators.md13
-rw-r--r--gcc/config/aarch64/predicates.md53
5 files changed, 81 insertions, 42 deletions
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index a32f7d78ea3..379df12031f 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -254,7 +254,6 @@ void aarch64_print_operand_address (FILE *, rtx);
/* Initialize builtins for SIMD intrinsics. */
void init_aarch64_simd_builtins (void);
-void aarch64_simd_const_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
void aarch64_simd_disambiguate_copy (rtx *, rtx *, rtx *, unsigned int);
/* Emit code to place a AdvSIMD pair result in memory locations (with equal
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index bb7be4b107d..2f033b81c3a 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -3801,12 +3801,12 @@
(define_insn "aarch64_<sur>shll_n<mode>"
[(set (match_operand:<VWIDE> 0 "register_operand" "=w")
(unspec:<VWIDE> [(match_operand:VDW 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
+ (match_operand:SI 2
+ "aarch64_simd_shift_imm_bitsize_<ve_mode>" "i")]
VSHLL))]
"TARGET_SIMD"
"*
int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- aarch64_simd_const_bounds (operands[2], 0, bit_width + 1);
if (INTVAL (operands[2]) == bit_width)
{
return \"shll\\t%0.<Vwtype>, %1.<Vtype>, %2\";
@@ -3827,7 +3827,6 @@
"TARGET_SIMD"
"*
int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- aarch64_simd_const_bounds (operands[2], 0, bit_width + 1);
if (INTVAL (operands[2]) == bit_width)
{
return \"shll2\\t%0.<Vwtype>, %1.<Vtype>, %2\";
@@ -3843,13 +3842,11 @@
(define_insn "aarch64_<sur>shr_n<mode>"
[(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
(unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
+ (match_operand:SI 2
+ "aarch64_simd_shift_imm_offset_<ve_mode>" "i")]
VRSHR_N))]
"TARGET_SIMD"
- "*
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- aarch64_simd_const_bounds (operands[2], 1, bit_width + 1);
- return \"<sur>shr\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2\";"
+ "<sur>shr\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2"
[(set_attr "type" "neon_sat_shift_imm<q>")]
)
@@ -3859,13 +3856,11 @@
[(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
(unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "0")
(match_operand:VSDQ_I_DI 2 "register_operand" "w")
- (match_operand:SI 3 "immediate_operand" "i")]
+ (match_operand:SI 3
+ "aarch64_simd_shift_imm_offset_<ve_mode>" "i")]
VSRA))]
"TARGET_SIMD"
- "*
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- aarch64_simd_const_bounds (operands[3], 1, bit_width + 1);
- return \"<sur>sra\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3\";"
+ "<sur>sra\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3"
[(set_attr "type" "neon_shift_acc<q>")]
)
@@ -3875,14 +3870,11 @@
[(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
(unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "0")
(match_operand:VSDQ_I_DI 2 "register_operand" "w")
- (match_operand:SI 3 "immediate_operand" "i")]
+ (match_operand:SI 3
+ "aarch64_simd_shift_imm_<offsetlr><ve_mode>" "i")]
VSLRI))]
"TARGET_SIMD"
- "*
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- aarch64_simd_const_bounds (operands[3], 1 - <VSLRI:offsetlr>,
- bit_width - <VSLRI:offsetlr> + 1);
- return \"s<lr>i\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3\";"
+ "s<lr>i\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3"
[(set_attr "type" "neon_shift_imm<q>")]
)
@@ -3891,13 +3883,11 @@
(define_insn "aarch64_<sur>qshl<u>_n<mode>"
[(set (match_operand:VSDQ_I 0 "register_operand" "=w")
(unspec:VSDQ_I [(match_operand:VSDQ_I 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
+ (match_operand:SI 2
+ "aarch64_simd_shift_imm_<ve_mode>" "i")]
VQSHL_N))]
"TARGET_SIMD"
- "*
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- aarch64_simd_const_bounds (operands[2], 0, bit_width);
- return \"<sur>qshl<u>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2\";"
+ "<sur>qshl<u>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2"
[(set_attr "type" "neon_sat_shift_imm<q>")]
)
@@ -3907,13 +3897,11 @@
(define_insn "aarch64_<sur>q<r>shr<u>n_n<mode>"
[(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
(unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
+ (match_operand:SI 2
+ "aarch64_simd_shift_imm_offset_<ve_mode>" "i")]
VQSHRN_N))]
"TARGET_SIMD"
- "*
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- aarch64_simd_const_bounds (operands[2], 1, bit_width + 1);
- return \"<sur>q<r>shr<u>n\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>, %2\";"
+ "<sur>q<r>shr<u>n\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>, %2"
[(set_attr "type" "neon_sat_shift_imm_narrow_q")]
)
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 76a20a61e77..eb4554bdd83 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -8224,16 +8224,6 @@ aarch64_simd_lane_bounds (rtx operand, HOST_WIDE_INT low, HOST_WIDE_INT high)
error ("lane out of range");
}
-void
-aarch64_simd_const_bounds (rtx operand, HOST_WIDE_INT low, HOST_WIDE_INT high)
-{
- gcc_assert (CONST_INT_P (operand));
- HOST_WIDE_INT lane = INTVAL (operand);
-
- if (lane < low || lane >= high)
- error ("constant out of range");
-}
-
/* Emit code to reinterpret one AdvSIMD type as another,
without altering bits. */
void
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index d42b5d8f9dd..d5576b429a6 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -540,6 +540,14 @@
(V2DF "v2di") (DF "di")
(SF "si")])
+;; Lower case element modes (as used in shift immediate patterns).
+(define_mode_attr ve_mode [(V8QI "qi") (V16QI "qi")
+ (V4HI "hi") (V8HI "hi")
+ (V2SI "si") (V4SI "si")
+ (DI "di") (V2DI "di")
+ (QI "qi") (HI "hi")
+ (SI "si")])
+
;; Vm for lane instructions is restricted to FP_LO_REGS.
(define_mode_attr vwx [(V4HI "x") (V8HI "x") (HI "x")
(V2SI "w") (V4SI "w") (SI "w")])
@@ -1006,8 +1014,9 @@
(UNSPEC_RADDHN2 "add")
(UNSPEC_RSUBHN2 "sub")])
-(define_int_attr offsetlr [(UNSPEC_SSLI "1") (UNSPEC_USLI "1")
- (UNSPEC_SSRI "0") (UNSPEC_USRI "0")])
+(define_int_attr offsetlr [(UNSPEC_SSLI "") (UNSPEC_USLI "")
+ (UNSPEC_SSRI "offset_")
+ (UNSPEC_USRI "offset_")])
;; Standard pattern names for floating-point rounding instructions.
(define_int_attr frint_pattern [(UNSPEC_FRINTZ "btrunc")
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 8191169e89b..d5b0b2a9d8d 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -279,3 +279,56 @@
{
return aarch64_const_vec_all_same_int_p (op, -1);
})
+
+;; Predicates used by the various SIMD shift operations. These
+;; fall in to 3 categories.
+;; Shifts with a range 0-(bit_size - 1) (aarch64_simd_shift_imm)
+;; Shifts with a range 1-bit_size (aarch64_simd_shift_imm_offset)
+;; Shifts with a range 0-bit_size (aarch64_simd_shift_imm_bitsize)
+(define_predicate "aarch64_simd_shift_imm_qi"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 7)")))
+
+(define_predicate "aarch64_simd_shift_imm_hi"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 15)")))
+
+(define_predicate "aarch64_simd_shift_imm_si"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
+
+(define_predicate "aarch64_simd_shift_imm_di"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 63)")))
+
+(define_predicate "aarch64_simd_shift_imm_offset_qi"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 1, 8)")))
+
+(define_predicate "aarch64_simd_shift_imm_offset_hi"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 1, 16)")))
+
+(define_predicate "aarch64_simd_shift_imm_offset_si"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 1, 32)")))
+
+(define_predicate "aarch64_simd_shift_imm_offset_di"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 1, 64)")))
+
+(define_predicate "aarch64_simd_shift_imm_bitsize_qi"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 8)")))
+
+(define_predicate "aarch64_simd_shift_imm_bitsize_hi"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 16)")))
+
+(define_predicate "aarch64_simd_shift_imm_bitsize_si"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 32)")))
+
+(define_predicate "aarch64_simd_shift_imm_bitsize_di"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 64)")))