OSDN Git Service

2012-01-30 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / c-c++-common / int128-2.c
1 /* { dg-do run { target int128 } } */
2 /* { dg-options "-std=gnu99" { target c } } */
3 /* { dg-options "" { target c++ } } */
4
5 #ifndef __cplusplus
6 extern void abort (void);
7 #else
8 extern "C" void abort (void);
9 #endif
10
11 #define MK_CONST128(A,B,C,D) \
12         ( (((unsigned __int128) (unsigned int) A) << 96) \
13          | (((unsigned __int128) (unsigned int) B) << 64) \
14          | (((unsigned __int128) (unsigned int) C) << 32) \
15          | ((unsigned __int128) (unsigned int) D) )
16
17 #define MK_CONST128_SIGNED(A,B,C,D) \
18         ((__int128) MK_CONST128(A, B, C, D))
19
20 #define MINUS_2 MK_CONST128_SIGNED (0xffffffffu, 0xffffffffu, 0xffffffffu, \
21                 0xfffffffeu)
22 #define MINUS_3 MK_CONST128_SIGNED (0xffffffffu, 0xffffffffu, 0xffffffffu, \
23                 0xfffffffdu)
24 #define MINUS_6 MK_CONST128_SIGNED (0xffffffffu, 0xffffffffu, 0xffffffffu, \
25                 0xfffffffau)
26 #define PLUS_1  MK_CONST128_SIGNED (0, 0, 0, 1)
27 #define PLUS_2  MK_CONST128_SIGNED (0, 0, 0, 2)
28 #define PLUS_3  MK_CONST128_SIGNED (0, 0, 0, 3)
29 #define PLUS_6  MK_CONST128_SIGNED (0, 0, 0, 6)
30 #define PLUS_10 MK_CONST128_SIGNED (0, 0, 0, 10)
31
32 #define U_8     MK_CONST128 (0, 0, 0, 8)
33 #define U_MAX   MK_CONST128 (0xffffffff,0xffffffff,0xffffffff,0xffffffff)
34 #define U_CST1  MK_CONST128 (0xbeeffeed, 0xdeafcafe, 0xaffefade, 0x12345678)
35 #define U_CST2  MK_CONST128 (0x41100112, 0x21503501, 0x50010521, 0xedcba987)
36
37 signed __int128 foo_neg (signed __int128 v)
38 {
39   return -v;
40 }
41
42 unsigned __int128 foo_xor (unsigned __int128 x, unsigned __int128 y)
43 {
44   return x ^ y;
45 }
46
47 unsigned __int128 foo_inv (unsigned __int128 v)
48 {
49   return ~v;
50 }
51
52 unsigned __int128 foo_rotate_left (unsigned __int128 v)
53 {
54   unsigned __int128 c;
55   int i;
56   for (i = 0; i < 128; i++)
57     {
58       c = v >> 127;
59       v <<= 1;
60       v |= c;
61     }
62   return v;
63 }
64
65 unsigned __int128 foo_rotate_right (unsigned __int128 v)
66 {
67   unsigned __int128 c;
68   int i;
69   for (i = 0; i < 128; i++)
70     {
71       c = (v & ((unsigned __int128) 1)) << 127;
72       v >>= 1;
73       v |= c;
74     }
75   return v;
76 }
77
78 void foo_swap (unsigned __int128 *x, unsigned __int128 *y)
79 {
80   unsigned __int128 x1 = x[0];
81   unsigned __int128 y1 = y[0];
82   x1 ^= y1 ^= x1 ^= y1;
83   x[0] = x1;
84   y[0] = y1;
85 }
86
87 __int128 foo_add (signed __int128 a, unsigned __int128 b)
88 {
89   return (__int128) (a + (__int128) b);
90 }
91
92 __int128 foo_sub (unsigned __int128 a, signed __int128 b)
93 {
94   return (__int128) ((__int128) a - b);
95 }
96
97 __int128 foo_mul (signed __int128 a, signed __int128 b)
98 {
99   return a * b;
100 }
101
102 __int128 foo_div (signed __int128 a, signed __int128 b)
103 {
104   return a / b;
105 }
106
107 __int128 foo_shl (signed __int128 a, int shift)
108 {
109   return a << (shift & 127);
110 }
111
112 __int128 foo_shr (signed __int128 a, int shift)
113 {
114   return a >> (shift & 127);
115 }
116
117 int main(void)
118 {
119   __int128 rslt;
120   unsigned __int128 u1, u2;
121
122   rslt = foo_add (MINUS_2, U_8);
123   if (rslt != PLUS_6)
124     abort ();
125   rslt = foo_sub (U_8, MINUS_2);
126   if (rslt != PLUS_10)
127      abort ();
128   rslt = foo_sub ((unsigned __int128) foo_mul (MINUS_2, MINUS_2), MINUS_2);
129   if (rslt != PLUS_6)
130     abort ();
131   if (rslt != foo_shl (PLUS_3, 1))
132     abort ();
133   rslt = foo_shl (MINUS_3, 1);
134   if (rslt != MINUS_6)
135     abort ();
136   if (foo_shr (MINUS_6, 1) != MINUS_3)
137     abort ();
138   if (foo_div (MINUS_6, MINUS_3) != PLUS_2)
139     abort ();
140   if (foo_rotate_left (U_CST1) != U_CST1)
141     abort ();
142   if (foo_rotate_right (U_CST1) != U_CST1)
143     abort ();
144   u1 = U_CST1;
145   u2 = U_8;
146   foo_swap (&u1, &u2);
147   if (u1 != U_8 || u2 != U_CST1)
148     abort ();
149
150   if (foo_inv (U_CST2) != U_CST1)
151     abort ();
152   if (foo_neg (PLUS_2) != MINUS_2)
153     abort ();
154   if (foo_neg ((signed __int128) U_CST1) != foo_add (PLUS_1, foo_xor (U_CST1, U_MAX)))
155     abort ();
156   return 0;
157 }