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 
f(pc)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 }
135