static mover_t generate_movi (const void *operand) { static char buffer[1024]; mover_t result; /* printf ("si?=%i ui?=%i\n", _siP (16, operand), _uiP (16, operand)); */ result = (mover_t)(jit_set_ip (buffer).iptr); jit_leaf (1); jit_movi_p (JIT_R0, operand); jit_movr_p (JIT_RET, JIT_R0); jit_ret (); jit_flush_code (buffer, jit_get_ip ().ptr); return result; }
int JIT_evaluate(ASTNode *root) { #ifdef __APPLE__ // Mac OS X hack codeBuffer = mmap (NULL, 4096, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); #endif pifi function = (pifi) (jit_set_ip(codeBuffer).iptr); jit_leaf(1); int regs[MAX_REG] = {0}; int ret = alloc_reg(regs); JIT_visit(root, regs, ret); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); return function(); }
mod_t generate_modi (int operand) { static char buffer[1024]; mod_t result; int arg; result = (mod_t)(jit_set_ip (buffer).iptr); jit_leaf (1); arg = jit_arg_i (); jit_getarg_i (JIT_R1, arg); jit_modi_i (JIT_R2, JIT_R1, operand); jit_movr_i (JIT_RET, JIT_R2); jit_ret (); jit_flush_code (buffer, jit_get_ip ().ptr); return result; }
int main() { pifi myFunction= (pifi) (jit_set_ip(codeBuffer).iptr); int ofs; /* offset of the argument */ jit_leaf(1); ofs = jit_arg_i(); jit_getarg_i(JIT_R0, ofs); jit_addi_i(JIT_RET, JIT_R0, 1); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); /* call the generated code, passing its size as argument */ #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS printf("%d + 1 = %d\n", 5, myFunction(5)); #endif return 0; }
int main() { pifi nfibs = (pifi) (jit_set_ip(codeBuffer).iptr); int in; /* offset of the argument */ jit_insn *ref; /* to patch the forward reference */ jit_insn *loop; /* start of the loop */ jit_prolog (1); in = jit_arg_ui (); jit_getarg_ui(JIT_R2, in); /* V0 = n */ jit_movi_ui (JIT_R1, 1); ref = jit_blti_ui (jit_forward(), JIT_R2, 2); jit_subi_ui (JIT_R2, JIT_R2, 1); jit_movi_ui (JIT_R0, 1); loop= jit_get_label(); jit_subi_ui (JIT_R2, JIT_R2, 1); /* we'll calculate one more */ jit_addr_ui (JIT_V0, JIT_R0, JIT_R1); /* V0 = R0 + R1 */ jit_movr_ui (JIT_R0, JIT_R1); /* R0 = R1 */ jit_addi_ui (JIT_R1, JIT_V0, 1); /* R1 = V0 + 1 */ jit_bnei_ui (loop, JIT_R2, 0); /* if (R2) goto loop; */ jit_patch(ref); /* patch forward jump */ jit_movr_ui (JIT_RET, JIT_R1); /* RET = R1 */ jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *) codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS /* call the generated code, passing 36 as an argument */ printf("nfibs(%d) = %d\n", 36, nfibs(36)); #endif return 0; }
int main() { pvfi myFunction; /* ptr to generated code */ char *start, *end; /* a couple of labels */ int ofs; /* to get the argument */ codeBuffer = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); if (codeBuffer == MAP_FAILED) { perror("mmap"); exit(0); } myFunction = (pvfi) (jit_set_ip(codeBuffer).vptr); start = jit_get_ip().ptr; jit_prolog(1); ofs = jit_arg_i(); jit_movi_p(JIT_R0, "looks like %d bytes sufficed\n"); jit_getarg_i(JIT_R1, ofs); jit_prepare_i(2); jit_pusharg_i(JIT_R1); /* push in reverse order */ jit_pusharg_p(JIT_R0); jit_finish(display_message); jit_ret(); end = jit_get_ip().ptr; jit_flush_code(codeBuffer, end); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, codeBuffer, end); #endif #ifndef LIGHTNING_CROSS /* call the generated code, with a dummy argument */ myFunction(1024); #endif return 0; }
int main () { pifi c2f, f2c; int i; codeBuffer = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); if (codeBuffer == MAP_FAILED) { perror("mmap"); exit(0); } jit_set_ip (codeBuffer); c2f = compile_rpn ("32 x 9 * 5 / +"); f2c = compile_rpn ("5 x 32_ + * 9 /"); #ifndef LIGHTNING_CROSS printf ("\nC:"); for (i = 0; i <= 100; i += 10) printf ("%3d ", i); printf ("\nF:"); for (i = 0; i <= 100; i += 10) printf ("%3d ", c2f (i)); printf ("\n"); printf ("\nF:"); for (i = 32; i <= 212; i += 10) printf ("%3d ", i); printf ("\nC:"); for (i = 32; i <= 212; i += 10) printf ("%3d ", f2c (i)); printf ("\n"); #endif return 0; }
int main() { jit_code code; volatile double x = 0.0; code.ptr = (char *) codeBuffer; jit_set_ip(codeBuffer); jit_leaf(0); jit_ldi_d(JIT_FPR0, &a); jit_movi_d(JIT_FPR1, 0.0); jit_gtr_d(JIT_R0, JIT_FPR0, JIT_FPR1); jit_ltr_d(JIT_R1, JIT_FPR0, JIT_FPR1); jit_subr_i(JIT_RET, JIT_R0, JIT_R1); /* [greater] - [less] = -1/0/1 */ jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS int_test("compare", code, -2.6, -2.4, 0, 2.4, 2.6); #endif #ifdef __GNUC__ jit_set_ip(codeBuffer); jit_leaf(0); jit_ldi_d(JIT_FPR0, &a); jit_movi_d(JIT_FPR1, 0.0); jit_eqr_d(JIT_R0, JIT_FPR0, JIT_FPR1); jit_ltgtr_d(JIT_R1, JIT_FPR0, JIT_FPR1); jit_lshi_i(JIT_R1, JIT_R1, 1); jit_orr_i(JIT_RET, JIT_R0, JIT_R1); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS int_test("nans", code, x / x, 1 / (a - a), -1 / (a - a), 0.0, -2.0); #endif #else printf ("nans\t\t1 3 3 0 3\n"); #endif jit_set_ip(codeBuffer); jit_leaf(0); jit_ldi_d(JIT_FPR0, &a); jit_truncr_d_i(JIT_RET, JIT_FPR0); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS int_test("trunc", code, -2.6, -2.4, 0, 2.4, 2.6); int_test("trunc", code, -3, -2, 0, 2, 3); #endif jit_set_ip(codeBuffer); jit_leaf(0); jit_ldi_d(JIT_FPR0, &a); jit_ceilr_d_i(JIT_RET, JIT_FPR0); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS int_test("ceil", code, -2.6, -2.4, 0, 2.4, 2.6); int_test("ceil", code, -3, -2, 0, 2, 3); #endif jit_set_ip(codeBuffer); jit_leaf(0); jit_ldi_d(JIT_FPR0, &a); jit_floorr_d_i(JIT_RET, JIT_FPR0); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS int_test("floor", code, -2.6, -2.4, 0, 2.4, 2.6); int_test("floor", code, -3, -2, 0, 2, 3); #endif jit_set_ip(codeBuffer); jit_leaf(0); jit_ldi_d(JIT_FPR0, &a); jit_roundr_d_i(JIT_RET, JIT_FPR0); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS int_test("round", code, -2.6, -2.4, 0, 2.4, 2.6); int_test("round", code, -3, -2, 0, 2, 3); #endif #if 0 && defined JIT_TRANSCENDENTAL jit_set_ip(codeBuffer); jit_leaf(0); jitfp_sti_d(&a, jitfp_log( jitfp_exp(jitfp_imm(1.0)) ) ); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); code.vptr(); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS printf("log e = \t%f\n", a); #endif jit_set_ip(codeBuffer); jit_leaf(0); jitfp_sti_d(&a, jitfp_atn( jitfp_imm(1.732050807657) ) ); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); code.vptr(); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS printf("pi = \t%f\n", a*3); #endif jit_set_ip(codeBuffer); jit_leaf(0); jitfp_sti_d(&a, jitfp_tan( jitfp_ldi_d(&a) ) ); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); code.vptr(); #ifdef LIGHTNING_DISASSEMBLE disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr); #endif #ifndef LIGHTNING_CROSS printf("tan^2 pi/3 = \t%f\n", a*a); #endif #endif /* JIT_TRANSCEDENTAL */ return (0); }
void run_gnulightning(void) { struct bfi * n = bfprog; int maxstack = 0, stackptr = 0; char *strbuf = 0; size_t maxstrlen = 0; #ifdef GNULIGHTv1 jit_insn** loopstack = 0; jit_insn *codeBuffer; void * startptr; int argp; #endif #ifdef GNULIGHTv2 jit_node_t *start, *end; /* For size of code */ jit_node_t** loopstack = 0; jit_node_t *argp; #endif if (cell_size == 8) tape_step = 1; else tape_step = sizeof(int); #ifdef GNULIGHTv1 /* TODO: Use mmap for allocating memory, the x86 execute protection * bit is on the segment so Linux has to say thay everything below * a specific address is executable. If you ask mmap for executable * memory it can put it below the current value. The mprotect() * function can't do this. */ if (total_nodes < 4096) codeBuffer = malloc(65536); else codeBuffer = malloc(16 * total_nodes); save_ptr_for_free(codeBuffer); codeptr = (codeptr_t) jit_set_ip(codeBuffer).vptr; startptr = jit_get_ip().ptr; /* Function call prolog */ jit_prolog(1); /* Get the data area pointer */ argp = jit_arg_p(); jit_getarg_p(REG_P, argp); #endif #ifdef GNULIGHTv2 init_jit(NULL); // argv[0]); _jit = jit_new_state(); start = jit_note(__FILE__, __LINE__); jit_prolog(); /* Get the data area pointer */ argp = jit_arg(); jit_getarg(REG_P, argp); #endif while(n) { switch(n->type) { case T_MOV: if (acc_loaded) acc_offset -= n->count; jit_addi(REG_P, REG_P, n->count * tape_step); break; case T_ADD: load_acc_offset(n->offset); set_acc_offset(n->offset); jit_addi(REG_ACC, REG_ACC, n->count); break; case T_SET: set_acc_offset(n->offset); if (acc_const && acc_const_val == n->count) { ; } else if (acc_const && acc_const_val+1 == n->count) { jit_addi(REG_ACC, REG_ACC, 1); } else if (acc_const && acc_const_val-1 == n->count) { jit_addi(REG_ACC, REG_ACC, -1); } else { jit_movi(REG_ACC, n->count); } acc_const = 1; acc_const_val = n->count; break; case T_CALC: if (n->offset == n->offset2 && n->count2 == 1) { load_acc_offset(n->offset); set_acc_offset(n->offset); if (n->count) jit_addi(REG_ACC, REG_ACC, n->count); } else if (n->count2 != 0) { load_acc_offset(n->offset2); set_acc_offset(n->offset); if (n->count2 == -1) jit_negr(REG_ACC, REG_ACC); else if (n->count2 != 1) jit_muli(REG_ACC, REG_ACC, n->count2); if (n->count) jit_addi(REG_ACC, REG_ACC, n->count); } else { clean_acc(); set_acc_offset(n->offset); jit_movi(REG_ACC, n->count); if (n->count2 != 0) { if (tape_step > 1) jit_ldxi_i(REG_A1, REG_P, n->offset2 * tape_step); else jit_ldxi_uc(REG_A1, REG_P, n->offset2); if (n->count2 == -1) jit_negr(REG_A1, REG_A1); else if (n->count2 != 1) jit_muli(REG_A1, REG_A1, n->count2); jit_addr(REG_ACC, REG_ACC, REG_A1); } } if (n->count3 != 0) { if (tape_step > 1) jit_ldxi_i(REG_A1, REG_P, n->offset3 * tape_step); else jit_ldxi_uc(REG_A1, REG_P, n->offset3); if (n->count3 == -1) jit_negr(REG_A1, REG_A1); else if (n->count3 != 1) jit_muli(REG_A1, REG_A1, n->count3); jit_addr(REG_ACC, REG_ACC, REG_A1); } break; case T_IF: case T_MULT: case T_CMULT: case T_WHL: load_acc_offset(n->offset); clean_acc(); acc_const = acc_loaded = 0; if (stackptr >= maxstack) { loopstack = realloc(loopstack, ((maxstack+=32)+2)*sizeof(*loopstack)); if (loopstack == 0) { perror("loop stack realloc failure"); exit(1); } } if (cell_mask > 0 && acc_hi_dirty) { if (cell_mask == 0xFF) jit_extr_uc(REG_ACC,REG_ACC); else jit_andi(REG_ACC, REG_ACC, cell_mask); } #ifdef GNULIGHTv1 loopstack[stackptr] = jit_beqi_i(jit_forward(), REG_ACC, 0); loopstack[stackptr+1] = jit_get_label(); #endif #ifdef GNULIGHTv2 loopstack[stackptr] = jit_beqi(REG_ACC, 0); loopstack[stackptr+1] = jit_label(); #endif stackptr += 2; break; case T_END: load_acc_offset(n->offset); clean_acc(); stackptr -= 2; if (stackptr < 0) { fprintf(stderr, "Code gen failure: Stack pointer negative.\n"); exit(1); } if (cell_mask > 0 && acc_hi_dirty) { if (cell_mask == 0xFF) jit_extr_uc(REG_ACC,REG_ACC); else jit_andi(REG_ACC, REG_ACC, cell_mask); } #ifdef GNULIGHTv1 jit_bnei_i(loopstack[stackptr+1], REG_ACC, 0); jit_patch(loopstack[stackptr]); #endif #ifdef GNULIGHTv2 { jit_node_t *ref; ref = jit_bnei(REG_ACC, 0); jit_patch_at(ref, loopstack[stackptr+1]); jit_patch(loopstack[stackptr]); } #endif break; case T_ENDIF: clean_acc(); acc_const = acc_loaded = 0; stackptr -= 2; if (stackptr < 0) { fprintf(stderr, "Code gen failure: Stack pointer negative.\n"); exit(1); } jit_patch(loopstack[stackptr]); break; case T_PRT: clean_acc(); load_acc_offset(n->offset); acc_loaded = 0; #ifdef GNULIGHTv1 jit_prepare_i(1); jit_pusharg_i(REG_ACC); jit_finish(putch); #endif #ifdef GNULIGHTv2 jit_prepare(); jit_pushargr(REG_ACC); jit_finishi(putch); #endif break; case T_CHR: clean_acc(); acc_const = acc_loaded = 0; if (n->count <= 0 || (n->count >= 127 && iostyle == 1) || !n->next || n->next->type != T_CHR) { jit_movi(REG_ACC, n->count); #ifdef GNULIGHTv1 jit_prepare_i(1); jit_pusharg_i(REG_ACC); jit_finish(putch); #endif #ifdef GNULIGHTv2 jit_prepare(); jit_pushargr(REG_ACC); jit_finishi(putch); #endif } else { unsigned i = 0; struct bfi * v = n; char *s; while(v->next && v->next->type == T_CHR && v->next->count > 0 && (v->next->count < 127 || iostyle != 1)) { if (i+2 > maxstrlen) { if (maxstrlen) maxstrlen *= 2; else maxstrlen = 4096; strbuf = realloc(strbuf, maxstrlen); if (!strbuf) { fprintf(stderr, "Reallocate of string buffer failed\n"); exit(42); } } strbuf[i++] = (char) /*GCC -Wconversion*/ v->count; n = v; v = v->next; } strbuf[i] = 0; s = strdup(strbuf); if (!s) { fprintf(stderr, "Save of string failed\n"); exit(43); } save_ptr_for_free(s); #ifdef GNULIGHTv1 jit_movi_p(REG_ACC, s); jit_prepare_i(1); jit_pusharg_i(REG_ACC); jit_finish(puts_without_nl); #endif #ifdef GNULIGHTv2 jit_prepare(); jit_pushargi((jit_word_t) s); jit_finishi(puts_without_nl); #endif } break; case T_INP: load_acc_offset(n->offset); set_acc_offset(n->offset); #ifdef GNULIGHTv1 jit_prepare_i(1); jit_pusharg_i(REG_ACC); jit_finish(getch); jit_retval_i(REG_ACC); #endif #ifdef GNULIGHTv2 jit_prepare(); jit_pushargr(REG_ACC); jit_finishi(getch); jit_retval(REG_ACC); #endif break; case T_STOP: #ifdef GNULIGHTv1 jit_prepare_i(0); jit_finish(failout); #endif #ifdef GNULIGHTv2 jit_prepare(); jit_finishi(failout); #endif break; case T_NOP: case T_DUMP: fprintf(stderr, "Warning on code generation: " "%s node: ptr+%d, cnt=%d, @(%d,%d).\n", tokennames[n->type], n->offset, n->count, n->line, n->col); break; default: fprintf(stderr, "Code gen error: " "%s\t" "%d:%d, %d:%d, %d:%d\n", tokennames[n->type], n->offset, n->count, n->offset2, n->count2, n->offset3, n->count3); exit(1); } n=n->next; #if 0 /*def GNULIGHTv2 */ if(n && enable_trace) { char *p, buf[250]; clean_acc(); acc_loaded = 0; sprintf(buf, "@(%d,%d)\n", n->line, n->col); p = strdup(buf); save_ptr_for_free(p); jit_prepare(); jit_pushargi((jit_word_t) p); jit_finishi(puts_without_nl); } #endif #ifdef GNULIGHTv1 /* TODO -- Check for codeBuffer overflow (add jmp to new) */ #endif } jit_ret(); if (strbuf) { maxstrlen = 0; free(strbuf); strbuf = 0; } delete_tree(); #ifdef GNULIGHTv1 jit_flush_code(startptr, jit_get_ip().ptr); if (verbose) fprintf(stderr, "Generated %d bytes of V1 GNU Lightning code, running\n", (int)(jit_get_ip().ptr - (char*)startptr)); start_runclock(); codeptr(map_hugeram()); finish_runclock(&run_time, &io_time); #endif #ifdef GNULIGHTv2 jit_epilog(); end = jit_note(__FILE__, __LINE__); codeptr = jit_emit(); if (verbose) fprintf(stderr, "Generated %d bytes of V2 GNU Lightning code, running\n", (int)((char*)jit_address(end) - (char*)jit_address(start))); jit_clear_state(); // jit_disassemble(); start_runclock(); codeptr(map_hugeram()); finish_runclock(&run_time, &io_time); #endif #if 0 /* This code writes the generated instructions to a file * so we can disassemble it using: ndisasm -b 32/64 code.bin */ { #ifdef GNULIGHTv1 char *p = startptr; int s = jit_get_ip().ptr - p; #endif #ifdef GNULIGHTv2 char *p = (char*)jit_address(start); int s = (char*)jit_address(end) - p; #endif FILE *fp = fopen("code.bin", "w"); int i; for (i = 0; i < s; ++i) { fputc(p[i], fp); } fclose(fp); } #endif #ifdef GNULIGHTv2 jit_destroy_state(); finish_jit(); #endif codeptr = 0; if (loopstack) { free(loopstack); loopstack = 0; } free_saved_memory(); }