Dead
[official-gcc.git] / gomp-20050608-branch / gcc / testsuite / gcc.c-torture / execute / 20040703-1.c
blobeba358d35ae31d7489e7fbf749b9690c050491b0
1 /* PR 16341 */
3 #define PART_PRECISION (sizeof (cpp_num_part) * 8)
5 typedef unsigned int cpp_num_part;
6 typedef struct cpp_num cpp_num;
7 struct cpp_num
9 cpp_num_part high;
10 cpp_num_part low;
11 int unsignedp; /* True if value should be treated as unsigned. */
12 int overflow; /* True if the most recent calculation overflowed. */
15 static int
16 num_positive (cpp_num num, unsigned int precision)
18 if (precision > PART_PRECISION)
20 precision -= PART_PRECISION;
21 return (num.high & (cpp_num_part) 1 << (precision - 1)) == 0;
24 return (num.low & (cpp_num_part) 1 << (precision - 1)) == 0;
27 static cpp_num
28 num_trim (cpp_num num, unsigned int precision)
30 if (precision > PART_PRECISION)
32 precision -= PART_PRECISION;
33 if (precision < PART_PRECISION)
34 num.high &= ((cpp_num_part) 1 << precision) - 1;
36 else
38 if (precision < PART_PRECISION)
39 num.low &= ((cpp_num_part) 1 << precision) - 1;
40 num.high = 0;
43 return num;
46 /* Shift NUM, of width PRECISION, right by N bits. */
47 static cpp_num
48 num_rshift (cpp_num num, unsigned int precision, unsigned int n)
50 cpp_num_part sign_mask;
51 int x = num_positive (num, precision);
53 if (num.unsignedp || x)
54 sign_mask = 0;
55 else
56 sign_mask = ~(cpp_num_part) 0;
58 if (n >= precision)
59 num.high = num.low = sign_mask;
60 else
62 /* Sign-extend. */
63 if (precision < PART_PRECISION)
64 num.high = sign_mask, num.low |= sign_mask << precision;
65 else if (precision < 2 * PART_PRECISION)
66 num.high |= sign_mask << (precision - PART_PRECISION);
68 if (n >= PART_PRECISION)
70 n -= PART_PRECISION;
71 num.low = num.high;
72 num.high = sign_mask;
75 if (n)
77 num.low = (num.low >> n) | (num.high << (PART_PRECISION - n));
78 num.high = (num.high >> n) | (sign_mask << (PART_PRECISION - n));
82 num = num_trim (num, precision);
83 num.overflow = 0;
84 return num;
86 #define num_zerop(num) ((num.low | num.high) == 0)
87 #define num_eq(num1, num2) (num1.low == num2.low && num1.high == num2.high)
89 cpp_num
90 num_lshift (cpp_num num, unsigned int precision, unsigned int n)
92 if (n >= precision)
94 num.overflow = !num.unsignedp && !num_zerop (num);
95 num.high = num.low = 0;
97 else
99 cpp_num orig;
100 unsigned int m = n;
102 orig = num;
103 if (m >= PART_PRECISION)
105 m -= PART_PRECISION;
106 num.high = num.low;
107 num.low = 0;
109 if (m)
111 num.high = (num.high << m) | (num.low >> (PART_PRECISION - m));
112 num.low <<= m;
114 num = num_trim (num, precision);
116 if (num.unsignedp)
117 num.overflow = 0;
118 else
120 cpp_num maybe_orig = num_rshift (num, precision, n);
121 num.overflow = !num_eq (orig, maybe_orig);
125 return num;
128 unsigned int precision = 64;
129 unsigned int n = 16;
131 cpp_num num = { 0, 3, 0, 0 };
133 int main()
135 cpp_num res = num_lshift (num, 64, n);
137 if (res.low != 0x30000)
138 abort ();
140 if (res.high != 0)
141 abort ();
143 if (res.overflow != 0)
144 abort ();
146 exit (0);