/* { dg-do run { target powerpc*-*-* } { xfail powerpc-ibm-aix* } } */ /* { dg-options "-maltivec" } */ /* Test for correct handling of AltiVec constants passed through '...' (va_arg). */ #include #include #include #include #include "altivec_check.h" #define CHECK_INVARIANT(expr) \ if (!(expr)) { \ printf ("ASSERT FAILED: %d: %s\n", __LINE__, #expr); \ abort (); \ } struct foo { int x; int y; }; struct vfoo { int x; __vector signed int v; int y; }; union u { __vector signed int v; signed int i[4]; }; struct foo x_g = { 3, 4}; struct vfoo vx_g = { 10, (vector signed int) {11, 12, 13, 14}, 15 }; __vector signed int v_g = (vector signed int) {22, 23, 24, 25}; struct vfoo vx2_g = { 30, (vector signed int) {31, 32, 33, 34}, 35 }; __vector signed int v2_g = (vector signed int) {40, 41, 42, 43}; int i_1 = 99, i_2 = 33; double d_2 = 1.5, d_3 = 1.75; double ld_1 = 1.25; void bar (int i, ... ) { struct foo xi; double d; double ld; float f; char c; short s; va_list ap; va_start(ap, i); xi = va_arg(ap, struct foo); s = (short)va_arg(ap, int); f = (float)va_arg(ap, double); ld = va_arg(ap, double); c = (char)va_arg(ap, int); d = va_arg(ap, double); va_end(ap); CHECK_INVARIANT (xi.x == x_g.x && xi.y == x_g.y); CHECK_INVARIANT (s == (short)i_2); CHECK_INVARIANT (f == (float)d_2); CHECK_INVARIANT (ld == ld_1); CHECK_INVARIANT (c == (char)i_1); CHECK_INVARIANT (d == d_3); } void baz (int i, ... ) { struct vfoo vx, vx2; __vector signed int v_i, v2_i; int j, k, l; va_list ap; va_start(ap, i); v_i = va_arg(ap, __vector signed int); j = va_arg(ap, int); vx = va_arg(ap, struct vfoo); k = va_arg(ap, int); v2_i = va_arg(ap, __vector signed int); l = va_arg(ap, int); vx2 = va_arg(ap, struct vfoo); va_end(ap); CHECK_INVARIANT (vec_all_eq (v_i, v_g)); CHECK_INVARIANT (j == i_1); CHECK_INVARIANT (vx.x == vx_g.x && vec_all_eq(vx.v, vx_g.v) && vx.y == vx_g.y); CHECK_INVARIANT (k == i_1); CHECK_INVARIANT (vec_all_eq (v2_i, v2_g)); CHECK_INVARIANT (l == i_1); CHECK_INVARIANT (vx2.x == vx2_g.x && vec_all_eq(vx2.v, vx2_g.v) && vx2.y == vx2_g.y); } void quux (int i, ... ) { __vector signed int v_i, v2_i; union u vi, v2i; va_list ap; va_start(ap, i); v_i = va_arg(ap, __vector signed int); v2_i = va_arg(ap, __vector signed int); va_end(ap); vi.v = v_i; v2i.v = v2_i; CHECK_INVARIANT (vec_all_eq (v_i, v_g)); CHECK_INVARIANT (vec_all_eq (v2_i, v_g)); CHECK_INVARIANT (vec_all_eq (vi.v, v_g)); CHECK_INVARIANT (vec_all_eq (v2i.v, v_g)); } void baz2 (int i, ... ) { struct vfoo vx; union u vxi; va_list ap; va_start(ap, i); vx = va_arg(ap, struct vfoo); va_end(ap); vxi.v = vx.v; CHECK_INVARIANT (vx.x == vx_g.x && vec_all_eq(vx.v, vx_g.v) && vx.y == vx_g.y); CHECK_INVARIANT (vec_all_eq (vxi.v, vx_g.v)); } int main(void) { CHECK_INVARIANT (sizeof(struct foo) == 8 && sizeof(struct vfoo) == 48); altivec_check(); bar(i_1, x_g, (short)i_2, (float)d_2, ld_1, (char)i_1, d_3); baz(i_1, v_g, i_1, vx_g, i_1, v2_g, i_1, vx2_g); quux(i_1, v_g, v_g); baz2(i_1, vx_g); return 0; }