void _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) { jit_int32_t regno; regno = jit_get_reg(jit_class_fpr); jit_movi_d(regno, u); if (jit_arg_d_reg_p(_jitc->function->call.argi)) { jit_stxi_d(-8, JIT_FP, regno); jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8); jit_ldxi(_O0 + _jitc->function->call.argi + 1, JIT_FP, -4); _jitc->function->call.argi += 2; } else if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_stxi_f(-8, JIT_FP, regno); jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8); ++_jitc->function->call.argi; jit_stxi_f(stack_framesize, JIT_SP, regno + 1); _jitc->function->call.size += sizeof(jit_float32_t); } else { jit_stxi_f(_jitc->function->call.size + stack_framesize, JIT_SP, regno); jit_stxi_f(_jitc->function->call.size + stack_framesize + 4, JIT_SP, regno + 1); _jitc->function->call.size += sizeof(jit_float64_t); } jit_unget_reg(regno); }
void _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) { jit_int32_t regno, gpr; assert(v->code == jit_code_arg_d); regno = jit_get_reg(jit_class_fpr); jit_movi_d(regno, u); if (jit_arg_d_reg_p(v->u.w)) { jit_stxi_d(-8, JIT_FP, regno); jit_ldxi(_I0 + v->u.w, JIT_FP, -8); jit_ldxi(_I0 + v->u.w + 1, JIT_FP, -4); } else if (jit_arg_reg_p(v->u.w)) { gpr = jit_get_reg(jit_class_gpr); jit_stxi_d(-8, JIT_FP, regno); jit_ldxi(_I0 + v->u.w, JIT_FP, -8); jit_ldxi(gpr, JIT_FP, -4); jit_stxi(stack_framesize, JIT_FP, gpr); jit_unget_reg(gpr); } else if ((v->u.w & 7) == 0) jit_stxi_d(v->u.w, JIT_FP, regno); else { jit_stxi_d(-8, JIT_FP, regno); gpr = jit_get_reg(jit_class_gpr); jit_ldxi(gpr, JIT_FP, -8); jit_stxi(v->u.w, JIT_FP, gpr); jit_ldxi(gpr, JIT_FP, -4); jit_stxi(v->u.w + 4, JIT_FP, gpr); jit_unget_reg(gpr); } jit_unget_reg(regno); }
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); }
bool compile(const Program &program, Translator &trans, Environment &env) { jit_node_t *ref; jit_node_t *fn = jit_note(NULL, 0); jit_prolog(); const int stack_base_offset = jit_allocai(32 * sizeof(double)); int stack_top_idx = 0; auto &&stackPush = [&](int reg) { jit_stxi_d(stack_base_offset + stack_top_idx * sizeof(double), JIT_FP, reg); ++stack_top_idx; }; auto &&stackPop = [&](int reg) { --stack_top_idx; jit_ldxi_d(reg, JIT_FP, stack_base_offset + stack_top_idx * sizeof(double)); return reg; }; size_t pc = 0; const size_t progsz = program.size(); while (pc < progsz) { const Instruction &instr = program[pc]; switch (instr.op) { case OP_NOP: break; case OP_PUSH: stackPush(JIT_F0); jit_movi_d(JIT_F0, instr.dval); break; case OP_ADD: { const int reg = stackPop(JIT_F1); jit_addr_d(JIT_F0, reg, JIT_F0); } break; case OP_SUB: { const int reg = stackPop(JIT_F1); jit_subr_d(JIT_F0, reg, JIT_F0); } break; case OP_MUL: { const int reg = stackPop(JIT_F1); jit_mulr_d(JIT_F0, reg, JIT_F0); } break; case OP_DIV: { const int reg = stackPop(JIT_F1); jit_divr_d(JIT_F0, reg, JIT_F0); } break; case OP_CALL: { stackPush(JIT_F0); const int sp = stack_top_idx - (instr.callop.nargs); jit_addi(JIT_R0, JIT_FP, stack_base_offset + sp * sizeof(double)); jit_prepare(); jit_pushargi((jit_word_t)&env); // 1st arg: userdata jit_pushargi(instr.callop.nargs); // 2nd arg: # of arguments jit_pushargr(JIT_R0); // 3rd arg: pointer to args on stack jit_pushargi((jit_word_t)&error_); // 4th arg: pointer to error message auto &&cb = trans.lookup(instr.callop.fidx); jit_finishi(reinterpret_cast<jit_pointer_t>(cb)); stack_top_idx -= instr.callop.nargs; // consume arguments on stack jit_retval_d(JIT_F0); jit_retval(JIT_R0); ref = jit_bnei(JIT_R0, 0); jit_reti_d(*reinterpret_cast<const double*>(&JIT_ERROR)); jit_patch(ref); } break; } ++pc; } jit_retr_d(JIT_F0); jit_epilog(); (void)jit_emit(); func_ = reinterpret_cast<JitFunction>(jit_address(fn)); return true; }
pdfd compile_rpn (char *expr) { pdfd fn; int ofs, sp = 1; fn = (pdfd) (jit_get_ip ().dptr); jit_leaf (1); ofs = jit_arg_d (); jit_getarg_d (regs[0], ofs); while (*expr) { char buf[32]; int n; /* This scanner is much less advanced than the one in rpn.c. */ if (sscanf (expr, "%[0-9]%n", buf, &n)) { double d = strtod (buf, NULL); expr += n - 1; jit_movi_d (regs[sp], d); sp++; } else if (*expr == '+') { jit_addr_d (regs[sp - 2], regs[sp - 2], regs[sp - 1]); sp--; } else if (*expr == '-') { jit_subr_d (regs[sp - 2], regs[sp - 2], regs[sp - 1]); sp--; } else if (*expr == '*') { jit_mulr_d (regs[sp - 2], regs[sp - 2], regs[sp - 1]); sp--; } else if (*expr == '/') { jit_divr_d (regs[sp - 2], regs[sp - 2], regs[sp - 1]); sp--; } else { fprintf (stderr, "cannot compile: %s\n", expr); abort (); } ++expr; } jit_movr_d (JIT_FPRET, regs[0]); jit_ret (); jit_flush_code ((char *) fn, jit_get_ip ().ptr); #ifdef LIGHTNING_DISASSEMBLE disassemble (stderr, (char *) fn, jit_get_ip ().ptr); #endif return fn; }
void _jit_reti_d(jit_state_t *_jit, jit_float64_t u) { jit_movi_d(JIT_FRET, u); jit_ret(); }