detect lzcnt/tzcnt support and use if available

This commit is contained in:
afinch7
2019-05-21 10:50:40 -04:00
parent 2563dc53a1
commit 48b7f8e443

View File

@@ -3241,6 +3241,14 @@ impl<'this, M: ModuleContext> Context<'this, M> {
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
; lzcnt Rd(temp.rq().unwrap()), [rsp + offset]
);
ValueLocation::Reg(temp)
} else {
let temp_2 = self.take_reg(I32).unwrap();
dynasm!(self.asm
@@ -3253,10 +3261,17 @@ impl<'this, M: ModuleContext> Context<'this, M> {
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();
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 _
@@ -3266,6 +3281,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
);
ValueLocation::Reg(temp)
}
}
};
self.free_value(val);
@@ -3283,6 +3299,13 @@ impl<'this, M: ModuleContext> Context<'this, M> {
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
; lzcnt Rq(temp.rq().unwrap()), [rsp + offset]
);
ValueLocation::Reg(temp)
} else {
let temp_2 = self.take_reg(I64).unwrap();
dynasm!(self.asm
@@ -3295,10 +3318,17 @@ impl<'this, M: ModuleContext> Context<'this, M> {
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();
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 _
@@ -3308,6 +3338,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
);
ValueLocation::Reg(temp)
}
}
};
self.free_value(val);
@@ -3325,6 +3356,13 @@ impl<'this, M: ModuleContext> Context<'this, M> {
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
; tzcnt Rd(temp.rq().unwrap()), [rsp + offset]
);
ValueLocation::Reg(temp)
} else {
let temp_zero_val = self.take_reg(I32).unwrap();
dynasm!(self.asm
@@ -3335,10 +3373,17 @@ 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();
let temp = self.take_reg(I32).unwrap();
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 _
@@ -3346,6 +3391,7 @@ impl<'this, M: ModuleContext> Context<'this, M> {
);
ValueLocation::Reg(temp)
}
}
};
self.free_value(val);
@@ -3363,6 +3409,13 @@ impl<'this, M: ModuleContext> Context<'this, M> {
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]
);
ValueLocation::Reg(temp)
} else {
let temp_zero_val = self.take_reg(I64).unwrap();
dynasm!(self.asm
@@ -3373,6 +3426,9 @@ 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();
let temp = self.take_reg(I64).unwrap();