OSDN Git Service

PR middle-end/34688
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.c-torture / compile / 950612-1.c
1 typedef enum
2 {
3   LODI,
4   STO,
5   ADDI,
6   ADD,
7   SUBI,
8   SUB,
9   MULI,
10   MUL,
11   DIVI,
12   DIV,
13   INC,
14   DEC
15 } INSN;
16
17 f (pc)
18      short *pc;
19 {
20   long long stack[16], *sp = &stack[16], acc = 0;
21
22   for (;;)
23     {
24       switch ((INSN)*pc++)
25         {
26         case LODI:
27           *--sp = acc;
28           acc = ((long long)*pc++) << 32;
29           break;
30         case STO:
31           return (acc >> 32) + (((((unsigned long long) acc) & 0xffffffff)  & (1 << 31)) != 0);
32           break;
33         case ADDI:
34           acc += ((long long)*pc++) << 32;
35           break;
36         case ADD:
37           acc = *sp++ + acc;
38           break;
39         case SUBI:
40           acc -= ((long long)*pc++) << 32;
41           break;
42         case SUB:
43           acc = *sp++ - acc;
44           break;
45         case MULI:
46           acc *= *pc++;
47           break;
48         case MUL:
49           {
50             long long aux;
51             unsigned char minus;
52
53             minus = 0;
54             aux = *sp++;
55             if (aux < 0)
56               {
57                 minus = ~minus;
58                 aux = -aux;
59               }
60             if (acc < 0)
61               {
62                 minus = ~minus;
63                 acc = -acc;
64               }
65             acc = ((((((unsigned long long) acc) & 0xffffffff)  * (((unsigned long long) aux) & 0xffffffff)) >> 32)
66                    + ((((unsigned long long) acc) >> 32)  * (((unsigned long long) aux) & 0xffffffff)  + (((unsigned long long) acc) & 0xffffffff)  + (((unsigned long long) aux) >> 32))
67                    + (((((unsigned long long) acc) >> 32)  * (((unsigned long long) aux) >> 32)) << 32));
68             if (minus)
69               acc = -acc;
70           }
71           break;
72         case DIVI:
73           {
74             short aux;
75
76             aux = *pc++;
77             acc = (acc + aux / 2) / aux;
78           }
79           break;
80         case DIV:
81           {
82             long long aux;
83             unsigned char minus;
84
85             minus = 0;
86             aux = *sp++;
87             if (aux < 0)
88               {
89                 minus = ~minus;
90                 aux = -aux;
91               }
92             if (acc < 0)
93               {
94                 minus = ~minus;
95                 acc = -acc;
96               }
97
98             if (((unsigned long long)acc)  == 0)
99               acc = (unsigned long long)-1 / 2;
100             else if ((((unsigned long long) ((unsigned long long)acc)) & 0xffffffff)  == 0)
101               acc = ((unsigned long long)aux)  / (((unsigned long long) ((unsigned long long)acc)) >> 32);
102             else if ((((unsigned long long) ((unsigned long long)acc)) >> 32)  == 0)
103               acc = ((((unsigned long long)aux)  / ((unsigned long long)acc)) << 32)
104                 + ((((unsigned long long)aux)  % ((unsigned long long)acc)) << 32) / ((unsigned long long)acc);
105             else
106               {
107                 unsigned char shift;
108                 unsigned long hi;
109
110                 shift = 32;
111                 hi = (((unsigned long long) ((unsigned long long)acc)) >> 32);
112                 do {
113                   if (hi & ((unsigned long)1 << (shift - 1)))
114                     break;
115                 } while (--shift != 0);
116                 printf("shift = %d\n", shift);
117                 acc = ((((unsigned long long)aux)  / ((unsigned long long)acc)) << 32)
118                   + (((((unsigned long long)aux)  % ((unsigned long long)acc)) << (32 - shift)) + ((((unsigned long long)acc)  >> shift) / 2)) / (((unsigned long long)acc)  >> shift);
119               }
120
121             if (minus)
122               acc = -acc;
123           }
124           break;
125         case INC:
126           acc += 1;
127           break;
128         case DEC:
129           acc -= 1;
130           break;
131         }
132       printf("%08lx.%08lx\n", (long)(((unsigned long long) acc) >> 32) , (long)(((unsigned long long) acc) & 0xffffffff));
133     }
134 }