use core::ops::{ Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign, }; use crate::F16; #[rustfmt::skip] // work around for https://github.com/rust-lang/rustfmt/issues/4823 macro_rules! make_types { ( #[bool] $(#[scalar = $ScalarBool:ident])? type $Bool:ident; #[u8] $(#[scalar = $ScalarU8:ident])? type $U8:ident; #[u16] $(#[scalar = $ScalarU16:ident])? type $U16:ident; #[u32] $(#[scalar = $ScalarU32:ident])? type $U32:ident; #[u64] $(#[scalar = $ScalarU64:ident])? type $U64:ident; #[i8] $(#[scalar = $ScalarI8:ident])? type $I8:ident; #[i16] $(#[scalar = $ScalarI16:ident])? type $I16:ident; #[i32] $(#[scalar = $ScalarI32:ident])? type $I32:ident; #[i64] $(#[scalar = $ScalarI64:ident])? type $I64:ident; #[f16] $(#[scalar = $ScalarF16:ident])? type $F16:ident; #[f32] $(#[scalar = $ScalarF32:ident])? type $F32:ident; #[f64] $(#[scalar = $ScalarF64:ident])? type $F64:ident; ) => { type Bool: Bool + Make + Select; type U8: UInt + Compare + Make + ConvertTo + Into + Into + Into + Into + Into + Into + Into + Into + Into; type U16: UInt + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + Into + Into + Into + Into + Into + Into; type U32: UInt + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + Into + Into + Into; type U64: UInt + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo; type I8: SInt + Compare + Make + ConvertTo + ConvertTo + Into + Into + ConvertTo + Into + Into + ConvertTo + Into + Into; type I16: SInt + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + Into + Into + ConvertTo + Into + Into; type I32: SInt + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + Into + Into; type I64: SInt + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo; type F16: Float + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + Into + ConvertTo + ConvertTo + Into; type F32: Float + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + Into; type F64: Float + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo; }; } /// reference used to build IR for Kazan; an empty type for `core::simd` pub trait Context: Copy { make_types! { #[bool] type Bool; #[u8] type U8; #[u16] type U16; #[u32] type U32; #[u64] type U64; #[i8] type I8; #[i16] type I16; #[i32] type I32; #[i64] type I64; #[f16] type F16; #[f32] type F32; #[f64] type F64; } make_types! { #[bool] #[scalar = ScalarBool] type Bool; #[u8] #[scalar = ScalarU8] type U8; #[u16] #[scalar = ScalarU16] type U16; #[u32] #[scalar = ScalarU32] type U32; #[u64] #[scalar = ScalarU64] type U64; #[i8] #[scalar = ScalarI8] type I8; #[i16] #[scalar = ScalarI16] type I16; #[i32] #[scalar = ScalarI32] type I32; #[i64] #[scalar = ScalarI64] type I64; #[f16] #[scalar = ScalarF16] type F16; #[f32] #[scalar = ScalarF32] type F32; #[f64] #[scalar = ScalarF64] type F64; } type Bool: Bool + Make + Select; type U8: UInt + Compare + Make + ConvertTo + Into + Into + Into + Into + Into + Into + Into + Into + Into; type U16: UInt + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + Into + Into + Into + Into + Into + Into; type U32: UInt + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + Into + Into + Into; type U64: UInt + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo; type I8: SInt + Compare + Make + ConvertTo + ConvertTo + Into + Into + ConvertTo + Into + Into + ConvertTo + Into + Into; type I16: SInt + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + Into + Into + ConvertTo + Into + Into; type I32: SInt + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + Into + Into; type I64: SInt + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo; type F16: Float + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + Into + ConvertTo + ConvertTo + Into; type F32: Float + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + Into; type F64: Float + Compare + Make + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo + ConvertTo; // Vector types type VecBool: From + Bool + Make + Select; type VecU8: From + UInt + Compare + Make; type VecI8: From + SInt + Compare + Make; type VecU16: From + UInt + Compare + Make; type VecI16: From + SInt + Compare + Make; type VecF16: From + Float + Compare + Make; type VecU32: From + UInt + Compare + Make; type VecI32: From + SInt + Compare + Make; type VecF32: From + Float + Compare + Make; type VecU64: From + UInt + Compare + Make; type VecI64: From + SInt + Compare + Make; type VecF64: From + Float + Compare + Make; fn make>(self, v: T::Prim) -> T { T::make(self, v) } } pub trait Make: Sized { type Prim; fn make(ctx: Context, v: Self::Prim) -> Self; } pub trait ConvertTo { fn to(self) -> T; } impl> ConvertTo for U { fn to(self) -> T { self.into() } } pub trait Number: Compare + Add + Sub + Mul + Div + Rem + AddAssign + SubAssign + MulAssign + DivAssign + RemAssign { } pub trait BitOps: Copy + BitAnd + BitOr + BitXor + Not + BitAndAssign + BitOrAssign + BitXorAssign { } pub trait Int: Number + BitOps + Shl + Shr + ShlAssign + ShrAssign { } pub trait UInt: Int {} pub trait SInt: Int + Neg {} pub trait Float: Number + Neg { type BitsType: UInt; fn abs(self) -> Self; fn trunc(self) -> Self; fn ceil(self) -> Self; fn floor(self) -> Self; fn round(self) -> Self; fn fma(self, a: Self, b: Self) -> Self; fn is_nan(self) -> Self::Bool; fn is_infinity(self) -> Self::Bool; fn is_finite(self) -> Self::Bool; fn from_bits(v: Self::BitsType) -> Self; fn to_bits(self) -> Self::BitsType; } pub trait Bool: BitOps {} pub trait Select: Bool { fn select(self, true_v: T, false_v: T) -> T; } pub trait Compare: Copy { type Bool: Bool + Select; fn eq(self, rhs: Self) -> Self::Bool; fn ne(self, rhs: Self) -> Self::Bool; fn lt(self, rhs: Self) -> Self::Bool; fn gt(self, rhs: Self) -> Self::Bool; fn le(self, rhs: Self) -> Self::Bool; fn ge(self, rhs: Self) -> Self::Bool; }