1typedef 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
17f (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