* [AArch64] [BE] [1/2] Make large opaque integer modes endianness-safe.
@ 2014-10-10 14:49 David Sherwood
2014-10-29 10:37 ` Tejas Belagod
0 siblings, 1 reply; 4+ messages in thread
From: David Sherwood @ 2014-10-10 14:49 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 897 bytes --]
Hi,
I have a fix (originally written by Tejas Belagod) for the following bug:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59810
Could someone take a look please?
Thanks!
David Sherwood.
ChangeLog:
gcc/:
2014-10-10 David Sherwood <david.sherwood@arm.com>
* config/aarch64/aarch64-protos.h (aarch64_simd_attr_length_rglist,
aarch64_reverse_mask): New decls.
* config/aarch64/iterators.md (UNSPEC_REV_REGLIST): New enum.
* config/aarch64/iterators.md (insn_count): New mode_attr.
* config/aarch64/aarch64-simd.md (vec_store_lanes(o/c/x)i,
vec_load_lanes(o/c/x)i): Fixed to work for Big Endian.
* config/aarch64/aarch64-simd.md (aarch64_rev_reglist,
aarch64_simd_(ld/st)(2/3/4)): Added.
* config/aarch64/aarch64.c (aarch64_simd_attr_length_rglist,
aarch64_reverse_mask): Added.
[-- Attachment #2: ccmc_v1.patch --]
[-- Type: application/octet-stream, Size: 10029 bytes --]
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index b5f53d2..7710f1f 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -196,6 +196,8 @@ bool aarch64_modes_tieable_p (enum machine_mode mode1,
bool aarch64_move_imm (HOST_WIDE_INT, enum machine_mode);
bool aarch64_mov_operand_p (rtx, enum aarch64_symbol_context,
enum 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 (enum machine_mode, HOST_WIDE_INT);
char *aarch64_output_scalar_simd_mov_immediate (rtx, enum machine_mode);
char *aarch64_output_simd_mov_immediate (rtx, enum machine_mode, unsigned);
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index cab26a3..126653f 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -3981,7 +3981,7 @@
;; Patterns for vector struct loads and stores.
-(define_insn "vec_load_lanesoi<mode>"
+(define_insn "aarch64_simd_ld2<mode>"
[(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)]
@@ -3991,7 +3991,26 @@
[(set_attr "type" "neon_load2_2reg<q>")]
)
-(define_insn "vec_store_lanesoi<mode>"
+(define_expand "vec_load_lanesoi<mode>"
+ [(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>mode);
+ emit_insn (gen_aarch64_simd_ld2<mode> (tmp, operands[1]));
+ emit_insn (gen_aarch64_rev_reglistoi (operands[0], tmp, mask));
+ }
+ else
+ emit_insn (gen_aarch64_simd_ld2<mode> (operands[0], operands[1]));
+ DONE;
+})
+
+(define_insn "aarch64_simd_st2<mode>"
[(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)]
@@ -4012,7 +4031,26 @@
[(set_attr "type" "neon_store3_one_lane<q>")]
)
-(define_insn "vec_load_lanesci<mode>"
+(define_expand "vec_store_lanesoi<mode>"
+ [(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>mode);
+ emit_insn (gen_aarch64_rev_reglistoi (tmp, operands[1], mask));
+ emit_insn (gen_aarch64_simd_st2<mode> (operands[0], tmp));
+ }
+ else
+ emit_insn (gen_aarch64_simd_st2<mode> (operands[0], operands[1]));
+ DONE;
+})
+
+(define_insn "aarch64_simd_ld3<mode>"
[(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)]
@@ -4022,7 +4060,26 @@
[(set_attr "type" "neon_load3_3reg<q>")]
)
-(define_insn "vec_store_lanesci<mode>"
+(define_expand "vec_load_lanesci<mode>"
+ [(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>mode);
+ emit_insn (gen_aarch64_simd_ld3<mode> (tmp, operands[1]));
+ emit_insn (gen_aarch64_rev_reglistci (operands[0], tmp, mask));
+ }
+ else
+ emit_insn (gen_aarch64_simd_ld3<mode> (operands[0], operands[1]));
+ DONE;
+})
+
+(define_insn "aarch64_simd_st3<mode>"
[(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)]
@@ -4043,7 +4100,26 @@
[(set_attr "type" "neon_store3_one_lane<q>")]
)
-(define_insn "vec_load_lanesxi<mode>"
+(define_expand "vec_store_lanesci<mode>"
+ [(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>mode);
+ emit_insn (gen_aarch64_rev_reglistci (tmp, operands[1], mask));
+ emit_insn (gen_aarch64_simd_st3<mode> (operands[0], tmp));
+ }
+ else
+ emit_insn (gen_aarch64_simd_st3<mode> (operands[0], operands[1]));
+ DONE;
+})
+
+(define_insn "aarch64_simd_ld4<mode>"
[(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)]
@@ -4053,7 +4129,26 @@
[(set_attr "type" "neon_load4_4reg<q>")]
)
-(define_insn "vec_store_lanesxi<mode>"
+(define_expand "vec_load_lanesxi<mode>"
+ [(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>mode);
+ emit_insn (gen_aarch64_simd_ld4<mode> (tmp, operands[1]));
+ emit_insn (gen_aarch64_rev_reglistxi (operands[0], tmp, mask));
+ }
+ else
+ emit_insn (gen_aarch64_simd_ld4<mode> (operands[0], operands[1]));
+ DONE;
+})
+
+(define_insn "aarch64_simd_st4<mode>"
[(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)]
@@ -4074,6 +4169,50 @@
[(set_attr "type" "neon_store4_one_lane<q>")]
)
+(define_expand "vec_store_lanesxi<mode>"
+ [(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>mode);
+ emit_insn (gen_aarch64_rev_reglistxi (tmp, operands[1], mask));
+ emit_insn (gen_aarch64_simd_st4<mode> (operands[0], tmp));
+ }
+ else
+ emit_insn (gen_aarch64_simd_st4<mode> (operands[0], operands[1]));
+ DONE;
+})
+
+(define_insn_and_split "aarch64_rev_reglist<mode>"
+[(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>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" "<insn_count>")]
+)
+
;; Reload patterns for AdvSIMD register list operands.
(define_expand "mov<mode>"
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 5144c35..9d05058 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -8072,6 +8072,14 @@ aarch64_simd_attr_length_move (rtx_insn *insn)
return 4;
}
+/* Compute and return the length of aarch64_simd_reglist<mode>, where <mode> 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
@@ -9600,6 +9608,27 @@ aarch64_cannot_change_mode_class (enum 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 efd006f..05e842c 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -299,6 +299,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.
])
;; -------------------------------------------------------------------
@@ -668,6 +669,8 @@
(V2DI "p") (V2DF "p")
(V2SF "p") (V4SF "v")])
+(define_mode_attr insn_count [(OI "8") (CI "12") (XI "16")])
+
;; -------------------------------------------------------------------
;; Code Iterators
;; -------------------------------------------------------------------
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [AArch64] [BE] [1/2] Make large opaque integer modes endianness-safe.
2014-10-10 14:49 [AArch64] [BE] [1/2] Make large opaque integer modes endianness-safe David Sherwood
@ 2014-10-29 10:37 ` Tejas Belagod
2014-11-04 11:12 ` Marcus Shawcroft
0 siblings, 1 reply; 4+ messages in thread
From: Tejas Belagod @ 2014-10-29 10:37 UTC (permalink / raw)
To: David Sherwood, gcc-patches
On 10/10/14 15:48, David Sherwood wrote:
> Hi,
>
> I have a fix (originally written by Tejas Belagod) for the following bug:
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59810
>
> Could someone take a look please?
>
> Thanks!
> David Sherwood.
>
> ChangeLog:
>
> gcc/:
> 2014-10-10 David Sherwood <david.sherwood@arm.com>
>
> * config/aarch64/aarch64-protos.h (aarch64_simd_attr_length_rglist,
> aarch64_reverse_mask): New decls.
> * config/aarch64/iterators.md (UNSPEC_REV_REGLIST): New enum.
> * config/aarch64/iterators.md (insn_count): New mode_attr.
> * config/aarch64/aarch64-simd.md (vec_store_lanes(o/c/x)i,
> vec_load_lanes(o/c/x)i): Fixed to work for Big Endian.
> * config/aarch64/aarch64-simd.md (aarch64_rev_reglist,
> aarch64_simd_(ld/st)(2/3/4)): Added.
> * config/aarch64/aarch64.c (aarch64_simd_attr_length_rglist,
> aarch64_reverse_mask): Added.
>
+ RTVEC_ELT (v, (i * usize + j)) = GEN_INT (((i+1) * usize) - 1 - j);
s/i+1/i + 1. Remove extra parentheses.
Tejas.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [AArch64] [BE] [1/2] Make large opaque integer modes endianness-safe.
2014-10-29 10:37 ` Tejas Belagod
@ 2014-11-04 11:12 ` Marcus Shawcroft
0 siblings, 0 replies; 4+ messages in thread
From: Marcus Shawcroft @ 2014-11-04 11:12 UTC (permalink / raw)
To: Tejas Belagod; +Cc: David Sherwood, gcc-patches
On 29 October 2014 10:34, Tejas Belagod <tejas.belagod@arm.com> wrote:
> On 10/10/14 15:48, David Sherwood wrote:
>> I have a fix (originally written by Tejas Belagod) for the following bug:
In which case you should add his name along side yours in the ChangeLog entry...
>> ChangeLog:
>>
>> gcc/:
>> 2014-10-10 David Sherwood <david.sherwood@arm.com>
>>
>> * config/aarch64/aarch64-protos.h
>> (aarch64_simd_attr_length_rglist,
>> aarch64_reverse_mask): New decls.
>> * config/aarch64/iterators.md (UNSPEC_REV_REGLIST): New enum.
>> * config/aarch64/iterators.md (insn_count): New mode_attr.
>> * config/aarch64/aarch64-simd.md (vec_store_lanes(o/c/x)i,
>> vec_load_lanes(o/c/x)i): Fixed to work for Big Endian.
>> * config/aarch64/aarch64-simd.md (aarch64_rev_reglist,
>> aarch64_simd_(ld/st)(2/3/4)): Added.
>> * config/aarch64/aarch64.c (aarch64_simd_attr_length_rglist,
>> aarch64_reverse_mask): Added.
>>
>
> + RTVEC_ELT (v, (i * usize + j)) = GEN_INT (((i+1) * usize) - 1 - j);
>
>
> s/i+1/i + 1. Remove extra parentheses.
>
> Tejas.
>
OK with the fix up requested by Tejas.
/Marcus
^ permalink raw reply [flat|nested] 4+ messages in thread
* RE: [AArch64] [BE] [1/2] Make large opaque integer modes endianness-safe.
@ 2014-10-28 8:56 David Sherwood
0 siblings, 0 replies; 4+ messages in thread
From: David Sherwood @ 2014-10-28 8:56 UTC (permalink / raw)
To: gcc-patches
Hi,
Sorry to bother you again. Could someone take a look at this change
please if they have time?
Thanks!
David.
-----Original Message-----
From: David Sherwood [mailto:david.sherwood@arm.com]
Sent: 10 October 2014 15:48
To: gcc-patches@gcc.gnu.org
Subject: [AArch64] [BE] [1/2] Make large opaque integer modes endianness-safe.
Hi,
I have a fix (originally written by Tejas Belagod) for the following bug:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59810
Could someone take a look please?
Thanks!
David Sherwood.
ChangeLog:
gcc/:
2014-10-10 David Sherwood <david.sherwood@arm.com>
* config/aarch64/aarch64-protos.h (aarch64_simd_attr_length_rglist,
aarch64_reverse_mask): New decls.
* config/aarch64/iterators.md (UNSPEC_REV_REGLIST): New enum.
* config/aarch64/iterators.md (insn_count): New mode_attr.
* config/aarch64/aarch64-simd.md (vec_store_lanes(o/c/x)i,
vec_load_lanes(o/c/x)i): Fixed to work for Big Endian.
* config/aarch64/aarch64-simd.md (aarch64_rev_reglist,
aarch64_simd_(ld/st)(2/3/4)): Added.
* config/aarch64/aarch64.c (aarch64_simd_attr_length_rglist,
aarch64_reverse_mask): Added.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-11-04 11:12 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-10 14:49 [AArch64] [BE] [1/2] Make large opaque integer modes endianness-safe David Sherwood
2014-10-29 10:37 ` Tejas Belagod
2014-11-04 11:12 ` Marcus Shawcroft
2014-10-28 8:56 David Sherwood
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).