deepjit: 1642
[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                         printf("pc: %d op: %c\n", pc, op);
31                         /* putchar(op); */
32
33                         /* printf(" %d/%d:\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\n", */
34                         /*         pc, sp, */
35                         /*         stack[0], stack[1], stack[2], stack[3], */
36                         /*         stack[4], stack[5], stack[6], stack[7]); */
37
38                         switch (op)
39                                 {
40                                 case '0':
41                                 case '1':
42                                 case '2':
43                                 case '3':
44                                 case '4':
45                                 case '5':
46                                 case '6':
47                                 case '7':
48                                 case '8':
49                                 case '9':
50                                         stack[sp] = op-'0';
51                                         sp++;
52                                         break;
53                                 case 'I': /* immediate */
54                                         stack[sp] = bytes_to_int(insns[pc+1], insns[pc+2], insns[pc+3], insns[pc+4]);
55                                         pc += 4;
56                                         sp++;
57                                         break;
58                                 case 'D': /* dup */
59                                         stack[sp] = stack[sp-1];
60                                         sp++;
61                                         break;
62                                 case 'X': /* exchange */
63                                         t = stack[sp-1];
64                                         stack[sp-1] = stack[sp-2];
65                                         stack[sp-2] = t;
66                                         break;
67                                 case 'P': /* pop */
68                                         sp--;
69                                         break;
70                                 case '+': /* add */
71                                         sp--;
72                                         stack[sp-1] = stack[sp-1] + stack[sp];
73                                         break;
74                                 case '-': /* subtract */
75                                         sp--;
76                                         stack[sp-1] = stack[sp-1] - stack[sp];
77                                         break;
78                                 case '*': /* multiply */
79                                         sp--;
80                                         stack[sp-1] = stack[sp-1] * stack[sp];
81                                         break;
82                                 case '~': /* not */
83                                         stack[sp-1] = ~stack[sp-1];
84                                         break;
85                                 case '<': /* less than */
86                                         sp--;
87                                         stack[sp-1] = stack[sp-1] < stack[sp] ? -1 : 0;
88                                         break;
89                                 case 'J': /* jump if true */
90                                         sp--;
91                                         if (stack[sp] != 0) {
92                                                 pc += (int8_t)insns[pc+1];
93                                         } else {
94                                                 pc++;
95                                         }
96                                         break;
97                                 default:
98                                         /* ignore everything else */
99                                         break;
100                                 }
101                         pc++;
102                 }
103
104         /* printf("  %d/%d:\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\n", */
105         /*         pc, sp, */
106         /*         stack[0], stack[1], stack[2], stack[3], */
107         /*         stack[4], stack[5], stack[6], stack[7]); */
108
109         return stack[sp-1];
110 }
111
112 int main() {
113
114         /* BENCHMARK START */
115         /* you don't need to understand that code, the answer is '6' */
116         int retval = vm(
117 "48*88*\
118 X1-X\
119 D+\
120 DJ\xf8\
121 P68*+\
122 DI\040\0\0\0\
123 <~J\005\
124 P88*"); 
125         /* BENCHMARK END */
126
127         putchar(retval);
128         
129         return retval;
130 }