Skip to content

Commit 3d59a47

Browse files
committed
Support SSE types in extern {} better.
This seems to work on x86-64, but I am not able to test on other platforms. cc rust-lang#20043
1 parent 4ebde95 commit 3d59a47

File tree

4 files changed

+102
-10
lines changed

4 files changed

+102
-10
lines changed

src/librustc_trans/trans/cabi_aarch64.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#![allow(non_upper_case_globals)]
1212

1313
use llvm;
14-
use llvm::{Integer, Pointer, Float, Double, Struct, Array};
14+
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
1515
use llvm::{StructRetAttribute, ZExtAttribute};
1616
use trans::cabi::{FnType, ArgType};
1717
use trans::context::CrateContext;
@@ -50,6 +50,11 @@ fn ty_align(ty: Type) -> uint {
5050
let elt = ty.element_type();
5151
ty_align(elt)
5252
}
53+
Vector => {
54+
let len = ty.vector_length();
55+
let elt = ty.element_type();
56+
ty_align(elt) * len
57+
}
5358
_ => panic!("ty_align: unhandled type")
5459
}
5560
}
@@ -80,6 +85,12 @@ fn ty_size(ty: Type) -> uint {
8085
let eltsz = ty_size(elt);
8186
len * eltsz
8287
}
88+
Vector => {
89+
let len = ty.vector_length();
90+
let elt = ty.element_type();
91+
let eltsz = ty_size(elt);
92+
len * eltsz
93+
}
8394
_ => panic!("ty_size: unhandled type")
8495
}
8596
}

src/librustc_trans/trans/cabi_arm.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#![allow(non_upper_case_globals)]
1212

1313
use llvm;
14-
use llvm::{Integer, Pointer, Float, Double, Struct, Array};
14+
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
1515
use llvm::{StructRetAttribute, ZExtAttribute};
1616
use trans::cabi::{FnType, ArgType};
1717
use trans::context::CrateContext;
@@ -57,6 +57,11 @@ fn general_ty_align(ty: Type) -> uint {
5757
let elt = ty.element_type();
5858
general_ty_align(elt)
5959
}
60+
Vector => {
61+
let len = ty.vector_length();
62+
let elt = ty.element_type();
63+
general_ty_align(elt) * len
64+
}
6065
_ => panic!("ty_align: unhandled type")
6166
}
6267
}
@@ -90,6 +95,11 @@ fn ios_ty_align(ty: Type) -> uint {
9095
let elt = ty.element_type();
9196
ios_ty_align(elt)
9297
}
98+
Vector => {
99+
let len = ty.vector_length();
100+
let elt = ty.element_type();
101+
ios_ty_align(elt) * len
102+
}
93103
_ => panic!("ty_align: unhandled type")
94104
}
95105
}
@@ -123,6 +133,12 @@ fn ty_size(ty: Type, align_fn: TyAlignFn) -> uint {
123133
let eltsz = ty_size(elt, align_fn);
124134
len * eltsz
125135
}
136+
Vector => {
137+
let len = ty.vector_length();
138+
let elt = ty.element_type();
139+
let eltsz = ty_size(elt, align_fn);
140+
len * eltsz
141+
}
126142
_ => panic!("ty_size: unhandled type")
127143
}
128144
}

src/librustc_trans/trans/cabi_mips.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use libc::c_uint;
1414
use std::cmp;
1515
use llvm;
16-
use llvm::{Integer, Pointer, Float, Double, Struct, Array};
16+
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
1717
use llvm::{StructRetAttribute, ZExtAttribute};
1818
use trans::cabi::{ArgType, FnType};
1919
use trans::context::CrateContext;
@@ -50,7 +50,12 @@ fn ty_align(ty: Type) -> uint {
5050
let elt = ty.element_type();
5151
ty_align(elt)
5252
}
53-
_ => panic!("ty_size: unhandled type")
53+
Vector => {
54+
let len = ty.vector_length();
55+
let elt = ty.element_type();
56+
ty_align(elt) * len
57+
}
58+
_ => panic!("ty_align: unhandled type")
5459
}
5560
}
5661

@@ -80,6 +85,12 @@ fn ty_size(ty: Type) -> uint {
8085
let eltsz = ty_size(elt);
8186
len * eltsz
8287
}
88+
Vector => {
89+
let len = ty.vector_length();
90+
let elt = ty.element_type();
91+
let eltsz = ty_size(elt);
92+
len * eltsz
93+
}
8394
_ => panic!("ty_size: unhandled type")
8495
}
8596
}

src/librustc_trans/trans/cabi_x86_64.rs

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use self::RegClass::*;
1616

1717
use llvm;
1818
use llvm::{Integer, Pointer, Float, Double};
19-
use llvm::{Struct, Array, Attribute};
19+
use llvm::{Struct, Array, Attribute, Vector};
2020
use llvm::{StructRetAttribute, ByValAttribute, ZExtAttribute};
2121
use trans::cabi::{ArgType, FnType};
2222
use trans::context::CrateContext;
@@ -114,7 +114,12 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
114114
let elt = ty.element_type();
115115
ty_align(elt)
116116
}
117-
_ => panic!("ty_size: unhandled type")
117+
Vector => {
118+
let len = ty.vector_length();
119+
let elt = ty.element_type();
120+
ty_align(elt) * len
121+
}
122+
_ => panic!("ty_align: unhandled type")
118123
}
119124
}
120125

@@ -143,6 +148,13 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
143148
let eltsz = ty_size(elt);
144149
len * eltsz
145150
}
151+
Vector => {
152+
let len = ty.vector_length();
153+
let elt = ty.element_type();
154+
let eltsz = ty_size(elt);
155+
len * eltsz
156+
}
157+
146158
_ => panic!("ty_size: unhandled type")
147159
}
148160
}
@@ -175,6 +187,12 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
175187
(_, X87Up) |
176188
(_, ComplexX87) => Memory,
177189

190+
(SSEFv, SSEUp) |
191+
(SSEFs, SSEUp) |
192+
(SSEDv, SSEUp) |
193+
(SSEDs, SSEUp) |
194+
(SSEInt(_), SSEUp) => return,
195+
178196
(_, _) => newv
179197
};
180198
cls[i] = to_write;
@@ -240,6 +258,27 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
240258
i += 1u;
241259
}
242260
}
261+
Vector => {
262+
let len = ty.vector_length();
263+
let elt = ty.element_type();
264+
let eltsz = ty_size(elt);
265+
let mut reg = match elt.kind() {
266+
Integer => SSEInt,
267+
Float => SSEFv,
268+
Double => SSEDv,
269+
_ => panic!("classify: unhandled vector element type")
270+
};
271+
272+
let mut i = 0u;
273+
while i < len {
274+
unify(cls, ix + (off + i * eltsz) / 8, reg);
275+
276+
// everything after the first one is the upper
277+
// half of a register.
278+
reg = SSEUp;
279+
i += 1u;
280+
}
281+
}
243282
_ => panic!("classify: unhandled type")
244283
}
245284
}
@@ -248,7 +287,7 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
248287
let mut i = 0u;
249288
let ty_kind = ty.kind();
250289
let e = cls.len();
251-
if cls.len() > 2u && (ty_kind == Struct || ty_kind == Array) {
290+
if cls.len() > 2u && (ty_kind == Struct || ty_kind == Array || ty_kind == Vector) {
252291
if cls[i].is_sse() {
253292
i += 1u;
254293
while i < e {
@@ -320,9 +359,19 @@ fn llreg_ty(ccx: &CrateContext, cls: &[RegClass]) -> Type {
320359
Int => {
321360
tys.push(Type::i64(ccx));
322361
}
323-
SSEFv => {
362+
SSEFv | SSEDv | SSEInt => {
363+
let (elts_per_word, elt_ty) = match cls[i] {
364+
SSEFv => (2, Type::f32(ccx)),
365+
SSEDv => (1, Type::f64(ccx)),
366+
// FIXME: need to handle the element types, since
367+
// C doesn't distinguish between the contained
368+
// types of the vector at all; normalise to u8,
369+
// maybe?
370+
SSEInt => panic!("llregtype: SSEInt not yet supported"),
371+
_ => unreachable!(),
372+
};
324373
let vec_len = llvec_len(&cls[(i + 1u)..]);
325-
let vec_ty = Type::vector(&Type::f32(ccx), (vec_len * 2u) as u64);
374+
let vec_ty = Type::vector(&elt_ty, (vec_len * elts_per_word) as u64);
326375
tys.push(vec_ty);
327376
i += vec_len;
328377
continue;
@@ -337,7 +386,12 @@ fn llreg_ty(ccx: &CrateContext, cls: &[RegClass]) -> Type {
337386
}
338387
i += 1u;
339388
}
340-
return Type::struct_(ccx, tys.as_slice(), false);
389+
if tys.len() == 1 && tys[0].kind() == Vector {
390+
// if the type contains only a vector, pass it as that vector.
391+
tys[0]
392+
} else {
393+
Type::struct_(ccx, tys.as_slice(), false)
394+
}
341395
}
342396

343397
pub fn compute_abi_info(ccx: &CrateContext,

0 commit comments

Comments
 (0)