From patchwork Mon May 21 09:16:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: ARM/NEON: vld1q_dup_s64 builtin Date: Sun, 20 May 2012 23:16:15 -0000 From: Christophe LYON X-Patchwork-Id: 160340 Message-Id: <4FBA07DF.6070801@st.com> To: Ramana Radhakrishnan Cc: gcc-patches > I tried applying your patch but ran into trouble with patch not liking > this . My suspicion is mailer munging white spaces in some form - > Could you send the patch as an attachment please rather than inline in > your mail ? > > regards, > Ramana > Here it is, as an attachment. Note however that this patch is against GCC-4.6.3. Thanks for testing. Christophe. 2012-05-16 Christophe Lyon * gcc/config/arm/neon.md (neon_vld1_dup): Restrict to VQ operands. (neon_vld1_dupv2di): New, fixes vld1q_dup_s64. * gcc/testsuite/gcc.target/arm/neon-vld1_dupQ.c: New test. 2012-04-25 Christophe Lyon Fix codex #161546: Index: gcc/testsuite/gcc.target/arm/neon-vld1_dupQ.c =================================================================== --- gcc.orig/gcc/testsuite/gcc.target/arm/neon-vld1_dupQ.c (revision 0) +++ gcc.new/gcc/testsuite/gcc.target/arm/neon-vld1_dupQ.c (revision 0) @@ -0,0 +1,24 @@ +/* Test the `vld1q_s64' ARM Neon intrinsic. */ + +/* { dg-do run } */ +/* { dg-require-effective-target arm_neon_hw } */ +/* { dg-options "-O0" } */ +/* { dg-add-options arm_neon } */ + +#include "arm_neon.h" +#include + +int main (void) +{ + int64x1_t input[2] = {(int64x1_t)0x0123456776543210LL, + (int64x1_t)0x89abcdeffedcba90LL}; + int64x1_t output[2] = {0, 0}; + int64x2_t var = vld1q_dup_s64(input); + + vst1q_s64(output, var); + if (output[0] != (int64x1_t)0x0123456776543210LL) + abort(); + if (output[1] != (int64x1_t)0x0123456776543210LL) + abort(); + return 0; +} Index: gcc/config/arm/neon.md =================================================================== --- gcc.orig/gcc/config/arm/neon.md (revision 2659) +++ gcc.new/gcc/config/arm/neon.md (working copy) @@ -4195,20 +4195,32 @@ ) (define_insn "neon_vld1_dup" - [(set (match_operand:VQX 0 "s_register_operand" "=w") - (unspec:VQX [(match_operand: 1 "neon_struct_operand" "Um")] + [(set (match_operand:VQ 0 "s_register_operand" "=w") + (unspec:VQ [(match_operand: 1 "neon_struct_operand" "Um")] UNSPEC_VLD1_DUP))] "TARGET_NEON" { - if (GET_MODE_NUNITS (mode) > 2) return "vld1.\t{%e0[], %f0[]}, %A1"; - else - return "vld1.\t%h0, %A1"; } [(set (attr "neon_type") - (if_then_else (gt (const_string "") (const_string "1")) - (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes") - (const_string "neon_vld1_1_2_regs")))] + (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes"))] +) + +(define_insn_and_split "neon_vld1_dupv2di" + [(set (match_operand:V2DI 0 "s_register_operand" "=w") + (vec_duplicate:V2DI (match_operand:DI 1 "neon_struct_operand" "Um")))] + "TARGET_NEON" + "#" + "&& reload_completed" + [(const_int 0)] + { + rtx tmprtx = gen_lowpart (DImode, operands[0]); + emit_insn (gen_neon_vld1_dupdi (tmprtx, operands[1])); + emit_move_insn (gen_highpart (DImode, operands[0]), tmprtx ); + DONE; + } + [(set_attr "length" "8") + (set (attr "neon_type") (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes"))] ) (define_expand "vec_store_lanes"