Browse Source

jit imul32

Fabian 3 years ago
parent
commit
705b22ee14
1 changed files with 36 additions and 6 deletions
  1. 36 6
      src/rust/jit_instructions.rs

+ 36 - 6
src/rust/jit_instructions.rs

@@ -1386,6 +1386,40 @@ fn gen_mul32(ctx: &mut JitContext) {
     codegen::gen_set_flags_changed(ctx.builder, FLAGS_ALL & !1 & !FLAG_OVERFLOW);
 }
 
+fn gen_imul32(ctx: &mut JitContext) {
+    ctx.builder.extend_signed_i32_to_i64();
+
+    codegen::gen_get_reg32(ctx, regs::EAX);
+    ctx.builder.extend_signed_i32_to_i64();
+    ctx.builder.mul_i64();
+
+    let result = ctx.builder.tee_new_local_i64();
+    ctx.builder.const_i64(32);
+    ctx.builder.shr_u_i64();
+    ctx.builder.wrap_i64_to_i32();
+    codegen::gen_set_reg32(ctx, regs::EDX);
+
+    ctx.builder.get_local_i64(&result);
+    ctx.builder.free_local_i64(result);
+    ctx.builder.wrap_i64_to_i32();
+    codegen::gen_set_reg32(ctx, regs::EAX);
+
+    codegen::gen_get_reg32(ctx, regs::EDX);
+    codegen::gen_get_reg32(ctx, regs::EAX);
+    ctx.builder.const_i32(31);
+    ctx.builder.shr_s_i32();
+    ctx.builder.eq_i32();
+    ctx.builder.if_void();
+    codegen::gen_clear_flags_bits(ctx.builder, 1 | FLAG_OVERFLOW);
+    ctx.builder.else_();
+    codegen::gen_set_flags_bits(ctx.builder, 1 | FLAG_OVERFLOW);
+    ctx.builder.block_end();
+
+    codegen::gen_set_last_result(ctx.builder, &ctx.register_locals[regs::EAX as usize]);
+    codegen::gen_set_last_op_size(ctx.builder, OPSIZE_32);
+    codegen::gen_set_flags_changed(ctx.builder, FLAGS_ALL & !1 & !FLAG_OVERFLOW);
+}
+
 fn gen_imul_reg32(
     builder: &mut WasmBuilder,
     dest_operand: &WasmLocal,
@@ -3582,15 +3616,11 @@ pub fn instr16_F7_5_reg_jit(ctx: &mut JitContext, r: u32) {
 }
 pub fn instr32_F7_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
     codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
-    codegen::gen_move_registers_from_locals_to_memory(ctx);
-    ctx.builder.call_fn1("imul32");
-    codegen::gen_move_registers_from_memory_to_locals(ctx);
+    gen_imul32(ctx);
 }
 pub fn instr32_F7_5_reg_jit(ctx: &mut JitContext, r: u32) {
     codegen::gen_get_reg32(ctx, r);
-    codegen::gen_move_registers_from_locals_to_memory(ctx);
-    ctx.builder.call_fn1("imul32");
-    codegen::gen_move_registers_from_memory_to_locals(ctx);
+    gen_imul32(ctx);
 }
 
 pub fn instr16_F7_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {