Add newtype for signedness in LLVM SIMD

This commit is contained in:
clubby789 2024-02-14 00:01:08 +00:00
parent 9bfc46c5d8
commit 3377dac31e

View File

@ -2094,9 +2094,16 @@ macro_rules! bitwise_red {
return Ok(args[0].immediate()); return Ok(args[0].immediate());
} }
#[derive(Copy, Clone)]
enum Sign {
Unsigned,
Signed,
}
use Sign::*;
enum Style { enum Style {
Float, Float,
Int(/* is signed? */ bool), Int(Sign),
Unsupported, Unsupported,
} }
@ -2104,11 +2111,11 @@ enum Style {
// vectors of pointer-sized integers should've been // vectors of pointer-sized integers should've been
// disallowed before here, so this unwrap is safe. // disallowed before here, so this unwrap is safe.
ty::Int(i) => ( ty::Int(i) => (
Style::Int(true), Style::Int(Signed),
i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(),
), ),
ty::Uint(u) => ( ty::Uint(u) => (
Style::Int(false), Style::Int(Unsigned),
u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(),
), ),
ty::Float(f) => (Style::Float, f.bit_width()), ty::Float(f) => (Style::Float, f.bit_width()),
@ -2116,11 +2123,11 @@ enum Style {
}; };
let (out_style, out_width) = match out_elem.kind() { let (out_style, out_width) = match out_elem.kind() {
ty::Int(i) => ( ty::Int(i) => (
Style::Int(true), Style::Int(Signed),
i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(),
), ),
ty::Uint(u) => ( ty::Uint(u) => (
Style::Int(false), Style::Int(Unsigned),
u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(),
), ),
ty::Float(f) => (Style::Float, f.bit_width()), ty::Float(f) => (Style::Float, f.bit_width()),
@ -2128,31 +2135,31 @@ enum Style {
}; };
match (in_style, out_style) { match (in_style, out_style) {
(Style::Int(in_is_signed), Style::Int(_)) => { (Style::Int(sign), Style::Int(_)) => {
return Ok(match in_width.cmp(&out_width) { return Ok(match in_width.cmp(&out_width) {
Ordering::Greater => bx.trunc(args[0].immediate(), llret_ty), Ordering::Greater => bx.trunc(args[0].immediate(), llret_ty),
Ordering::Equal => args[0].immediate(), Ordering::Equal => args[0].immediate(),
Ordering::Less => { Ordering::Less => match sign {
if in_is_signed { Sign::Signed => bx.sext(args[0].immediate(), llret_ty),
bx.sext(args[0].immediate(), llret_ty) Sign::Unsigned => bx.zext(args[0].immediate(), llret_ty),
} else { },
bx.zext(args[0].immediate(), llret_ty)
}
}
}); });
} }
(Style::Int(in_is_signed), Style::Float) => { (Style::Int(Sign::Signed), Style::Float) => {
return Ok(if in_is_signed { return Ok(bx.sitofp(args[0].immediate(), llret_ty));
bx.sitofp(args[0].immediate(), llret_ty)
} else {
bx.uitofp(args[0].immediate(), llret_ty)
});
} }
(Style::Float, Style::Int(out_is_signed)) => { (Style::Int(Sign::Unsigned), Style::Float) => {
return Ok(match (out_is_signed, name == sym::simd_as) { return Ok(bx.uitofp(args[0].immediate(), llret_ty));
(false, false) => bx.fptoui(args[0].immediate(), llret_ty), }
(true, false) => bx.fptosi(args[0].immediate(), llret_ty), (Style::Float, Style::Int(sign)) => {
(_, true) => bx.cast_float_to_int(out_is_signed, args[0].immediate(), llret_ty), return Ok(match (sign, name == sym::simd_as) {
(Sign::Unsigned, false) => bx.fptoui(args[0].immediate(), llret_ty),
(Sign::Signed, false) => bx.fptosi(args[0].immediate(), llret_ty),
(_, true) => bx.cast_float_to_int(
matches!(sign, Sign::Signed),
args[0].immediate(),
llret_ty,
),
}); });
} }
(Style::Float, Style::Float) => { (Style::Float, Style::Float) => {