public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [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).