int build_code(Dst_DECL)
{
  int ret = 0;
  size_t codesz = 0;
  uint8_t* code = NULL;

  int nglob = GLOB_MAX;
  void **glob = (void **)malloc(nglob*sizeof(void *));
  memset(glob, 0, nglob*sizeof(void *));

  dasm_init(Dst, DASM_MAXSECTION);
  dasm_setupglobal(Dst, glob, nglob);
  dasm_setup(Dst, build_actionlist);

  (void)create_backend(Dst);

  /* Finalize */
  (void)dasm_checkstep(Dst, -1); /* sanity check */
  if((ret = dasm_link(Dst, &codesz))) return ret;
  code = (uint8_t *)pa_malloc(codesz, true);
  if((ret = dasm_encode(Dst, (void *)code))) return ret;

  //write_raw("debug.out", code, codesz);

  dasm_gen_func fp = (dasm_gen_func)code;
  ret = fp();

  printf("generated function return value = %d\n",ret);

  dasm_free(Dst);
  free(glob);
  free(code);
  return 0;
}
Exemple #2
0
static jitcompiler *newjitcompiler(mgroup *group) {
  jitcompiler *jc = malloc(sizeof(jitcompiler));
  jc->group = group;
  jc->pclabel_count = 0;
  jc->lastlabelofs = -1;
  upb_inttable_init(&jc->pclabels, UPB_CTYPE_UINT32);
  upb_inttable_init(&jc->pcdefined, UPB_CTYPE_BOOL);
  upb_inttable_init(&jc->asmlabels, UPB_CTYPE_PTR);
  jc->globals = malloc(UPB_JIT_GLOBAL__MAX * sizeof(*jc->globals));

  dasm_init(jc, 1);
  dasm_setupglobal(jc, jc->globals, UPB_JIT_GLOBAL__MAX);
  dasm_setup(jc, upb_jit_actionlist);

  return jc;
}
Exemple #3
0
/* Build the machine code. */
static int build_code(BuildCtx *ctx)
{
  int status;
  int i;

  /* Initialize DynASM structures. */
  ctx->nglob = GLOB__MAX;
  ctx->glob = (void **)malloc(ctx->nglob*sizeof(void *));
  memset(ctx->glob, 0, ctx->nglob*sizeof(void *));
  ctx->nreloc = 0;

  ctx->globnames = globnames;
  ctx->relocsym = (const char **)malloc(NRELOCSYM*sizeof(const char *));
  ctx->nrelocsym = 0;
  for (i = 0; i < (int)NRELOCSYM; i++) relocmap[i] = -1;

  ctx->dasm_ident = DASM_IDENT;
  ctx->dasm_arch = DASM_ARCH;

  dasm_init(Dst, DASM_MAXSECTION);
  dasm_setupglobal(Dst, ctx->glob, ctx->nglob);
  dasm_setup(Dst, build_actionlist);

  /* Call arch-specific backend to emit the code. */
  ctx->npc = build_backend(ctx);

  /* Finalize the code. */
  (void)dasm_checkstep(Dst, -1);
  if ((status = dasm_link(Dst, &ctx->codesz))) return status;
  ctx->code = (uint8_t *)malloc(ctx->codesz);
  if ((status = dasm_encode(Dst, (void *)ctx->code))) return status;

  /* Allocate symbol table and bytecode offsets. */
  ctx->beginsym = sym_decorate(ctx, "", LABEL_PREFIX "vm_asm_begin");
  ctx->sym = (BuildSym *)malloc((ctx->npc+ctx->nglob+1)*sizeof(BuildSym));
  ctx->nsym = 0;
  ctx->bc_ofs = (int32_t *)malloc(ctx->npc*sizeof(int32_t));

  /* Collect the opcodes (PC labels). */
  for (i = 0; i < ctx->npc; i++) {
    int32_t ofs = dasm_getpclabel(Dst, i);
    if (ofs < 0) return 0x22000000|i;
    ctx->bc_ofs[i] = ofs;
    if ((LJ_HASJIT ||
	 !(i == BC_JFORI || i == BC_JFORL || i == BC_JITERL || i == BC_JLOOP ||
	   i == BC_IFORL || i == BC_IITERL || i == BC_ILOOP)) &&
	(LJ_HASFFI || i != BC_KCDATA))
      sym_insert(ctx, ofs, LABEL_PREFIX_BC, bc_names[i]);
  }

  /* Collect the globals (named labels). */
  for (i = 0; i < ctx->nglob; i++) {
    const char *gl = globnames[i];
    int len = (int)strlen(gl);
    if (!ctx->glob[i]) {
      fprintf(stderr, "Error: undefined global %s\n", gl);
      exit(2);
    }
    /* Skip the _Z symbols. */
    if (!(len >= 2 && gl[len-2] == '_' && gl[len-1] == 'Z'))
      sym_insert(ctx, (int32_t)((uint8_t *)(ctx->glob[i]) - ctx->code),
		 LABEL_PREFIX, globnames[i]);
  }

  /* Close the address range. */
  sym_insert(ctx, (int32_t)ctx->codesz, "", "");
  ctx->nsym--;

  dasm_free(Dst);

  return 0;
}
Exemple #4
0
static bfprogram bf_compile(const char* program) {
    unsigned int loops[MAX_NESTING];
    int nloops = 0;
    int n;
//    int nskip = 0;
//    uchar* tape_begin = state->tape;
//   uchar* ptr = state->tape;
//    uchar* tape_end = state->tape + TAPE_SIZE - 1;

    dasm_State* d;
    unsigned int npc = 8;
    unsigned int nextpc = 0;

    //|.arch a64
#if DASM_VERSION != 10300
#error "Version mismatch between DynASM and included encoding engine"
#endif

    //|.section code
#define DASM_SECTION_CODE	0
#define DASM_MAXSECTION		1

    dasm_init(&d, DASM_MAXSECTION);

    //|.globals bf_
enum {
  bf_main,
  bf__MAX
};
    void* labels[bf__MAX];
    dasm_setupglobal(&d, labels, bf__MAX);

    //|.actionlist bf_actions
static const unsigned int bf_actions[87] = {
0x00010000,
0x00060014,
0xd10103ff,
0xa90053f3,
0xa9015bf5,
0xa90263f7,
0xf9001bfe,
0xaa0003f4,
0xf9400293,
0x00090d8a,
0xaa1303f5,
0x90000017,
0x000f0001,
0x8b170276,
0x00000000,
0x90000017,
0x000f0001,
0x8b170273,
0xeb16027f,
0x54000009,
0x00053001,
0x90000017,
0x000f0001,
0xcb170273,
0x0006000b,
0x00000000,
0x90000017,
0x000f0001,
0xcb170273,
0xeb15027f,
0x54000002,
0x00053001,
0x90000017,
0x000f0001,
0x8b170273,
0x0006000b,
0x00000000,
0x39400277,
0x00020000,
0x00000018,
0x000f0000,
0x0b1802f7,
0x39000277,
0x00000000,
0x39400277,
0x00020000,
0x00000018,
0x000f0000,
0x4b1802f7,
0x39000277,
0x00000000,
0xaa1403e0,
0xf9400297,
0x00090d8a,
0xd63f02e0,
0x39000260,
0x00000000,
0x39400261,
0xaa1403e0,
0xf9400297,
0x00090d8a,
0xd63f02e0,
0x00000000,
0x00020000,
0x00000017,
0x000f0000,
0x39000277,
0x00000000,
0x39400277,
0x710002ff,
0x54000000,
0x00073000,
0x00080000,
0x00000000,
0x39400277,
0x710002ff,
0x54000001,
0x00073000,
0x00080000,
0x00000000,
0xa94053f3,
0xa9415bf5,
0xa94263f7,
0xf9401bfe,
0x910103ff,
0xd65f03c0,
0x00000000
};

    dasm_setup(&d, bf_actions);

    dasm_growpc(&d, npc);

    //|.define aPtr, x19
    //|.define aState, x20
    //|.define aTapeBegin, x21
    //|.define aTapeEnd, x22
    //|.define TMP, x23
    //|.define TMP1, x24
    //|.define TMPw, w23
    //|.define TMP1w, w24
    //|.define cArg1w, w0
    //|.define cArg2w, w1
    //|.define cRetw, w0
    //|.define cArg1, x0
    //|.define cArg2, x1
    //|.define cRet, x0
    //|.macro prologue
        //| sub sp, sp, #0x40
        //| stp aPtr, aState, [sp]
        //| stp aTapeBegin, aTapeEnd, [sp, #0x10]
        //| stp TMP, TMP1, [sp, #0x20]
        //| str lr, [sp, #0x30]
        //| mov aState, cArg1
    //|.endmacro
    //|.macro epilogue
        //| ldp aPtr, aState, [sp]
        //| ldp aTapeBegin, aTapeEnd, [sp, #0x10]
        //| ldp TMP, TMP1, [sp, #0x20]
        //| ldr lr, [sp, #0x30]
        //| add sp, sp, #0x40
        //| ret
    //|.endmacro

    const char* p = program;

    //|.type bfstate, bf_state_t, aState
#define Dt1(_V) (int)(ptrdiff_t)&(((bf_state_t *)0)_V)

    dasm_State** Dst = &d;
    //|.code
    dasm_put(Dst, 0);
    //|->main:
    //| prologue
    //| ldr aPtr, bfstate->tape
    //| mov aTapeBegin, aPtr
    //| mov TMP, #TAPE_SIZE - 1
    //| add aTapeEnd, aPtr, TMP
    dasm_put(Dst, 1, (long)(Dt1(->tape)), (long)(TAPE_SIZE - 1));
    while (1) {
        switch (*p++) {
        case '>':
            for (n=1; *p == '>'; n++, p++);
            // ptr += n;
            // while (ptr > tape_end)
            //     ptr -= TAPE_SIZE;
            //| mov TMP, #(n%TAPE_SIZE)
            //| add aPtr, aPtr, TMP
            //| cmp aPtr, aTapeEnd
            //| b.ls >1
            //| mov TMP, #TAPE_SIZE
            //| sub aPtr, aPtr, TMP
            //|1:
            dasm_put(Dst, 15, (long)((n%TAPE_SIZE)), (long)(TAPE_SIZE));
            break;
        case '<':
            for (n=1; *p == '<'; n++, p++);
            //ptr -= n;
            //while (ptr < tape_begin)
            //    ptr += TAPE_SIZE;
            //| mov TMP, #(n%TAPE_SIZE)
            //| sub aPtr, aPtr, TMP
            //| cmp aPtr, aTapeBegin
            //| b.hs >1
            //| mov TMP, #TAPE_SIZE
            //| add aPtr, aPtr, TMP
            //|1:
            dasm_put(Dst, 26, (long)((n%TAPE_SIZE)), (long)(TAPE_SIZE));
            break;
        case '+':
            for (n=1; *p == '+'; n++, p++);
            //*ptr += n;
            //| ldrb TMPw, [aPtr]
            //| mov TMP1w, #n
            //| add TMPw, TMPw, TMP1w
            //| strb TMPw, [aPtr]
            dasm_put(Dst, 37, (long)(n));
            break;
        case '-':
            for (n=1; *p == '-'; n++, p++);
            //*ptr -= n;
            //| ldrb TMPw, [aPtr]
            //| mov TMP1w, #n
            //| sub TMPw, TMPw, TMP1w
            //| strb TMPw, [aPtr]
            dasm_put(Dst, 44, (long)(n));
            break;
        case ',':
            //*ptr = state->get_ch(state);
            //| mov cArg1, aState
            //| ldr TMP, bfstate->get_ch
            //| blr TMP
            //| strb cRetw, [aPtr]
            dasm_put(Dst, 51, (long)(Dt1(->get_ch)));
            break;
        case '.':
            //state->put_ch(state, *ptr);
            //| ldrb cArg2w, [aPtr]
            //| mov cArg1, aState
            //| ldr TMP, bfstate->put_ch
            //| blr TMP
            dasm_put(Dst, 57, (long)(Dt1(->put_ch)));
            break;
        case '[':
            if (nloops == MAX_NESTING)
                bad_program("Nesting too deep");
            //if (*ptr) {
            //    loops[nloops++] = p;
            //    break;
            //}
            //nskip = 1;
            //while (nskip > 0) {
            //    switch (*p++) {
            //    case '[': nskip++; break;
            //    case ']': nskip--; break;
            //    case '\0':
            //        bad_program("end of file when there's open '['");
            //        break;
            //    //ignore all other instruction.
            //    }
            //}

            if (p[0] == '-' && p[1] == ']') {
                p += 2;
                //| mov TMPw, #0
                //| strb TMPw, [aPtr]
                dasm_put(Dst, 63, (long)(0));
            } else {
                if (nextpc == npc) {
                    npc *= 2;
                    dasm_growpc(&d, npc);
                }
                //| ldrb TMPw, [aPtr]
                //| cmp TMPw, #0
                //| b.eq =>nextpc + 1
                //|=>nextpc:
                dasm_put(Dst, 68, (long)(nextpc + 1), (long)(nextpc));
                loops[nloops++] = nextpc;
                nextpc += 2;
            }
            break;
        case ']':
            if (nloops <= 0)
                bad_program("] has no matched [");
            //if (*ptr) {
            //    p = loops[nloops-1];
            //} else {
            //    nloops --;
            //}
            --nloops;
            //| ldrb TMPw, [aPtr]
            //| cmp TMPw, #0
            //| b.ne =>loops[nloops]
            //|=>loops[nloops]+1:
            dasm_put(Dst, 74, (long)(loops[nloops]), (long)(loops[nloops]+1));
            break;
        case '\0':
            if (nloops > 0)
                bad_program("end of file where there's open '['");
            // return;
            //| epilogue
            dasm_put(Dst, 80);
            link_and_encode(&d);
            dasm_free(&d);
            return (bfprogram)labels[bf_main];
        //ignore all other instruction.
        }
    }
}
Exemple #5
0
static void _new_env(dasm_State **state, const void *actionlist){
  dasm_init(state, 1);
  dasm_setupglobal(Dst, labels, SPROTO_CODE__MAX);
  dasm_setup(state, actionlist);
  maxpc = 0;
}
SRE_API sre_int_t
sre_vm_thompson_jit_compile(sre_pool_t *pool, sre_program_t *prog,
    sre_vm_thompson_code_t **pcode)
{
#if (SRE_TARGET != SRE_ARCH_X64)
    return SRE_DECLINED;
#else
    int              status;
    size_t           codesz;
    size_t           size;
    unsigned char   *mem;
    dasm_State      *dasm;
    void           **glob;
    unsigned         nglobs = SRE_VM_THOMPSON_GLOB__MAX;

    sre_vm_thompson_code_t      *code;

    glob = sre_pcalloc(pool, nglobs * sizeof(void *));
    if (glob == NULL) {
        return SRE_ERROR;
    }

    dasm_init(&dasm, 1);
    dasm_setupglobal(&dasm, glob, nglobs);
    dasm_setup(&dasm, sre_vm_thompson_jit_actions);

    dd("thread size: %d", (int) sizeof(sre_vm_thompson_thread_t));

    if (sre_vm_thompson_jit_do_compile(&dasm, pool, prog) != SRE_OK) {
        dasm_free(&dasm);
        return SRE_ERROR;
    }

    status = dasm_link(&dasm, &codesz);
    if (status != DASM_S_OK) {
        dasm_free(&dasm);
        return SRE_ERROR;
    }

    size = codesz + sizeof(sre_vm_thompson_code_t);

    dd("size: %d, codesiz: %d", (int) size, (int) codesz);

    mem = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
    if (mem == MAP_FAILED) {
        perror("mmap");
        dasm_free(&dasm);
        return SRE_ERROR;
    }

    code = (sre_vm_thompson_code_t *) mem;

    code->size = size;
    code->handler = (sre_vm_thompson_exec_pt)
        (mem + sizeof(sre_vm_thompson_code_t));

    *pcode = code;

    dasm_encode(&dasm, code->handler);

#if (DDEBUG)
    {
        int              i;
        int              len;
        FILE            *f;
        const char      *gl;

        /*
         * write generated machine code to a temporary file.
         * wiew with objdump or ndisasm
         */
        f = fopen("/tmp/thompson-jit.bin", "wb");
        fwrite(code->handler, codesz, 1, f);
        fclose(f);

        f = fopen("/tmp/thompson-jit.txt", "w");
        fprintf(f, "code section: start=%p len=%lu\n", code->handler,
                (unsigned long) codesz);

        fprintf(f, "global names:\n");

        for (i = 0; i < nglobs; i++) {
            gl = sre_vm_thompson_jit_global_names[i];
            len = (int) strlen(gl);
            if (!glob[i]) {
                continue;
            }
            /* Skip the _Z symbols. */
            if (!(len >= 2 && gl[len-2] == '_' && gl[len-1] == 'Z')) {
                fprintf(f, "  %s => %p\n", gl, glob[i]);
            }
        }

        fprintf(f, "\npc labels:\n");
        for (i = 0; i < dasm->pcsize; i++) {
            int32_t ofs = dasm_getpclabel(&dasm, i);
            if (ofs >= 0) {
                fprintf(f, "  %d => %ld\n", i, (long) ofs);
            }
        }

        fclose(f);
    }
#endif

    dasm_free(&dasm);

    if (mprotect(mem, size, PROT_EXEC | PROT_READ) != 0) {
        (void) munmap(code, code->size);
        return SRE_ERROR;
    }

    dd("code start addr: %p", code->handler);

    return SRE_OK;
#endif /* SRE_TARGET == SRE_ARCH_X64 */
}