#include #include #include #include #define NOOP 0 #define LOAD 1 #define STORE 2 #define PUSH 3 #define ADD 4 #define INC 5 #define LT 6 #define J 7 #define JT 8 #define IMM 9 #define END 10 int program[] = { IMM, 0, STORE, 0, STORE, 1,/*L:*/ LOAD, 1, PUSH, LOAD, 0, ADD, STORE, 1, LOAD, 0, INC, STORE, 0, PUSH, IMM, 0x989680, LT, JT, -18, END }; typedef struct thread { int *ss, *bp, *sp; } thread_t; typedef int (*pift_t)(thread_t *); pift_t compile(int *program, int length) { int *base; jit_insn *code; jit_insn **labels; int thread; /* random guess about size */ code = malloc(length * 32 * sizeof(int)); /* XXX no label information here... */ labels = malloc(length * sizeof(jit_insn*)); jit_set_ip(code); jit_prolog(1); thread = jit_arg_i(); jit_getarg_i(JIT_V1, thread); /* v1 = thread */ for (base = program; length > 0; --length, ++program) { labels[program - base] = jit_get_label(); switch (*program) { case NOOP: break; case LOAD: ++program; /* r1 = thread->ss */ jit_ldxi_i(JIT_R1, JIT_V1, offsetof(thread_t, bp)); /* r0 = r1[*program] */ jit_ldxi_i(JIT_R0, JIT_R1, *program * sizeof(int)); break; case STORE: ++program; /* r1 = thread->ss */ jit_ldxi_i(JIT_R1, JIT_V1, offsetof(thread_t, bp)); /* r1[*program] = r0 */ jit_stxi_i(*program * sizeof(int), JIT_R1, JIT_R0); break; case PUSH: /* r1 = thread->sp */ jit_ldxi_i(JIT_R1, JIT_V1, offsetof(thread_t, sp)); /* r2 = r1 + sizeof(int) */ jit_addi_i(JIT_R2, JIT_R1, sizeof(int)); /* thread->sp = r2 */ jit_stxi_i(offsetof(thread_t, sp), JIT_V1, JIT_R2); /* *r1 = r0 */ jit_stxi_i(0, JIT_R1, JIT_R0); break; case ADD: /* r1 = thread->sp */ jit_ldxi_i(JIT_R1, JIT_V1, offsetof(thread_t, sp)); /* r2 = r1 - sizeof(int) */ jit_subi_i(JIT_R2, JIT_R1, sizeof(int)); /* r1 = *r1 */ jit_ldr_i(JIT_R1, JIT_R1); /* r0 = r1 + r0 */ jit_addr_i(JIT_R0, JIT_R1, JIT_R0); /* thread->sp = r2 */ jit_stxi_i(offsetof(thread_t, sp), JIT_V1, JIT_R2); break; case INC: /* r0 = r0 + 1 */ jit_addi_i(JIT_R0, JIT_R0, 1); break; case LT: /* r1 = thread->sp */ jit_ldxi_i(JIT_R1, JIT_V1, offsetof(thread_t, sp)); /* r2 = r1 - sizeof(int) */ jit_subi_i(JIT_R2, JIT_R1, sizeof(int)); /* r1 = *r1 */ jit_ldr_i(JIT_R1, JIT_R1); /* r0 = r1 < r0 */ jit_ltr_i(JIT_R0, JIT_R1, JIT_R0); /* thread->sp = r2 */ jit_stxi_i(offsetof(thread_t, sp), JIT_V1, JIT_R2); break; case J: /* XXX no forward jumps in sample test */ ++program; jit_jmpi(labels[program - base + *program]); break; case JT: /* XXX no forward jumps in sample test */ ++program; jit_bnei_ui(labels[program - base + *program], JIT_R0, 0); break; case IMM: /* r0 = immediate */ ++program; jit_movi_i(JIT_R0, *program); break; case END: jit_retval(JIT_R0); jit_ret(); jit_flush_code(code, jit_get_ip().ptr); return (pift_t)(jit_get_ip().iptr); } } abort(); } void vm(void) { pift_t jit; thread_t thread; thread.ss = malloc(16 * sizeof(int)); thread.bp = thread.sp = thread.ss; jit = compile(program, sizeof(program) / sizeof(int)); printf("%d\n", (*jit)(&thread)); } int main(int argc, char *argv[]) { vm(); return 0; }