From 09fccb6243ff7fe953e2026da794d8dda5875bef Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Mon, 13 Jan 2014 23:18:05 +0000 Subject: [PATCH] rs6000-c.c (altivec_resolve_overloaded_builtin): Implement -maltivec=be for vec_insert and vec_extract. gcc: 2014-01-13 Bill Schmidt * config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): Implement -maltivec=be for vec_insert and vec_extract. gcc/testsuite: 2014-01-13 Bill Schmidt * gcc.dg/vmx/insert.c: New. * gcc.dg/vmx/insert-be-order.c: New. * gcc.dg/vmx/extract.c: New. * gcc.dg/vmx/extract-be-order.c: New. From-SVN: r206590 --- gcc/ChangeLog | 5 +++ gcc/config/rs6000/rs6000-c.c | 26 +++++++++++- gcc/testsuite/ChangeLog | 7 ++++ gcc/testsuite/gcc.dg/vmx/extract-be-order.c | 33 +++++++++++++++ gcc/testsuite/gcc.dg/vmx/extract.c | 21 ++++++++++ gcc/testsuite/gcc.dg/vmx/insert-be-order.c | 65 +++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vmx/insert.c | 37 ++++++++++++++++ 7 files changed, 192 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vmx/extract-be-order.c create mode 100644 gcc/testsuite/gcc.dg/vmx/extract.c create mode 100644 gcc/testsuite/gcc.dg/vmx/insert-be-order.c create mode 100644 gcc/testsuite/gcc.dg/vmx/insert.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5c674bc..d52bb3a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2014-01-13 Bill Schmidt + + * config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): + Implement -maltivec=be for vec_insert and vec_extract. + 2014-01-10 DJ Delorie * config/msp430/msp430.md (call_internal): Don't allow memory diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c index 70e75e6..2072b76 100644 --- a/gcc/config/rs6000/rs6000-c.c +++ b/gcc/config/rs6000/rs6000-c.c @@ -4172,7 +4172,7 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, return build_constructor (type, vec); } - /* For now use pointer tricks to do the extaction, unless we are on VSX + /* For now use pointer tricks to do the extraction, unless we are on VSX extracting a double from a constant offset. */ if (fcode == ALTIVEC_BUILTIN_VEC_EXTRACT) { @@ -4200,6 +4200,17 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2))) goto bad; + /* If we are targeting little-endian, but -maltivec=be has been + specified to override the element order, adjust the element + number accordingly. */ + if (!BYTES_BIG_ENDIAN && rs6000_altivec_element_order == 2) + { + unsigned int last_elem = TYPE_VECTOR_SUBPARTS (arg1_type) - 1; + arg2 = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (arg2), + build_int_cstu (TREE_TYPE (arg2), last_elem), + arg2); + } + /* If we can use the VSX xxpermdi instruction, use that for extract. */ mode = TYPE_MODE (arg1_type); if ((mode == V2DFmode || mode == V2DImode) && VECTOR_MEM_VSX_P (mode) @@ -4256,7 +4267,7 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, return stmt; } - /* For now use pointer tricks to do the insertation, unless we are on VSX + /* For now use pointer tricks to do the insertion, unless we are on VSX inserting a double to a constant offset.. */ if (fcode == ALTIVEC_BUILTIN_VEC_INSERT) { @@ -4286,6 +4297,17 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2))) goto bad; + /* If we are targeting little-endian, but -maltivec=be has been + specified to override the element order, adjust the element + number accordingly. */ + if (!BYTES_BIG_ENDIAN && rs6000_altivec_element_order == 2) + { + unsigned int last_elem = TYPE_VECTOR_SUBPARTS (arg1_type) - 1; + arg2 = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (arg2), + build_int_cstu (TREE_TYPE (arg2), last_elem), + arg2); + } + /* If we can use the VSX xxpermdi instruction, use that for insert. */ mode = TYPE_MODE (arg1_type); if ((mode == V2DFmode || mode == V2DImode) && VECTOR_UNIT_VSX_P (mode) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 459e365..1576e52 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-01-13 Bill Schmidt + + * gcc.dg/vmx/insert.c: New. + * gcc.dg/vmx/insert-be-order.c: New. + * gcc.dg/vmx/extract.c: New. + * gcc.dg/vmx/extract-be-order.c: New. + 2014-01-13 Jakub Jelinek PR tree-optimization/59387 diff --git a/gcc/testsuite/gcc.dg/vmx/extract-be-order.c b/gcc/testsuite/gcc.dg/vmx/extract-be-order.c new file mode 100644 index 0000000..5c09471 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vmx/extract-be-order.c @@ -0,0 +1,33 @@ +/* { dg-options "-maltivec=be -mabi=altivec -std=gnu99 -mno-vsx" } */ + +#include "harness.h" + +static void test() +{ + vector unsigned char va = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + vector signed char vb = {-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7}; + vector unsigned short vc = {0,1,2,3,4,5,6,7}; + vector signed short vd = {-4,-3,-2,-1,0,1,2,3}; + vector unsigned int ve = {0,1,2,3}; + vector signed int vf = {-2,-1,0,1}; + vector float vg = {-2.0f,-1.0f,0.0f,1.0f}; + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + check (vec_extract (va, 5) == 10, "vec_extract (va, 5)"); + check (vec_extract (vb, 0) == 7, "vec_extract (vb, 0)"); + check (vec_extract (vc, 7) == 0, "vec_extract (vc, 7)"); + check (vec_extract (vd, 3) == 0, "vec_extract (vd, 3)"); + check (vec_extract (ve, 2) == 1, "vec_extract (ve, 2)"); + check (vec_extract (vf, 1) == 0, "vec_extract (vf, 1)"); + check (vec_extract (vg, 0) == 1.0f, "vec_extract (vg, 0)"); +#else + check (vec_extract (va, 5) == 5, "vec_extract (va, 5)"); + check (vec_extract (vb, 0) == -8, "vec_extract (vb, 0)"); + check (vec_extract (vc, 7) == 7, "vec_extract (vc, 7)"); + check (vec_extract (vd, 3) == -1, "vec_extract (vd, 3)"); + check (vec_extract (ve, 2) == 2, "vec_extract (ve, 2)"); + check (vec_extract (vf, 1) == -1, "vec_extract (vf, 1)"); + check (vec_extract (vg, 0) == -2.0f, "vec_extract (vg, 0)"); +#endif +} + diff --git a/gcc/testsuite/gcc.dg/vmx/extract.c b/gcc/testsuite/gcc.dg/vmx/extract.c new file mode 100644 index 0000000..6fc4725 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vmx/extract.c @@ -0,0 +1,21 @@ +#include "harness.h" + +static void test() +{ + vector unsigned char va = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + vector signed char vb = {-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7}; + vector unsigned short vc = {0,1,2,3,4,5,6,7}; + vector signed short vd = {-4,-3,-2,-1,0,1,2,3}; + vector unsigned int ve = {0,1,2,3}; + vector signed int vf = {-2,-1,0,1}; + vector float vg = {-2.0f,-1.0f,0.0f,1.0f}; + + check (vec_extract (va, 5) == 5, "vec_extract (va, 5)"); + check (vec_extract (vb, 0) == -8, "vec_extract (vb, 0)"); + check (vec_extract (vc, 7) == 7, "vec_extract (vc, 7)"); + check (vec_extract (vd, 3) == -1, "vec_extract (vd, 3)"); + check (vec_extract (ve, 2) == 2, "vec_extract (ve, 2)"); + check (vec_extract (vf, 1) == -1, "vec_extract (vf, 1)"); + check (vec_extract (vg, 0) == -2.0f, "vec_extract (vg, 0)"); +} + diff --git a/gcc/testsuite/gcc.dg/vmx/insert-be-order.c b/gcc/testsuite/gcc.dg/vmx/insert-be-order.c new file mode 100644 index 0000000..592ef28 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vmx/insert-be-order.c @@ -0,0 +1,65 @@ +/* { dg-options "-maltivec=be -mabi=altivec -std=gnu99 -mno-vsx" } */ + +#include "harness.h" + +static void test() +{ + vector unsigned char va = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + vector signed char vb = {-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7}; + vector unsigned short vc = {0,1,2,3,4,5,6,7}; + vector signed short vd = {-4,-3,-2,-1,0,1,2,3}; + vector unsigned int ve = {0,1,2,3}; + vector signed int vf = {-2,-1,0,1}; + vector float vg = {-2.0f,-1.0f,0.0f,1.0f}; + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + check (vec_all_eq (vec_insert (16, va, 5), + ((vector unsigned char) + {0,1,2,3,4,5,6,7,8,9,16,11,12,13,14,15})), + "vec_insert (va LE)"); + check (vec_all_eq (vec_insert (-16, vb, 0), + ((vector signed char) + {-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,-16})), + "vec_insert (vb LE)"); + check (vec_all_eq (vec_insert (16, vc, 7), + ((vector unsigned short){16,1,2,3,4,5,6,7})), + "vec_insert (vc LE)"); + check (vec_all_eq (vec_insert (-16, vd, 3), + ((vector signed short){-4,-3,-2,-1,-16,1,2,3})), + "vec_insert (vd LE)"); + check (vec_all_eq (vec_insert (16, ve, 2), + ((vector unsigned int){0,16,2,3})), + "vec_insert (ve LE)"); + check (vec_all_eq (vec_insert (-16, vf, 1), + ((vector signed int){-2,-1,-16,1})), + "vec_insert (vf LE)"); + check (vec_all_eq (vec_insert (-16.0f, vg, 0), + ((vector float){-2.0f,-1.0f,0.0f,-16.0f})), + "vec_insert (vg LE)"); +#else + check (vec_all_eq (vec_insert (16, va, 5), + ((vector unsigned char) + {0,1,2,3,4,16,6,7,8,9,10,11,12,13,14,15})), + "vec_insert (va BE)"); + check (vec_all_eq (vec_insert (-16, vb, 0), + ((vector signed char) + {-16,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7})), + "vec_insert (vb BE)"); + check (vec_all_eq (vec_insert (16, vc, 7), + ((vector unsigned short){0,1,2,3,4,5,6,16})), + "vec_insert (vc BE)"); + check (vec_all_eq (vec_insert (-16, vd, 3), + ((vector signed short){-4,-3,-2,-16,0,1,2,3})), + "vec_insert (vd BE)"); + check (vec_all_eq (vec_insert (16, ve, 2), + ((vector unsigned int){0,1,16,3})), + "vec_insert (ve BE)"); + check (vec_all_eq (vec_insert (-16, vf, 1), + ((vector signed int){-2,-16,0,1})), + "vec_insert (vf BE)"); + check (vec_all_eq (vec_insert (-16.0f, vg, 0), + ((vector float){-16.0f,-1.0f,0.0f,1.0f})), + "vec_insert (vg BE)"); +#endif +} + diff --git a/gcc/testsuite/gcc.dg/vmx/insert.c b/gcc/testsuite/gcc.dg/vmx/insert.c new file mode 100644 index 0000000..39cd75d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vmx/insert.c @@ -0,0 +1,37 @@ +#include "harness.h" + +static void test() +{ + vector unsigned char va = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + vector signed char vb = {-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7}; + vector unsigned short vc = {0,1,2,3,4,5,6,7}; + vector signed short vd = {-4,-3,-2,-1,0,1,2,3}; + vector unsigned int ve = {0,1,2,3}; + vector signed int vf = {-2,-1,0,1}; + vector float vg = {-2.0f,-1.0f,0.0f,1.0f}; + + check (vec_all_eq (vec_insert (16, va, 5), + ((vector unsigned char) + {0,1,2,3,4,16,6,7,8,9,10,11,12,13,14,15})), + "vec_insert (va)"); + check (vec_all_eq (vec_insert (-16, vb, 0), + ((vector signed char) + {-16,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7})), + "vec_insert (vb)"); + check (vec_all_eq (vec_insert (16, vc, 7), + ((vector unsigned short){0,1,2,3,4,5,6,16})), + "vec_insert (vc)"); + check (vec_all_eq (vec_insert (-16, vd, 3), + ((vector signed short){-4,-3,-2,-16,0,1,2,3})), + "vec_insert (vd)"); + check (vec_all_eq (vec_insert (16, ve, 2), + ((vector unsigned int){0,1,16,3})), + "vec_insert (ve)"); + check (vec_all_eq (vec_insert (-16, vf, 1), + ((vector signed int){-2,-16,0,1})), + "vec_insert (vf)"); + check (vec_all_eq (vec_insert (-16.0f, vg, 0), + ((vector float){-16.0f,-1.0f,0.0f,1.0f})), + "vec_insert (vg)"); +} + -- 2.7.4