OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [gcc.c-torture/] [execute/] [20040703-1.c] - Blame information for rev 801

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 688 jeremybenn
/* PR 16341 */
2
 
3
#define PART_PRECISION (sizeof (cpp_num_part) * 8)
4
 
5
typedef unsigned int cpp_num_part;
6
typedef struct cpp_num cpp_num;
7
struct cpp_num
8
{
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.  */
13
};
14
 
15
static  int
16
num_positive (cpp_num num, unsigned int precision)
17
{
18
   if (precision > PART_PRECISION)
19
     {
20
       precision -= PART_PRECISION;
21
       return (num.high & (cpp_num_part) 1 << (precision - 1)) == 0;
22
     }
23
 
24
   return (num.low & (cpp_num_part) 1 << (precision - 1)) == 0;
25
}
26
 
27
static cpp_num
28
num_trim (cpp_num num, unsigned int precision)
29
{
30
   if (precision > PART_PRECISION)
31
     {
32
       precision -= PART_PRECISION;
33
       if (precision < PART_PRECISION)
34
         num.high &= ((cpp_num_part) 1 << precision) - 1;
35
     }
36
   else
37
     {
38
       if (precision < PART_PRECISION)
39
         num.low &= ((cpp_num_part) 1 << precision) - 1;
40
       num.high = 0;
41
     }
42
 
43
   return num;
44
}
45
 
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)
49
{
50
   cpp_num_part sign_mask;
51
   int x = num_positive (num, precision);
52
 
53
   if (num.unsignedp || x)
54
     sign_mask = 0;
55
   else
56
     sign_mask = ~(cpp_num_part) 0;
57
 
58
   if (n >= precision)
59
     num.high = num.low = sign_mask;
60
   else
61
     {
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);
67
 
68
       if (n >= PART_PRECISION)
69
         {
70
           n -= PART_PRECISION;
71
           num.low = num.high;
72
           num.high = sign_mask;
73
         }
74
 
75
       if (n)
76
         {
77
           num.low = (num.low >> n) | (num.high << (PART_PRECISION - n));
78
           num.high = (num.high >> n) | (sign_mask << (PART_PRECISION - n));
79
         }
80
     }
81
 
82
   num = num_trim (num, precision);
83
   num.overflow = 0;
84
   return num;
85
}
86
                              #define num_zerop(num) ((num.low | num.high) == 0)
87
#define num_eq(num1, num2) (num1.low == num2.low && num1.high == num2.high)
88
 
89
cpp_num
90
num_lshift (cpp_num num, unsigned int precision, unsigned int n)
91
{
92
   if (n >= precision)
93
     {
94
       num.overflow = !num.unsignedp && !num_zerop (num);
95
       num.high = num.low = 0;
96
     }
97
   else
98
     {
99
       cpp_num orig;
100
       unsigned int m = n;
101
 
102
       orig = num;
103
       if (m >= PART_PRECISION)
104
         {
105
           m -= PART_PRECISION;
106
           num.high = num.low;
107
           num.low = 0;
108
         }
109
       if (m)
110
         {
111
           num.high = (num.high << m) | (num.low >> (PART_PRECISION - m));
112
           num.low <<= m;
113
         }
114
       num = num_trim (num, precision);
115
 
116
       if (num.unsignedp)
117
         num.overflow = 0;
118
       else
119
         {
120
           cpp_num maybe_orig = num_rshift (num, precision, n);
121
           num.overflow = !num_eq (orig, maybe_orig);
122
         }
123
     }
124
 
125
   return num;
126
}
127
 
128
unsigned int precision = 64;
129
unsigned int n = 16;
130
 
131
cpp_num num = { 0, 3, 0, 0 };
132
 
133
int main()
134
{
135
   cpp_num res = num_lshift (num, 64, n);
136
 
137
   if (res.low != 0x30000)
138
     abort ();
139
 
140
   if (res.high != 0)
141
     abort ();
142
 
143
   if (res.overflow != 0)
144
     abort ();
145
 
146
   exit (0);
147
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.