#include enum jit_reg { R0 = 0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, // SP Stack Pointer R14, // LR Link Register R15 // PC Program Counter }; enum arg_reg { ARGR0 = 0, ARGR1, ARGR2 }; #define RSP R13 static uint32_t* code; static uint32_t code_idx; static uint32_t cpool_idx; // constant pool #define JIT_MAX_LABELS 32 static int label_idx = 0; static Label jit_labels[JIT_MAX_LABELS]; static Label jit_labels_unres[JIT_MAX_LABELS]; // unresolved (forward) labels static int unres_labels = 0; /* 31-28 cond 27: 0 26: 1 25: 0 24: P (1 = offset addressing) 23: U (1 = +, 0 = -) 22: 0 (1 = byte access) 21: W (0 = offset addressing) 20: L (0 = store 1 = load) */ void jit_init(int gap) { // cleans up jit state label_idx = 0; unres_labels = 0; code_idx = 0; cpool_idx = gap; for (int i=0; iidx - code_idx) - 2; //printf("offset to %s: %d (*4)\r\n",label,offset); if (offset<0) { offset = 0x1000000-(-offset); op|=offset; code[code_idx++] = op; } } else { //printf("! label not found %s, adding unresolved.\r\n",label); jit_labels_unres[unres_labels].name = strdup(label); jit_labels_unres[unres_labels].idx = code_idx; code[code_idx++] = op; unres_labels++; } } void jit_je(char* label) { uint32_t op = 0x0a000000; // beq jit_emit_branch(op, label); } void jit_jge(char* label) { uint32_t op = 0xaa000000; // bge jit_emit_branch(op, label); } void jit_jne(char* label) { uint32_t op = 0x1a000000; // bne jit_emit_branch(op, label); } void jit_jneg(char* label) { uint32_t op = 0x4a000000; // bmi jit_emit_branch(op, label); } void jit_jmp(char* label) { //printf("jmp to label: %s\r\n",label); uint32_t op = 0xea000000; // b jit_emit_branch(op, label); } void jit_label(char* label) { jit_labels[label_idx].name = strdup(label); jit_labels[label_idx].idx = code_idx; Label* unres_lbl = NULL; while ((unres_lbl = find_unresolved_label(label))) { //printf("! forward label to %s at idx %d resolved.\r\n",label,unres_lbl->idx); code[unres_lbl->idx] |= (code_idx - unres_lbl->idx) - 2; free(unres_lbl->name); unres_lbl->name = NULL; unres_lbl->idx = 0; } label_idx++; } void jit_ret() { jit_movr(15,14); // lr -> pc } void jit_push(int r1, int r2) { uint32_t op = 0xe92d0000; for (int i=r1; i<=r2; i++) { op |= (1<