pull/81/head
Dibyendu Majumdar 9 years ago
parent 7205991bc3
commit 3b5090a6e6

@ -81,7 +81,7 @@ Following is the status as of 15 June 2015.
+-------------------------+----------+--------------------------------------------------+
| OP_GETUPVAL | NO | R(A) := UpValue[B] |
+-------------------------+----------+--------------------------------------------------+
| OP_GETTABUP | NO | R(A) := UpValue[B][RK(C)] |
| OP_GETTABUP | YES | R(A) := UpValue[B][RK(C)] |
+-------------------------+----------+--------------------------------------------------+
| OP_GETTABLE | NO | R(A) := R(B)[RK(C)] |
+-------------------------+----------+--------------------------------------------------+
@ -129,21 +129,21 @@ Following is the status as of 15 June 2015.
+-------------------------+----------+--------------------------------------------------+
| OP_CONCAT | NO | R(A) := R(B).. ... ..R(C) |
+-------------------------+----------+--------------------------------------------------+
| OP_JMP | NO | c+=sBx; if (A) close all upvalues >= R(A - 1) |
| OP_JMP | YES | c+=sBx; if (A) close all upvalues >= R(A - 1) |
+-------------------------+----------+--------------------------------------------------+
| OP_EQ | NO | if ((RK(B) == RK(C)) ~= A) then pc++ |
| OP_EQ | YES | if ((RK(B) == RK(C)) ~= A) then pc++ |
+-------------------------+----------+--------------------------------------------------+
| OP_LT | NO | if ((RK(B) < RK(C)) ~= A) then pc++ |
| OP_LT | YES | if ((RK(B) < RK(C)) ~= A) then pc++ |
+-------------------------+----------+--------------------------------------------------+
| OP_LE | NO | if ((RK(B) <= RK(C)) ~= A) then pc++ |
| OP_LE | YES | if ((RK(B) <= RK(C)) ~= A) then pc++ |
+-------------------------+----------+--------------------------------------------------+
| OP_TEST | NO | if not (R(A) <=> C) then pc++ |
+-------------------------+----------+--------------------------------------------------+
| OP_TESTSET | NO | if (R(B) <=> C) then R(A) := R(B) else pc++ |
+-------------------------+----------+--------------------------------------------------+
| OP_CALL | NO | R(A), .. ,R(A+C-2) := R(A)(R(A+1), .. ,R(A+B-1)) |
| OP_CALL | YES | R(A), .. ,R(A+C-2) := R(A)(R(A+1), .. ,R(A+B-1)) |
+-------------------------+----------+--------------------------------------------------+
| OP_TAILCALL | NO | return R(A)(R(A+1), ... ,R(A+B-1)) |
| OP_TAILCALL | YES | return R(A)(R(A+1), ... ,R(A+B-1)) |
| | | Compiled as OP_CALL so no tail call optimization |
+-------------------------+----------+--------------------------------------------------+
| OP_RETURN | YES | return R(A), ... ,R(A+B-2) (see note) |

@ -35,8 +35,8 @@ void ravi_emit_JMP(ravi_function_def_t *def, int A, int j, int pc) {
assert(def->jmp_targets[j]->jmp);
if (def->current_block_terminated) {
gcc_jit_block *jmp_block =
gcc_jit_function_new_block(def->jit_function, unique_name(def, "OP_JMP", pc));
gcc_jit_block *jmp_block = gcc_jit_function_new_block(
def->jit_function, unique_name(def, "OP_JMP", pc));
ravi_set_current_block(def, jmp_block);
}
@ -46,13 +46,16 @@ void ravi_emit_JMP(ravi_function_def_t *def, int A, int j, int pc) {
// base + a - 1
gcc_jit_rvalue *val = ravi_emit_get_register(def, A - 1);
// Call luaF_close
gcc_jit_block_add_eval(def->current_block, NULL, ravi_function_call2_rvalue(def, def->ravi->types->luaF_closeT, gcc_jit_param_as_rvalue(def->L), val));
gcc_jit_block_add_eval(
def->current_block, NULL,
ravi_function_call2_rvalue(def, def->ravi->types->luaF_closeT,
gcc_jit_param_as_rvalue(def->L), val));
}
ravi_emit_branch(def, def->jmp_targets[j]->jmp);
gcc_jit_block *block =
gcc_jit_function_new_block(def->jit_function, unique_name(def, "OP_JMP_post", pc));
gcc_jit_block *block = gcc_jit_function_new_block(
def->jit_function, unique_name(def, "OP_JMP_post", pc));
ravi_set_current_block(def, block);
}
@ -88,30 +91,32 @@ void ravi_emit_CALL(ravi_function_def_t *def, int A, int B, int C, int pc) {
// int c = luaD_precall(L, ra, nresults); /* C or JITed function? */
gcc_jit_rvalue *ra = ravi_emit_get_register(def, A);
gcc_jit_rvalue *nresults_const =
gcc_jit_context_new_rvalue_from_int(def->function_context, def->ravi->types->C_intT, nresults);
gcc_jit_rvalue *precall_result =
ravi_function_call3_rvalue(def, def->ravi->types->luaD_precallT,
gcc_jit_param_as_rvalue(def->L), ra,
nresults_const);
gcc_jit_rvalue *zero_const =
gcc_jit_context_new_rvalue_from_int(def->function_context, def->ravi->types->C_intT, 0);
gcc_jit_rvalue *precall_bool =
gcc_jit_context_new_comparison(def->function_context, NULL, GCC_JIT_COMPARISON_EQ, precall_result, zero_const);
gcc_jit_rvalue *nresults_const = gcc_jit_context_new_rvalue_from_int(
def->function_context, def->ravi->types->C_intT, nresults);
gcc_jit_rvalue *precall_result = ravi_function_call3_rvalue(
def, def->ravi->types->luaD_precallT, gcc_jit_param_as_rvalue(def->L), ra,
nresults_const);
gcc_jit_rvalue *zero_const = gcc_jit_context_new_rvalue_from_int(
def->function_context, def->ravi->types->C_intT, 0);
gcc_jit_rvalue *precall_bool = gcc_jit_context_new_comparison(
def->function_context, NULL, GCC_JIT_COMPARISON_EQ, precall_result,
zero_const);
gcc_jit_block *then_block = gcc_jit_function_new_block(
def->jit_function, unique_name(def, "OP_CALL_if_lua_function", pc));
gcc_jit_block *else_block =
gcc_jit_function_new_block(def->jit_function, unique_name(def, "OP_CALL_else_lua_function", pc));
gcc_jit_block *end_block =
gcc_jit_function_new_block(def->jit_function, unique_name(def, "OP_CALL_done", pc));
def->jit_function, unique_name(def, "OP_CALL_if_lua_function", pc));
gcc_jit_block *else_block = gcc_jit_function_new_block(
def->jit_function, unique_name(def, "OP_CALL_else_lua_function", pc));
gcc_jit_block *end_block = gcc_jit_function_new_block(
def->jit_function, unique_name(def, "OP_CALL_done", pc));
ravi_emit_conditional_branch(def, precall_bool, then_block, else_block);
ravi_set_current_block(def, then_block);
// Lua function, not compiled, so call luaV_execute
gcc_jit_block_add_eval(def->current_block, NULL,
ravi_function_call1_rvalue(def, def->ravi->types->luaV_executeT, gcc_jit_param_as_rvalue(def->L)));
gcc_jit_block_add_eval(
def->current_block, NULL,
ravi_function_call1_rvalue(def, def->ravi->types->luaV_executeT,
gcc_jit_param_as_rvalue(def->L)));
ravi_emit_branch(def, end_block);
ravi_set_current_block(def, else_block);
@ -121,14 +126,14 @@ void ravi_emit_CALL(ravi_function_def_t *def, int A, int B, int C, int pc) {
// called so we need to update L->top
// if (c == 1 && nresults >= 0)
// L->top = ci->top; /* adjust results if C function */
gcc_jit_rvalue *one_const =
gcc_jit_context_new_rvalue_from_int(def->function_context, def->ravi->types->C_intT, 1);
gcc_jit_rvalue *precall_C =
gcc_jit_context_new_comparison(def->function_context, NULL, GCC_JIT_COMPARISON_EQ, precall_result,
one_const);
gcc_jit_block *then1_block = gcc_jit_function_new_block(def->jit_function,
unique_name(def, "OP_CALL_if_C_function", pc));
gcc_jit_rvalue *one_const = gcc_jit_context_new_rvalue_from_int(
def->function_context, def->ravi->types->C_intT, 1);
gcc_jit_rvalue *precall_C = gcc_jit_context_new_comparison(
def->function_context, NULL, GCC_JIT_COMPARISON_EQ, precall_result,
one_const);
gcc_jit_block *then1_block = gcc_jit_function_new_block(
def->jit_function, unique_name(def, "OP_CALL_if_C_function", pc));
ravi_emit_conditional_branch(def, precall_C, then1_block, end_block);
ravi_set_current_block(def, then1_block);

@ -344,18 +344,19 @@ void ravi_emit_load_base(ravi_function_def_t *def) {
// L->top = ci->top
void ravi_emit_refresh_L_top(ravi_function_def_t *def) {
// Load ci->top
gcc_jit_lvalue *citop = gcc_jit_rvalue_dereference_field(gcc_jit_lvalue_as_rvalue(def->ci_val),
NULL, def->ravi->types->CallInfo_top);
gcc_jit_lvalue *citop =
gcc_jit_rvalue_dereference_field(gcc_jit_lvalue_as_rvalue(def->ci_val),
NULL, def->ravi->types->CallInfo_top);
// Get L->top
gcc_jit_lvalue *top = gcc_jit_rvalue_dereference_field(
gcc_jit_param_as_rvalue(def->L), NULL, def->ravi->types->lua_State_top);
gcc_jit_param_as_rvalue(def->L), NULL, def->ravi->types->lua_State_top);
// Assign ci>top to L->top
gcc_jit_block_add_assignment(def->current_block, NULL, top, gcc_jit_lvalue_as_rvalue(citop));
gcc_jit_block_add_assignment(def->current_block, NULL, top,
gcc_jit_lvalue_as_rvalue(citop));
}
/* Get access to the register identified by A - registers as just &base[offset]
*/
gcc_jit_rvalue *ravi_emit_get_register(ravi_function_def_t *def, int A) {
@ -556,34 +557,36 @@ gcc_jit_rvalue *ravi_function_call1_rvalue(ravi_function_def_t *def,
return gcc_jit_context_new_call(def->function_context, NULL, f, 1, args);
}
gcc_jit_rvalue* ravi_emit_get_upvals(ravi_function_def_t *def,
int offset) {
gcc_jit_lvalue *upvals = gcc_jit_rvalue_dereference_field(gcc_jit_lvalue_as_rvalue(def->lua_closure_val),
NULL, def->ravi->types->LClosure_upvals);
gcc_jit_lvalue *upval = gcc_jit_context_new_array_access(def->function_context, NULL, gcc_jit_lvalue_as_rvalue(upvals),
gcc_jit_context_new_rvalue_from_int(def->function_context, def->ravi->types->C_intT, offset));
gcc_jit_rvalue *ravi_emit_get_upvals(ravi_function_def_t *def, int offset) {
gcc_jit_lvalue *upvals = gcc_jit_rvalue_dereference_field(
gcc_jit_lvalue_as_rvalue(def->lua_closure_val), NULL,
def->ravi->types->LClosure_upvals);
gcc_jit_lvalue *upval = gcc_jit_context_new_array_access(
def->function_context, NULL, gcc_jit_lvalue_as_rvalue(upvals),
gcc_jit_context_new_rvalue_from_int(def->function_context,
def->ravi->types->C_intT, offset));
return gcc_jit_lvalue_as_rvalue(upval);
}
// Get upval->v
gcc_jit_lvalue *ravi_emit_get_upval_v(ravi_function_def_t *def,
gcc_jit_rvalue *pupval) {
// const char *debugstr =
// gcc_jit_object_get_debug_string(gcc_jit_rvalue_as_object(pupval));
// fprintf(stderr, "%s\n", debugstr);
gcc_jit_rvalue *pupval) {
// const char *debugstr =
// gcc_jit_object_get_debug_string(gcc_jit_rvalue_as_object(pupval));
// fprintf(stderr, "%s\n", debugstr);
return gcc_jit_rvalue_dereference_field(pupval, NULL, def->ravi->types->UpVal_v);
return gcc_jit_rvalue_dereference_field(pupval, NULL,
def->ravi->types->UpVal_v);
}
// Get upval->u.value
gcc_jit_lvalue *
ravi_emit_get_upval_value(ravi_function_def_t *def,
gcc_jit_rvalue *pupval) {
gcc_jit_lvalue *u = gcc_jit_rvalue_dereference_field(pupval, NULL, def->ravi->types->UpVal_u);
gcc_jit_lvalue *ravi_emit_get_upval_value(ravi_function_def_t *def,
gcc_jit_rvalue *pupval) {
gcc_jit_lvalue *u =
gcc_jit_rvalue_dereference_field(pupval, NULL, def->ravi->types->UpVal_u);
return gcc_jit_lvalue_access_field(u, NULL, def->ravi->types->UpVal_u_value);
}
void ravi_set_current_block(ravi_function_def_t *def, gcc_jit_block *block) {
def->current_block = block;
def->current_block_terminated = false;
@ -595,10 +598,13 @@ void ravi_emit_branch(ravi_function_def_t *def, gcc_jit_block *target_block) {
def->current_block_terminated = true;
}
void ravi_emit_conditional_branch(ravi_function_def_t *def, gcc_jit_rvalue *cond, gcc_jit_block *true_block,
void ravi_emit_conditional_branch(ravi_function_def_t *def,
gcc_jit_rvalue *cond,
gcc_jit_block *true_block,
gcc_jit_block *false_block) {
assert(!def->current_block_terminated);
gcc_jit_block_end_with_conditional(def->current_block, NULL, cond, true_block, false_block);
gcc_jit_block_end_with_conditional(def->current_block, NULL, cond, true_block,
false_block);
def->current_block_terminated = true;
}
@ -737,23 +743,22 @@ int raviV_compile(struct lua_State *L, struct Proto *p, int manual_request,
int B = GETARG_B(i);
int C = GETARG_C(i);
const char *opname =
(op == OP_EQ
? "OP_EQ"
: (op == OP_LT ? "OP_LT" : "OP_LE"));
(op == OP_EQ ? "OP_EQ" : (op == OP_LT ? "OP_LT" : "OP_LE"));
gcc_jit_function *comparison_function =
(op == OP_EQ
? def.ravi->types->luaV_equalobjT
: (op == OP_LT ? def.ravi->types->luaV_lessthanT : def.ravi->types->luaV_lessequalT));
(op == OP_EQ ? def.ravi->types->luaV_equalobjT
: (op == OP_LT ? def.ravi->types->luaV_lessthanT
: def.ravi->types->luaV_lessequalT));
// OP_EQ is followed by OP_JMP - we process this
// along with OP_EQ
pc++;
i = code[pc];
op = GET_OPCODE(i);
lua_assert(op == OP_JMP);
lua_assert(op == OP_JMP);
int sbx = GETARG_sBx(i);
// j below is the jump target
int j = sbx + pc + 1;
ravi_emit_EQ_LE_LT(&def, A, B, C, j, GETARG_A(i), comparison_function, opname, pc);
ravi_emit_EQ_LE_LT(&def, A, B, C, j, GETARG_A(i), comparison_function,
opname, pc);
} break;
case OP_GETTABUP: {
@ -762,7 +767,6 @@ int raviV_compile(struct lua_State *L, struct Proto *p, int manual_request,
ravi_emit_GETTABUP(&def, A, B, C, pc);
} break;
default:
break;
}
@ -770,7 +774,7 @@ int raviV_compile(struct lua_State *L, struct Proto *p, int manual_request,
gcc_jit_context_dump_to_file(def.function_context, "fdump.txt", 0);
// gcc_jit_context_dump_reproducer_to_file(def.function_context, "rdump.txt");
//gcc_jit_context_set_logfile (def.function_context, stderr, 0, 0);
// gcc_jit_context_set_logfile (def.function_context, stderr, 0, 0);
if (gcc_jit_context_get_first_error(def.function_context)) {
fprintf(stderr, "aborting due to JIT error: %s\n",

@ -25,7 +25,8 @@
// implements EQ, LE and LT - by using the supplied lua function to call.
void ravi_emit_EQ_LE_LT(ravi_function_def_t *def, int A, int B, int C, int j,
int jA, gcc_jit_function *callee, const char *opname, int pc) {
int jA, gcc_jit_function *callee, const char *opname,
int pc) {
// case OP_EQ: {
// TValue *rb = RKB(i);
// TValue *rc = RKC(i);
@ -46,22 +47,22 @@ void ravi_emit_EQ_LE_LT(ravi_function_def_t *def, int A, int B, int C, int j,
gcc_jit_rvalue *rhs_ptr = ravi_emit_get_register_or_constant(def, C);
// Call luaV_equalobj with register B and C
gcc_jit_rvalue *result =
ravi_function_call3_rvalue(def, callee, gcc_jit_param_as_rvalue(def->L), lhs_ptr, rhs_ptr);
gcc_jit_rvalue *result = ravi_function_call3_rvalue(
def, callee, gcc_jit_param_as_rvalue(def->L), lhs_ptr, rhs_ptr);
// Test if result is equal to operand A
gcc_jit_rvalue *A_const = gcc_jit_context_new_rvalue_from_int(def->function_context, def->ravi->types->C_intT, A);
gcc_jit_rvalue *result_eq_A = gcc_jit_context_new_comparison(def->function_context, NULL, GCC_JIT_COMPARISON_EQ,
result, A_const);
gcc_jit_rvalue *A_const = gcc_jit_context_new_rvalue_from_int(
def->function_context, def->ravi->types->C_intT, A);
gcc_jit_rvalue *result_eq_A = gcc_jit_context_new_comparison(
def->function_context, NULL, GCC_JIT_COMPARISON_EQ, result, A_const);
// If result == A then we need to execute the next statement which is a jump
char temp[80];
snprintf(temp, sizeof temp, "%s_then", opname);
gcc_jit_block *then_block = gcc_jit_function_new_block(
def->jit_function, unique_name(def, temp, pc));
gcc_jit_block *then_block =
gcc_jit_function_new_block(def->jit_function, unique_name(def, temp, pc));
snprintf(temp, sizeof temp, "%s_else", opname);
gcc_jit_block *else_block =
gcc_jit_function_new_block(
def->jit_function, unique_name(def, temp, pc));
gcc_jit_function_new_block(def->jit_function, unique_name(def, temp, pc));
ravi_emit_conditional_branch(def, result_eq_A, then_block, else_block);
ravi_set_current_block(def, then_block);
@ -75,10 +76,13 @@ void ravi_emit_EQ_LE_LT(ravi_function_def_t *def, int A, int B, int C, int j,
ravi_emit_load_base(def);
// base + a - 1
gcc_jit_rvalue *val = ravi_emit_get_register(def, jA-1);
gcc_jit_rvalue *val = ravi_emit_get_register(def, jA - 1);
// Call luaF_close
gcc_jit_block_add_eval(def->current_block, NULL, ravi_function_call2_rvalue(def, def->ravi->types->luaF_closeT, gcc_jit_param_as_rvalue(def->L), val));
gcc_jit_block_add_eval(
def->current_block, NULL,
ravi_function_call2_rvalue(def, def->ravi->types->luaF_closeT,
gcc_jit_param_as_rvalue(def->L), val));
}
// Do the jump
ravi_emit_branch(def, def->jmp_targets[j]->jmp);

@ -45,9 +45,8 @@ void ravi_emit_LOADFZ(ravi_function_def_t *def, int A) {
// destvalue->n = 0.0
ravi_emit_store_reg_n_withtype(
def,
gcc_jit_context_new_rvalue_from_double(
def->function_context, def->ravi->types->lua_NumberT, 0.0),
def, gcc_jit_context_new_rvalue_from_double(
def->function_context, def->ravi->types->lua_NumberT, 0.0),
dest);
}

@ -30,13 +30,16 @@ void ravi_emit_GETTABUP(ravi_function_def_t *def, int A, int B, int C, int pc) {
fprintf(stderr, "GETTABUP called");
(void) pc;
(void)pc;
ravi_emit_load_base(def);
gcc_jit_rvalue *ra = ravi_emit_get_register(def, A);
gcc_jit_rvalue *rc = ravi_emit_get_register_or_constant(def, C);
gcc_jit_rvalue *upval = ravi_emit_get_upvals(def, B);
gcc_jit_lvalue *v = ravi_emit_get_upval_v(def, upval);
gcc_jit_block_add_eval(def->current_block, NULL, ravi_function_call4_rvalue(def, def->ravi->types->luaV_gettableT, gcc_jit_param_as_rvalue(def->L),
gcc_jit_lvalue_as_rvalue(v), rc, ra));
gcc_jit_block_add_eval(
def->current_block, NULL,
ravi_function_call4_rvalue(def, def->ravi->types->luaV_gettableT,
gcc_jit_param_as_rvalue(def->L),
gcc_jit_lvalue_as_rvalue(v), rc, ra));
}

@ -163,7 +163,8 @@ bool ravi_setup_lua_types(ravi_gcc_context_t *ravi) {
t->Value_value_gc = fields[0] =
gcc_jit_context_new_field(ravi->context, NULL, t->pGCObjectT, "gc");
fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->C_pvoidT, "p");
t->Value_value_b = fields[2] = gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "b");
t->Value_value_b = fields[2] =
gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "b");
fields[3] =
gcc_jit_context_new_field(ravi->context, NULL, t->plua_CFunctionT, "f");
t->Value_value_i = fields[4] =
@ -180,7 +181,8 @@ bool ravi_setup_lua_types(ravi_gcc_context_t *ravi) {
// };
t->Value_value = fields[0] =
gcc_jit_context_new_field(ravi->context, NULL, t->ValueT, "value_");
t->Value_tt = fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "tt_");
t->Value_tt = fields[1] =
gcc_jit_context_new_field(ravi->context, NULL, t->C_intT, "tt_");
t->TValueT = gcc_jit_context_new_struct_type(ravi->context, NULL,
"ravi_TValue", 2, fields);
t->pTValueT = gcc_jit_type_get_pointer(gcc_jit_struct_as_type(t->TValueT));
@ -642,7 +644,8 @@ bool ravi_setup_lua_types(ravi_gcc_context_t *ravi) {
t->CallInfo_func = fields[0] =
gcc_jit_context_new_field(ravi->context, NULL, t->StkIdT, "func");
t->CallInfo_top = fields[1] = gcc_jit_context_new_field(ravi->context, NULL, t->StkIdT, "top");
t->CallInfo_top = fields[1] =
gcc_jit_context_new_field(ravi->context, NULL, t->StkIdT, "top");
fields[2] =
gcc_jit_context_new_field(ravi->context, NULL, t->pCallInfoT, "previous");
fields[3] =
@ -771,10 +774,12 @@ bool ravi_setup_lua_types(ravi_gcc_context_t *ravi) {
t->UpVal_uT = gcc_jit_context_new_union_type(ravi->context, NULL,
"ravi_UpVal_u", 2, fields);
t->UpVal_v = fields[0] = gcc_jit_context_new_field(ravi->context, NULL, t->pTValueT, "v");
t->UpVal_v = fields[0] =
gcc_jit_context_new_field(ravi->context, NULL, t->pTValueT, "v");
fields[1] =
gcc_jit_context_new_field(ravi->context, NULL, t->lu_memT, "refcount");
t->UpVal_u = fields[2] = gcc_jit_context_new_field(ravi->context, NULL, t->UpVal_uT, "u");
t->UpVal_u = fields[2] =
gcc_jit_context_new_field(ravi->context, NULL, t->UpVal_uT, "u");
gcc_jit_struct_set_fields(t->UpValT, NULL, 3, fields);
gcc_jit_param *params[12];

Loading…
Cancel
Save