Exemplo n.º 1
0
dblFunc
makeCallFunc (dblFunc theFunc)
{
  dblFunc retVal;
  int dbl1, dbl2;
  retVal = (dblFunc) jit_get_ip ().iptr;
  jit_prolog (2);
  dbl1 = jit_arg_d ();
  dbl2 = jit_arg_d ();

  jit_prepare_d (2);
  jit_getarg_d (JIT_FPR0, dbl1);
  jit_getarg_d (JIT_FPR1, dbl2);
  jit_mulr_d (JIT_FPR1, JIT_FPR1, JIT_FPR0);
  jit_pusharg_d (JIT_FPR1);
  jit_pusharg_d (JIT_FPR0);
  jit_finish ((void *) theFunc);
  jit_retval_d (JIT_FPRET);
  jit_ret ();
  jit_flush_code ((char *) retVal, jit_get_ip ().ptr);

#ifdef LIGHTNING_DISASSEMBLE
  disassemble (stderr, (char *) retVal, jit_get_ip ().ptr);
#endif

  return retVal;
}
Exemplo n.º 2
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;
    }