d31264fab717b5e0467ea53d97a3220b1f29877b
[calu.git] / 8_benchs / angabe / vm.c
1 /* a ridiculously simplified "virtual machine" */
2
3 #include <stdint.h>
4 #include <stdio.h>
5
6 /* convert four int8_t values into a single int32_t value */
7 static int32_t bytes_to_int(int8_t a, int8_t b, int8_t c, int8_t d) {
8         return
9                   (((int32_t)a & 0xff) << 0)
10                 | (((int32_t)b & 0xff) << 8)
11                 | (((int32_t)c & 0xff) << 16)
12                 | (((int32_t)d & 0xff) << 24);
13 }
14
15 /* the stack of the virtual machine */
16 int32_t stack [256];
17
18 /* the interpreter for the vm */
19 /* FREESTYLE OPTIMIZATIONS */
20 int vm(const char *insns) 
21 {
22         int pc = 0;
23         int sp = 0;
24         
25         while (insns[pc] != '\0')
26                 {
27                         int8_t op = insns[pc];
28                         int32_t t;
29
30                         /* putchar(op); */
31
32                         /* printf(" %d/%d:\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\n", */
33                         /*         pc, sp, */
34                         /*         stack[0], stack[1], stack[2], stack[3], */
35                         /*         stack[4], stack[5], stack[6], stack[7]); */
36
37                         switch (op)
38                                 {
39                                 case '0':
40                                 case '1':
41                                 case '2':
42                                 case '3':
43                                 case '4':
44                                 case '5':
45                                 case '6':
46                                 case '7':
47                                 case '8':
48                                 case '9':
49                                         stack[sp] = op-'0';
50                                         sp++;
51                                         break;
52                                 case 'I': /* immediate */
53                                         stack[sp] = bytes_to_int(insns[pc+1], insns[pc+2], insns[pc+3], insns[pc+4]);
54                                         pc += 4;
55                                         sp++;
56                                         break;
57                                 case 'D': /* dup */
58                                         stack[sp] = stack[sp-1];
59                                         sp++;
60                                         break;
61                                 case 'X': /* exchange */
62                                         t = stack[sp-1];
63                                         stack[sp-1] = stack[sp-2];
64                                         stack[sp-2] = t;
65                                         break;
66                                 case 'P': /* pop */
67                                         sp--;
68                                         break;
69                                 case '+': /* add */
70                                         sp--;
71                                         stack[sp-1] = stack[sp-1] + stack[sp];
72                                         break;
73                                 case '-': /* subtract */
74                                         sp--;
75                                         stack[sp-1] = stack[sp-1] - stack[sp];
76                                         break;
77                                 case '*': /* multiply */
78                                         sp--;
79                                         stack[sp-1] = stack[sp-1] * stack[sp];
80                                         break;
81                                 case '~': /* not */
82                                         stack[sp-1] = ~stack[sp-1];
83                                         break;
84                                 case '<': /* less than */
85                                         sp--;
86                                         stack[sp-1] = stack[sp-1] < stack[sp] ? -1 : 0;
87                                         break;
88                                 case 'J': /* jump if true */
89                                         sp--;
90                                         if (stack[sp] != 0) {
91                                                 pc += (int8_t)insns[pc+1];
92                                         } else {
93                                                 pc++;
94                                         }
95                                         break;
96                                 default:
97                                         /* ignore everything else */
98                                         break;
99                                 }
100                         pc++;
101                 }
102
103         /* printf("  %d/%d:\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\n", */
104         /*         pc, sp, */
105         /*         stack[0], stack[1], stack[2], stack[3], */
106         /*         stack[4], stack[5], stack[6], stack[7]); */
107
108         return stack[sp-1];
109 }
110
111 int main() {
112
113         /* BENCHMARK START */
114         /* you don't need to understand that code, the answer is '6' */
115         int retval = vm(
116 "48*88*\
117 X1-X\
118 D+\
119 DJ\xf8\
120 P68*+\
121 DI\040\0\0\0\
122 <~J\005\
123 P88*"); 
124         /* BENCHMARK END */
125
126         putchar(retval);
127         
128         return retval;
129 }