optimise getof

This commit is contained in:
Fabian 2022-11-04 12:30:33 -06:00
parent 6fcbe7b3d0
commit 0ea7c7cd81

View file

@ -1784,48 +1784,78 @@ pub fn gen_getsf(ctx: &mut JitContext) {
}
pub fn gen_getof(ctx: &mut JitContext) {
gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_UNOPTIMISED);
gen_get_flags_changed(ctx.builder);
let flags_changed = ctx.builder.tee_new_local();
ctx.builder.const_i32(FLAG_OVERFLOW);
ctx.builder.and_i32();
ctx.builder.if_i32();
{
gen_get_last_op1(ctx.builder, &ctx.previous_instruction);
let last_op1 = ctx.builder.tee_new_local();
gen_get_last_result(ctx.builder, &ctx.previous_instruction);
let last_result = ctx.builder.tee_new_local();
ctx.builder.xor_i32();
match &ctx.previous_instruction {
Instruction::Cmp { opsize, .. } | Instruction::Sub { opsize, .. } => {
let &opsize = opsize;
gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_OPTIMISED);
gen_get_last_op1(ctx.builder, &ctx.previous_instruction);
gen_get_last_result(ctx.builder, &ctx.previous_instruction);
ctx.builder.xor_i32();
ctx.builder.get_local(&last_result);
ctx.builder.get_local(&last_op1);
ctx.builder.sub_i32();
gen_get_flags_changed(ctx.builder);
ctx.builder.const_i32(31);
ctx.builder.shr_u_i32();
ctx.builder.sub_i32();
gen_get_last_op1(ctx.builder, &ctx.previous_instruction);
gen_get_last_op1(ctx.builder, &ctx.previous_instruction);
gen_get_last_result(ctx.builder, &ctx.previous_instruction);
ctx.builder.sub_i32();
ctx.builder.xor_i32();
ctx.builder.and_i32();
ctx.builder.get_local(&last_result);
ctx.builder.xor_i32();
ctx.builder.const_i32(if opsize == OPSIZE_32 {
0x8000_0000u32 as i32
}
else if opsize == OPSIZE_16 {
0x8000
}
else {
0x80
});
ctx.builder.and_i32();
},
&Instruction::Other | Instruction::Arithmetic { .. } => {
// TODO: add
gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_UNOPTIMISED);
gen_get_flags_changed(ctx.builder);
let flags_changed = ctx.builder.tee_new_local();
ctx.builder.const_i32(FLAG_OVERFLOW);
ctx.builder.and_i32();
ctx.builder.if_i32();
{
gen_get_last_op1(ctx.builder, &ctx.previous_instruction);
let last_op1 = ctx.builder.tee_new_local();
gen_get_last_result(ctx.builder, &ctx.previous_instruction);
let last_result = ctx.builder.tee_new_local();
ctx.builder.xor_i32();
ctx.builder.and_i32();
ctx.builder.get_local(&last_result);
ctx.builder.get_local(&last_op1);
ctx.builder.sub_i32();
gen_get_flags_changed(ctx.builder);
ctx.builder.const_i32(31);
ctx.builder.shr_u_i32();
ctx.builder.sub_i32();
gen_get_last_op_size(ctx.builder);
ctx.builder.shr_u_i32();
ctx.builder.const_i32(1);
ctx.builder.and_i32();
ctx.builder.get_local(&last_result);
ctx.builder.xor_i32();
ctx.builder.free_local(last_op1);
ctx.builder.free_local(last_result);
ctx.builder.and_i32();
gen_get_last_op_size(ctx.builder);
ctx.builder.shr_u_i32();
ctx.builder.const_i32(1);
ctx.builder.and_i32();
ctx.builder.free_local(last_op1);
ctx.builder.free_local(last_result);
}
ctx.builder.else_();
{
gen_get_flags(ctx.builder);
ctx.builder.const_i32(FLAG_OVERFLOW);
ctx.builder.and_i32();
}
ctx.builder.block_end();
ctx.builder.free_local(flags_changed);
},
}
ctx.builder.else_();
{
gen_get_flags(ctx.builder);
ctx.builder.const_i32(FLAG_OVERFLOW);
ctx.builder.and_i32();
}
ctx.builder.block_end();
ctx.builder.free_local(flags_changed);
}
pub fn gen_test_be(ctx: &mut JitContext, negate: ConditionNegate) {