1
Fork 0

Support SSE with integer types in x86-64 FFI.

Unlike the intrinics in C, this types the SSE values base on integer
size. This matches the LLVM intrinsics which have concrete vector types
(`<4 x i32>` etc.), and is no loss of expressivity: if one is using a C
function that really takes an untyped integral SSE value, just give it
whatever Rust type makes most sense.
This commit is contained in:
Huon Wilson 2015-01-15 13:49:41 +11:00
parent 5edbe1f5dd
commit 7d4f358de7

View file

@ -32,7 +32,7 @@ enum RegClass {
SSEFv, SSEFv,
SSEDs, SSEDs,
SSEDv, SSEDv,
SSEInt, SSEInt(/* bitwidth */ u64),
/// Data that can appear in the upper half of an SSE register. /// Data that can appear in the upper half of an SSE register.
SSEUp, SSEUp,
X87, X87,
@ -57,7 +57,7 @@ impl TypeMethods for Type {
impl RegClass { impl RegClass {
fn is_sse(&self) -> bool { fn is_sse(&self) -> bool {
match *self { match *self {
SSEFs | SSEFv | SSEDs | SSEDv => true, SSEFs | SSEFv | SSEDs | SSEDv | SSEInt(_) => true,
_ => false _ => false
} }
} }
@ -254,7 +254,7 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
let elt = ty.element_type(); let elt = ty.element_type();
let eltsz = ty_size(elt); let eltsz = ty_size(elt);
let mut reg = match elt.kind() { let mut reg = match elt.kind() {
Integer => SSEInt, Integer => SSEInt(elt.int_width()),
Float => SSEFv, Float => SSEFv,
Double => SSEDv, Double => SSEDv,
_ => panic!("classify: unhandled vector element type") _ => panic!("classify: unhandled vector element type")
@ -350,19 +350,19 @@ fn llreg_ty(ccx: &CrateContext, cls: &[RegClass]) -> Type {
Int => { Int => {
tys.push(Type::i64(ccx)); tys.push(Type::i64(ccx));
} }
SSEFv | SSEDv | SSEInt => { SSEFv | SSEDv | SSEInt(_) => {
let (elts_per_word, elt_ty) = match cls[i] { let (elts_per_word, elt_ty) = match cls[i] {
SSEFv => (2, Type::f32(ccx)), SSEFv => (2, Type::f32(ccx)),
SSEDv => (1, Type::f64(ccx)), SSEDv => (1, Type::f64(ccx)),
// FIXME: need to handle the element types, since SSEInt(bits) => {
// C doesn't distinguish between the contained assert!(bits == 8 || bits == 16 || bits == 32 || bits == 64,
// types of the vector at all; normalise to u8, "llreg_ty: unsupported SSEInt width {}", bits);
// maybe? (64 / bits, Type::ix(ccx, bits))
SSEInt => panic!("llregtype: SSEInt not yet supported"), }
_ => unreachable!(), _ => unreachable!(),
}; };
let vec_len = llvec_len(&cls[(i + 1u)..]); let vec_len = llvec_len(&cls[(i + 1u)..]);
let vec_ty = Type::vector(&elt_ty, (vec_len * elts_per_word) as u64); let vec_ty = Type::vector(&elt_ty, vec_len as u64 * elts_per_word);
tys.push(vec_ty); tys.push(vec_ty);
i += vec_len; i += vec_len;
continue; continue;