]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
altivec.md (altivec_lve<VI_char>x): Replace define_insn with define_expand and new...
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Sun, 23 Feb 2014 15:27:48 +0000 (15:27 +0000)
committerWilliam Schmidt <wschmidt@gcc.gnu.org>
Sun, 23 Feb 2014 15:27:48 +0000 (15:27 +0000)
gcc:

2014-02-23  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

* config/rs6000/altivec.md (altivec_lve<VI_char>x): Replace
define_insn with define_expand and new define_insn
*altivec_lve<VI_char>x_internal.
(altivec_stve<VI_char>x): Replace define_insn with define_expand
and new define_insn *altivec_stve<VI_char>x_internal.
* config/rs6000/rs6000-protos.h (altivec_expand_stvex_be): New
prototype.
* config/rs6000/rs6000.c (altivec_expand_lvx_be): Document use by
lve*x built-ins.
(altivec_expand_stvex_be): New function.

gcc/testsuite:

2014-02-23  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

* gcc.dg/vmx/lde.c: New test.
* gcc.dg/vmx/lde-be-order.c: New test.
* gcc.dg/vmx/ste.c: New test.
* gcc.dg/vmx/ste-be-order.c: New test.

From-SVN: r208049

gcc/ChangeLog
gcc/config/rs6000/altivec.md
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vmx/lde-be-order.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vmx/lde.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vmx/ste-be-order.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vmx/ste.c [new file with mode: 0644]

index 8ee5a2b2e4dffd11a7e00d215e5a8e0fa0bcb00f..af67073ba12b77e8e77b90391c160d90d8e4cae1 100644 (file)
@@ -1,3 +1,16 @@
+2014-02-23  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+        * config/rs6000/altivec.md (altivec_lve<VI_char>x): Replace
+        define_insn with define_expand and new define_insn
+        *altivec_lve<VI_char>x_internal.
+        (altivec_stve<VI_char>x): Replace define_insn with define_expand
+        and new define_insn *altivec_stve<VI_char>x_internal.
+        * config/rs6000/rs6000-protos.h (altivec_expand_stvex_be): New
+        prototype.
+        * config/rs6000/rs6000.c (altivec_expand_lvx_be): Document use by
+        lve*x built-ins.
+        (altivec_expand_stvex_be): New function.
+
 2014-02-22  Joern Rennecke  <joern.rennecke@embecosm.com>
 
        * config/avr/avr.c (avr_can_eliminate): Allow elimination from
index 5b5541987967194b8f6ce7ed1639296be4abeb42..08357795ce93f291e2558d92591a2b843f364e8c 100644 (file)
 ;; Parallel some of the LVE* and STV*'s with unspecs because some have
 ;; identical rtl but different instructions-- and gcc gets confused.
 
-(define_insn "altivec_lve<VI_char>x"
+(define_expand "altivec_lve<VI_char>x"
+  [(parallel
+    [(set (match_operand:VI 0 "register_operand" "=v")
+         (match_operand:VI 1 "memory_operand" "Z"))
+     (unspec [(const_int 0)] UNSPEC_LVE)])]
+  "TARGET_ALTIVEC"
+{
+  if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
+    {
+      altivec_expand_lvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_LVE);
+      DONE;
+    }
+})
+
+(define_insn "*altivec_lve<VI_char>x_internal"
   [(parallel
     [(set (match_operand:VI 0 "register_operand" "=v")
          (match_operand:VI 1 "memory_operand" "Z"))
   "stvxl %1,%y0"
   [(set_attr "type" "vecstore")])
 
-(define_insn "altivec_stve<VI_char>x"
+(define_expand "altivec_stve<VI_char>x"
+  [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
+       (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))]
+  "TARGET_ALTIVEC"
+{
+  if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
+    {
+      altivec_expand_stvex_be (operands[0], operands[1], <MODE>mode, UNSPEC_STVE);
+      DONE;
+    }
+})
+
+(define_insn "*altivec_stve<VI_char>x_internal"
   [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
        (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))]
   "TARGET_ALTIVEC"
index 84d466ec890054ce14f1e2d215f43def51240d22..3f971f0912fac56b04bc38bc4a0664cac5f00d97 100644 (file)
@@ -60,6 +60,7 @@ extern void altivec_expand_vec_perm_le (rtx op[4]);
 extern bool rs6000_expand_vec_perm_const (rtx op[4]);
 extern void altivec_expand_lvx_be (rtx, rtx, enum machine_mode, unsigned);
 extern void altivec_expand_stvx_be (rtx, rtx, enum machine_mode, unsigned);
+extern void altivec_expand_stvex_be (rtx, rtx, enum machine_mode, unsigned);
 extern void rs6000_expand_extract_even (rtx, rtx, rtx);
 extern void rs6000_expand_interleave (rtx, rtx, rtx, bool);
 extern void build_mask64_2_operands (rtx, rtx *);
index a9c99bdc1ccf2a7983a64cdbdc6d5c1977e6abff..2dff39ef66536bcf9ddbc8dd522f69879db7e1a2 100644 (file)
@@ -11848,7 +11848,7 @@ swap_selector_for_mode (enum machine_mode mode)
   return force_reg (V16QImode, gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm)));
 }
 
-/* Generate code for an "lvx" or "lvxl" built-in for a little endian target
+/* Generate code for an "lvx", "lvxl", or "lve*x" built-in for a little endian target
    with -maltivec=be specified.  Issue the load followed by an element-reversing
    permute.  */
 void
@@ -11885,6 +11885,23 @@ altivec_expand_stvx_be (rtx op0, rtx op1, enum machine_mode mode, unsigned unspe
   emit_insn (par);
 }
 
+/* Generate code for a "stve*x" built-in for a little endian target with -maltivec=be
+   specified.  Issue the store preceded by an element-reversing permute.  */
+void
+altivec_expand_stvex_be (rtx op0, rtx op1, enum machine_mode mode, unsigned unspec)
+{
+  enum machine_mode inner_mode = GET_MODE_INNER (mode);
+  rtx tmp = gen_reg_rtx (mode);
+  rtx stvx = gen_rtx_UNSPEC (inner_mode, gen_rtvec (1, tmp), unspec);
+  rtx sel = swap_selector_for_mode (mode);
+  rtx vperm;
+
+  gcc_assert (REG_P (op1));
+  vperm = gen_rtx_UNSPEC (mode, gen_rtvec (3, op1, op1, sel), UNSPEC_VPERM);
+  emit_insn (gen_rtx_SET (VOIDmode, tmp, vperm));
+  emit_insn (gen_rtx_SET (VOIDmode, op0, stvx));
+}
+
 static rtx
 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
 {
index 0effdc65b5507847ddee5202a2f2b09b61fffee2..efd818b5ead776f6b4327fd127a94225c00a5450 100644 (file)
@@ -1,3 +1,10 @@
+2014-02-23  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+        * gcc.dg/vmx/lde.c: New test.
+        * gcc.dg/vmx/lde-be-order.c: New test.
+        * gcc.dg/vmx/ste.c: New test.
+        * gcc.dg/vmx/ste-be-order.c: New test.
+
 2014-02-22  Hans-Peter Nilsson  <hp@axis.com>
 
        PR testsuite/60173
diff --git a/gcc/testsuite/gcc.dg/vmx/lde-be-order.c b/gcc/testsuite/gcc.dg/vmx/lde-be-order.c
new file mode 100644 (file)
index 0000000..9a6d5ba
--- /dev/null
@@ -0,0 +1,73 @@
+/* { dg-options "-maltivec=be -mabi=altivec -std=gnu99 -mno-vsx" } */
+
+#include "harness.h"
+
+static unsigned char svuc[16] __attribute__ ((aligned (16)));
+static signed char svsc[16] __attribute__ ((aligned (16)));
+static unsigned short svus[8] __attribute__ ((aligned (16)));
+static signed short svss[8] __attribute__ ((aligned (16)));
+static unsigned int svui[4] __attribute__ ((aligned (16)));
+static signed int svsi[4] __attribute__ ((aligned (16)));
+static float svf[4] __attribute__ ((aligned (16)));
+
+static void init ()
+{
+  int i;
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+  for (i = 15; i >= 0; --i)
+#else
+  for (i = 0; i < 16; ++i)
+#endif
+    {
+      svuc[i] = i;
+      svsc[i] = i - 8;
+    }
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+  for (i = 7; i >= 0; --i)
+#else
+  for (i = 0; i < 8; ++i)
+#endif
+    {
+      svus[i] = i;
+      svss[i] = i - 4;
+    }
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+  for (i = 3; i >= 0; --i)
+#else
+  for (i = 0; i < 4; ++i)
+#endif
+    {
+      svui[i] = i;
+      svsi[i] = i - 2;
+      svf[i] = i * 1.0f;
+    }
+}
+
+static void test ()
+{
+  vector unsigned char vuc;
+  vector signed char vsc;
+  vector unsigned short vus;
+  vector signed short vss;
+  vector unsigned int vui;
+  vector signed int vsi;
+  vector float vf;
+
+  init ();
+
+  vuc = vec_lde (9*1, (unsigned char *)svuc);
+  vsc = vec_lde (14*1, (signed char *)svsc);
+  vus = vec_lde (7*2, (unsigned short *)svus);
+  vss = vec_lde (1*2, (signed short *)svss);
+  vui = vec_lde (3*4, (unsigned int *)svui);
+  vsi = vec_lde (2*4, (signed int *)svsi);
+  vf  = vec_lde (0*4, (float *)svf);
+
+  check (vec_extract (vuc, 9) == 9, "vuc");
+  check (vec_extract (vsc, 14) == 6, "vsc");
+  check (vec_extract (vus, 7) == 7, "vus");
+  check (vec_extract (vss, 1) == -3, "vss");
+  check (vec_extract (vui, 3) == 3, "vui");
+  check (vec_extract (vsi, 2) == 0, "vsi");
+  check (vec_extract (vf,  0) == 0.0, "vf");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/lde.c b/gcc/testsuite/gcc.dg/vmx/lde.c
new file mode 100644 (file)
index 0000000..5594963
--- /dev/null
@@ -0,0 +1,59 @@
+#include "harness.h"
+
+static unsigned char svuc[16] __attribute__ ((aligned (16)));
+static signed char svsc[16] __attribute__ ((aligned (16)));
+static unsigned short svus[8] __attribute__ ((aligned (16)));
+static signed short svss[8] __attribute__ ((aligned (16)));
+static unsigned int svui[4] __attribute__ ((aligned (16)));
+static signed int svsi[4] __attribute__ ((aligned (16)));
+static float svf[4] __attribute__ ((aligned (16)));
+
+static void init ()
+{
+  unsigned int i;
+  for (i = 0; i < 16; ++i)
+    {
+      svuc[i] = i;
+      svsc[i] = i - 8;
+    }
+  for (i = 0; i < 8; ++i)
+    {
+      svus[i] = i;
+      svss[i] = i - 4;
+    }
+  for (i = 0; i < 4; ++i)
+    {
+      svui[i] = i;
+      svsi[i] = i - 2;
+      svf[i] = i * 1.0f;
+    }
+}
+
+static void test ()
+{
+  vector unsigned char vuc;
+  vector signed char vsc;
+  vector unsigned short vus;
+  vector signed short vss;
+  vector unsigned int vui;
+  vector signed int vsi;
+  vector float vf;
+
+  init ();
+
+  vuc = vec_lde (9*1, (unsigned char *)svuc);
+  vsc = vec_lde (14*1, (signed char *)svsc);
+  vus = vec_lde (7*2, (unsigned short *)svus);
+  vss = vec_lde (1*2, (signed short *)svss);
+  vui = vec_lde (3*4, (unsigned int *)svui);
+  vsi = vec_lde (2*4, (signed int *)svsi);
+  vf  = vec_lde (0*4, (float *)svf);
+
+  check (vec_extract (vuc, 9) == 9, "vuc");
+  check (vec_extract (vsc, 14) == 6, "vsc");
+  check (vec_extract (vus, 7) == 7, "vus");
+  check (vec_extract (vss, 1) == -3, "vss");
+  check (vec_extract (vui, 3) == 3, "vui");
+  check (vec_extract (vsi, 2) == 0, "vsi");
+  check (vec_extract (vf,  0) == 0.0, "vf");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/ste-be-order.c b/gcc/testsuite/gcc.dg/vmx/ste-be-order.c
new file mode 100644 (file)
index 0000000..75f2004
--- /dev/null
@@ -0,0 +1,53 @@
+/* { dg-options "-maltivec=be -mabi=altivec -std=gnu99 -mno-vsx" } */
+
+#include "harness.h"
+
+static unsigned char svuc[16] __attribute__ ((aligned (16)));
+static signed char svsc[16] __attribute__ ((aligned (16)));
+static unsigned short svus[8] __attribute__ ((aligned (16)));
+static signed short svss[8] __attribute__ ((aligned (16)));
+static unsigned int svui[4] __attribute__ ((aligned (16)));
+static signed int svsi[4] __attribute__ ((aligned (16)));
+static float svf[4] __attribute__ ((aligned (16)));
+
+static void check_arrays ()
+{
+  check (svuc[9] == 9, "svuc");
+  check (svsc[14] == 6, "svsc");
+  check (svus[7] == 7, "svus");
+  check (svss[1] == -3, "svss");
+  check (svui[3] == 3, "svui");
+  check (svsi[2] == 0, "svsi");
+  check (svf[0] == 0.0, "svf");
+}
+
+static void test ()
+{
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+  vector unsigned char vuc = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
+  vector signed char vsc = {7,6,5,4,3,2,1,0,-1,-2,-3,-4,-5,-6,-7,-8};
+  vector unsigned short vus = {7,6,5,4,3,2,1,0};
+  vector signed short vss = {3,2,1,0,-1,-2,-3,-4};
+  vector unsigned int vui = {3,2,1,0};
+  vector signed int vsi = {1,0,-1,-2};
+  vector float vf = {3.0,2.0,1.0,0.0};
+#else
+  vector unsigned char vuc = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+  vector signed char vsc = {-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7};
+  vector unsigned short vus = {0,1,2,3,4,5,6,7};
+  vector signed short vss = {-4,-3,-2,-1,0,1,2,3};
+  vector unsigned int vui = {0,1,2,3};
+  vector signed int vsi = {-2,-1,0,1};
+  vector float vf = {0.0,1.0,2.0,3.0};
+#endif
+
+  vec_ste (vuc, 9*1, (unsigned char *)svuc);
+  vec_ste (vsc, 14*1, (signed char *)svsc);
+  vec_ste (vus, 7*2, (unsigned short *)svus);
+  vec_ste (vss, 1*2, (signed short *)svss);
+  vec_ste (vui, 3*4, (unsigned int *)svui);
+  vec_ste (vsi, 2*4, (signed int *)svsi);
+  vec_ste (vf,  0*4, (float *)svf);
+
+  check_arrays ();
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/ste.c b/gcc/testsuite/gcc.dg/vmx/ste.c
new file mode 100644 (file)
index 0000000..9bbda3b
--- /dev/null
@@ -0,0 +1,41 @@
+#include "harness.h"
+
+static unsigned char svuc[16] __attribute__ ((aligned (16)));
+static signed char svsc[16] __attribute__ ((aligned (16)));
+static unsigned short svus[8] __attribute__ ((aligned (16)));
+static signed short svss[8] __attribute__ ((aligned (16)));
+static unsigned int svui[4] __attribute__ ((aligned (16)));
+static signed int svsi[4] __attribute__ ((aligned (16)));
+static float svf[4] __attribute__ ((aligned (16)));
+
+static void check_arrays ()
+{
+  check (svuc[9] == 9, "svuc");
+  check (svsc[14] == 6, "svsc");
+  check (svus[7] == 7, "svus");
+  check (svss[1] == -3, "svss");
+  check (svui[3] == 3, "svui");
+  check (svsi[2] == 0, "svsi");
+  check (svf[0] == 0.0, "svf");
+}
+
+static void test ()
+{
+  vector unsigned char vuc = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+  vector signed char vsc = {-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7};
+  vector unsigned short vus = {0,1,2,3,4,5,6,7};
+  vector signed short vss = {-4,-3,-2,-1,0,1,2,3};
+  vector unsigned int vui = {0,1,2,3};
+  vector signed int vsi = {-2,-1,0,1};
+  vector float vf = {0.0,1.0,2.0,3.0};
+
+  vec_ste (vuc, 9*1, (unsigned char *)svuc);
+  vec_ste (vsc, 14*1, (signed char *)svsc);
+  vec_ste (vus, 7*2, (unsigned short *)svus);
+  vec_ste (vss, 1*2, (signed short *)svss);
+  vec_ste (vui, 3*4, (unsigned int *)svui);
+  vec_ste (vsi, 2*4, (signed int *)svsi);
+  vec_ste (vf,  0*4, (float *)svf);
+
+  check_arrays ();
+}