* config/aarch64/aarch64-simd.md (aarch64_combine<mode>): convert to split.
(aarch64_simd_combine<mode>): New instruction expansion.
* config/aarch64/aarch64-protos.h (aarch64_split_simd_combine): New
function prototype.
* config/aarch64/aarch64.c (aarch64_split_combine): New function.
* config/aarch64/iterators.md (Vdbl): Add entry for DF.
From-SVN: r200020
+2013-06-12 Sofiane Naci <sofiane.naci@arm.com>
+
+ * config/aarch64/aarch64-simd.md (aarch64_combine<mode>): convert to split.
+ (aarch64_simd_combine<mode>): New instruction expansion.
+ * config/aarch64/aarch64-protos.h (aarch64_split_simd_combine): New
+ function prototype.
+ * config/aarch64/aarch64.c (aarch64_split_combine): New function.
+ * config/aarch64/iterators.md (Vdbl): Add entry for DF.
+
2013-06-12 Jan Hubicka <jh@suse.cz>
* cgraph.c (verify_edge_corresponds_to_fndecl): Be lax about
bool aarch64_split_128bit_move_p (rtx, rtx);
+void aarch64_split_simd_combine (rtx, rtx, rtx);
+
void aarch64_split_simd_move (rtx, rtx);
/* Check for a legitimate floating point constant for FMOV. */
(set_attr "simd_mode" "<MODE>")]
)
-(define_insn "aarch64_combine<mode>"
+(define_insn_and_split "aarch64_combine<mode>"
[(set (match_operand:<VDBL> 0 "register_operand" "=&w")
(vec_concat:<VDBL> (match_operand:VDC 1 "register_operand" "w")
(match_operand:VDC 2 "register_operand" "w")))]
"TARGET_SIMD"
- "mov\\t%0.d[0], %1.d[0]\;ins\\t%0.d[1], %2.d[0]"
- [(set_attr "simd_type" "simd_ins")
- (set_attr "simd_mode" "<MODE>")]
-)
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ aarch64_split_simd_combine (operands[0], operands[1], operands[2]);
+ DONE;
+})
+
+(define_expand "aarch64_simd_combine<mode>"
+ [(set (match_operand:<VDBL> 0 "register_operand" "=&w")
+ (vec_concat:<VDBL> (match_operand:VDC 1 "register_operand" "w")
+ (match_operand:VDC 2 "register_operand" "w")))]
+ "TARGET_SIMD"
+ {
+ emit_insn (gen_move_lo_quad_<Vdbl> (operands[0], operands[1]));
+ emit_insn (gen_move_hi_quad_<Vdbl> (operands[0], operands[2]));
+ DONE;
+ })
;; <su><addsub>l<q>.
|| ! (FP_REGNUM_P (REGNO (dst)) && FP_REGNUM_P (REGNO (src))));
}
+/* Split a complex SIMD combine. */
+
+void
+aarch64_split_simd_combine (rtx dst, rtx src1, rtx src2)
+{
+ enum machine_mode src_mode = GET_MODE (src1);
+ enum machine_mode dst_mode = GET_MODE (dst);
+
+ gcc_assert (VECTOR_MODE_P (dst_mode));
+
+ if (REG_P (dst) && REG_P (src1) && REG_P (src2))
+ {
+ rtx (*gen) (rtx, rtx, rtx);
+
+ switch (src_mode)
+ {
+ case V8QImode:
+ gen = gen_aarch64_simd_combinev8qi;
+ break;
+ case V4HImode:
+ gen = gen_aarch64_simd_combinev4hi;
+ break;
+ case V2SImode:
+ gen = gen_aarch64_simd_combinev2si;
+ break;
+ case V2SFmode:
+ gen = gen_aarch64_simd_combinev2sf;
+ break;
+ case DImode:
+ gen = gen_aarch64_simd_combinedi;
+ break;
+ case DFmode:
+ gen = gen_aarch64_simd_combinedf;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ emit_insn (gen (dst, src1, src2));
+ return;
+ }
+}
+
/* Split a complex SIMD move. */
void
;; Double modes of vector modes (lower case).
(define_mode_attr Vdbl [(V8QI "v16qi") (V4HI "v8hi")
(V2SI "v4si") (V2SF "v4sf")
- (SI "v2si") (DI "v2di")])
+ (SI "v2si") (DI "v2di")
+ (DF "v2df")])
;; Narrowed modes for VDN.
(define_mode_attr VNARROWD [(V4HI "V8QI") (V2SI "V4HI")