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 } 135