From 0893f7c741abb5868de02b7ad840af8f0c093008 Mon Sep 17 00:00:00 2001 From: Jeffrey Charles Date: Fri, 2 Jun 2023 11:08:52 -0400 Subject: [PATCH] Add support to Winch for i*.eqz instructions (#6508) --- fuzz/fuzz_targets/differential.rs | 2 ++ winch/codegen/src/codegen/context.rs | 11 ++++++++ winch/codegen/src/visitor.rs | 18 ++++++++++++ .../filetests/filetests/x64/i32_eqz/const.wat | 19 +++++++++++++ .../filetests/filetests/x64/i32_eqz/local.wat | 28 +++++++++++++++++++ .../filetests/filetests/x64/i32_eqz/param.wat | 20 +++++++++++++ .../filetests/x64/i64_eqz/32_const.wat | 19 +++++++++++++ .../filetests/x64/i64_eqz/64_const.wat | 20 +++++++++++++ .../filetests/filetests/x64/i64_eqz/local.wat | 28 +++++++++++++++++++ .../filetests/filetests/x64/i64_eqz/param.wat | 20 +++++++++++++ 10 files changed, 185 insertions(+) create mode 100644 winch/filetests/filetests/x64/i32_eqz/const.wat create mode 100644 winch/filetests/filetests/x64/i32_eqz/local.wat create mode 100644 winch/filetests/filetests/x64/i32_eqz/param.wat create mode 100644 winch/filetests/filetests/x64/i64_eqz/32_const.wat create mode 100644 winch/filetests/filetests/x64/i64_eqz/64_const.wat create mode 100644 winch/filetests/filetests/x64/i64_eqz/local.wat create mode 100644 winch/filetests/filetests/x64/i64_eqz/param.wat diff --git a/fuzz/fuzz_targets/differential.rs b/fuzz/fuzz_targets/differential.rs index 5c6a35a202ce..da17604f1a57 100644 --- a/fuzz/fuzz_targets/differential.rs +++ b/fuzz/fuzz_targets/differential.rs @@ -326,6 +326,8 @@ fn winch_supports_module(module: &[u8]) -> bool { | I64GeS { .. } | I32GeU { .. } | I64GeU { .. } + | I32Eqz { .. } + | I64Eqz { .. } | LocalGet { .. } | LocalSet { .. } | Call { .. } diff --git a/winch/codegen/src/codegen/context.rs b/winch/codegen/src/codegen/context.rs index 12d3f8de4123..ff667537edb5 100644 --- a/winch/codegen/src/codegen/context.rs +++ b/winch/codegen/src/codegen/context.rs @@ -124,6 +124,17 @@ impl<'a> CodeGenContext<'a> { }; } + /// Prepares arguments for emitting a unary operation. + pub fn unop(&mut self, masm: &mut M, size: OperandSize, emit: &mut F) + where + F: FnMut(&mut M, RegImm, OperandSize), + M: MacroAssembler, + { + let reg = self.pop_to_reg(masm, None, size); + emit(masm, reg.into(), size); + self.stack.push(Val::reg(reg)); + } + /// Prepares arguments for emitting an i32 binary operation. pub fn i32_binop(&mut self, masm: &mut M, emit: &mut F) where diff --git a/winch/codegen/src/visitor.rs b/winch/codegen/src/visitor.rs index 2dcf56201da4..eaa1a7ec19be 100644 --- a/winch/codegen/src/visitor.rs +++ b/winch/codegen/src/visitor.rs @@ -67,6 +67,8 @@ macro_rules! def_unsupported { (emit I64GeS $($rest:tt)*) => {}; (emit I32GeU $($rest:tt)*) => {}; (emit I64GeU $($rest:tt)*) => {}; + (emit I32Eqz $($rest:tt)*) => {}; + (emit I64Eqz $($rest:tt)*) => {}; (emit LocalGet $($rest:tt)*) => {}; (emit LocalSet $($rest:tt)*) => {}; (emit Call $($rest:tt)*) => {}; @@ -268,6 +270,22 @@ where self.cmp_i64s(CmpKind::GeU); } + fn visit_i32_eqz(&mut self) { + use OperandSize::*; + + self.context.unop(self.masm, S32, &mut |masm, reg, size| { + masm.cmp_with_set(reg, reg, RegImm::imm(0), CmpKind::Eq, size); + }); + } + + fn visit_i64_eqz(&mut self) { + use OperandSize::*; + + self.context.unop(self.masm, S64, &mut |masm, reg, size| { + masm.cmp_with_set(reg, reg, RegImm::imm(0), CmpKind::Eq, size); + }); + } + fn visit_end(&mut self) {} fn visit_local_get(&mut self, index: u32) { diff --git a/winch/filetests/filetests/x64/i32_eqz/const.wat b/winch/filetests/filetests/x64/i32_eqz/const.wat new file mode 100644 index 000000000000..d6624bef9cad --- /dev/null +++ b/winch/filetests/filetests/x64/i32_eqz/const.wat @@ -0,0 +1,19 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (i32.const 1) + (i32.eqz) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 4883ec08 sub rsp, 8 +;; 8: 4c893424 mov qword ptr [rsp], r14 +;; c: b801000000 mov eax, 1 +;; 11: 83f800 cmp eax, 0 +;; 14: b800000000 mov eax, 0 +;; 19: 400f94c0 sete al +;; 1d: 4883c408 add rsp, 8 +;; 21: 5d pop rbp +;; 22: c3 ret diff --git a/winch/filetests/filetests/x64/i32_eqz/local.wat b/winch/filetests/filetests/x64/i32_eqz/local.wat new file mode 100644 index 000000000000..a1631bc8195e --- /dev/null +++ b/winch/filetests/filetests/x64/i32_eqz/local.wat @@ -0,0 +1,28 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (local $foo i32) + + (i32.const 2) + (local.set $foo) + + (local.get $foo) + (i32.eqz) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 4883ec10 sub rsp, 0x10 +;; 8: 48c744240800000000 +;; mov qword ptr [rsp + 8], 0 +;; 11: 4c89742404 mov qword ptr [rsp + 4], r14 +;; 16: b802000000 mov eax, 2 +;; 1b: 8944240c mov dword ptr [rsp + 0xc], eax +;; 1f: 8b44240c mov eax, dword ptr [rsp + 0xc] +;; 23: 83f800 cmp eax, 0 +;; 26: b800000000 mov eax, 0 +;; 2b: 400f94c0 sete al +;; 2f: 4883c410 add rsp, 0x10 +;; 33: 5d pop rbp +;; 34: c3 ret diff --git a/winch/filetests/filetests/x64/i32_eqz/param.wat b/winch/filetests/filetests/x64/i32_eqz/param.wat new file mode 100644 index 000000000000..66b55364521e --- /dev/null +++ b/winch/filetests/filetests/x64/i32_eqz/param.wat @@ -0,0 +1,20 @@ +;;! target = "x86_64" + +(module + (func (param i32) (result i32) + (local.get 0) + (i32.eqz) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 4883ec10 sub rsp, 0x10 +;; 8: 897c240c mov dword ptr [rsp + 0xc], edi +;; c: 4c89742404 mov qword ptr [rsp + 4], r14 +;; 11: 8b44240c mov eax, dword ptr [rsp + 0xc] +;; 15: 83f800 cmp eax, 0 +;; 18: b800000000 mov eax, 0 +;; 1d: 400f94c0 sete al +;; 21: 4883c410 add rsp, 0x10 +;; 25: 5d pop rbp +;; 26: c3 ret diff --git a/winch/filetests/filetests/x64/i64_eqz/32_const.wat b/winch/filetests/filetests/x64/i64_eqz/32_const.wat new file mode 100644 index 000000000000..257d0f0067e4 --- /dev/null +++ b/winch/filetests/filetests/x64/i64_eqz/32_const.wat @@ -0,0 +1,19 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (i64.const 1) + (i64.eqz) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 4883ec08 sub rsp, 8 +;; 8: 4c893424 mov qword ptr [rsp], r14 +;; c: 48c7c001000000 mov rax, 1 +;; 13: 4883f800 cmp rax, 0 +;; 17: b800000000 mov eax, 0 +;; 1c: 400f94c0 sete al +;; 20: 4883c408 add rsp, 8 +;; 24: 5d pop rbp +;; 25: c3 ret diff --git a/winch/filetests/filetests/x64/i64_eqz/64_const.wat b/winch/filetests/filetests/x64/i64_eqz/64_const.wat new file mode 100644 index 000000000000..7326c59dedec --- /dev/null +++ b/winch/filetests/filetests/x64/i64_eqz/64_const.wat @@ -0,0 +1,20 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (i64.const 9223372036854775807) + (i64.eqz) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 4883ec08 sub rsp, 8 +;; 8: 4c893424 mov qword ptr [rsp], r14 +;; c: 48b8ffffffffffffff7f +;; movabs rax, 0x7fffffffffffffff +;; 16: 4883f800 cmp rax, 0 +;; 1a: b800000000 mov eax, 0 +;; 1f: 400f94c0 sete al +;; 23: 4883c408 add rsp, 8 +;; 27: 5d pop rbp +;; 28: c3 ret diff --git a/winch/filetests/filetests/x64/i64_eqz/local.wat b/winch/filetests/filetests/x64/i64_eqz/local.wat new file mode 100644 index 000000000000..849164e6cc7f --- /dev/null +++ b/winch/filetests/filetests/x64/i64_eqz/local.wat @@ -0,0 +1,28 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (local $foo i64) + + (i64.const 2) + (local.set $foo) + + (local.get $foo) + (i64.eqz) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 4883ec10 sub rsp, 0x10 +;; 8: 48c744240800000000 +;; mov qword ptr [rsp + 8], 0 +;; 11: 4c893424 mov qword ptr [rsp], r14 +;; 15: 48c7c002000000 mov rax, 2 +;; 1c: 4889442408 mov qword ptr [rsp + 8], rax +;; 21: 488b442408 mov rax, qword ptr [rsp + 8] +;; 26: 4883f800 cmp rax, 0 +;; 2a: b800000000 mov eax, 0 +;; 2f: 400f94c0 sete al +;; 33: 4883c410 add rsp, 0x10 +;; 37: 5d pop rbp +;; 38: c3 ret diff --git a/winch/filetests/filetests/x64/i64_eqz/param.wat b/winch/filetests/filetests/x64/i64_eqz/param.wat new file mode 100644 index 000000000000..48972c40b832 --- /dev/null +++ b/winch/filetests/filetests/x64/i64_eqz/param.wat @@ -0,0 +1,20 @@ +;;! target = "x86_64" + +(module + (func (param i64) (result i32) + (local.get 0) + (i64.eqz) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 4883ec10 sub rsp, 0x10 +;; 8: 48897c2408 mov qword ptr [rsp + 8], rdi +;; d: 4c893424 mov qword ptr [rsp], r14 +;; 11: 488b442408 mov rax, qword ptr [rsp + 8] +;; 16: 4883f800 cmp rax, 0 +;; 1a: b800000000 mov eax, 0 +;; 1f: 400f94c0 sete al +;; 23: 4883c410 add rsp, 0x10 +;; 27: 5d pop rbp +;; 28: c3 ret