diff --git a/cranelift/codegen/src/ir/immediates.rs b/cranelift/codegen/src/ir/immediates.rs index a98a9596f6..4421f1fdaa 100644 --- a/cranelift/codegen/src/ir/immediates.rs +++ b/cranelift/codegen/src/ir/immediates.rs @@ -8,7 +8,7 @@ use alloc::vec::Vec; use core::cmp::Ordering; use core::convert::TryFrom; use core::fmt::{self, Display, Formatter}; -use core::ops::{Add, Div, Mul, Neg, Sub}; +use core::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Not, Sub}; use core::str::FromStr; use core::{i32, u32}; #[cfg(feature = "enable-serde")] @@ -921,6 +921,38 @@ impl Div for Ieee32 { } } +impl BitAnd for Ieee32 { + type Output = Ieee32; + + fn bitand(self, rhs: Self) -> Self::Output { + Self::with_bits(self.bits() & rhs.bits()) + } +} + +impl BitOr for Ieee32 { + type Output = Ieee32; + + fn bitor(self, rhs: Self) -> Self::Output { + Self::with_bits(self.bits() | rhs.bits()) + } +} + +impl BitXor for Ieee32 { + type Output = Ieee32; + + fn bitxor(self, rhs: Self) -> Self::Output { + Self::with_bits(self.bits() ^ rhs.bits()) + } +} + +impl Not for Ieee32 { + type Output = Ieee32; + + fn not(self) -> Self::Output { + Self::with_bits(!self.bits()) + } +} + impl Ieee64 { /// Create a new `Ieee64` containing the bits of `x`. pub fn with_bits(x: u64) -> Self { @@ -1113,6 +1145,38 @@ impl Div for Ieee64 { } } +impl BitAnd for Ieee64 { + type Output = Ieee64; + + fn bitand(self, rhs: Self) -> Self::Output { + Self::with_bits(self.bits() & rhs.bits()) + } +} + +impl BitOr for Ieee64 { + type Output = Ieee64; + + fn bitor(self, rhs: Self) -> Self::Output { + Self::with_bits(self.bits() | rhs.bits()) + } +} + +impl BitXor for Ieee64 { + type Output = Ieee64; + + fn bitxor(self, rhs: Self) -> Self::Output { + Self::with_bits(self.bits() ^ rhs.bits()) + } +} + +impl Not for Ieee64 { + type Output = Ieee64; + + fn not(self) -> Self::Output { + Self::with_bits(!self.bits()) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/cranelift/filetests/filetests/runtests/float-bitops.clif b/cranelift/filetests/filetests/runtests/float-bitops.clif new file mode 100644 index 0000000000..9ccfa070e0 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/float-bitops.clif @@ -0,0 +1,61 @@ +test interpret + +function %bnot_f32(f32) -> f32 { +block0(v0: f32): + v1 = bnot v0 + return v1 +} + +; run: %bnot_f32(0x0.0) == -NaN:0x3fffff +; run: %bnot_f32(-0x0.0) == +NaN:0x3fffff +; run: %bnot_f32(-NaN:0x3fffff) == 0x0.0 +; run: %bnot_f32(0x1.666666p-25) == -0x1.999998p26 +; run: %bnot_f32(0x1.aaaaaap43) == -0x1.555554p-42 + + +function %band_f32(f32, f32) -> f32 { +block0(v0: f32, v1: f32): + v2 = band v0, v1 + return v2 +} + +; run: %band_f32(0x0.0, 0x0.0) == 0x0.0 +; run: %band_f32(-0x0.0, -0x0.0) == -0x0.0 +; run: %band_f32(-0x0.0, 0x0.0) == 0x0.0 +; run: %band_f32(-NaN:0x3f0000, 0x0.01fffep-126) == 0x0.0 +; run: %band_f32(-NaN:0x3fffff, -NaN:0x3fffff) == -NaN:0x3fffff +; run: %band_f32(-NaN:0x3fffff, 0x1.aaaaaap43) == 0x1.aaaaaap43 +; run: %band_f32(-NaN:0x3fffff, -0x1.555554p-42) == -0x1.555554p-42 +; run: %band_f32(0x1.aaaaaap43, -0x1.555554p-42) == 0x0.0 + + +function %bor_f32(f32, f32) -> f32 { +block0(v0: f32, v1: f32): + v2 = bor v0, v1 + return v2 +} + +; run: %bor_f32(0x0.0, 0x0.0) == 0x0.0 +; run: %bor_f32(-0x0.0, -0x0.0) == -0x0.0 +; run: %bor_f32(-0x0.0, 0x0.0) == -0x0.0 +; run: %bor_f32(-NaN:0x3f0000, 0x0.01fffep-126) == -NaN:0x3fffff +; run: %bor_f32(-NaN:0x3fffff, -NaN:0x3fffff) == -NaN:0x3fffff +; run: %bor_f32(-NaN:0x3fffff, 0x1.aaaaaap43) == -NaN:0x3fffff +; run: %bor_f32(-NaN:0x3fffff, 0x1.666666p-25) == -NaN:0x3fffff +; run: %bor_f32(0x1.aaaaaap43, -0x1.555554p-42) == -NaN:0x3fffff + + +function %bxor_f32(f32, f32) -> f32 { +block0(v0: f32, v1: f32): + v2 = bxor v0, v1 + return v2 +} + +; run: %bxor_f32(0x0.0, 0x0.0) == 0x0.0 +; run: %bxor_f32(-0x0.0, -0x0.0) == 0x0.0 +; run: %bxor_f32(-0x0.0, 0x0.0) == -0x0.0 +; run: %bxor_f32(-NaN:0x3f0000, 0x0.01fffep-126) == -NaN:0x3fffff +; run: %bxor_f32(-NaN:0x3fffff, -NaN:0x3fffff) == 0x0.0 +; run: %bxor_f32(-NaN:0x3fffff, 0x1.aaaaaap43) == -0x1.555554p-42 +; run: %bxor_f32(-NaN:0x3fffff, 0x1.666666p-25) == -0x1.999998p26 +; run: %bxor_f32(0x1.aaaaaap43, -0x1.555554p-42) == -NaN:0x3fffff \ No newline at end of file diff --git a/cranelift/interpreter/src/value.rs b/cranelift/interpreter/src/value.rs index d5964d69fa..ef043c801b 100644 --- a/cranelift/interpreter/src/value.rs +++ b/cranelift/interpreter/src/value.rs @@ -662,19 +662,19 @@ impl Value for DataValue { } fn and(self, other: Self) -> ValueResult { - binary_match!(&(&self, &other); [B, I8, I16, I32, I64]) + binary_match!(&(self, other); [B, I8, I16, I32, I64, F32, F64]) } fn or(self, other: Self) -> ValueResult { - binary_match!(|(&self, &other); [B, I8, I16, I32, I64]) + binary_match!(|(self, other); [B, I8, I16, I32, I64, F32, F64]) } fn xor(self, other: Self) -> ValueResult { - binary_match!(^(&self, &other); [I8, I16, I32, I64]) + binary_match!(^(self, other); [I8, I16, I32, I64, F32, F64]) } fn not(self) -> ValueResult { - unary_match!(!(&self); [B, I8, I16, I32, I64]) + unary_match!(!(self); [B, I8, I16, I32, I64, F32, F64]) } fn count_ones(self) -> ValueResult {