Example #1
0
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);
}
Example #2
0
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);
}
Example #3
0
void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{
    if (jit_arg_d_reg_p(_jitc->function->call.argi)) {
	jit_stxi_d(-8, JIT_FP, u);
	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, u);
	jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8);
	++_jitc->function->call.argi;
	jit_stxi_f(stack_framesize, JIT_SP, u + 1);
	_jitc->function->call.size += sizeof(jit_float32_t);
    }
    else {
	jit_stxi_f(_jitc->function->call.size + stack_framesize,
		   JIT_SP, u);
	jit_stxi_f(_jitc->function->call.size + stack_framesize + 4,
		   JIT_SP, u + 1);
	_jitc->function->call.size += sizeof(jit_float64_t);
    }
}
Example #4
0
void _JIT_stack_push(jit_state_t *_jit, int reg, int *sp) {
    jit_stxi_d(*sp, JIT_FP, reg);
    *sp += sizeof(double);
}
Example #5
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;
    }