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:
parent
5edbe1f5dd
commit
7d4f358de7
1 changed files with 10 additions and 10 deletions
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue