1/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
2/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
3/* { dg-require-effective-target powerpc_altivec_ok } */
4/* { dg-options "-maltivec" } */
5
6/* Test for correct handling of AltiVec constants passed
7   through '...' (va_arg).  */
8
9#include <stdarg.h>
10#include <stdio.h>
11#include <stdlib.h>
12
13#include <altivec.h>
14
15#define CHECK_INVARIANT(expr) \
16  if (!(expr)) { \
17    printf ("ASSERT FAILED: %d: %s\n", __LINE__, #expr); \
18    abort (); \
19  }
20
21struct foo { int x; int y; };
22struct vfoo { int x; __vector signed int v; int y; };
23union u { __vector signed int v; signed int i[4]; };
24
25struct foo x_g = { 3, 4};
26struct vfoo vx_g = { 10, {11, 12, 13, 14}, 15 };
27__vector signed int v_g = {22, 23, 24, 25};
28struct vfoo vx2_g = { 30, {31, 32, 33, 34}, 35 };
29__vector signed int v2_g = {40, 41, 42, 43};
30int i_1 = 99, i_2 = 33;
31double d_2 = 1.5, d_3 = 1.75;
32double ld_1 = 1.25;
33
34void bar (int i, ... )
35{
36    struct foo xi;
37    double d;
38    double ld;
39    float f;
40    char c;
41    short s;
42    va_list ap;
43    va_start(ap, i);
44    xi = va_arg(ap, struct foo);
45    s = (short)va_arg(ap, int);
46    f = (float)va_arg(ap, double);
47    ld = va_arg(ap, double);
48    c = (char)va_arg(ap, int);
49    d = va_arg(ap, double);
50    va_end(ap);
51
52    CHECK_INVARIANT (xi.x == x_g.x && xi.y == x_g.y);
53    CHECK_INVARIANT (s == (short)i_2);
54    CHECK_INVARIANT (f == (float)d_2);
55    CHECK_INVARIANT (ld == ld_1);
56    CHECK_INVARIANT (c == (char)i_1);
57    CHECK_INVARIANT (d == d_3);
58}
59
60void baz (int i, ... )
61{
62    struct vfoo vx, vx2;
63    __vector signed int v_i, v2_i;
64    int j, k, l;
65    va_list ap;
66    va_start(ap, i);
67    v_i = va_arg(ap, __vector signed int);
68    j = va_arg(ap, int);
69    vx = va_arg(ap, struct vfoo);
70    k = va_arg(ap, int);
71    v2_i = va_arg(ap, __vector signed int);
72    l = va_arg(ap, int);
73    vx2 = va_arg(ap, struct vfoo);
74    va_end(ap);
75
76    CHECK_INVARIANT (vec_all_eq (v_i, v_g));
77    CHECK_INVARIANT (j == i_1);
78    CHECK_INVARIANT (vx.x == vx_g.x);
79    CHECK_INVARIANT (vec_all_eq (vx.v, vx_g.v));
80    CHECK_INVARIANT (vx.y == vx_g.y);
81    CHECK_INVARIANT (k == i_1);
82    CHECK_INVARIANT (vec_all_eq (v2_i, v2_g));
83    CHECK_INVARIANT (l == i_1);
84    CHECK_INVARIANT (vx2.x == vx2_g.x);
85    CHECK_INVARIANT (vec_all_eq (vx2.v, vx2_g.v));
86    CHECK_INVARIANT (vx2.y == vx2_g.y);
87}
88
89void quux (int i, ... )
90{
91    __vector signed int v_i, v2_i;
92    union u vi, v2i;
93    va_list ap;
94    va_start(ap, i);
95    v_i = va_arg(ap, __vector signed int);
96    v2_i = va_arg(ap, __vector signed int);
97    va_end(ap);
98    vi.v = v_i;
99    v2i.v = v2_i;
100
101    CHECK_INVARIANT (vec_all_eq (v_i, v_g));
102    CHECK_INVARIANT (vec_all_eq (v2_i, v_g));
103    CHECK_INVARIANT (vec_all_eq (vi.v, v_g));
104    CHECK_INVARIANT (vec_all_eq (v2i.v, v_g));
105}
106
107void baz2 (int i, ... )
108{
109    struct vfoo vx;
110    union u vxi;
111    va_list ap;
112    va_start(ap, i);
113    vx = va_arg(ap, struct vfoo);
114    va_end(ap);
115    vxi.v = vx.v;
116
117    CHECK_INVARIANT (vx.x == vx_g.x);
118    CHECK_INVARIANT (vec_all_eq (vx.v, vx_g.v));
119    CHECK_INVARIANT (vx.y == vx_g.y);
120    CHECK_INVARIANT (vec_all_eq (vxi.v, vx_g.v));
121}
122
123void main1(void)
124{
125    CHECK_INVARIANT (sizeof(struct foo) == 8 && sizeof(struct vfoo) == 48);
126
127    bar(i_1, x_g, (short)i_2, (float)d_2, ld_1, (char)i_1, d_3);
128    baz(i_1, v_g, i_1, vx_g, i_1, v2_g, i_1, vx2_g);
129    quux(i_1, v_g, v_g);
130    baz2(i_1, vx_g);
131}
132
133int main(void)
134{
135    main1();
136    return 0;
137}
138