Skip to content

Commit 7d4f358

Browse files
committed
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.
1 parent 5edbe1f commit 7d4f358

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

src/librustc_trans/trans/cabi_x86_64.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ enum RegClass {
3232
SSEFv,
3333
SSEDs,
3434
SSEDv,
35-
SSEInt,
35+
SSEInt(/* bitwidth */ u64),
3636
/// Data that can appear in the upper half of an SSE register.
3737
SSEUp,
3838
X87,
@@ -57,7 +57,7 @@ impl TypeMethods for Type {
5757
impl RegClass {
5858
fn is_sse(&self) -> bool {
5959
match *self {
60-
SSEFs | SSEFv | SSEDs | SSEDv => true,
60+
SSEFs | SSEFv | SSEDs | SSEDv | SSEInt(_) => true,
6161
_ => false
6262
}
6363
}
@@ -254,7 +254,7 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
254254
let elt = ty.element_type();
255255
let eltsz = ty_size(elt);
256256
let mut reg = match elt.kind() {
257-
Integer => SSEInt,
257+
Integer => SSEInt(elt.int_width()),
258258
Float => SSEFv,
259259
Double => SSEDv,
260260
_ => panic!("classify: unhandled vector element type")
@@ -350,19 +350,19 @@ fn llreg_ty(ccx: &CrateContext, cls: &[RegClass]) -> Type {
350350
Int => {
351351
tys.push(Type::i64(ccx));
352352
}
353-
SSEFv | SSEDv | SSEInt => {
353+
SSEFv | SSEDv | SSEInt(_) => {
354354
let (elts_per_word, elt_ty) = match cls[i] {
355355
SSEFv => (2, Type::f32(ccx)),
356356
SSEDv => (1, Type::f64(ccx)),
357-
// FIXME: need to handle the element types, since
358-
// C doesn't distinguish between the contained
359-
// types of the vector at all; normalise to u8,
360-
// maybe?
361-
SSEInt => panic!("llregtype: SSEInt not yet supported"),
357+
SSEInt(bits) => {
358+
assert!(bits == 8 || bits == 16 || bits == 32 || bits == 64,
359+
"llreg_ty: unsupported SSEInt width {}", bits);
360+
(64 / bits, Type::ix(ccx, bits))
361+
}
362362
_ => unreachable!(),
363363
};
364364
let vec_len = llvec_len(&cls[(i + 1u)..]);
365-
let vec_ty = Type::vector(&elt_ty, (vec_len * elts_per_word) as u64);
365+
let vec_ty = Type::vector(&elt_ty, vec_len as u64 * elts_per_word);
366366
tys.push(vec_ty);
367367
i += vec_len;
368368
continue;

0 commit comments

Comments
 (0)