Skip to content

Commit

Permalink
Add i32.popcnt and i64.popcnt to winch
Browse files Browse the repository at this point in the history
Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com>
Co-authored-by: Chris Fallin <chris@cfallin.org>
  • Loading branch information
3 people committed Jun 13, 2023
1 parent 1d60443 commit 87b4096
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 0 deletions.
4 changes: 4 additions & 0 deletions winch/codegen/src/isa/aarch64/masm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ impl Masm for MacroAssembler {
self.asm.load_constant(0, reg);
}

fn popcnt(&mut self, _reg: Reg, _size: OperandSize) {
todo!()
}

fn push(&mut self, reg: Reg) -> u32 {
let size = <Self::ABI as abi::ABI>::word_bytes();
self.reserve_stack(size);
Expand Down
13 changes: 13 additions & 0 deletions winch/codegen/src/isa/x64/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,19 @@ impl Assembler {
});
}

pub fn popcnt(&mut self, reg: Reg, size: OperandSize) {
assert!(
self.isa_flags.has_popcnt(),
"has_popcnt isa flag required for winch"
);
self.emit(Inst::UnaryRmR {
size: size.into(),
op: args::UnaryRmROpcode::Popcnt,
src: Gpr::new(reg.into()).unwrap().into(),
dst: Writable::from_reg(Gpr::new(reg.into()).unwrap()),
});
}

/// Emit a test instruction with two register operands.
pub fn test_rr(&mut self, src: Reg, dst: Reg, size: OperandSize) {
self.emit(Inst::CmpRmiR {
Expand Down
4 changes: 4 additions & 0 deletions winch/codegen/src/isa/x64/masm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,10 @@ impl Masm for MacroAssembler {
fn jmp(&mut self, target: MachLabel) {
self.asm.jmp(target);
}

fn popcnt(&mut self, reg: Reg, size: OperandSize) {
self.asm.popcnt(reg, size)
}
}

impl MacroAssembler {
Expand Down
2 changes: 2 additions & 0 deletions winch/codegen/src/masm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ pub(crate) trait MacroAssembler {
/// Zero a particular register.
fn zero(&mut self, reg: Reg);

fn popcnt(&mut self, reg: Reg, size: OperandSize);

/// Zero a given memory range.
///
/// The default implementation divides the given memory range
Expand Down
18 changes: 18 additions & 0 deletions winch/codegen/src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ macro_rules! def_unsupported {
(emit I64Clz $($rest:tt)*) => {};
(emit I32Ctz $($rest:tt)*) => {};
(emit I64Ctz $($rest:tt)*) => {};
(emit I32Popcnt $($rest:tt)*) => {};
(emit I64Popcnt $($rest:tt)*) => {};
(emit LocalGet $($rest:tt)*) => {};
(emit LocalSet $($rest:tt)*) => {};
(emit Call $($rest:tt)*) => {};
Expand Down Expand Up @@ -450,6 +452,22 @@ where
}
}

fn visit_i32_popcnt(&mut self) {
use OperandSize::*;

self.context.unop(self.masm, S32, &mut |masm, reg, size| {
masm.popcnt(reg, size);
})
}

fn visit_i64_popcnt(&mut self) {
use OperandSize::*;

self.context.unop(self.masm, S64, &mut |masm, reg, size| {
masm.popcnt(reg, size);
})
}

fn visit_local_get(&mut self, index: u32) {
let context = &mut self.context;
let slot = context
Expand Down
18 changes: 18 additions & 0 deletions winch/filetests/filetests/x64/i32_popcnt/const.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
;;! target = "x86_64"
;;! flags = ["has_popcnt", "has_sse42"]

(module
(func (result i32)
i32.const 3
i32.popcnt
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 4883ec08 sub rsp, 8
;; 8: 4c893424 mov qword ptr [rsp], r14
;; c: b803000000 mov eax, 3
;; 11: f30fb8c0 popcnt eax, eax
;; 15: 4883c408 add rsp, 8
;; 19: 5d pop rbp
;; 1a: c3 ret
19 changes: 19 additions & 0 deletions winch/filetests/filetests/x64/i32_popcnt/reg.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
;;! target = "x86_64"
;;! flags = ["has_popcnt", "has_sse42"]

(module
(func (param i32) (result i32)
local.get 0
i32.popcnt
)
)
;; 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: f30fb8c0 popcnt eax, eax
;; 19: 4883c410 add rsp, 0x10
;; 1d: 5d pop rbp
;; 1e: c3 ret
18 changes: 18 additions & 0 deletions winch/filetests/filetests/x64/i64_popcnt/const.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
;;! target = "x86_64"
;;! flags = ["has_popcnt", "has_sse42"]

(module
(func (result i64)
i64.const 3
i64.popcnt
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 4883ec08 sub rsp, 8
;; 8: 4c893424 mov qword ptr [rsp], r14
;; c: 48c7c003000000 mov rax, 3
;; 13: f3480fb8c0 popcnt rax, rax
;; 18: 4883c408 add rsp, 8
;; 1c: 5d pop rbp
;; 1d: c3 ret
19 changes: 19 additions & 0 deletions winch/filetests/filetests/x64/i64_popcnt/reg.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
;;! target = "x86_64"
;;! flags = ["has_popcnt", "has_sse42"]

(module
(func (param i64) (result i64)
local.get 0
i64.popcnt
)
)
;; 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: f3480fb8c0 popcnt rax, rax
;; 1b: 4883c410 add rsp, 0x10
;; 1f: 5d pop rbp
;; 20: c3 ret

0 comments on commit 87b4096

Please sign in to comment.