aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMichael Hope <michael.hope@linaro.org>2012-03-23 15:40:02 +1300
committerMichael Hope <michael.hope@linaro.org>2012-03-23 15:40:02 +1300
commita350686ad674f067c9f0eb013d987277e3fbb0c3 (patch)
treeb42827a83c2de2495cd13cf1d549ff36030ea001 /gcc
parentc9fd4ab3fafaaa4e76cdd90a9d7cc0e5d7c4c220 (diff)
Don't force vget_lane returning a 64-bit result to transfer to core
registers. Backport from mainline r185603: gcc/ 2012-03-21 Richard Earnshaw <rearnsha@arm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/arm/neon-testgen.ml5
-rw-r--r--gcc/config/arm/neon.md22
-rw-r--r--gcc/config/arm/neon.ml8
-rw-r--r--gcc/testsuite/gcc.target/arm/neon/vgetQ_lanes64.c4
-rw-r--r--gcc/testsuite/gcc.target/arm/neon/vgetQ_laneu64.c4
5 files changed, 29 insertions, 14 deletions
diff --git a/gcc/config/arm/neon-testgen.ml b/gcc/config/arm/neon-testgen.ml
index eb2917da9b1..a69a53917b1 100644
--- a/gcc/config/arm/neon-testgen.ml
+++ b/gcc/config/arm/neon-testgen.ml
@@ -79,9 +79,12 @@ let emit_automatics chan c_types features =
(* The intrinsic returns a value. We need to do explict register
allocation for vget_low tests or they fail because of copy
elimination. *)
- ((if List.mem Fixed_return_reg features then
+ ((if List.mem Fixed_vector_reg features then
Printf.fprintf chan " register %s out_%s asm (\"d18\");\n"
return_ty return_ty
+ else if List.mem Fixed_core_reg features then
+ Printf.fprintf chan " register %s out_%s asm (\"r0\");\n"
+ return_ty return_ty
else
Printf.fprintf chan " %s out_%s;\n" return_ty return_ty);
emit ())
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index 078a8fd47ee..9a523751843 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -2720,14 +2720,24 @@
})
(define_expand "neon_vget_lanev2di"
- [(match_operand:DI 0 "s_register_operand" "=r")
- (match_operand:V2DI 1 "s_register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")
- (match_operand:SI 3 "immediate_operand" "i")]
+ [(match_operand:DI 0 "s_register_operand" "")
+ (match_operand:V2DI 1 "s_register_operand" "")
+ (match_operand:SI 2 "immediate_operand" "")
+ (match_operand:SI 3 "immediate_operand" "")]
"TARGET_NEON"
{
- neon_lane_bounds (operands[2], 0, 2);
- emit_insn (gen_vec_extractv2di (operands[0], operands[1], operands[2]));
+ switch (INTVAL (operands[2]))
+ {
+ case 0:
+ emit_move_insn (operands[0], gen_lowpart (DImode, operands[1]));
+ break;
+ case 1:
+ emit_move_insn (operands[0], gen_highpart (DImode, operands[1]));
+ break;
+ default:
+ neon_lane_bounds (operands[2], 0, 1);
+ FAIL;
+ }
DONE;
})
diff --git a/gcc/config/arm/neon.ml b/gcc/config/arm/neon.ml
index 363e55c713c..63389a3ecb6 100644
--- a/gcc/config/arm/neon.ml
+++ b/gcc/config/arm/neon.ml
@@ -234,7 +234,8 @@ type features =
cases. The function supplied must return the integer to be written
into the testcase for the argument number (0-based) supplied to it. *)
| Const_valuator of (int -> int)
- | Fixed_return_reg
+ | Fixed_vector_reg
+ | Fixed_core_reg
exception MixedMode of elts * elts
@@ -999,7 +1000,8 @@ let ops =
Vget_lane,
[InfoWord;
Disassembles_as [Use_operands [| Corereg; Corereg; Dreg |]];
- Instruction_name ["vmov"]; Const_valuator (fun _ -> 0)],
+ Instruction_name ["vmov"; "fmrrd"]; Const_valuator (fun _ -> 0);
+ Fixed_core_reg],
Use_operands [| Corereg; Qreg; Immed |],
"vgetQ_lane", notype_2, [S64; U64];
@@ -1115,7 +1117,7 @@ let ops =
notype_1, pf_su_8_64;
Vget_low, [Instruction_name ["vmov"];
Disassembles_as [Use_operands [| Dreg; Dreg |]];
- Fixed_return_reg],
+ Fixed_vector_reg],
Use_operands [| Dreg; Qreg |], "vget_low",
notype_1, pf_su_8_32;
Vget_low, [No_op],
diff --git a/gcc/testsuite/gcc.target/arm/neon/vgetQ_lanes64.c b/gcc/testsuite/gcc.target/arm/neon/vgetQ_lanes64.c
index b7f7f33502a..e3d3c178e50 100644
--- a/gcc/testsuite/gcc.target/arm/neon/vgetQ_lanes64.c
+++ b/gcc/testsuite/gcc.target/arm/neon/vgetQ_lanes64.c
@@ -10,11 +10,11 @@
void test_vgetQ_lanes64 (void)
{
- int64_t out_int64_t;
+ register int64_t out_int64_t asm ("r0");
int64x2_t arg0_int64x2_t;
out_int64_t = vgetq_lane_s64 (arg0_int64x2_t, 0);
}
-/* { dg-final { scan-assembler "vmov\[ \]+\[rR\]\[0-9\]+, \[rR\]\[0-9\]+, \[dD\]\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */
+/* { dg-final { scan-assembler "((vmov)|(fmrrd))\[ \]+\[rR\]\[0-9\]+, \[rR\]\[0-9\]+, \[dD\]\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */
/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/neon/vgetQ_laneu64.c b/gcc/testsuite/gcc.target/arm/neon/vgetQ_laneu64.c
index 33c463e6409..3426e469487 100644
--- a/gcc/testsuite/gcc.target/arm/neon/vgetQ_laneu64.c
+++ b/gcc/testsuite/gcc.target/arm/neon/vgetQ_laneu64.c
@@ -10,11 +10,11 @@
void test_vgetQ_laneu64 (void)
{
- uint64_t out_uint64_t;
+ register uint64_t out_uint64_t asm ("r0");
uint64x2_t arg0_uint64x2_t;
out_uint64_t = vgetq_lane_u64 (arg0_uint64x2_t, 0);
}
-/* { dg-final { scan-assembler "vmov\[ \]+\[rR\]\[0-9\]+, \[rR\]\[0-9\]+, \[dD\]\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */
+/* { dg-final { scan-assembler "((vmov)|(fmrrd))\[ \]+\[rR\]\[0-9\]+, \[rR\]\[0-9\]+, \[dD\]\[0-9\]+!?\(\[ \]+@\[a-zA-Z0-9 \]+\)?\n" } } */
/* { dg-final { cleanup-saved-temps } } */