Added gen_direct_jump() for unary branches

This commit is contained in:
Maxime Chevalier-Boisvert 2021-01-19 11:11:11 -05:00 коммит произвёл Alan Wu
Родитель 187435c117
Коммит 37ad374607
3 изменённых файлов: 90 добавлений и 67 удалений

Просмотреть файл

@ -689,24 +689,6 @@ gen_branchunless(jitstate_t* jit, ctx_t* ctx)
return true;
}
void
gen_jump_branch(codeblock_t* cb, uint8_t* target0, uint8_t* target1, uint8_t shape)
{
switch (shape)
{
case SHAPE_NEXT0:
break;
case SHAPE_NEXT1:
assert (false);
break;
case SHAPE_DEFAULT:
jmp_ptr(cb, target0);
break;
}
}
static bool
gen_jump(jitstate_t* jit, ctx_t* ctx)
{
@ -720,13 +702,9 @@ gen_jump(jitstate_t* jit, ctx_t* ctx)
//
// Generate the jump instruction
gen_branch(
gen_direct_jump(
ctx,
jump_block,
ctx,
BLOCKID_NULL,
ctx,
gen_jump_branch
jump_block
);
return true;
@ -978,13 +956,9 @@ gen_opt_send_without_block(jitstate_t* jit, ctx_t* ctx)
// Jump (fall through) to the call continuation block
// We do this to end the current block after the call
blockid_t cont_block = { jit->iseq, jit_next_idx(jit) };
gen_branch(
gen_direct_jump(
ctx,
cont_block,
ctx,
BLOCKID_NULL,
ctx,
gen_jump_branch
cont_block
);
return true;

Просмотреть файл

@ -292,49 +292,17 @@ void gen_branch(
)
{
assert (target0.iseq != NULL);
assert (target1.iseq != NULL);
assert (num_branches < MAX_BRANCHES);
uint32_t branch_idx = num_branches++;
// Branch targets or stub adddresses (code pointers)
uint8_t* dst_addr0;
uint8_t* dst_addr1;
// Shape of the branch
uint8_t branch_shape;
// If there's only one branch target
if (target1.iseq == NULL)
{
block_t* p_block = find_block_version(target0, ctx0);
// If the version already exists
if (p_block)
{
add_incoming(p_block, branch_idx);
dst_addr0 = cb_get_ptr(cb, p_block->start_pos);
dst_addr1 = NULL;
branch_shape = SHAPE_DEFAULT;
}
else
{
// The target block will follow next
// It will be compiled in gen_block_version()
dst_addr0 = NULL;
dst_addr1 = NULL;
branch_shape = SHAPE_NEXT0;
}
}
else
{
// Get the branch targets or stubs
dst_addr0 = get_branch_target(target0, ctx0, branch_idx, 0);
dst_addr1 = get_branch_target(target1, ctx1, branch_idx, 1);
branch_shape = SHAPE_DEFAULT;
}
// Get the branch targets or stubs
uint8_t* dst_addr0 = get_branch_target(target0, ctx0, branch_idx, 0);
uint8_t* dst_addr1 = get_branch_target(target1, ctx1, branch_idx, 1);
// Call the branch generation function
uint32_t start_pos = cb->write_pos;
gen_fn(cb, dst_addr0, dst_addr1, branch_shape);
gen_fn(cb, dst_addr0, dst_addr1, SHAPE_DEFAULT);
uint32_t end_pos = cb->write_pos;
// Register this branch entry
@ -346,6 +314,82 @@ void gen_branch(
{ *ctx0, *ctx1 },
{ dst_addr0, dst_addr1 },
gen_fn,
SHAPE_DEFAULT
};
branch_entries[branch_idx] = branch_entry;
}
void
gen_jump_branch(codeblock_t* cb, uint8_t* target0, uint8_t* target1, uint8_t shape)
{
switch (shape)
{
case SHAPE_NEXT0:
break;
case SHAPE_NEXT1:
assert (false);
break;
case SHAPE_DEFAULT:
jmp_ptr(cb, target0);
break;
}
}
void gen_direct_jump(
const ctx_t* ctx,
blockid_t target0
)
{
assert (target0.iseq != NULL);
assert (num_branches < MAX_BRANCHES);
uint32_t branch_idx = num_branches++;
// Branch targets or stub adddress
uint8_t* dst_addr0;
// Shape of the branch
uint8_t branch_shape;
// Branch start and end positions
uint32_t start_pos;
uint32_t end_pos;
block_t* p_block = find_block_version(target0, ctx);
// If the version already exists
if (p_block)
{
add_incoming(p_block, branch_idx);
dst_addr0 = cb_get_ptr(cb, p_block->start_pos);
branch_shape = SHAPE_DEFAULT;
// Call the branch generation function
start_pos = cb->write_pos;
gen_jump_branch(cb, dst_addr0, NULL, branch_shape);
end_pos = cb->write_pos;
}
else
{
// The target block will follow next
// It will be compiled in gen_block_version()
dst_addr0 = NULL;
branch_shape = SHAPE_NEXT0;
start_pos = cb->write_pos;
end_pos = cb->write_pos;
}
// Register this branch entry
branch_t branch_entry = {
start_pos,
end_pos,
*ctx,
{ target0, BLOCKID_NULL },
{ *ctx, *ctx },
{ dst_addr0, NULL },
gen_jump_branch,
branch_shape
};

Просмотреть файл

@ -125,6 +125,11 @@ void gen_branch(
branchgen_fn gen_fn
);
void gen_direct_jump(
const ctx_t* ctx,
blockid_t target0
);
void invalidate(block_t* block);
void ujit_init_core(void);