From a5fa03abb2727667a37a16fdcf1ef4b96afd6b2d Mon Sep 17 00:00:00 2001 From: afinch7 Date: Tue, 14 May 2019 16:14:00 -0400 Subject: [PATCH 1/5] fix for ctz and clz --- .gitignore | 1 + src/backend.rs | 159 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 156 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 6e4b41eb77..19b8943105 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ rusty-tags.* docs/_build *~ \#*\# +.vscode \ No newline at end of file diff --git a/src/backend.rs b/src/backend.rs index 46cfcc9b14..e8479f09a3 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -3230,10 +3230,161 @@ impl<'this, M: ModuleContext> Context<'this, M> { self.push(out); } - unop!(i32_clz, lzcnt, Rd, u32, u32::leading_zeros); - unop!(i64_clz, lzcnt, Rq, u64, |a: u64| a.leading_zeros() as u64); - unop!(i32_ctz, tzcnt, Rd, u32, u32::trailing_zeros); - unop!(i64_ctz, tzcnt, Rq, u64, |a: u64| a.trailing_zeros() as u64); + pub fn i32_clz(&mut self) { + let val = self.pop(); + + let out_val = match val { + ValueLocation::Immediate(imm) => + ValueLocation::Immediate( + ((imm.as_int().unwrap() as i32).leading_zeros() as i32).into() + ), + ValueLocation::Stack(offset) => { + let offset = self.adjusted_offset(offset); + let temp = self.take_reg(I32).unwrap(); + let temp_2 = self.take_reg(I32).unwrap(); + + dynasm!(self.asm + ; bsr Rd(temp.rq().unwrap()), [rsp + offset] + ; mov Rd(temp_2.rq().unwrap()), DWORD 0x3fu64 as _ + ; cmove Rd(temp.rq().unwrap()), Rd(temp_2.rq().unwrap()) + ; mov Rd(temp_2.rq().unwrap()), DWORD 0x1fu64 as _ + ; xor Rd(temp.rq().unwrap()), Rd(temp_2.rq().unwrap()) + ); + ValueLocation::Reg(temp) + } + ValueLocation::Reg(_) | ValueLocation::Cond(_) => { + let reg = self.into_reg(GPRType::Rq, val).unwrap(); + let temp = self.take_reg(I32).unwrap(); + + dynasm!(self.asm + ; bsr Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) + ; mov Rd(reg.rq().unwrap()), DWORD 0x3fu64 as _ + ; cmove Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) + ; mov Rd(reg.rq().unwrap()), DWORD 0x1fu64 as _ + ; xor Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) + ); + ValueLocation::Reg(temp) + } + }; + + self.free_value(val); + self.push(out_val); + } + + pub fn i64_clz(&mut self) { + let val = self.pop(); + + let out_val = match val { + ValueLocation::Immediate(imm) => + ValueLocation::Immediate( + ((imm.as_int().unwrap() as u64).leading_zeros() as u64).into() + ), + ValueLocation::Stack(offset) => { + let offset = self.adjusted_offset(offset); + let temp = self.take_reg(I64).unwrap(); + let temp_2 = self.take_reg(I64).unwrap(); + + dynasm!(self.asm + ; bsr Rq(temp.rq().unwrap()), [rsp + offset] + ; mov Rq(temp_2.rq().unwrap()), QWORD 0x7fu64 as _ + ; cmove Rq(temp.rq().unwrap()), Rq(temp_2.rq().unwrap()) + ; mov Rq(temp_2.rq().unwrap()), QWORD 0x3fu64 as _ + ; xor Rq(temp.rq().unwrap()), Rq(temp_2.rq().unwrap()) + ); + ValueLocation::Reg(temp) + } + ValueLocation::Reg(_) | ValueLocation::Cond(_) => { + let reg = self.into_reg(GPRType::Rq, val).unwrap(); + let temp = self.take_reg(I64).unwrap(); + + dynasm!(self.asm + ; bsr Rq(temp.rq().unwrap()), Rq(reg.rq().unwrap()) + ; mov Rq(reg.rq().unwrap()), QWORD 0x7fu64 as _ + ; cmove Rq(temp.rq().unwrap()), Rq(reg.rq().unwrap()) + ; mov Rq(reg.rq().unwrap()), QWORD 0x3fu64 as _ + ; xor Rq(temp.rq().unwrap()), Rq(reg.rq().unwrap()) + ); + ValueLocation::Reg(temp) + } + }; + + self.free_value(val); + self.push(out_val); + } + + pub fn i32_ctz(&mut self) { + let val = self.pop(); + + let out_val = match val { + ValueLocation::Immediate(imm) => + ValueLocation::Immediate( + ((imm.as_int().unwrap() as u32).trailing_zeros() as u32).into() + ), + ValueLocation::Stack(offset) => { + let offset = self.adjusted_offset(offset); + let temp = self.take_reg(I32).unwrap(); + let temp_zero_val = self.take_reg(I32).unwrap(); + + dynasm!(self.asm + ; bsf Rd(temp.rq().unwrap()), [rsp + offset] + ; mov Rd(temp_zero_val.rq().unwrap()), DWORD 0x20u32 as _ + ; cmove Rd(temp.rq().unwrap()), Rd(temp_zero_val.rq().unwrap()) + ); + ValueLocation::Reg(temp) + } + ValueLocation::Reg(_) | ValueLocation::Cond(_) => { + let reg = self.into_reg(GPRType::Rq, val).unwrap(); + let temp = self.take_reg(I32).unwrap(); + + dynasm!(self.asm + ; bsf Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) + ; mov Rd(reg.rq().unwrap()), DWORD 0x20u32 as _ + ; cmove Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) + ); + ValueLocation::Reg(temp) + } + }; + + self.free_value(val); + self.push(out_val); + } + + pub fn i64_ctz(&mut self) { + let val = self.pop(); + + let out_val = match val { + ValueLocation::Immediate(imm) => + ValueLocation::Immediate( + ((imm.as_int().unwrap() as u64).trailing_zeros() as u64).into() + ), + ValueLocation::Stack(offset) => { + let offset = self.adjusted_offset(offset); + let temp = self.take_reg(I64).unwrap(); + let temp_zero_val = self.take_reg(I64).unwrap(); + + dynasm!(self.asm + ; bsf Rq(temp.rq().unwrap()), [rsp + offset] + ; mov Rq(temp_zero_val.rq().unwrap()), QWORD 0x40u64 as _ + ; cmove Rq(temp.rq().unwrap()), Rq(temp_zero_val.rq().unwrap()) + ); + ValueLocation::Reg(temp) + } + ValueLocation::Reg(_) | ValueLocation::Cond(_) => { + let reg = self.into_reg(GPRType::Rq, val).unwrap(); + let temp = self.take_reg(I64).unwrap(); + + dynasm!(self.asm + ; bsf Rq(temp.rq().unwrap()), Rq(reg.rq().unwrap()) + ; mov Rq(reg.rq().unwrap()), QWORD 0x40u64 as _ + ; cmove Rq(temp.rq().unwrap()), Rq(reg.rq().unwrap()) + ); + ValueLocation::Reg(temp) + } + }; + + self.free_value(val); + self.push(out_val); + } pub fn i32_extend_u(&mut self) { let val = self.pop(); From 6e9cff13a22d2b94626d2e90d59cacb1c0d19b63 Mon Sep 17 00:00:00 2001 From: afinch7 Date: Wed, 15 May 2019 08:01:43 -0400 Subject: [PATCH 2/5] revert .gitignore changes --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 19b8943105..6e4b41eb77 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,3 @@ rusty-tags.* docs/_build *~ \#*\# -.vscode \ No newline at end of file From 2563dc53a17e938f89a3ed4ac39e4a829f42a9b1 Mon Sep 17 00:00:00 2001 From: afinch7 Date: Wed, 15 May 2019 08:20:23 -0400 Subject: [PATCH 3/5] fixed registry leak and literal casts --- src/backend.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/backend.rs b/src/backend.rs index e8479f09a3..e5fbfcd0ad 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -3236,7 +3236,7 @@ impl<'this, M: ModuleContext> Context<'this, M> { let out_val = match val { ValueLocation::Immediate(imm) => ValueLocation::Immediate( - ((imm.as_int().unwrap() as i32).leading_zeros() as i32).into() + imm.as_i32().unwrap().leading_zeros().into() ), ValueLocation::Stack(offset) => { let offset = self.adjusted_offset(offset); @@ -3250,6 +3250,7 @@ impl<'this, M: ModuleContext> Context<'this, M> { ; mov Rd(temp_2.rq().unwrap()), DWORD 0x1fu64 as _ ; xor Rd(temp.rq().unwrap()), Rd(temp_2.rq().unwrap()) ); + self.free_value(ValueLocation::Reg(temp_2)); ValueLocation::Reg(temp) } ValueLocation::Reg(_) | ValueLocation::Cond(_) => { @@ -3277,7 +3278,7 @@ impl<'this, M: ModuleContext> Context<'this, M> { let out_val = match val { ValueLocation::Immediate(imm) => ValueLocation::Immediate( - ((imm.as_int().unwrap() as u64).leading_zeros() as u64).into() + imm.as_i64().unwrap().leading_zeros().into() ), ValueLocation::Stack(offset) => { let offset = self.adjusted_offset(offset); @@ -3291,6 +3292,7 @@ impl<'this, M: ModuleContext> Context<'this, M> { ; mov Rq(temp_2.rq().unwrap()), QWORD 0x3fu64 as _ ; xor Rq(temp.rq().unwrap()), Rq(temp_2.rq().unwrap()) ); + self.free_value(ValueLocation::Reg(temp_2)); ValueLocation::Reg(temp) } ValueLocation::Reg(_) | ValueLocation::Cond(_) => { @@ -3318,7 +3320,7 @@ impl<'this, M: ModuleContext> Context<'this, M> { let out_val = match val { ValueLocation::Immediate(imm) => ValueLocation::Immediate( - ((imm.as_int().unwrap() as u32).trailing_zeros() as u32).into() + imm.as_i32().unwrap().trailing_zeros().into() ), ValueLocation::Stack(offset) => { let offset = self.adjusted_offset(offset); @@ -3330,6 +3332,7 @@ impl<'this, M: ModuleContext> Context<'this, M> { ; mov Rd(temp_zero_val.rq().unwrap()), DWORD 0x20u32 as _ ; cmove Rd(temp.rq().unwrap()), Rd(temp_zero_val.rq().unwrap()) ); + self.free_value(ValueLocation::Reg(temp_zero_val)); ValueLocation::Reg(temp) } ValueLocation::Reg(_) | ValueLocation::Cond(_) => { @@ -3355,7 +3358,7 @@ impl<'this, M: ModuleContext> Context<'this, M> { let out_val = match val { ValueLocation::Immediate(imm) => ValueLocation::Immediate( - ((imm.as_int().unwrap() as u64).trailing_zeros() as u64).into() + imm.as_i64().unwrap().trailing_zeros().into() ), ValueLocation::Stack(offset) => { let offset = self.adjusted_offset(offset); @@ -3367,6 +3370,7 @@ impl<'this, M: ModuleContext> Context<'this, M> { ; mov Rq(temp_zero_val.rq().unwrap()), QWORD 0x40u64 as _ ; cmove Rq(temp.rq().unwrap()), Rq(temp_zero_val.rq().unwrap()) ); + self.free_value(ValueLocation::Reg(temp_zero_val)); ValueLocation::Reg(temp) } ValueLocation::Reg(_) | ValueLocation::Cond(_) => { From 48b7f8e44320ee93b0fbbc10409c5539337e906e Mon Sep 17 00:00:00 2001 From: afinch7 Date: Tue, 21 May 2019 10:50:40 -0400 Subject: [PATCH 4/5] detect lzcnt/tzcnt support and use if available --- src/backend.rs | 172 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 114 insertions(+), 58 deletions(-) diff --git a/src/backend.rs b/src/backend.rs index e5fbfcd0ad..b17322b029 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -3241,30 +3241,46 @@ impl<'this, M: ModuleContext> Context<'this, M> { ValueLocation::Stack(offset) => { let offset = self.adjusted_offset(offset); let temp = self.take_reg(I32).unwrap(); - let temp_2 = self.take_reg(I32).unwrap(); + - dynasm!(self.asm - ; bsr Rd(temp.rq().unwrap()), [rsp + offset] - ; mov Rd(temp_2.rq().unwrap()), DWORD 0x3fu64 as _ - ; cmove Rd(temp.rq().unwrap()), Rd(temp_2.rq().unwrap()) - ; mov Rd(temp_2.rq().unwrap()), DWORD 0x1fu64 as _ - ; xor Rd(temp.rq().unwrap()), Rd(temp_2.rq().unwrap()) - ); - self.free_value(ValueLocation::Reg(temp_2)); - ValueLocation::Reg(temp) + if is_x86_feature_detected!("lzcnt") { + dynasm!(self.asm + ; lzcnt Rd(temp.rq().unwrap()), [rsp + offset] + ); + ValueLocation::Reg(temp) + } else { + let temp_2 = self.take_reg(I32).unwrap(); + + dynasm!(self.asm + ; bsr Rd(temp.rq().unwrap()), [rsp + offset] + ; mov Rd(temp_2.rq().unwrap()), DWORD 0x3fu64 as _ + ; cmove Rd(temp.rq().unwrap()), Rd(temp_2.rq().unwrap()) + ; mov Rd(temp_2.rq().unwrap()), DWORD 0x1fu64 as _ + ; xor Rd(temp.rq().unwrap()), Rd(temp_2.rq().unwrap()) + ); + self.free_value(ValueLocation::Reg(temp_2)); + ValueLocation::Reg(temp) + } } ValueLocation::Reg(_) | ValueLocation::Cond(_) => { let reg = self.into_reg(GPRType::Rq, val).unwrap(); let temp = self.take_reg(I32).unwrap(); - dynasm!(self.asm - ; bsr Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) - ; mov Rd(reg.rq().unwrap()), DWORD 0x3fu64 as _ - ; cmove Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) - ; mov Rd(reg.rq().unwrap()), DWORD 0x1fu64 as _ - ; xor Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) - ); - ValueLocation::Reg(temp) + if is_x86_feature_detected!("lzcnt") { + dynasm!(self.asm + ; lzcnt Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) + ); + ValueLocation::Reg(temp) + } else { + dynasm!(self.asm + ; bsr Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) + ; mov Rd(reg.rq().unwrap()), DWORD 0x3fu64 as _ + ; cmove Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) + ; mov Rd(reg.rq().unwrap()), DWORD 0x1fu64 as _ + ; xor Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) + ); + ValueLocation::Reg(temp) + } } }; @@ -3283,30 +3299,45 @@ impl<'this, M: ModuleContext> Context<'this, M> { ValueLocation::Stack(offset) => { let offset = self.adjusted_offset(offset); let temp = self.take_reg(I64).unwrap(); - let temp_2 = self.take_reg(I64).unwrap(); - dynasm!(self.asm - ; bsr Rq(temp.rq().unwrap()), [rsp + offset] - ; mov Rq(temp_2.rq().unwrap()), QWORD 0x7fu64 as _ - ; cmove Rq(temp.rq().unwrap()), Rq(temp_2.rq().unwrap()) - ; mov Rq(temp_2.rq().unwrap()), QWORD 0x3fu64 as _ - ; xor Rq(temp.rq().unwrap()), Rq(temp_2.rq().unwrap()) - ); - self.free_value(ValueLocation::Reg(temp_2)); - ValueLocation::Reg(temp) + if is_x86_feature_detected!("lzcnt") { + dynasm!(self.asm + ; lzcnt Rq(temp.rq().unwrap()), [rsp + offset] + ); + ValueLocation::Reg(temp) + } else { + let temp_2 = self.take_reg(I64).unwrap(); + + dynasm!(self.asm + ; bsr Rq(temp.rq().unwrap()), [rsp + offset] + ; mov Rq(temp_2.rq().unwrap()), QWORD 0x7fu64 as _ + ; cmove Rq(temp.rq().unwrap()), Rq(temp_2.rq().unwrap()) + ; mov Rq(temp_2.rq().unwrap()), QWORD 0x3fu64 as _ + ; xor Rq(temp.rq().unwrap()), Rq(temp_2.rq().unwrap()) + ); + self.free_value(ValueLocation::Reg(temp_2)); + ValueLocation::Reg(temp) + } } ValueLocation::Reg(_) | ValueLocation::Cond(_) => { let reg = self.into_reg(GPRType::Rq, val).unwrap(); let temp = self.take_reg(I64).unwrap(); - dynasm!(self.asm - ; bsr Rq(temp.rq().unwrap()), Rq(reg.rq().unwrap()) - ; mov Rq(reg.rq().unwrap()), QWORD 0x7fu64 as _ - ; cmove Rq(temp.rq().unwrap()), Rq(reg.rq().unwrap()) - ; mov Rq(reg.rq().unwrap()), QWORD 0x3fu64 as _ - ; xor Rq(temp.rq().unwrap()), Rq(reg.rq().unwrap()) - ); - ValueLocation::Reg(temp) + if is_x86_feature_detected!("lzcnt") { + dynasm!(self.asm + ; lzcnt Rq(temp.rq().unwrap()), Rq(reg.rq().unwrap()) + ); + ValueLocation::Reg(temp) + } else { + dynasm!(self.asm + ; bsr Rq(temp.rq().unwrap()), Rq(reg.rq().unwrap()) + ; mov Rq(reg.rq().unwrap()), QWORD 0x7fu64 as _ + ; cmove Rq(temp.rq().unwrap()), Rq(reg.rq().unwrap()) + ; mov Rq(reg.rq().unwrap()), QWORD 0x3fu64 as _ + ; xor Rq(temp.rq().unwrap()), Rq(reg.rq().unwrap()) + ); + ValueLocation::Reg(temp) + } } }; @@ -3325,26 +3356,41 @@ impl<'this, M: ModuleContext> Context<'this, M> { ValueLocation::Stack(offset) => { let offset = self.adjusted_offset(offset); let temp = self.take_reg(I32).unwrap(); - let temp_zero_val = self.take_reg(I32).unwrap(); - dynasm!(self.asm - ; bsf Rd(temp.rq().unwrap()), [rsp + offset] - ; mov Rd(temp_zero_val.rq().unwrap()), DWORD 0x20u32 as _ - ; cmove Rd(temp.rq().unwrap()), Rd(temp_zero_val.rq().unwrap()) - ); - self.free_value(ValueLocation::Reg(temp_zero_val)); - ValueLocation::Reg(temp) + if is_x86_feature_detected!("lzcnt") { + dynasm!(self.asm + ; tzcnt Rd(temp.rq().unwrap()), [rsp + offset] + ); + ValueLocation::Reg(temp) + } else { + let temp_zero_val = self.take_reg(I32).unwrap(); + + dynasm!(self.asm + ; bsf Rd(temp.rq().unwrap()), [rsp + offset] + ; mov Rd(temp_zero_val.rq().unwrap()), DWORD 0x20u32 as _ + ; cmove Rd(temp.rq().unwrap()), Rd(temp_zero_val.rq().unwrap()) + ); + self.free_value(ValueLocation::Reg(temp_zero_val)); + ValueLocation::Reg(temp) + } } ValueLocation::Reg(_) | ValueLocation::Cond(_) => { let reg = self.into_reg(GPRType::Rq, val).unwrap(); let temp = self.take_reg(I32).unwrap(); - dynasm!(self.asm - ; bsf Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) - ; mov Rd(reg.rq().unwrap()), DWORD 0x20u32 as _ - ; cmove Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) - ); - ValueLocation::Reg(temp) + if is_x86_feature_detected!("lzcnt") { + dynasm!(self.asm + ; tzcnt Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) + ); + ValueLocation::Reg(temp) + } else { + dynasm!(self.asm + ; bsf Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) + ; mov Rd(reg.rq().unwrap()), DWORD 0x20u32 as _ + ; cmove Rd(temp.rq().unwrap()), Rd(reg.rq().unwrap()) + ); + ValueLocation::Reg(temp) + } } }; @@ -3363,15 +3409,25 @@ impl<'this, M: ModuleContext> Context<'this, M> { ValueLocation::Stack(offset) => { let offset = self.adjusted_offset(offset); let temp = self.take_reg(I64).unwrap(); - let temp_zero_val = self.take_reg(I64).unwrap(); + + if is_x86_feature_detected!("lzcnt") { + dynasm!(self.asm + ; tzcnt Rq(temp.rq().unwrap()), [rsp + offset] + ); + ValueLocation::Reg(temp) + } else { + let temp_zero_val = self.take_reg(I64).unwrap(); - dynasm!(self.asm - ; bsf Rq(temp.rq().unwrap()), [rsp + offset] - ; mov Rq(temp_zero_val.rq().unwrap()), QWORD 0x40u64 as _ - ; cmove Rq(temp.rq().unwrap()), Rq(temp_zero_val.rq().unwrap()) - ); - self.free_value(ValueLocation::Reg(temp_zero_val)); - ValueLocation::Reg(temp) + dynasm!(self.asm + ; bsf Rq(temp.rq().unwrap()), [rsp + offset] + ; mov Rq(temp_zero_val.rq().unwrap()), QWORD 0x40u64 as _ + ; cmove Rq(temp.rq().unwrap()), Rq(temp_zero_val.rq().unwrap()) + ); + self.free_value(ValueLocation::Reg(temp_zero_val)); + ValueLocation::Reg(temp) + } + + } ValueLocation::Reg(_) | ValueLocation::Cond(_) => { let reg = self.into_reg(GPRType::Rq, val).unwrap(); From 9b6abc149797be731efb75e4f8e5af10dde62227 Mon Sep 17 00:00:00 2001 From: afinch7 Date: Wed, 22 May 2019 09:47:04 -0400 Subject: [PATCH 5/5] fmt --- src/backend.rs | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/backend.rs b/src/backend.rs index b17322b029..535da45656 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -3234,14 +3234,12 @@ impl<'this, M: ModuleContext> Context<'this, M> { let val = self.pop(); let out_val = match val { - ValueLocation::Immediate(imm) => - ValueLocation::Immediate( - imm.as_i32().unwrap().leading_zeros().into() - ), + ValueLocation::Immediate(imm) => { + ValueLocation::Immediate(imm.as_i32().unwrap().leading_zeros().into()) + } ValueLocation::Stack(offset) => { let offset = self.adjusted_offset(offset); let temp = self.take_reg(I32).unwrap(); - if is_x86_feature_detected!("lzcnt") { dynasm!(self.asm @@ -3292,10 +3290,9 @@ impl<'this, M: ModuleContext> Context<'this, M> { let val = self.pop(); let out_val = match val { - ValueLocation::Immediate(imm) => - ValueLocation::Immediate( - imm.as_i64().unwrap().leading_zeros().into() - ), + ValueLocation::Immediate(imm) => { + ValueLocation::Immediate(imm.as_i64().unwrap().leading_zeros().into()) + } ValueLocation::Stack(offset) => { let offset = self.adjusted_offset(offset); let temp = self.take_reg(I64).unwrap(); @@ -3328,7 +3325,7 @@ impl<'this, M: ModuleContext> Context<'this, M> { ; lzcnt Rq(temp.rq().unwrap()), Rq(reg.rq().unwrap()) ); ValueLocation::Reg(temp) - } else { + } else { dynasm!(self.asm ; bsr Rq(temp.rq().unwrap()), Rq(reg.rq().unwrap()) ; mov Rq(reg.rq().unwrap()), QWORD 0x7fu64 as _ @@ -3349,10 +3346,9 @@ impl<'this, M: ModuleContext> Context<'this, M> { let val = self.pop(); let out_val = match val { - ValueLocation::Immediate(imm) => - ValueLocation::Immediate( - imm.as_i32().unwrap().trailing_zeros().into() - ), + ValueLocation::Immediate(imm) => { + ValueLocation::Immediate(imm.as_i32().unwrap().trailing_zeros().into()) + } ValueLocation::Stack(offset) => { let offset = self.adjusted_offset(offset); let temp = self.take_reg(I32).unwrap(); @@ -3402,14 +3398,13 @@ impl<'this, M: ModuleContext> Context<'this, M> { let val = self.pop(); let out_val = match val { - ValueLocation::Immediate(imm) => - ValueLocation::Immediate( - imm.as_i64().unwrap().trailing_zeros().into() - ), + ValueLocation::Immediate(imm) => { + ValueLocation::Immediate(imm.as_i64().unwrap().trailing_zeros().into()) + } ValueLocation::Stack(offset) => { let offset = self.adjusted_offset(offset); let temp = self.take_reg(I64).unwrap(); - + if is_x86_feature_detected!("lzcnt") { dynasm!(self.asm ; tzcnt Rq(temp.rq().unwrap()), [rsp + offset] @@ -3426,8 +3421,6 @@ impl<'this, M: ModuleContext> Context<'this, M> { self.free_value(ValueLocation::Reg(temp_zero_val)); ValueLocation::Reg(temp) } - - } ValueLocation::Reg(_) | ValueLocation::Cond(_) => { let reg = self.into_reg(GPRType::Rq, val).unwrap(); @@ -5482,4 +5475,3 @@ impl IntoLabel for (LabelValue, LabelValue) { Box::new(const_values(self.0, self.1)) } } -