Skip to content

Commit

Permalink
cmov: XOR within the ASM block (#925)
Browse files Browse the repository at this point in the history
  • Loading branch information
brxken128 authored Oct 3, 2023
1 parent 895b4a5 commit 582883a
Showing 1 changed file with 66 additions and 6 deletions.
72 changes: 66 additions & 6 deletions cmov/src/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@ macro_rules! cmov {
};
}

macro_rules! cmov_eq {
($xor:expr, $instruction:expr, $lhs:expr, $rhs:expr, $condition:expr, $dst:expr) => {
let mut tmp = *$dst as u16;
unsafe {
asm! {
$xor,
$instruction,
inout(reg) *$lhs => _,
in(reg) *$rhs,
inlateout(reg) tmp,
in(reg) $condition as u16,
options(pure, nomem, nostack),
};
}
*$dst = tmp as u8;
};
}

impl Cmov for u16 {
#[inline]
fn cmovnz(&mut self, value: &Self, condition: Condition) {
Expand All @@ -40,12 +58,26 @@ impl Cmov for u16 {
impl CmovEq for u16 {
#[inline]
fn cmoveq(&self, rhs: &Self, input: Condition, output: &mut Condition) {
output.cmovz(&input, (self ^ rhs) as u8);
cmov_eq!(
"xor {0:x}, {1:x}",
"cmovz {2:e}, {3:e}",
self,
rhs,
input,
output
);
}

#[inline]
fn cmovne(&self, rhs: &Self, input: Condition, output: &mut Condition) {
output.cmovnz(&input, (self ^ rhs) as u8);
cmov_eq!(
"xor {0:x}, {1:x}",
"cmovnz {2:e}, {3:e}",
self,
rhs,
input,
output
);
}
}

Expand All @@ -64,12 +96,26 @@ impl Cmov for u32 {
impl CmovEq for u32 {
#[inline]
fn cmoveq(&self, rhs: &Self, input: Condition, output: &mut Condition) {
output.cmovz(&input, (self ^ rhs) as u8);
cmov_eq!(
"xor {0:e}, {1:e}",
"cmovz {2:e}, {3:e}",
self,
rhs,
input,
output
);
}

#[inline]
fn cmovne(&self, rhs: &Self, input: Condition, output: &mut Condition) {
output.cmovnz(&input, (self ^ rhs) as u8);
cmov_eq!(
"xor {0:e}, {1:e}",
"cmovnz {2:e}, {3:e}",
self,
rhs,
input,
output
);
}
}

Expand Down Expand Up @@ -140,11 +186,25 @@ impl Cmov for u64 {
impl CmovEq for u64 {
#[inline]
fn cmoveq(&self, rhs: &Self, input: Condition, output: &mut Condition) {
output.cmovz(&input, (self ^ rhs) as u8);
cmov_eq!(
"xor {0:r}, {1:r}",
"cmovz {2:r}, {3:r}",
self,
rhs,
input,
output
);
}

#[inline]
fn cmovne(&self, rhs: &Self, input: Condition, output: &mut Condition) {
output.cmovnz(&input, (self ^ rhs) as u8);
cmov_eq!(
"xor {0:r}, {1:r}",
"cmovnz {2:r}, {3:r}",
self,
rhs,
input,
output
);
}
}

0 comments on commit 582883a

Please sign in to comment.