From: David Sherwood Date: Wed, 21 Jan 2015 17:53:44 +0000 (+0000) Subject: gcc/ X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=668046d17599f7596f01cfbb8ebd0f00c4531e5b;p=gcc.git gcc/ 2015-01-21 David Sherwood Tejas Belagod * config/aarch64/aarch64-protos.h (aarch64_simd_attr_length_rglist) (aarch64_reverse_mask): New decls. * config/aarch64/iterators.md (UNSPEC_REV_REGLIST): New enum. (insn_count): New mode_attr. * config/aarch64/aarch64-simd.md (vec_store_lanesoi, vec_store_lanesci) (vec_store_lanesxi, vec_load_lanesoi, vec_load_lanesci) (vec_load_lanesxi): Made ABI compliant for Big Endian targets. (aarch64_rev_reglist, aarch64_simd_ld2, aarch64_simd_ld3) (aarch64_simd_ld4, aarch64_simd_st2, aarch64_simd_st3) (aarch64_simd_st4): New patterns. * config/aarch64/aarch64.c (aarch64_simd_attr_length_rglist) (aarch64_reverse_mask): New functions. Co-Authored-By: Tejas Belagod From-SVN: r219959 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 988097b3523..2921413e661 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2015-01-21 David Sherwood + Tejas Belagod + + * config/aarch64/aarch64-protos.h (aarch64_simd_attr_length_rglist) + (aarch64_reverse_mask): New decls. + * config/aarch64/iterators.md (UNSPEC_REV_REGLIST): New enum. + (insn_count): New mode_attr. + * config/aarch64/aarch64-simd.md (vec_store_lanesoi, vec_store_lanesci) + (vec_store_lanesxi, vec_load_lanesoi, vec_load_lanesci) + (vec_load_lanesxi): Made ABI compliant for Big Endian targets. + (aarch64_rev_reglist, aarch64_simd_ld2, aarch64_simd_ld3) + (aarch64_simd_ld4, aarch64_simd_st2, aarch64_simd_st3) + (aarch64_simd_st4): New patterns. + * config/aarch64/aarch64.c (aarch64_simd_attr_length_rglist) + (aarch64_reverse_mask): New functions. + 2015-01-21 Richard Sandiford * config/aarch64/aarch64-protos.h (aarch64_simd_disambiguate_copy): diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 165aa6bac50..0b3d03525e7 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -203,6 +203,8 @@ bool aarch64_modes_tieable_p (machine_mode mode1, bool aarch64_move_imm (HOST_WIDE_INT, machine_mode); bool aarch64_mov_operand_p (rtx, enum aarch64_symbol_context, machine_mode); +int aarch64_simd_attr_length_rglist (enum machine_mode); +rtx aarch64_reverse_mask (enum machine_mode); bool aarch64_offset_7bit_signed_scaled_p (machine_mode, HOST_WIDE_INT); char *aarch64_output_scalar_simd_mov_immediate (rtx, machine_mode); char *aarch64_output_simd_mov_immediate (rtx, machine_mode, unsigned); diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 870054dee4b..17ac56c010f 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -3880,7 +3880,7 @@ ;; Patterns for vector struct loads and stores. -(define_insn "vec_load_lanesoi" +(define_insn "aarch64_simd_ld2" [(set (match_operand:OI 0 "register_operand" "=w") (unspec:OI [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv") (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] @@ -3912,7 +3912,26 @@ [(set_attr "type" "neon_load2_one_lane")] ) -(define_insn "vec_store_lanesoi" +(define_expand "vec_load_lanesoi" + [(set (match_operand:OI 0 "register_operand" "=w") + (unspec:OI [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv") + (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_LD2))] + "TARGET_SIMD" +{ + if (BYTES_BIG_ENDIAN) + { + rtx tmp = gen_reg_rtx (OImode); + rtx mask = aarch64_reverse_mask (mode); + emit_insn (gen_aarch64_simd_ld2 (tmp, operands[1])); + emit_insn (gen_aarch64_rev_reglistoi (operands[0], tmp, mask)); + } + else + emit_insn (gen_aarch64_simd_ld2 (operands[0], operands[1])); + DONE; +}) + +(define_insn "aarch64_simd_st2" [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv") (unspec:OI [(match_operand:OI 1 "register_operand" "w") (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] @@ -3933,7 +3952,26 @@ [(set_attr "type" "neon_store3_one_lane")] ) -(define_insn "vec_load_lanesci" +(define_expand "vec_store_lanesoi" + [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv") + (unspec:OI [(match_operand:OI 1 "register_operand" "w") + (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_ST2))] + "TARGET_SIMD" +{ + if (BYTES_BIG_ENDIAN) + { + rtx tmp = gen_reg_rtx (OImode); + rtx mask = aarch64_reverse_mask (mode); + emit_insn (gen_aarch64_rev_reglistoi (tmp, operands[1], mask)); + emit_insn (gen_aarch64_simd_st2 (operands[0], tmp)); + } + else + emit_insn (gen_aarch64_simd_st2 (operands[0], operands[1])); + DONE; +}) + +(define_insn "aarch64_simd_ld3" [(set (match_operand:CI 0 "register_operand" "=w") (unspec:CI [(match_operand:CI 1 "aarch64_simd_struct_operand" "Utv") (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] @@ -3965,7 +4003,26 @@ [(set_attr "type" "neon_load3_one_lane")] ) -(define_insn "vec_store_lanesci" +(define_expand "vec_load_lanesci" + [(set (match_operand:CI 0 "register_operand" "=w") + (unspec:CI [(match_operand:CI 1 "aarch64_simd_struct_operand" "Utv") + (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_LD3))] + "TARGET_SIMD" +{ + if (BYTES_BIG_ENDIAN) + { + rtx tmp = gen_reg_rtx (CImode); + rtx mask = aarch64_reverse_mask (mode); + emit_insn (gen_aarch64_simd_ld3 (tmp, operands[1])); + emit_insn (gen_aarch64_rev_reglistci (operands[0], tmp, mask)); + } + else + emit_insn (gen_aarch64_simd_ld3 (operands[0], operands[1])); + DONE; +}) + +(define_insn "aarch64_simd_st3" [(set (match_operand:CI 0 "aarch64_simd_struct_operand" "=Utv") (unspec:CI [(match_operand:CI 1 "register_operand" "w") (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] @@ -3986,7 +4043,26 @@ [(set_attr "type" "neon_store3_one_lane")] ) -(define_insn "vec_load_lanesxi" +(define_expand "vec_store_lanesci" + [(set (match_operand:CI 0 "aarch64_simd_struct_operand" "=Utv") + (unspec:CI [(match_operand:CI 1 "register_operand" "w") + (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_ST3))] + "TARGET_SIMD" +{ + if (BYTES_BIG_ENDIAN) + { + rtx tmp = gen_reg_rtx (CImode); + rtx mask = aarch64_reverse_mask (mode); + emit_insn (gen_aarch64_rev_reglistci (tmp, operands[1], mask)); + emit_insn (gen_aarch64_simd_st3 (operands[0], tmp)); + } + else + emit_insn (gen_aarch64_simd_st3 (operands[0], operands[1])); + DONE; +}) + +(define_insn "aarch64_simd_ld4" [(set (match_operand:XI 0 "register_operand" "=w") (unspec:XI [(match_operand:XI 1 "aarch64_simd_struct_operand" "Utv") (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] @@ -4018,7 +4094,26 @@ [(set_attr "type" "neon_load4_one_lane")] ) -(define_insn "vec_store_lanesxi" +(define_expand "vec_load_lanesxi" + [(set (match_operand:XI 0 "register_operand" "=w") + (unspec:XI [(match_operand:XI 1 "aarch64_simd_struct_operand" "Utv") + (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_LD4))] + "TARGET_SIMD" +{ + if (BYTES_BIG_ENDIAN) + { + rtx tmp = gen_reg_rtx (XImode); + rtx mask = aarch64_reverse_mask (mode); + emit_insn (gen_aarch64_simd_ld4 (tmp, operands[1])); + emit_insn (gen_aarch64_rev_reglistxi (operands[0], tmp, mask)); + } + else + emit_insn (gen_aarch64_simd_ld4 (operands[0], operands[1])); + DONE; +}) + +(define_insn "aarch64_simd_st4" [(set (match_operand:XI 0 "aarch64_simd_struct_operand" "=Utv") (unspec:XI [(match_operand:XI 1 "register_operand" "w") (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] @@ -4039,6 +4134,50 @@ [(set_attr "type" "neon_store4_one_lane")] ) +(define_expand "vec_store_lanesxi" + [(set (match_operand:XI 0 "aarch64_simd_struct_operand" "=Utv") + (unspec:XI [(match_operand:XI 1 "register_operand" "w") + (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_ST4))] + "TARGET_SIMD" +{ + if (BYTES_BIG_ENDIAN) + { + rtx tmp = gen_reg_rtx (XImode); + rtx mask = aarch64_reverse_mask (mode); + emit_insn (gen_aarch64_rev_reglistxi (tmp, operands[1], mask)); + emit_insn (gen_aarch64_simd_st4 (operands[0], tmp)); + } + else + emit_insn (gen_aarch64_simd_st4 (operands[0], operands[1])); + DONE; +}) + +(define_insn_and_split "aarch64_rev_reglist" +[(set (match_operand:VSTRUCT 0 "register_operand" "=&w") + (unspec:VSTRUCT + [(match_operand:VSTRUCT 1 "register_operand" "w") + (match_operand:V16QI 2 "register_operand" "w")] + UNSPEC_REV_REGLIST))] + "TARGET_SIMD" + "#" + "&& reload_completed" + [(const_int 0)] +{ + int i; + int nregs = GET_MODE_SIZE (mode) / UNITS_PER_VREG; + for (i = 0; i < nregs; i++) + { + rtx op0 = gen_rtx_REG (V16QImode, REGNO (operands[0]) + i); + rtx op1 = gen_rtx_REG (V16QImode, REGNO (operands[1]) + i); + emit_insn (gen_aarch64_tbl1v16qi (op0, op1, operands[2])); + } + DONE; +} + [(set_attr "type" "neon_tbl1_q") + (set_attr "length" "")] +) + ;; Reload patterns for AdvSIMD register list operands. (define_expand "mov" diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index d7310d95e34..e057c590c20 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -8687,6 +8687,14 @@ aarch64_simd_attr_length_move (rtx_insn *insn) return 4; } +/* Compute and return the length of aarch64_simd_reglist, where is + one of VSTRUCT modes: OI, CI, EI, or XI. */ +int +aarch64_simd_attr_length_rglist (enum machine_mode mode) +{ + return (GET_MODE_SIZE (mode) / UNITS_PER_VREG) * 4; +} + /* Implement target hook TARGET_VECTOR_ALIGNMENT. The AAPCS64 sets the maximum alignment of a vector to 128 bits. */ static HOST_WIDE_INT @@ -10215,6 +10223,27 @@ aarch64_cannot_change_mode_class (machine_mode from, return true; } +rtx +aarch64_reverse_mask (enum machine_mode mode) +{ + /* We have to reverse each vector because we dont have + a permuted load that can reverse-load according to ABI rules. */ + rtx mask; + rtvec v = rtvec_alloc (16); + int i, j; + int nunits = GET_MODE_NUNITS (mode); + int usize = GET_MODE_UNIT_SIZE (mode); + + gcc_assert (BYTES_BIG_ENDIAN); + gcc_assert (AARCH64_VALID_SIMD_QREG_MODE (mode)); + + for (i = 0; i < nunits; i++) + for (j = 0; j < usize; j++) + RTVEC_ELT (v, i * usize + j) = GEN_INT ((i + 1) * usize - 1 - j); + mask = gen_rtx_CONST_VECTOR (V16QImode, v); + return force_reg (V16QImode, mask); +} + /* Implement MODES_TIEABLE_P. */ bool diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 1294a084bd1..606ccc33eec 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -276,6 +276,7 @@ UNSPEC_SHA256SU1 ; Used in aarch64-simd.md. UNSPEC_PMULL ; Used in aarch64-simd.md. UNSPEC_PMULL2 ; Used in aarch64-simd.md. + UNSPEC_REV_REGLIST ; Used in aarch64-simd.md. ]) ;; ------------------------------------------------------------------- @@ -652,6 +653,8 @@ (define_mode_attr vsi2qi [(V2SI "v8qi") (V4SI "v16qi")]) (define_mode_attr VSI2QI [(V2SI "V8QI") (V4SI "V16QI")]) +(define_mode_attr insn_count [(OI "8") (CI "12") (XI "16")]) + ;; ------------------------------------------------------------------- ;; Code Iterators ;; -------------------------------------------------------------------