コード例 #1
0
ファイル: bp.c プロジェクト: pcpa/lightning
int main()
{
  pifi      nfibs;
  int	    in;				/* offset of the argument */
  jit_insn  *ref;			/* to patch the forward reference */
  jit_insn  *mref;                     /* ref of move to backpatch */
  jit_insn  *tp;                       /* location to patch */

  codeBuffer = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC,
                    MAP_PRIVATE | MAP_ANON, -1, 0);
  if (codeBuffer == MAP_FAILED) {
    perror("mmap");
    exit(0);
  }

  nfibs = (pifi) (jit_set_ip(codeBuffer).iptr);

        jit_prolog   (1);
  in =  jit_arg_ui   ();
        jit_getarg_ui(JIT_V0, in);              /* V0 = n */
  mref= jit_movi_p(JIT_V2,jit_forward ());      /* Generate a dumb movi */
        jit_jmpr(JIT_V2);
        /* generate some dump filler that will never be executed!*/
        jit_addi_ui(JIT_V0,JIT_V0,1);
        jit_addi_ui(JIT_V0,JIT_V0,1);        
        jit_addi_ui(JIT_V0,JIT_V0,1);        
        jit_addi_ui(JIT_V0,JIT_V0,1);        
  tp  = jit_get_label ();
  ref = jit_blti_ui  (jit_forward(), JIT_V0, 2);
        jit_subi_ui  (JIT_V1, JIT_V0, 1);       /* V1 = n-1 */
        jit_subi_ui  (JIT_V2, JIT_V0, 2);       /* V2 = n-2 */
        jit_prepare  (1);
          jit_pusharg_ui(JIT_V1);
        jit_finish(nfibs);
        jit_retval(JIT_V1);                     /* V1 = nfibs(n-1) */
        jit_prepare(1);
          jit_pusharg_ui(JIT_V2);
        jit_finish(nfibs);
        jit_retval(JIT_V2);                     /* V2 = nfibs(n-2) */
        jit_addi_ui(JIT_V1,  JIT_V1,  1);
        jit_addr_ui(JIT_RET, JIT_V1, JIT_V2);   /* RET = V1 + V2 + 1 */
        jit_ret();

  jit_patch(ref);                               /* patch jump */
        jit_movi_i(JIT_RET, 1);                 /* RET = 1 */
        jit_ret();

  jit_patch_movi(mref,tp);                      /* Ok. Do the back-patching */

  /* call the generated code, passing 32 as an argument */
  jit_flush_code(codeBuffer, jit_get_ip().ptr);

#ifdef LIGHTNING_DISASSEMBLE
  disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr);
#endif
#ifndef LIGHTNING_CROSS
  printf("nfibs(%d) = %d\n", 32, nfibs(32));
#endif
  return 0;
}
コード例 #2
0
ファイル: funcfp.c プロジェクト: pcpa/lightning
floatFunc
makeCallFloatFunc (floatFunc theFunc)
{
  floatFunc retVal;
  int dbl1, dbl2;
  retVal = (floatFunc) jit_get_ip ().iptr;
  jit_prolog (2);
  dbl1 = jit_arg_f ();
  dbl2 = jit_arg_f ();

  jit_prepare_f (2);
  jit_getarg_f (JIT_FPR0, dbl1);
  jit_getarg_f (JIT_FPR1, dbl2);
  jit_mulr_f (JIT_FPR1, JIT_FPR1, JIT_FPR0);
  jit_pusharg_f (JIT_FPR1);
  jit_pusharg_f (JIT_FPR0);
  jit_finish ((void *) theFunc);
  jit_retval_f (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;
}
コード例 #3
0
ファイル: divi.c プロジェクト: pcpa/lightning
static divider_t
generate_divider (int operand, unsigned int *size)
{
  divider_t result;
  int arg;

  buffer = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC,
		MAP_PRIVATE | MAP_ANON, -1, 0);
  if (buffer == MAP_FAILED) {
    perror("mmap");
    exit(0);
  }

  result = (divider_t)(jit_set_ip (buffer).iptr);
  jit_leaf (1);
  arg = jit_arg_i ();
  jit_getarg_i (JIT_R1, arg);

  jit_divi_i (JIT_R2, JIT_R1, operand);
  jit_movr_i (JIT_RET, JIT_R2);

  jit_ret ();
  jit_flush_code (buffer, jit_get_ip ().ptr);

  *size = (jit_insn *)jit_get_ip ().ptr - buffer;

  return result;
}
コード例 #4
0
ファイル: modi.c プロジェクト: pcpa/lightning
mod_t
generate_modi (int operand)
{
  mod_t result;
  int arg;

  buffer = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC,
		MAP_PRIVATE | MAP_ANON, -1, 0);
  if (buffer == MAP_FAILED) {
    perror("mmap");
    exit(0);
  }

  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;
}
コード例 #5
0
ファイル: printf.C プロジェクト: pippijn/rasm
int main()
{
  static jit_insn codeBuffer[1024];
  static jit_state _jit;

  pvfi		myFunction;		/* ptr to generated code */
  char		*start, *end;		/* a couple of labels */
  int		ofs;			/* to get the argument */

  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, passing its size as argument */
  myFunction(sizeof(codeBuffer));
#endif
  return 0;
}
コード例 #6
0
ファイル: ret.C プロジェクト: pippijn/rasm
static int_return_int_t
generate_function_proxy (int_return_int_t func)
{
  static jit_insn buffer[1024];
  static jit_state _jit;
  int_return_int_t result;
  int arg;

  result = (int_return_int_t)(jit_set_ip (buffer).ptr);
  jit_prolog (1);
  arg = jit_arg_i ();
  jit_getarg_i (JIT_R1, arg);

  /* Reset `JIT_RET'.  */
  jit_movi_i (JIT_RET, -1);

  /* Invoke a FUNC.  */
  jit_prepare (1);
  jit_pusharg_i (JIT_R1);
  (void)jit_finish (func);

  /* Copy the result of FUNC from `JIT_RET' into our own result register.  */
  jit_retval_i (JIT_RET);

  jit_ret ();
  jit_flush_code (buffer, jit_get_ip ().ptr);

  return result;
}
コード例 #7
0
ファイル: jit_sparc.c プロジェクト: 8l/bomberjacket
void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{
    if (JIT_FRET != u)
	jit_movr_d(JIT_FRET, u);
    else
	jit_live(JIT_FRET);
    jit_ret();
}
コード例 #8
0
ファイル: push-pop.c プロジェクト: pcpa/lightning
static stakumilo_t
generate_push_pop (void)
{
  static const char msg[] = "we got %i\n";
  stakumilo_t result;
  int arg;
  int retval;

  buffer = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC,
		MAP_PRIVATE | MAP_ANON, -1, 0);
  if (buffer == MAP_FAILED) {
    perror("mmap");
    exit(0);
  }

  result = (stakumilo_t)(jit_set_ip (buffer).ptr);
  jit_prolog (1);
  arg = jit_arg_i ();
  jit_getarg_i (JIT_R1, arg);

  /* Save R1 on the stack.  */
  jit_pushr_i (JIT_R1);

  /* Save two other registers just for the sake of using the stack.  */
  jit_movi_i (JIT_R0, -1);
  jit_movi_i (JIT_R2, -1);
  jit_pushr_i (JIT_R0);
  jit_pushr_i (JIT_R2);
  /* most likely need stack aligned at 16 bytes, dummy push to force align */
  jit_pushr_i (JIT_R2);

  jit_movr_i (JIT_R0, JIT_R1);
  jit_movi_p (JIT_R1, msg);

  /* Invoke a function that may modify R1.  */
  jit_prepare (2);
  jit_pusharg_i (JIT_R0);
  jit_pusharg_p (JIT_R1);
  (void)jit_finish (display_message);

  /* dummy pop for the sake of calling function with 16 byte aligned stack */
  jit_popr_i (JIT_R2);
  /* Restore the dummy registers.  */
  jit_popr_i (JIT_R2);
  jit_popr_i (JIT_R0);

  /* Restore R1.  */
  jit_popr_i (JIT_R1);

  jit_movr_i (JIT_RET, JIT_R1);

  jit_ret ();
  jit_flush_code (buffer, jit_get_ip ().ptr);

  return result;
}
コード例 #9
0
static stakumilo_t
generate_push_pop (void)
{
  static const char msg[] = "we got %i\n";
  static char buffer[1024];
  stakumilo_t result;
  int arg;

  result = (stakumilo_t)(jit_set_ip (buffer).ptr);
  jit_prolog (1);
  arg = jit_arg_i ();
  jit_getarg_i (JIT_R1, arg);

  /* Save R1 on the stack.  */
  jit_pushr_i (JIT_R1);

  /* Save two other registers just for the sake of using the stack.  */
  jit_movi_i (JIT_R0, -1);
  jit_movi_i (JIT_R2, -1);
  jit_pushr_i (JIT_R0);
  jit_pushr_i (JIT_R2);

  jit_movr_i (JIT_R0, JIT_R1);
  jit_movi_p (JIT_R1, msg);

  /* Invoke a function that may modify R1.  */
  jit_prepare (2);
  jit_pusharg_i (JIT_R0);
  jit_pusharg_p (JIT_R1);
  (void)jit_finish (display_message);

  /* Restore the dummy registers.  */
  jit_popr_i (JIT_R2);
  jit_popr_i (JIT_R0);

  /* Restore R1.  */
  jit_popr_i (JIT_R1);

  jit_movr_i (JIT_RET, JIT_R1);

  jit_ret ();
  jit_flush_code (buffer, jit_get_ip ().ptr);

  return result;
}
コード例 #10
0
ファイル: movi.c プロジェクト: erikdubbelboer/brainfuck-jit
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;
}
コード例 #11
0
ファイル: modi.c プロジェクト: erikdubbelboer/brainfuck-jit
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;
}
コード例 #12
0
ファイル: jit.c プロジェクト: triplekill/calc
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();
}
コード例 #13
0
ファイル: incr.C プロジェクト: pippijn/rasm
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;
}
コード例 #14
0
ファイル: funcfp.c プロジェクト: pcpa/lightning
/* Generate a function that computes and returns the sum of 
   its two double arguments (return an int)
   i.e., double foo(double x,double y) { return x + y;} */
floatFunc
makeFloatFunc ()
{
  floatFunc retVal;
  int dbl1, dbl2;
  retVal = (floatFunc) jit_get_ip ().iptr;
  jit_prolog (2);
  dbl1 = jit_arg_f ();
  dbl2 = jit_arg_f ();
  jit_getarg_f (JIT_FPR0, dbl1);
  jit_getarg_f (JIT_FPR1, dbl2);
  jit_addr_f (JIT_FPR0, JIT_FPR0, JIT_FPR1);
  jit_movr_f (JIT_FPRET, JIT_FPR0);
  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;
}
コード例 #15
0
ファイル: fibit.c プロジェクト: erikdubbelboer/brainfuck-jit
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;
}
コード例 #16
0
ファイル: printf.c プロジェクト: pcpa/lightning
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;
}
コード例 #17
0
ファイル: testfp.c プロジェクト: erikdubbelboer/brainfuck-jit
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);
}
コード例 #18
0
ファイル: rpnfp.c プロジェクト: pcpa/lightning
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;
}
コード例 #19
0
ファイル: bfloo.cpp プロジェクト: cslarsen/presentation-vm
jit_pointer_t compile(const std::vector<Oper>& ops, jit_word_t *memory, const bool flush = true)
{
  jit_prolog();
  jit_movi(JIT_V0, reinterpret_cast<jit_word_t>(memory));
  jit_movi(JIT_V1, 0);

  std::stack<Loop> loops;

  jit_node_t* start = jit_note(__FILE__, __LINE__);

  for ( size_t n=0; n<ops.size(); ++n ) {
    switch ( ops[n].code ) {
      case '<':
        jit_str(JIT_V0, JIT_V1);
        jit_subi(JIT_V0, JIT_V0, ops[n].count * sizeof(jit_word_t));
        jit_ldr(JIT_V1, JIT_V0);
        break;

      case '>':
        jit_str(JIT_V0, JIT_V1);
        jit_addi(JIT_V0, JIT_V0, ops[n].count * sizeof(jit_word_t));
        jit_ldr(JIT_V1, JIT_V0);
        break;

      case 'z':
        jit_movi(JIT_V1, 0);
        break;

      case '+':
        jit_addi(JIT_V1, JIT_V1, ops[n].count);
        break;

      case '-':
        jit_subi(JIT_V1, JIT_V1, ops[n].count);
        break;

      case '.':
        jit_prepare();
        jit_pushargr(JIT_V1);
        jit_finishi(reinterpret_cast<jit_pointer_t>(putchar));

        if ( flush ) {
          jit_prepare();
          jit_pushargi(reinterpret_cast<jit_word_t>(stdout));
          jit_finishi(reinterpret_cast<jit_pointer_t>(fflush));
        }
        break;

      case ',':
        jit_prepare();
        jit_finishi(reinterpret_cast<jit_pointer_t>(getchar));
        jit_retval(JIT_V1);
        break;

      case '[': {
        Loop loop;
        loop.end = jit_forward();
        jit_node_t *j = jit_beqi(JIT_V1, 0);
        jit_patch_at(j, loop.end);
        loop.body = jit_label();
        loops.push(loop);
      } break;

      case ']': {
        Loop loop = loops.top();
        jit_node_t *j = jit_bnei(JIT_V1, 0);
        jit_patch_at(j, loop.body);
        jit_link(loop.end);
        loops.pop();
        break;
      }
      default:
        break;
    }
  }

  jit_node_t* stop = jit_note(__FILE__, __LINE__);

  jit_ret();
  jit_epilog();
  jit_pointer_t r = jit_emit();
  fprintf(stderr, "compiled to %zu bytes\n", (char*)jit_address(stop) -
      (char*)jit_address(start));
  return r;
}
コード例 #20
0
ファイル: jit.c プロジェクト: NoSuchProcess/phantomuserland
errno_t jit_compile_method(struct pvm_code_handler *code)
{

    struct jit_out      jo;
    struct jit_out      *j = &jo;

    //struct data_area_4_thread *da = (struct data_area_4_thread *)&(current_thread.data->da);
    // TODO: check for current_thread to be thread for real

    // JITted code supposed to be called with da in BX

    //jit_gen_push( j, JIT_R_BX );
    //jit_gen_call( j, JIT_F_LOAD_F_ACC );
    //pvm_exec_load_fast_acc(da); // For any case

    {
#warning resleep?
    // Thread was snapped sleeping - resleep it
        //if(da->sleep_flag)        phantom_thread_sleep_worker( da );
        /*
        jit_load_thread_field( j, offsetof(da->sleep_flag) ); // to AX, gen flags
        jit_label jl = jit_get_label( j );
        jit_jz( jl );

        jit_gen_push( j, JIT_R_BX );
        jit_gen_call( j, JIT_F_THREAD_SLEEP_WORKER );
        jit_mark_label( j, jl );
        */
    }

    while(1)
    {

        /*
        if(phantom_virtual_machine_snap_request)
        {
            pvm_exec_save_fast_acc(da); // Before snap
            phantom_thread_wait_4_snap();
            //pvm_exec_load_fast_acc(da); // We don't need this, if we die, we will enter again from above :)
        }
        */

        {
            jit_check_snap_request( j );
            /*
            jit_label jl = jit_get_label( j );
            jit_jz( jl );

            //jit_gen_push( j, JIT_R_BX );
            jit_gen_call( j, JIT_F_WAIT_SNAP );
            jit_mark_label( j, jl );
            */
        }


        jit_mark_possible_label(j);

        unsigned char instruction = pvm_code_get_byte(code);
        //printf("instr 0x%02X ", instruction);


        switch(instruction)
        {
        case opcode_nop:
            //if( debug_print_instr ) printf("nop; ");
            break;

        case opcode_debug:

            {
                int type = pvm_code_get_byte(code); //cf->cs.get_instr( cf->IP );

                //printf("\n\nDebug 0x%02X", type );
                if( type & 0x80 )
                {
                    //printf(" (" );
                    pvm_object_t o = pvm_code_get_string(code);
                    //pvm_object_print(o);
                    ref_dec_o(o);
                    //printf(")" );
                }

                if( type & 0x01 ) debug_print_instr = 1;
                if( type & 0x02 ) debug_print_instr = 0;

                /*
                if( is_empty() ) printf(", istack empty");
                else                    printf(",\n\tistack top = %d", is_top() );
                if( os_empty() ) printf(", ostack empty");
                else
                {
                    printf(",\n\tostack top = {" );
                    pvm_object_print( os_top() );
                    printf("}" );
                }
                printf(";\n\n");
                */
            }

            break;


            // int stack ops ---------------------------------------

        case opcode_is_dup:
            if( debug_print_instr ) printf("is dup; ");
            jit_is_push( j, jit_is_top( j ) );
            break;

        case opcode_is_drop:
            if( debug_print_instr ) printf("is drop; ");
            jit_is_pop( j );
            break;

        case opcode_iconst_0:
            if( debug_print_instr ) printf("iconst 0; ");
            jit_is_push( j, jit_iconst( j, 0 ) );
            break;

        case opcode_iconst_1:
            if( debug_print_instr ) printf("iconst 1; ");
            jit_is_push( j, jit_iconst( j, 1 ) );
            break;

        case opcode_iconst_8bit:
            {
                int v = pvm_code_get_byte(code);
                jit_is_push( j, jit_iconst( j, v ) );
                if( debug_print_instr ) printf("iconst8 = %d; ", v);
                break;
            }

        case opcode_iconst_32bit:
            {
                int v = pvm_code_get_int32(code);
                jit_is_push( j, jit_iconst( j, v ) );
                if( debug_print_instr ) printf("iconst32 = %d; ", v);
                break;
            }


        case opcode_isum:
            if( debug_print_instr ) printf("isum; ");
            jit_binary_op( j, jit_gen_add );
            break;

        case opcode_imul:
            if( debug_print_instr ) printf("imul; ");
            {
                //int mul = is_pop();
                //is_push( is_pop() * mul );
                jit_binary_op( j, jit_gen_mul );
            }
            break;

        case opcode_isubul:
            if( debug_print_instr ) printf("isubul; ");
            {
                jit_value_t u = jit_is_pop( j );
                jit_value_t l = jit_is_pop( j );
                jit_value_t r = jit_gen_sub( j, u, l );
                jit_is_push( j, r );
            }
            break;

        case opcode_isublu:
            if( debug_print_instr ) printf("isublu; ");
            {
                jit_value_t u = jit_is_pop( j );
                jit_value_t l = jit_is_pop( j );
                jit_value_t r = jit_gen_sub( j, l, u );
                jit_is_push( j, r );
            }
            break;

        case opcode_idivul:
            if( debug_print_instr ) printf("idivul; ");
            {
                jit_value_t u = jit_is_pop( j );
                jit_value_t l = jit_is_pop( j );
                jit_value_t r = jit_gen_div( j, u, l );
                jit_is_push( j, r );
            }
            break;

        case opcode_idivlu:
            if( debug_print_instr ) printf("idivlu; ");
            {
                jit_value_t u = jit_is_pop( j );
                jit_value_t l = jit_is_pop( j );
                jit_value_t r = jit_gen_div( j, l, u );
                jit_is_push( j, r );
            }
            break;

        case opcode_ior:
            if( debug_print_instr ) printf("ior; ");
            //{ int operand = is_pop();	is_push( is_pop() | operand ); }
            jit_binary_op( j, jit_gen_binor );
            break;

        case opcode_iand:
            if( debug_print_instr ) printf("iand; ");
            //{ int operand = is_pop();	is_push( is_pop() & operand ); }
            jit_binary_op( j, jit_gen_binand );
            break;

        case opcode_ixor:
            if( debug_print_instr ) printf("ixor; ");
            //{ int operand = is_pop();	is_push( is_pop() ^ operand ); }
            jit_binary_op( j, jit_gen_binxor );
            break;

        case opcode_inot:
            if( debug_print_instr ) printf("inot; ");
            jit_unary_op( j, jit_gen_binnot );
            break;



        case opcode_log_or:
            if( debug_print_instr ) printf("lor; ");
            jit_binary_op( j, jit_gen_logor );
            break;

        case opcode_log_and:
            if( debug_print_instr ) printf("land; ");
            jit_binary_op( j, jit_gen_logand );
            break;

        case opcode_log_xor:
            if( debug_print_instr ) printf("lxor; ");
            jit_binary_op( j, jit_gen_logxor );
            break;

        case opcode_log_not:
            if( debug_print_instr ) printf("lnot; ");
            jit_unary_op( j, jit_gen_lognot );
            break;


        case opcode_ige:	// >=
            if( debug_print_instr ) printf("ige; ");
            jit_binary_op( j, jit_gen_ige );
            break;
        case opcode_ile:	// <=
            if( debug_print_instr ) printf("ile; ");
            jit_binary_op( j, jit_gen_ile );
            break;
        case opcode_igt:	// >
            if( debug_print_instr ) printf("igt; ");
            jit_binary_op( j, jit_gen_igt );
            break;
        case opcode_ilt:	// <
            if( debug_print_instr ) printf("ilt; ");
            jit_binary_op( j, jit_gen_ilt );
            break;



        case opcode_i2o:
            if( debug_print_instr ) printf("i2o; ");
            jit_push_arg( j, jit_is_pop( j ) );
            jit_os_push( j, jit_gen_call( j, JIT_F_CREATE_INT_OBJ ) );
            break;

        case opcode_o2i:
            if( debug_print_instr ) printf("o2i; ");
            {
                jit_is_push( j, jit_o2int( j, jit_os_pop( j ) ) );// push AX
                //jit_refdec( j ); // TODO jit_o2int must refdec?
            }
            break;


        case opcode_os_eq:
            if( debug_print_instr ) printf("os eq; ");
            {
                jit_value_t v1 = jit_os_pop( j );
                jit_value_t v2 = jit_os_pop( j );

                jit_is_push( j, jit_gen_cmp( j, v1, v2 ) );

                jit_refdec( j, v1 );
                jit_refdec( j, v2 );

                break;
            }

        case opcode_os_neq:
            if( debug_print_instr ) printf("os neq; ");
            {
                jit_value_t v1 = jit_os_pop( j );
                jit_value_t v2 = jit_os_pop( j );

                jit_is_push( j, jit_gen_lognot( j, jit_gen_cmp( j, v1, v2 )) );

                jit_refdec( j, v1 );
                jit_refdec( j, v2 );

                break;
            }

        case opcode_os_isnull:
            if( debug_print_instr ) printf("isnull; ");
            {
                jit_value_t o1 = jit_os_pop( j );
                jit_is_push( j, jit_is_null( j, o1 ) );
                jit_refdec( j, o1 );
                break;
            }

        case opcode_os_push_null:
        case opcode_summon_null:
            if( debug_print_instr ) printf("push null; ");
            {
                jit_os_push( j, jit_get_null( j ) );
                break;
            }

            // summoning, special ----------------------------------------------------

        case opcode_summon_thread:
            if( debug_print_instr ) printf("summon thread; ");
            jit_os_push( j, jit_get_thread( j ) );
            break;

        case opcode_summon_this:
            if( debug_print_instr ) printf("summon this; ");
            jit_os_push( j, jit_refinc( j, jit_get_this( j ) ) );
            break;

        case opcode_summon_class_class:
            if( debug_print_instr ) printf("summon class class; ");
            jit_os_push( j, jit_get_class_class( j ) );
            break;

        case opcode_summon_interface_class:
            if( debug_print_instr ) printf("summon interface class; ");
            // locked refcnt
            jit_os_push( j, jit_get_iface_class( j ) );
            break;

        case opcode_summon_code_class:
            if( debug_print_instr ) printf("summon code class; ");
            // locked refcnt
            jit_os_push( j, jit_get_code_class( j ) );
            break;

        case opcode_summon_int_class:
            if( debug_print_instr ) printf("summon int class; ");
            // locked refcnt
            jit_os_push( j, jit_get_int_class( j ) );
            break;

        case opcode_summon_string_class:
            if( debug_print_instr ) printf("summon string class; ");
            // locked refcnt
            jit_os_push( j, jit_get_string_class( j ) );
            break;

        case opcode_summon_array_class:
            if( debug_print_instr ) printf("summon array class; ");
            // locked refcnt
            jit_os_push( j, jit_get_array_class( j ) );
            break;

            // TODO we can turn class to const, but the we have to keep refcount for it in
            // const space and release when we release compiled code
            // TODO const list is just an array? easy to release all

        case opcode_summon_by_name:
            {
                if( debug_print_instr ) printf("summon by name; ");

                struct pvm_object name = pvm_code_get_string(code);
                struct pvm_object cl = pvm_exec_lookup_class_by_name( name ); // TODO XXX must inc ref
                ref_dec_o(name);

                // Need throw here?

                if( pvm_is_null( cl ) ) {
                    printf("JIT: summon by name: null class\n");
                    return ENOENT;

                    // TODO XXX generate summon in run time?

                }
                int cid = jit_alloc_const( j, cl );
                jit_os_push( j, jit_get_const( j, cid ) );

            }
            break;

            /**
             * A BIG NOTE for object creation
             *
             * We must be SURE that it is NOT ever possible to pass
             * non-internal object as init data to internal and vice versa!
             * It would be a securily hole!
             *
             **/


        case opcode_new:
            if( debug_print_instr ) printf("new; ");
            {
                //pvm_object_t cl = os_pop();
                //os_push( pvm_create_object( cl ) );
                //ref_dec_o( cl );  // object keep class ref

                jit_os_pop( j );// pop AX, DX
                jit_os_push( j, jit_gen_call( j, JIT_F_CREATE_OBJ ) );// push AX, DX
            }
            break;

        case opcode_copy:
            if( debug_print_instr ) printf("copy; ");
            {
                jit_push_arg( j, jit_os_pop( j ) );
                jit_os_push( j, jit_gen_call( j, JIT_F_COPY_OBJ ) );
                // jit_refdec( j, JIT_R_CX ); XXX TODO need?
            }
            break;

            // if you want to enable these, work out refcount
            // and security issues first!
            // compose/decompose
#if 0
        case opcode_os_compose32:
            if( debug_print_instr ) printf(" compose32; ");
            {
                int num = pvm_code_get_int32(code);
                struct pvm_object in_class = os_pop();
                os_push( pvm_exec_compose_object( in_class, da->_ostack, num ) );
            }
            break;

        case opcode_os_decompose:
            if( debug_print_instr ) printf(" decompose; ");
            {
                struct pvm_object to_decomp = os_pop();
                int num = da_po_limit(to_decomp.data);
                is_push( num );
                while( num )
                {
                    num--;
                    struct pvm_object o = pvm_get_ofield( to_decomp, num);
                    os_push( ref_inc_o( o ) );
                }
                os_push(to_decomp.data->_class);
            }
            break;
#endif
            // string ----------------------------------------------------------------

        case opcode_sconst_bin:
            if( debug_print_instr ) printf("sconst bin; ");
            //os_push(pvm_code_get_string(code));
            {
                int constid = jit_alloc_const( j, pvm_code_get_string( code ) );
                jit_os_push( j, jit_get_const( j, constid ) );
            }
            break;


            // flow ------------------------------------------------------------------

        case opcode_jmp:
            {
                int newip = pvm_code_get_rel_IP_as_abs(code);
                if( debug_print_instr ) printf("jmp %d; ", newip );
                //da->code.IP = pvm_code_get_rel_IP_as_abs(code);
                jit_jump( j, newip );
            }
            break;


        case opcode_djnz:
            {
                if( debug_print_instr ) printf("djnz " );
                int newip = pvm_code_get_rel_IP_as_abs(code);

                //is_push( is_pop() - 1 );
                jit_decrement( j, jit_is_top(j) );
                jit_jnz( j, newip, jit_is_top(j) );

                //if( debug_print_instr ) printf("(%d) -> %d; ", is_top() , new_IP );
            }
            break;

        case opcode_jz:
            {
                if( debug_print_instr ) printf("jz " );
                int newip = pvm_code_get_rel_IP_as_abs(code);
                jit_jz( j, newip, jit_is_pop(j) );
            }
            break;


        case opcode_switch:
            {
#warning impl
                /*
                if( debug_print_instr ) printf("switch ");
                unsigned int tabsize    = pvm_code_get_int32(code);
                int shift               = pvm_code_get_int32(code);
                unsigned int divisor    = pvm_code_get_int32(code);
                int stack_top = is_pop();

                if( debug_print_instr ) printf("(%d+%d)/%d, ", stack_top, shift, divisor );


                unsigned int start_table_IP = da->code.IP;
                unsigned int displ = (stack_top+shift)/divisor;
                unsigned int new_IP = start_table_IP+(tabsize*4); // default

                if( debug_print_instr ) printf("displ %d, etab addr %d ", displ, new_IP );


                if( displ < tabsize )
                {
                    da->code.IP = start_table_IP+(displ*4); // BUG! 4!
                    if( debug_print_instr ) printf("load from %d, ", da->code.IP );
                    new_IP = pvm_code_get_rel_IP_as_abs(code);
                }
                da->code.IP = new_IP;

                if( debug_print_instr ) printf("switch(%d) ->%d; ", displ, new_IP );
                */
                printf("no switch yet");
                return ENXIO;
            }
            break;


        case opcode_ret:
            {
                if( debug_print_instr ) printf( "\nret\n" );
                jit_ret(j);
            }
            break;

            // exceptions are like ret ---------------------------------------------------

        case opcode_throw:
            if( debug_print_instr ) printf( "\nthrow\n" );
            jit_throw(j, jit_os_pop(j) );
            break;

        case opcode_push_catcher:
            {
                unsigned addr = pvm_code_get_rel_IP_as_abs(code);
                if( debug_print_instr ) printf("push catcher %u; ", addr );
                jit_es_push( j, jit_os_pop(j), addr );
            }
            break;

        case opcode_pop_catcher:
            if( debug_print_instr ) printf("pop catcher; ");
            jit_refdec( j, jit_es_pop(j) );
            break;

            // ok, now method calls ------------------------------------------------------

            // these 4 are parameter-less calls!
        case opcode_short_call_0:
            jit_os_push( j, jit_call_method( j, 0, 0, 1) );
            break;
        case opcode_short_call_1:
            jit_os_push( j, jit_call_method( j, 1, 0, 1) );
            break;
        case opcode_short_call_2:
            jit_os_push( j, jit_call_method( j, 2, 0, 1) );
            break;
        case opcode_short_call_3:
            jit_os_push( j, jit_call_method( j, 3, 0, 1) );
            break;

        case opcode_call_8bit:
            {
                unsigned int method_index = pvm_code_get_byte(code);
                unsigned int n_param = pvm_code_get_int32(code);
                jit_os_push( j, jit_call_method( j, method_index, n_param, 1) ); // optimization for soon return
            }
            break;
        case opcode_call_32bit:
            {
                unsigned int method_index = pvm_code_get_int32(code);
                unsigned int n_param = pvm_code_get_int32(code);
                jit_os_push( j, jit_call_method( j, method_index, n_param, 1) ); // optimization for soon return
            }
            break;


            // object stack --------------------------------------------------------------

        case opcode_os_dup:
            if( debug_print_instr ) printf("os dup; ");
            jit_os_push( j, jit_refinc( j, jit_os_top( j ) ) );
            break;

        case opcode_os_drop:
            if( debug_print_instr ) printf("os drop; ");
            jit_refdec( j, jit_os_pop( j ) );
            break;

        case opcode_os_pull32:
            if( debug_print_instr ) printf("os pull; ");
            {
                int pos = pvm_code_get_int32(code);
                jit_os_push( j, jit_refinc( j, jit_os_pull( j, pos ) )  ); // TODO XXX load must refinc!
            }
            break;

        case opcode_os_load8:
            {
                int slot = pvm_code_get_byte(code);
                jit_os_push( j, jit_os_load( j, slot ) ); // TODO XXX load must refinc!
            }
            break;

        case opcode_os_load32:
            {
                int slot = pvm_code_get_int32(code);
                jit_os_push( j, jit_os_load( j, slot ) ); // TODO XXX load must refinc!
                break;
            }

        case opcode_os_save8:
            {
                int slot = pvm_code_get_byte(code);
                jit_os_save( j, slot, jit_os_pop( j ) );
            }
            break;

        case opcode_os_save32:
            {
                int slot = pvm_code_get_int32(code);
                jit_os_save( j, slot, jit_os_pop( j ) );
            }
            break;

        case opcode_is_load8:
            //pvm_exec_iload(da, pvm_code_get_byte(code));
            {
                int slot = pvm_code_get_byte(code);
                jit_value_t ov = jit_os_load( j, slot );
                jit_value_t iv = jit_o2int( j, ov ); // TODO XXX jit_o2int must gen refdec
                jit_is_push( j, iv );
            }
            break;

        case opcode_is_save8:
            {
                int slot = pvm_code_get_byte(code);
                jit_push_arg( j, jit_is_pop( j ) ); // TODO arg is int?
                // pvm_create_int_object
                jit_os_save( j, slot, jit_gen_call( j, JIT_F_CREATE_INT_OBJ ) );
            }
            break;

        case opcode_os_get32:
            {
                int pos = pvm_code_get_int32(code);
                jit_value_t v = jit_os_absget( j, pos ); // AX, DX = obj
                //jit_refinc( j, v ); // TODO XXX must not be needed - absget must inc!
                jit_os_push( j, v );
            }
            break;

        case opcode_os_set32:
            {
                int pos = pvm_code_get_int32(code);
                jit_os_absset( j, pos, jit_os_pop( j ) );
            }
            break;

        case opcode_is_get32:
            {
                int pos = pvm_code_get_int32(code);
                jit_is_push( j, jit_is_absget( j, pos ) );
            }
            break;
        case opcode_is_set32:
            {
                int pos = pvm_code_get_int32(code);
                jit_is_absset( j, pos, jit_is_pop( j ) );
            }
            break;

        default:
            if( (instruction & 0xF0 ) == opcode_sys_0 )
            {
                jit_sys( j, instruction & 0x0F);
                /*
    sys_sleep:
                // Only sys can put thread asleep
                // If we are snapped here we, possibly, will continue from
                // the entry to this func. So save fasc acc and recheck
                // sleep condition on the func entry.
                if(da->sleep_flag)
                {
                    pvm_exec_save_fast_acc(da); // Before snap
                    phantom_thread_sleep_worker( da );
                }
                break;
                */
            }

            if( instruction  == opcode_sys_8bit )
            {
                jit_sys( j, pvm_code_get_byte(code)); 
                //goto sys_sleep;
                break;
            }

            if( (instruction & 0xE0 ) == opcode_call_00 )
            {
                unsigned int n_param = pvm_code_get_byte(code);
                jit_os_push( j, jit_call_method( j, instruction & 0x1F, n_param, 0) ); //no optimization for soon return
                break;
            }

            printf("JIT: Unknown op code 0x%X\n", instruction );

            return ENOENT;
        }
    }
}
コード例 #21
0
ファイル: rpn.c プロジェクト: pcpa/lightning
/* This function does all of lexing, parsing, and picking a good
   order of evaluation...  Needless to say, this is not the best
   possible design, but it avoids cluttering everything with globals. */
pifi
compile_rpn (char *expr)
{
  struct stack_element stack[32];
  int sp = 0;
  int curr_tos = -1;		/* stack element currently in R0 */
  int spill_base, spill_sp;

  pifi fn;
  int ofs;
  fn = (pifi) (jit_get_ip ().iptr);
  jit_leaf (1);
  ofs = jit_arg_i ();

  spill_sp = spill_base = jit_allocai (32 * sizeof (int));

  while (*expr)
    {
      int with_imm;
      int imm;
      int tok;
      int src1, src2;

      /* This is the lexer.  */
      switch (*expr)
	{
	case ' ': case '\t':
	  expr++;
	  continue;

	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
	  stack[sp].kind = IMM;
	  stack[sp++].imm = strtol (expr, &expr, 0);
	  continue;

	case 'x':
	  expr++;
	  stack[sp++].kind = ARG;
	  continue;

	case '~':
	  /* NOT.  Implemented as a XOR with -1.  */
	  stack[sp].kind = IMM;
	  stack[sp++].imm = ~0;
	  tok = '^';
	  break;

	case '_':
	  /* Unary minus.  Transform to 0 - X and go on.
	     Also used to enter negative constants (32_ = -32).  */
	  expr++;
	  stack[sp] = stack[sp - 1];

	  /* Ensure CURR_TOS is correct.  */
	  if (curr_tos == sp - 1)
	    curr_tos = sp;

	  stack[sp - 1].kind = IMM;
	  stack[sp - 1].imm = 0;
	  sp++;
	  tok = '-';
	  break;

	case '+':
	case '-':
	case '*':
	case '/':
	case '%':
	case '&':
	case '|':
	case '^':
	case '=':
	  tok = *expr++;
	  break;

	case '!':
	  /* Get != */
	  expr++;
	  assert (*expr == '=');
	  tok = NE;
	  break;

	case '<':
	  /* Get <, <<, <= */
	  if (expr[1] == '=')
	    expr += 2, tok = LE;
	  else if (expr[1] == '<')
	    expr += 2, tok = LSH;
	  else
	    expr++, tok = '<';
	  break;

	case '>':
	  /* Get >, >>, >>>, >= */
	  if (expr[1] == '=')
	    expr += 2, tok = GE;
	  else if (expr[1] == '>' && expr[2] == '>')
	    expr += 3, tok = RSHU;
	  else if (expr[1] == '>')
	    expr += 2, tok = RSH;
	  else
	    expr++, tok = '>';
	  break;

	default:
	  abort ();
	}

      assert (sp >= 2);

      /* Constant folding.  */
      if (stack[sp - 1].kind == IMM && stack[sp - 2].kind == IMM)
	{
	  stack[sp - 2].imm =
	    fold (stack[sp - 2].imm, stack[sp - 1].imm, tok);
	  sp--;
	  continue;
	}

      /* If possible, ensure that the constant is the RHS, possibly
	 by changing TOK (if it is a comparison).  */
      if (stack[sp - 2].kind == IMM)
	{
	  int swapped_operation = swap_op (tok);
          if (swapped_operation)
	    {
	      tok = swapped_operation;
	      stack[sp - 2].kind = stack[sp - 1].kind;
	      stack[sp - 1].kind = IMM;
	      stack[sp - 1].imm = stack[sp - 2].imm;

	      /* Ensure CURR_TOS is correct.  */
	      if (curr_tos == sp - 1)
	        curr_tos = sp - 2;
	    }
        }

      /* Get the second argument into a register, if not an immediate.
         Also decide which argument will be prepared into JIT_R0 and
         which will be prepared into JIT_V0.  */
      with_imm = 0;
      src1 = JIT_R0;
      src2 = JIT_V0;
      switch (stack[sp - 1].kind)
	{
	case IMM:
	  /* RHS is an immediate, use an immediate instruction.  */
	  with_imm = 1;
	  imm = stack[sp - 1].imm;
	  break;

	case EXPR:
	  /* RHS is an expression, check if it is already in JIT_R0.  */
	  if (curr_tos == sp - 1)
	    {
	      /* Invert the two sources.  */
	      src1 = JIT_V0;
	      src2 = JIT_R0;
	    }
	  else
	    popr (JIT_V0, &spill_sp);

	  curr_tos = -1;
	  break;

	case ARG:
	  jit_getarg_i (JIT_V0, ofs);
	  break;
	}

      /* Get the first argument into a register indicated by SRC1.  */
      switch (stack[sp - 2].kind)
	{
	case IMM:
	  /* LHS is an immediate, check if we must spill the top of stack.  */
	  if (curr_tos != -1)
	    {
	      pushr (JIT_R0, &spill_sp);
	      curr_tos = -1;
	    }

	  jit_movi_i (src1, stack[sp - 2].imm);
	  break;

	case EXPR:
	  /* LHS is an expression, check if it is already in JIT_R0.  */
	  if (curr_tos != sp - 2)
	    {
	      popr (src1, &spill_sp);
	      curr_tos = -1;
	    }
	  else
	    assert (src1 == JIT_R0);
	  break;

	case ARG:
	  if (curr_tos != -1)
	    {
	      pushr (JIT_R0, &spill_sp);
	      curr_tos = -1;
	    }

	  jit_getarg_i (src1, ofs);
	  break;
	}

      /* Set up the new stack entry, which is cached in R0.  */
      sp -= 2;
      curr_tos = sp;
      stack[sp++].kind = EXPR;

      /* Perform the computation.  */
      if (with_imm)
	gen_reg_imm (src1, imm, tok);
      else
	gen_reg_reg (src1, src2, tok);
    }

  assert (sp == 1);
  switch (stack[0].kind)
    {
    case IMM:
      jit_movi_i (JIT_RET, stack[0].imm);
      break;

    case EXPR:
      assert (curr_tos == 0);
      jit_movr_i (JIT_RET, JIT_R0);
      break;

    case ARG:
      jit_getarg_i (JIT_V0, ofs);
      break;
    }

  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;
}
コード例 #22
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();
}
コード例 #23
0
ファイル: lightning.c プロジェクト: rdebath/Brainfuck
void
outrun(int ch, int count)
{
    jit_node_t    *argp;

    switch(ch) {
    case '!':
	if (bytecell) tape_step = 1; else
	tape_step = sizeof(int);

        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);
	break;

    case '~':
	jit_ret();
	jit_epilog();
	end = jit_note(__FILE__, __LINE__);
	codeptr = jit_emit();
	jit_clear_state();
	codeptr(calloc(tape_step, tapelen));
	jit_destroy_state();
	finish_jit();
	codeptr = 0;
	if (loopstack) { free(loopstack); loopstack = 0; }
	break;

    case '>':
	jit_addi(REG_P, REG_P, count * tape_step);
	break;

    case '<':
	jit_subi(REG_P, REG_P, count * tape_step);
	break;

    case '+':
	if (tape_step>1)
	    jit_ldr_i(REG_ACC, REG_P);
	else
	    jit_ldr_uc(REG_ACC, REG_P);
	jit_addi(REG_ACC, REG_ACC, count);
	if (tape_step>1)
	    jit_str_i(REG_P, REG_ACC);
	else
	    jit_str_c(REG_P, REG_ACC);
	break;

    case '-':
	if (tape_step>1)
	    jit_ldr_i(REG_ACC, REG_P);
	else
	    jit_ldr_uc(REG_ACC, REG_P);
	jit_subi(REG_ACC, REG_ACC, count);
	if (tape_step>1)
	    jit_str_i(REG_P, REG_ACC);
	else
	    jit_str_c(REG_P, REG_ACC);
	break;

    case '[':
	if (tape_step>1)
	    jit_ldr_i(REG_ACC, REG_P);
	else
	    jit_ldr_uc(REG_ACC, REG_P);

	if (stackptr >= maxstack) {
	    loopstack = realloc(loopstack,
			((maxstack+=32)+2)*sizeof(*loopstack));
	    if (loopstack == 0) {
		perror("loop stack realloc failure");
		exit(1);
	    }
	}

	loopstack[stackptr] = jit_beqi(REG_ACC, 0);
	loopstack[stackptr+1] = jit_label();
	stackptr += 2;
	break;

    case ']':
	if (tape_step>1)
	    jit_ldr_i(REG_ACC, REG_P);
	else
	    jit_ldr_uc(REG_ACC, REG_P);

	stackptr -= 2;
	if (stackptr < 0) {
	    fprintf(stderr, "Code gen failure: Stack pointer negative.\n");
	    exit(1);
	}

	{
	    jit_node_t *ref;
	    ref = jit_bnei(REG_ACC, 0);
	    jit_patch_at(ref, loopstack[stackptr+1]);
	    jit_patch(loopstack[stackptr]);
	}
	break;

    case '.':
	if (tape_step>1)
	    jit_ldr_i(REG_ACC, REG_P);
	else
	    jit_ldr_uc(REG_ACC, REG_P);

	jit_prepare();
	jit_pushargr(REG_ACC);
	jit_finishi(putchar);
	break;

    case ',':
	jit_prepare();
	jit_pushargr(REG_ACC);
	jit_finishi(getchar);
	jit_retval(REG_ACC);

	if (tape_step>1)
	    jit_str_i(REG_P, REG_ACC);
	else
	    jit_str_c(REG_P, REG_ACC);

	break;
    }
}
コード例 #24
0
ファイル: jit_sparc.c プロジェクト: 8l/bomberjacket
void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
{
    jit_movi_d(JIT_FRET, u);
    jit_ret();
}
コード例 #25
0
ファイル: compiler_x64_hosted.c プロジェクト: rvedam/interim
int compile_for_platform(Cell* expr, Cell** res) {
  jit_out = fopen("/tmp/jit_out.s","w");
  
  jit_init();
  
  register void* sp asm ("sp");
  Frame empty_frame = {NULL, 0, 0, sp};
  int success = compile_expr(expr, &empty_frame, TAG_ANY);
  jit_ret();

  if (!success) {
    printf("<compile_expr failed: %d>\r\n",success);
  }

  if (success) {
    int codesz = 1024;
    fclose(jit_out);

    struct stat src_stat;
    stat("/tmp/jit_out.s", &src_stat);
    off_t generated_sz = src_stat.st_size;

    FILE* asm_f = fopen("/tmp/jit_out.s","r");
    uint32_t* jit_asm = malloc(generated_sz);
    memset(jit_asm,0,generated_sz);
    fread(jit_asm,1,generated_sz,asm_f);
    fclose(asm_f);
        
#ifdef DEBUG
    printf("\nJIT ---------------------\n%s-------------------------\n\n",jit_asm);
#endif
    free(jit_asm);
        
    // prefix with arm-none-eabi- on ARM  -mlittle-endian
    
    system("as -L /tmp/jit_out.s -o /tmp/jit_out.o");
#if defined(__APPLE__) && defined(__MACH__)
    system("gobjcopy /tmp/jit_out.o -O binary /tmp/jit_out.bin");
#else
    system("objcopy /tmp/jit_out.o -O binary /tmp/jit_out.bin");
#endif

    stat("/tmp/jit_out.bin", &src_stat);
    
    generated_sz = src_stat.st_size;
    while (generated_sz>codesz) {
      codesz*=2;
      printf ("<compiler: doubling code block size to %d>\r\n",codesz);
    }
    
    FILE* binary_f = fopen("/tmp/jit_out.bin","r");
    
    uint32_t* jit_binary = mmap(0, codesz, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
    
    int bytes_read = fread(jit_binary,1,codesz,binary_f);
    fclose(binary_f);

#ifdef DEBUG
    printf("<assembled bytes: %d at: %p>\n",bytes_read,jit_binary);
    char cmd[256];
    sprintf(cmd,"cp /tmp/jit_out.o /tmp/jit_%p.o",jit_binary);
    system(cmd);
    sprintf(cmd,"cp /tmp/jit_out.s /tmp/jit_%p.s",jit_binary);
    system(cmd);
#endif

    if (bytes_read>codesz) {
      printf("<error: max assembly size of %d exhausted. aborting>\n",codesz);
      munmap(jit_binary,codesz);
      return 0;
    }

    // read symbols for linking lambdas
#if defined(__APPLE__) && defined(__MACH__)
    system("gnm /tmp/jit_out.o > /tmp/jit_out.syms 2> /dev/null");
#else
    system("nm /tmp/jit_out.o > /tmp/jit_out.syms");
#endif
    FILE* link_f = fopen("/tmp/jit_out.syms","r");
    if (link_f) {
      char* link_line=malloc(128);
      while(fgets(link_line, 128, link_f)) {

        if (strlen(link_line)>22) {
          char ida=link_line[19];
          char idb=link_line[20];
          char idc=link_line[21];
          //printf("link_line: %s %c %c %c\n",link_line,ida,idb,idc);

          if (ida=='L' && idc=='_') {
            Cell* lambda = (Cell*)strtoul(&link_line[24], NULL, 16);
            if (idb=='0') {
              // function entrypoint
              // TODO: 64/32 bit
              unsigned long long offset = strtoul(link_line, NULL, 16);
              void* binary = ((uint8_t*)jit_binary) + offset;
              //printf("function %p entrypoint: %p (+%ld)\n",lambda,binary,offset);

              if (lambda->tag == TAG_LAMBDA) {
                lambda->dr.next = binary;
              } else {
                printf("fatal error: no lambda found at %p!\n",lambda);
              }
            }
            else if (idb=='1') {
              // function exit
              unsigned long long offset = strtoul(link_line, NULL, 16);
              //printf("function exit point: %p\n",offset);
            }
          }
        }
      }
      free(link_line);
    }

    int mp_res = mprotect(jit_binary, codesz, PROT_EXEC|PROT_READ);
    
    if (!mp_res) {
      *res = execute_jitted(jit_binary);
      success = 1;
    } else {
      printf("<mprotect result: %d\n>",mp_res);
      *res = NULL;
      success = 0;
    }
  }
  return success;
}
コード例 #26
0
ファイル: jit_sparc.c プロジェクト: 8l/bomberjacket
void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
{
    jit_movi_f(JIT_FRET, u);
    jit_ret();
}
コード例 #27
0
ファイル: jit_sparc.c プロジェクト: 8l/bomberjacket
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
{
    jit_movi(JIT_RET, u);
    jit_ret();
}