Browse Source

optimise flag generation after adc/sbb

Fabian 1 year ago
parent
commit
1588687e2a
3 changed files with 67 additions and 5 deletions
  1. 18 5
      src/rust/codegen.rs
  2. 5 0
      src/rust/jit.rs
  3. 44 0
      src/rust/jit_instructions.rs

+ 18 - 5
src/rust/codegen.rs

@@ -347,6 +347,11 @@ fn gen_get_last_result(builder: &mut WasmBuilder, previous_instruction: &Instruc
             opsize: OPSIZE_32,
             ..
         }
+        | Instruction::AdcSbb {
+            dest: InstructionOperandDest::WasmLocal(l),
+            opsize: OPSIZE_32,
+            ..
+        }
         | Instruction::Sub {
             dest: InstructionOperandDest::WasmLocal(l),
             opsize: OPSIZE_32,
@@ -1646,6 +1651,7 @@ pub fn gen_getzf(ctx: &mut JitContext, negate: ConditionNegate) {
         Instruction::Cmp { .. }
         | Instruction::Sub { .. }
         | Instruction::Add { .. }
+        | Instruction::AdcSbb { .. }
         | Instruction::NonZeroShift { .. } => {
             gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_OPTIMISED);
             gen_get_last_result(ctx.builder, &ctx.previous_instruction);
@@ -1763,7 +1769,7 @@ pub fn gen_getcf(ctx: &mut JitContext, negate: ConditionNegate) {
             ctx.builder
                 .const_i32(if negate == ConditionNegate::True { 1 } else { 0 });
         },
-        Instruction::NonZeroShift { .. } => {
+        Instruction::NonZeroShift { .. } | Instruction::AdcSbb { .. } => {
             gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_OPTIMISED);
             gen_get_flags(ctx.builder);
             ctx.builder.const_i32(FLAG_CARRY);
@@ -1817,6 +1823,7 @@ pub fn gen_getsf(ctx: &mut JitContext, negate: ConditionNegate) {
         Instruction::Cmp { opsize, .. }
         | Instruction::Sub { opsize, .. }
         | Instruction::Add { opsize, .. }
+        | Instruction::AdcSbb { opsize, .. }
         | Instruction::Bitwise { opsize, .. }
         | Instruction::NonZeroShift { opsize, .. } => {
             let &opsize = opsize;
@@ -1926,7 +1933,7 @@ pub fn gen_getof(ctx: &mut JitContext) {
             gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_OPTIMISED);
             ctx.builder.const_i32(0);
         },
-        Instruction::NonZeroShift { .. } => {
+        Instruction::NonZeroShift { .. } | Instruction::AdcSbb { .. } => {
             gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_OPTIMISED);
             gen_get_flags(ctx.builder);
             ctx.builder.const_i32(FLAG_OVERFLOW);
@@ -2078,7 +2085,7 @@ pub fn gen_test_be(ctx: &mut JitContext, negate: ConditionNegate) {
                 ctx.builder.eqz_i32();
             }
         },
-        Instruction::Other | Instruction::NonZeroShift { .. } => {
+        Instruction::Other | Instruction::NonZeroShift { .. } | Instruction::AdcSbb { .. } => {
             gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_UNOPTIMISED);
             gen_getcf(ctx, ConditionNegate::False);
             gen_getzf(ctx, ConditionNegate::False);
@@ -2194,7 +2201,10 @@ pub fn gen_test_l(ctx: &mut JitContext, negate: ConditionNegate) {
             gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_OPTIMISED);
             gen_getsf(ctx, negate);
         },
-        &Instruction::Other | Instruction::Add { .. } | Instruction::NonZeroShift { .. } => {
+        &Instruction::Other
+        | Instruction::Add { .. }
+        | Instruction::NonZeroShift { .. }
+        | Instruction::AdcSbb { .. } => {
             gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_UNOPTIMISED);
             if let Instruction::Add { .. } = ctx.previous_instruction {
                 gen_profiler_stat_increment(
@@ -2324,7 +2334,10 @@ pub fn gen_test_le(ctx: &mut JitContext, negate: ConditionNegate) {
                 ctx.builder.eqz_i32();
             }
         },
-        Instruction::Other | Instruction::Add { .. } | Instruction::NonZeroShift { .. } => {
+        Instruction::Other
+        | Instruction::Add { .. }
+        | Instruction::NonZeroShift { .. }
+        | Instruction::AdcSbb { .. } => {
             gen_profiler_stat_increment(ctx.builder, profiler::stat::CONDITION_UNOPTIMISED);
             if let Instruction::Add { .. } = ctx.previous_instruction {
                 gen_profiler_stat_increment(

+ 5 - 0
src/rust/jit.rs

@@ -274,6 +274,11 @@ pub enum Instruction {
         opsize: i32,
         is_inc: bool,
     },
+    AdcSbb {
+        dest: InstructionOperandDest,
+        source: InstructionOperand,
+        opsize: i32,
+    },
     NonZeroShift {
         dest: InstructionOperandDest,
         opsize: i32,

+ 44 - 0
src/rust/jit_instructions.rs

@@ -1121,6 +1121,17 @@ fn gen_adc8(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &Loc
     ctx.builder.call_fn2_ret("adc8");
     ctx.builder.const_i32(0xFF);
     ctx.builder.and_i32();
+
+    ctx.current_instruction = Instruction::AdcSbb {
+        opsize: OPSIZE_8,
+        dest: local_to_instruction_operand(ctx, dest_operand),
+        source: if source_operand.eq_local(dest_operand) {
+            InstructionOperand::Other // aliasing
+        }
+        else {
+            source_operand.to_instruction_operand(ctx)
+        },
+    };
 }
 fn gen_adc32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
     ctx.builder.get_local(&dest_operand);
@@ -1188,6 +1199,17 @@ fn gen_adc32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &Lo
     ctx.builder.get_local(&res);
     ctx.builder.set_local(dest_operand);
     ctx.builder.free_local(res);
+
+    ctx.current_instruction = Instruction::AdcSbb {
+        opsize: OPSIZE_32,
+        dest: local_to_instruction_operand(ctx, dest_operand),
+        source: if source_operand.eq_local(dest_operand) {
+            InstructionOperand::Other // aliasing
+        }
+        else {
+            source_operand.to_instruction_operand(ctx)
+        },
+    };
 }
 
 fn gen_sbb8(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
@@ -1198,6 +1220,17 @@ fn gen_sbb8(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &Loc
     ctx.builder.call_fn2_ret("sbb8");
     ctx.builder.const_i32(0xFF);
     ctx.builder.and_i32();
+
+    ctx.current_instruction = Instruction::AdcSbb {
+        opsize: OPSIZE_8,
+        dest: local_to_instruction_operand(ctx, dest_operand),
+        source: if source_operand.eq_local(dest_operand) {
+            InstructionOperand::Other // aliasing
+        }
+        else {
+            source_operand.to_instruction_operand(ctx)
+        },
+    };
 }
 fn gen_sbb32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {
     ctx.builder.get_local(&dest_operand);
@@ -1265,6 +1298,17 @@ fn gen_sbb32(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &Lo
     ctx.builder.get_local(&res);
     ctx.builder.set_local(dest_operand);
     ctx.builder.free_local(res);
+
+    ctx.current_instruction = Instruction::AdcSbb {
+        opsize: OPSIZE_32,
+        dest: local_to_instruction_operand(ctx, dest_operand),
+        source: if source_operand.eq_local(dest_operand) {
+            InstructionOperand::Other // aliasing
+        }
+        else {
+            source_operand.to_instruction_operand(ctx)
+        },
+    };
 }
 
 fn gen_and8(ctx: &mut JitContext, dest_operand: &WasmLocal, source_operand: &LocalOrImmediate) {