Skip to content

Commit

Permalink
Define argument registers
Browse files Browse the repository at this point in the history
  • Loading branch information
bdw committed Aug 18, 2015
1 parent 2390e0a commit 66f2bf8
Show file tree
Hide file tree
Showing 6 changed files with 273 additions and 29 deletions.
188 changes: 176 additions & 12 deletions src/jit/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ void MVM_jit_compiler_init(MVMThreadContext *tc, MVMJitCompiler *cl, MVMJitGraph
cl->dasm_globals = MVM_malloc(num_globals * sizeof(void*));
dasm_setupglobal(cl, cl->dasm_globals, num_globals);
dasm_setup(cl, MVM_jit_actions());
/* space for our dynamic labels */
dasm_growpc(cl, jg->labels_num);
/* Store graph we're compiling */
cl->graph = jg;
/* next (internal) label to assign */
cl->next_label = jg->labels_num;
cl->label_max = jg->labels_num + 8;
/* space for dynamic labels */
dasm_growpc(cl, cl->label_max);
}

void MVM_jit_compiler_deinit(MVMThreadContext *tc, MVMJitCompiler *cl) {
Expand All @@ -43,7 +46,7 @@ MVMJitCode * MVM_jit_compile_graph(MVMThreadContext *tc, MVMJitGraph *jg) {
while (node) {
switch(node->type) {
case MVM_JIT_NODE_LABEL:
MVM_jit_emit_label(tc, &cl, jg, &node->u.label);
MVM_jit_emit_label(tc, &cl, jg, node->u.label.name);
break;
case MVM_JIT_NODE_PRIMITIVE:
MVM_jit_emit_primitive(tc, &cl, jg, &node->u.prim);
Expand Down Expand Up @@ -147,29 +150,190 @@ void MVM_jit_destroy_code(MVMThreadContext *tc, MVMJitCode *code) {
MVM_free(code);
}

/* Compile time labelling facility, as opposed to graph labels; these
* don't need to be stored for access later */
static MVMint32 alloc_internal_label(MVMThreadContext *tc, MVMJitCompiler *cl, MVMint32 num) {
MVMint32 next_label = cl->next_label;
if (num + next_label >= cl->label_max) {
/* Double the compile-time allocated labels */
cl->label_max = cl->graph->labels_num + 2 * (cl->label_max - cl->graph->labels_num);
dasm_growpc(cl, cl->label_max);
}
/* 'Allocate' num labels */
cl->next_label += num;
return next_label;
}


static void prepare_tile(MVMThreadContext *tc, MVMJitTreeTraverser *traverser, MVMJitExprTree *tree, MVMint32 node) {
MVMJitCompiler *cl = traverser->data;
switch (tree->nodes[node]) {
case MVM_JIT_WHEN:
{
MVMint32 cond = tree->nodes[node+1];
tree->info[node].internal_label = alloc_internal_label(tc, cl, 1);
if (tree->nodes[cond] == MVM_JIT_ALL || tree->nodes[cond] == MVM_JIT_ANY) {
/* Assign the label downward for short-circuit evaluation */
tree->info[cond].internal_label = tree->info[node].internal_label;
}
}
break;
case MVM_JIT_IF:
case MVM_JIT_EITHER:
{
MVMint32 cond = tree->nodes[node+1];
tree->info[node].internal_label = alloc_internal_label(tc, cl, 2);
if (tree->nodes[cond] == MVM_JIT_ALL || tree->nodes[cond] == MVM_JIT_ANY) {
/* Assign the label downward for short-circuit evaluation */
tree->info[cond].internal_label = tree->info[node].internal_label;
}
}
break;
default:
break;
}
}

static void compile_labels(MVMThreadContext *tc, MVMJitTreeTraverser *traverser, MVMJitExprTree *tree, MVMint32 node, MVMint32 i) {
MVMJitCompiler *cl = traverser->data;
switch (tree->nodes[node]) {
case MVM_JIT_WHEN:
if (i == 0) {
/* after condition */
MVMint32 cond = tree->nodes[node+1];
if (tree->nodes[cond] == MVM_JIT_ALL || tree->nodes[cond] == MVM_JIT_ANY) {
/* short-circuit evaluation of ALL and ANY has
already taken care of the jump beyond the
block */
} else {
MVM_jit_emit_conditional_branch(tc, cl, tree->nodes[cond],
tree->info[node].internal_label);
}
break;
} else {
/* i == 1, so we're ready to emit our internal label now */
MVM_jit_emit_label(tc, cl, cl->graph, tree->info[node].internal_label);
}
break;
case MVM_JIT_IF:
case MVM_JIT_EITHER:
/* TODO take care of (delimited) register invalidation! */
if (i == 0) {
MVMint32 cond = tree->nodes[node+1];
if (tree->nodes[cond] == MVM_JIT_ALL || tree->nodes[cond] == MVM_JIT_ANY) {
/* Nothing to do */
} else {
MVM_jit_emit_conditional_branch(tc, cl, tree->nodes[cond],
tree->info[node].internal_label);
}
} else if (i == 1) {
MVMJitBranch branch;
branch.ins = NULL;
branch.dest = tree->info[node].internal_label + 1;
MVM_jit_emit_branch(tc, cl, cl->graph, &branch);
MVM_jit_emit_label(tc, cl, cl->graph, tree->info[node].internal_label);
} else {
MVM_jit_emit_label(tc, cl, cl->graph, tree->info[node].internal_label + 1);
}
break;
case MVM_JIT_ALL:
{
MVMint32 cond = tree->nodes[node+2+i];
break;
}
default:
break;
}

}

#if MVM_JIT_ARCH == MVM_JIT_ARCH_X64

static MVMint8 x64_gpr_args[] = {
X64_ARG_GPR(MVM_JIT_REGNAME)
};


static MVMint8 x64_sse_args[] = {
X64_ARG_SSE(MVM_JIT_REGNAME)
};

#if MVM_JIT_PLATFORM == MVM_JIT_PLATFORM_WIN32
static void compile_arglist(MVMThreadContext *tc, MVMJitCompiler *compiler,
MVMJitExprTree *tree, MVMint32 node) {
MVMint32 i, nchild = tree->nodes[node+1], first_child = node + 2;
for (i = 0; i < MIN(nchild, 4); i++) {
MVMint32 carg = tree->nodes[first_child+i];
MVMint32 val = tree->nodes[carg+1];
MVMint32 argtyp = tree->nodes[carg+2];
if (argtype == MVM_JIT_NUM) {
MVMint8 reg = x64_sse_args[i];
MVM_jit_register_take(tc, cl, reg, MVM_JIT_X64_SSE, val);
MVM_jit_emit_load(tc, cl, reg, MVM_JIT_X64_SSE);
} else {
MVMint8 reg = x64_gpr_args[i];
MVM_jit_register_take(tc, cl, reg, MVM_JIT_X64_GPR, val);
}
}
for (. i < nchild; i++) {
}
}
#else

static void compile_arglist(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitExprTree *tree,
MVMint32 node) {
MVM_oops(tc, "compile_arglist NYI");
}
#endif

#else
static void compile_arglist(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitExprTree *tree,
MVMint32 node) {
MVM_oops(tc, "compile_arglist NYI for this architecture");
}

#endif




#define EXPR_ARGS(t,n) (t->info[n].op_info->nchild < 0 ? t->nodes + n + t->nodes[n+1] + 2 : \
t->nodes + n + t->info[n].op_info->nchild + 1);

static void compile_tile(MVMThreadContext *tc, MVMJitCompiler *cl, MVMJitExprTree *tree, MVMint32 node) {
static void compile_tile(MVMThreadContext *tc, MVMJitTreeTraverser *traverser, MVMJitExprTree *tree, MVMint32 node) {
MVMJitCompiler *cl = traverser->data;
MVMJitExprNodeInfo *info = &tree->info[node];
MVMJitExprValue *values[8];
MVMJitExprNode *args = EXPR_ARGS(tree, node);
MVMint32 i;
if (info->tile == NULL)
return;

values[0] = &info->value;
MVM_jit_tile_get_values(tc, tree, node, info->tile->path, values+1);
/* TODO implement register allocation */
switch (tree->nodes[node]) {
case MVM_JIT_ARGLIST:
compile_arglist(tc, cl, tree, node);
break;
default:
{
if (info->tile == NULL)
return;
values[0] = &info->value;
MVM_jit_tile_get_values(tc, tree, node, info->tile->path, values+1);
/* TODO implement register allocation */
info->tile->rule(tc, cl, tree, node, values, args);
}
}

info->tile->rule(tc, cl, tree, node, values, args);
}

void MVM_jit_compile_expr_tree(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, MVMJitExprTree *tree) {
MVMJitTreeTraverser traverser;

traverser.preorder = &prepare_tile;
traverser.inorder = &compile_labels;
traverser.postorder = &compile_tile;

/* First stage, tile the tree */
MVM_jit_tile_expr_tree(tc, tree);

MVM_oops(tc, "NYI");
MVM_jit_expr_tree_traverse(tc, tree, &traverser);
}


Expand Down
7 changes: 6 additions & 1 deletion src/jit/internal.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* Internal header for the MoarVM JIT compiler. Probably best not to use it
* outside the JIT */

#define MVM_JIT_ARCH_STUB 0
#define MVM_JIT_ARCH_X64 1
#define MVM_JIT_PLATFORM_POSIX 1
#define MVM_JIT_PLATFORM_WIN32 2
Expand All @@ -15,7 +16,9 @@
struct MVMJitCompiler {
dasm_State *dasm_handle;
void **dasm_globals;
MVMJitGraph *graph;
MVMint32 next_label;
MVMint32 label_max;
};

/* Declarations for architecture-specific codegen stuff */
Expand All @@ -30,8 +33,10 @@ void MVM_jit_emit_call_c(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitG
MVMJitCallC *call_spec);
void MVM_jit_emit_branch(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg,
MVMJitBranch *branc_spec);
void MVM_jit_emit_conditional_branch(MVMThreadContext *tc, MVMJitCompiler *compiler,
MVMint32 cond, MVMint32 label);
void MVM_jit_emit_label(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg,
MVMJitLabel *label);
MVMint32 label);
void MVM_jit_emit_guard(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg,
MVMJitGuard *guard);
void MVM_jit_emit_invoke(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg,
Expand Down
10 changes: 6 additions & 4 deletions src/jit/pseudo.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,12 @@ static void emit_expr_op(MVMThreadContext *tc, CompilerRegisterState *state, MVM
case MVM_JIT_CALL:
MVM_jit_log(tc, "call %s\n", X64_REGISTER_NAMES[regs[0]]);
break;
default: {
const MVMJitExprOpInfo *info = MVM_jit_expr_op_info(tc, op);
MVM_jit_log(tc, "not yet sure how to compile %s\n", info->name);
}
default:
{
const MVMJitExprOpInfo *info = MVM_jit_expr_op_info(tc, op);
MVM_jit_log(tc, "not yet sure how to compile %s\n", info->name);
}
break;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/jit/register.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
* INVALIDATE spills all ALLOCATED registers (but does not touch USED registers) */

static MVMint8 free_gpr[] = {
X64_FREE_GPR(MVM_JIT_GPRNAME)
X64_FREE_GPR(MVM_JIT_REGNAME)
};


Expand Down
59 changes: 50 additions & 9 deletions src/jit/x64/arch.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
#ifdef MVM_JIT_X64_ARCH_H
#error "arch.h included twice"
#endif
#define MVM_JIT_X64_ARCH_H 1

/* register classes */
#define MVM_JIT_X64_GPR 0
#define MVM_JIT_X64_SSE 1
Expand All @@ -25,15 +20,33 @@
_(R14), \
_(R15)

#define MVM_JIT_GPRNAME(x) MVM_JIT_X64_ ## x

#define X64_SSE(_) \
_(XMM0), \
_(XMM1), \
_(XMM2), \
_(XMM3), \
_(XMM4), \
_(XMM5), \
_(XMM6), \
_(XMM7)

#define MVM_JIT_REGNAME(x) MVM_JIT_X64_ ## x

enum {
X64_GPR(MVM_JIT_REGNAME)
};

enum {
X64_GPR(MVM_JIT_GPRNAME)
X64_SSE(MVM_JIT_REGNAME)
};

#define MVM_JIT_NUM_REG_CLASS 2


#if MVM_JIT_PLATFORM == MVM_JIT_PLATFORM_POSIX
/* Define the GPR usable for general calculations */
#if MVM_JIT_PLATFORM == MVM_JIT_POSIX

#define X64_FREE_GPR(_) \
_(RAX), \
_(RCX), \
Expand All @@ -44,8 +57,26 @@ X64_GPR(MVM_JIT_GPRNAME)
_(R9), \
_(R10), \
_(R11)

/* GPR used for arguments */

#define X64_ARG_GPR(_) \
_(RDI), \
_(RSI), \
_(RDX), \
_(RCX), \
_(R8), \
_(R9)

/* SSE used for arguments */

#define X64_ARG_SSE(_) \
X64_SSE(_)


#else
/* Microsoft :-( */

/* Microsoft why you give us so few registers :-( */
#define X64_FREE_GPR(_) \
_(RAX), \
_(RCX), \
Expand All @@ -54,5 +85,15 @@ X64_GPR(MVM_JIT_GPRNAME)
_(R9), \
_(R10), \
_(R11)
#define X64_ARG_GPR(_) \
_(RCX), \
_(RDX), \
_(R8), \
_(R9)
#define X64_ARG_SSE(_) \
_(XMM0), \
_(XMM1), \
_(XMM2), \
_(XMM3)
#endif

Loading

0 comments on commit 66f2bf8

Please sign in to comment.