[AArch64] Merge stores of D-register values with different modes
[official-gcc.git] / gcc / testsuite / gcc.c-torture / compile / 950612-1.c
blobcb3cb0a59d69dc72ffeff4f5e2c0d3c629409349
1 typedef enum
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;
17 f (pc)
18 short *pc;
20 long long stack[16], *sp = &stack[16], acc = 0;
22 for (;;)
24 switch ((INSN)*pc++)
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:
50 long long aux;
51 unsigned char minus;
53 minus = 0;
54 aux = *sp++;
55 if (aux < 0)
57 minus = ~minus;
58 aux = -aux;
60 if (acc < 0)
62 minus = ~minus;
63 acc = -acc;
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;
71 break;
72 case DIVI:
74 short aux;
76 aux = *pc++;
77 acc = (acc + aux / 2) / aux;
79 break;
80 case DIV:
82 long long aux;
83 unsigned char minus;
85 minus = 0;
86 aux = *sp++;
87 if (aux < 0)
89 minus = ~minus;
90 aux = -aux;
92 if (acc < 0)
94 minus = ~minus;
95 acc = -acc;
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
107 unsigned char shift;
108 unsigned long hi;
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);
121 if (minus)
122 acc = -acc;
124 break;
125 case INC:
126 acc += 1;
127 break;
128 case DEC:
129 acc -= 1;
130 break;
132 printf("%08lx.%08lx\n", (long)(((unsigned long long) acc) >> 32) , (long)(((unsigned long long) acc) & 0xffffffff));