Add simd_saturating_{add,sub} intrinsics
This commit is contained in:
parent
d173180116
commit
94defa9364
7 changed files with 894 additions and 8 deletions
|
|
@ -510,14 +510,24 @@ impl CodegenCx<'b, 'tcx> {
|
|||
let t_f32 = self.type_f32();
|
||||
let t_f64 = self.type_f64();
|
||||
|
||||
let t_v2f32 = self.type_vector(t_f32, 2);
|
||||
let t_v4f32 = self.type_vector(t_f32, 4);
|
||||
let t_v8f32 = self.type_vector(t_f32, 8);
|
||||
let t_v16f32 = self.type_vector(t_f32, 16);
|
||||
macro_rules! vector_types {
|
||||
($id_out:ident: $elem_ty:ident, $len:expr) => {
|
||||
let $id_out = self.type_vector($elem_ty, $len);
|
||||
};
|
||||
($($id_out:ident: $elem_ty:ident, $len:expr;)*) => {
|
||||
$(vector_types!($id_out: $elem_ty, $len);)*
|
||||
}
|
||||
}
|
||||
vector_types! {
|
||||
t_v2f32: t_f32, 2;
|
||||
t_v4f32: t_f32, 4;
|
||||
t_v8f32: t_f32, 8;
|
||||
t_v16f32: t_f32, 16;
|
||||
|
||||
let t_v2f64 = self.type_vector(t_f64, 2);
|
||||
let t_v4f64 = self.type_vector(t_f64, 4);
|
||||
let t_v8f64 = self.type_vector(t_f64, 8);
|
||||
t_v2f64: t_f64, 2;
|
||||
t_v4f64: t_f64, 4;
|
||||
t_v8f64: t_f64, 8;
|
||||
}
|
||||
|
||||
ifn!("llvm.memset.p0i8.i16", fn(i8p, t_i8, t_i16, t_i32, i1) -> void);
|
||||
ifn!("llvm.memset.p0i8.i32", fn(i8p, t_i8, t_i32, t_i32, i1) -> void);
|
||||
|
|
|
|||
|
|
@ -1850,7 +1850,52 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
|
|||
simd_xor: Uint, Int => xor;
|
||||
simd_fmax: Float => maxnum;
|
||||
simd_fmin: Float => minnum;
|
||||
|
||||
}
|
||||
|
||||
if name == "simd_saturating_add" || name == "simd_saturating_sub" {
|
||||
let lhs = args[0].immediate();
|
||||
let rhs = args[1].immediate();
|
||||
let is_add = name == "simd_saturating_add";
|
||||
let ptr_bits = bx.tcx().data_layout.pointer_size.bits() as _;
|
||||
let (signed, elem_width, elem_ty) = match in_elem.sty {
|
||||
ty::Int(i) =>
|
||||
(
|
||||
true,
|
||||
i.bit_width().unwrap_or(ptr_bits),
|
||||
bx.cx.type_int_from_ty(i)
|
||||
),
|
||||
ty::Uint(i) =>
|
||||
(
|
||||
false,
|
||||
i.bit_width().unwrap_or(ptr_bits),
|
||||
bx.cx.type_uint_from_ty(i)
|
||||
),
|
||||
_ => {
|
||||
return_error!(
|
||||
"expected element type `{}` of vector type `{}` \
|
||||
to be a signed or unsigned integer type",
|
||||
arg_tys[0].simd_type(tcx).sty, arg_tys[0]
|
||||
);
|
||||
}
|
||||
};
|
||||
let llvm_intrinsic = &format!(
|
||||
"llvm.{}{}.sat.v{}i{}",
|
||||
if signed { 's' } else { 'u' },
|
||||
if is_add { "add" } else { "sub" },
|
||||
in_len, elem_width
|
||||
);
|
||||
let vec_ty = bx.cx.type_vector(elem_ty, in_len as u64);
|
||||
|
||||
let f = bx.declare_cfn(
|
||||
&llvm_intrinsic,
|
||||
bx.type_func(&[vec_ty, vec_ty], vec_ty)
|
||||
);
|
||||
llvm::SetUnnamedAddr(f, false);
|
||||
let v = bx.call(f, &[lhs, rhs], None);
|
||||
return Ok(v);
|
||||
}
|
||||
|
||||
span_bug!(span, "unknown SIMD intrinsic");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue