Exemple #1
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;
    }
Exemple #2
0
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;
}