mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-25 06:03:16 +00:00
Support SSE types in extern {} better.
This seems to work on x86-64, but I am not able to test on other platforms. cc #20043
This commit is contained in:
parent
4ebde950f5
commit
3d59a476e5
@ -11,7 +11,7 @@
|
|||||||
#![allow(non_upper_case_globals)]
|
#![allow(non_upper_case_globals)]
|
||||||
|
|
||||||
use llvm;
|
use llvm;
|
||||||
use llvm::{Integer, Pointer, Float, Double, Struct, Array};
|
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
|
||||||
use llvm::{StructRetAttribute, ZExtAttribute};
|
use llvm::{StructRetAttribute, ZExtAttribute};
|
||||||
use trans::cabi::{FnType, ArgType};
|
use trans::cabi::{FnType, ArgType};
|
||||||
use trans::context::CrateContext;
|
use trans::context::CrateContext;
|
||||||
@ -50,6 +50,11 @@ fn ty_align(ty: Type) -> uint {
|
|||||||
let elt = ty.element_type();
|
let elt = ty.element_type();
|
||||||
ty_align(elt)
|
ty_align(elt)
|
||||||
}
|
}
|
||||||
|
Vector => {
|
||||||
|
let len = ty.vector_length();
|
||||||
|
let elt = ty.element_type();
|
||||||
|
ty_align(elt) * len
|
||||||
|
}
|
||||||
_ => panic!("ty_align: unhandled type")
|
_ => panic!("ty_align: unhandled type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,6 +85,12 @@ fn ty_size(ty: Type) -> uint {
|
|||||||
let eltsz = ty_size(elt);
|
let eltsz = ty_size(elt);
|
||||||
len * eltsz
|
len * eltsz
|
||||||
}
|
}
|
||||||
|
Vector => {
|
||||||
|
let len = ty.vector_length();
|
||||||
|
let elt = ty.element_type();
|
||||||
|
let eltsz = ty_size(elt);
|
||||||
|
len * eltsz
|
||||||
|
}
|
||||||
_ => panic!("ty_size: unhandled type")
|
_ => panic!("ty_size: unhandled type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#![allow(non_upper_case_globals)]
|
#![allow(non_upper_case_globals)]
|
||||||
|
|
||||||
use llvm;
|
use llvm;
|
||||||
use llvm::{Integer, Pointer, Float, Double, Struct, Array};
|
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
|
||||||
use llvm::{StructRetAttribute, ZExtAttribute};
|
use llvm::{StructRetAttribute, ZExtAttribute};
|
||||||
use trans::cabi::{FnType, ArgType};
|
use trans::cabi::{FnType, ArgType};
|
||||||
use trans::context::CrateContext;
|
use trans::context::CrateContext;
|
||||||
@ -57,6 +57,11 @@ fn general_ty_align(ty: Type) -> uint {
|
|||||||
let elt = ty.element_type();
|
let elt = ty.element_type();
|
||||||
general_ty_align(elt)
|
general_ty_align(elt)
|
||||||
}
|
}
|
||||||
|
Vector => {
|
||||||
|
let len = ty.vector_length();
|
||||||
|
let elt = ty.element_type();
|
||||||
|
general_ty_align(elt) * len
|
||||||
|
}
|
||||||
_ => panic!("ty_align: unhandled type")
|
_ => panic!("ty_align: unhandled type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,6 +95,11 @@ fn ios_ty_align(ty: Type) -> uint {
|
|||||||
let elt = ty.element_type();
|
let elt = ty.element_type();
|
||||||
ios_ty_align(elt)
|
ios_ty_align(elt)
|
||||||
}
|
}
|
||||||
|
Vector => {
|
||||||
|
let len = ty.vector_length();
|
||||||
|
let elt = ty.element_type();
|
||||||
|
ios_ty_align(elt) * len
|
||||||
|
}
|
||||||
_ => panic!("ty_align: unhandled type")
|
_ => panic!("ty_align: unhandled type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,6 +133,12 @@ fn ty_size(ty: Type, align_fn: TyAlignFn) -> uint {
|
|||||||
let eltsz = ty_size(elt, align_fn);
|
let eltsz = ty_size(elt, align_fn);
|
||||||
len * eltsz
|
len * eltsz
|
||||||
}
|
}
|
||||||
|
Vector => {
|
||||||
|
let len = ty.vector_length();
|
||||||
|
let elt = ty.element_type();
|
||||||
|
let eltsz = ty_size(elt, align_fn);
|
||||||
|
len * eltsz
|
||||||
|
}
|
||||||
_ => panic!("ty_size: unhandled type")
|
_ => panic!("ty_size: unhandled type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use llvm;
|
use llvm;
|
||||||
use llvm::{Integer, Pointer, Float, Double, Struct, Array};
|
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
|
||||||
use llvm::{StructRetAttribute, ZExtAttribute};
|
use llvm::{StructRetAttribute, ZExtAttribute};
|
||||||
use trans::cabi::{ArgType, FnType};
|
use trans::cabi::{ArgType, FnType};
|
||||||
use trans::context::CrateContext;
|
use trans::context::CrateContext;
|
||||||
@ -50,7 +50,12 @@ fn ty_align(ty: Type) -> uint {
|
|||||||
let elt = ty.element_type();
|
let elt = ty.element_type();
|
||||||
ty_align(elt)
|
ty_align(elt)
|
||||||
}
|
}
|
||||||
_ => panic!("ty_size: unhandled type")
|
Vector => {
|
||||||
|
let len = ty.vector_length();
|
||||||
|
let elt = ty.element_type();
|
||||||
|
ty_align(elt) * len
|
||||||
|
}
|
||||||
|
_ => panic!("ty_align: unhandled type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +85,12 @@ fn ty_size(ty: Type) -> uint {
|
|||||||
let eltsz = ty_size(elt);
|
let eltsz = ty_size(elt);
|
||||||
len * eltsz
|
len * eltsz
|
||||||
}
|
}
|
||||||
|
Vector => {
|
||||||
|
let len = ty.vector_length();
|
||||||
|
let elt = ty.element_type();
|
||||||
|
let eltsz = ty_size(elt);
|
||||||
|
len * eltsz
|
||||||
|
}
|
||||||
_ => panic!("ty_size: unhandled type")
|
_ => panic!("ty_size: unhandled type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ use self::RegClass::*;
|
|||||||
|
|
||||||
use llvm;
|
use llvm;
|
||||||
use llvm::{Integer, Pointer, Float, Double};
|
use llvm::{Integer, Pointer, Float, Double};
|
||||||
use llvm::{Struct, Array, Attribute};
|
use llvm::{Struct, Array, Attribute, Vector};
|
||||||
use llvm::{StructRetAttribute, ByValAttribute, ZExtAttribute};
|
use llvm::{StructRetAttribute, ByValAttribute, ZExtAttribute};
|
||||||
use trans::cabi::{ArgType, FnType};
|
use trans::cabi::{ArgType, FnType};
|
||||||
use trans::context::CrateContext;
|
use trans::context::CrateContext;
|
||||||
@ -114,7 +114,12 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
|
|||||||
let elt = ty.element_type();
|
let elt = ty.element_type();
|
||||||
ty_align(elt)
|
ty_align(elt)
|
||||||
}
|
}
|
||||||
_ => panic!("ty_size: unhandled type")
|
Vector => {
|
||||||
|
let len = ty.vector_length();
|
||||||
|
let elt = ty.element_type();
|
||||||
|
ty_align(elt) * len
|
||||||
|
}
|
||||||
|
_ => panic!("ty_align: unhandled type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +148,13 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
|
|||||||
let eltsz = ty_size(elt);
|
let eltsz = ty_size(elt);
|
||||||
len * eltsz
|
len * eltsz
|
||||||
}
|
}
|
||||||
|
Vector => {
|
||||||
|
let len = ty.vector_length();
|
||||||
|
let elt = ty.element_type();
|
||||||
|
let eltsz = ty_size(elt);
|
||||||
|
len * eltsz
|
||||||
|
}
|
||||||
|
|
||||||
_ => panic!("ty_size: unhandled type")
|
_ => panic!("ty_size: unhandled type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,6 +187,12 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
|
|||||||
(_, X87Up) |
|
(_, X87Up) |
|
||||||
(_, ComplexX87) => Memory,
|
(_, ComplexX87) => Memory,
|
||||||
|
|
||||||
|
(SSEFv, SSEUp) |
|
||||||
|
(SSEFs, SSEUp) |
|
||||||
|
(SSEDv, SSEUp) |
|
||||||
|
(SSEDs, SSEUp) |
|
||||||
|
(SSEInt(_), SSEUp) => return,
|
||||||
|
|
||||||
(_, _) => newv
|
(_, _) => newv
|
||||||
};
|
};
|
||||||
cls[i] = to_write;
|
cls[i] = to_write;
|
||||||
@ -240,6 +258,27 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
|
|||||||
i += 1u;
|
i += 1u;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Vector => {
|
||||||
|
let len = ty.vector_length();
|
||||||
|
let elt = ty.element_type();
|
||||||
|
let eltsz = ty_size(elt);
|
||||||
|
let mut reg = match elt.kind() {
|
||||||
|
Integer => SSEInt,
|
||||||
|
Float => SSEFv,
|
||||||
|
Double => SSEDv,
|
||||||
|
_ => panic!("classify: unhandled vector element type")
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut i = 0u;
|
||||||
|
while i < len {
|
||||||
|
unify(cls, ix + (off + i * eltsz) / 8, reg);
|
||||||
|
|
||||||
|
// everything after the first one is the upper
|
||||||
|
// half of a register.
|
||||||
|
reg = SSEUp;
|
||||||
|
i += 1u;
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => panic!("classify: unhandled type")
|
_ => panic!("classify: unhandled type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,7 +287,7 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
|
|||||||
let mut i = 0u;
|
let mut i = 0u;
|
||||||
let ty_kind = ty.kind();
|
let ty_kind = ty.kind();
|
||||||
let e = cls.len();
|
let e = cls.len();
|
||||||
if cls.len() > 2u && (ty_kind == Struct || ty_kind == Array) {
|
if cls.len() > 2u && (ty_kind == Struct || ty_kind == Array || ty_kind == Vector) {
|
||||||
if cls[i].is_sse() {
|
if cls[i].is_sse() {
|
||||||
i += 1u;
|
i += 1u;
|
||||||
while i < e {
|
while i < e {
|
||||||
@ -320,9 +359,19 @@ fn llreg_ty(ccx: &CrateContext, cls: &[RegClass]) -> Type {
|
|||||||
Int => {
|
Int => {
|
||||||
tys.push(Type::i64(ccx));
|
tys.push(Type::i64(ccx));
|
||||||
}
|
}
|
||||||
SSEFv => {
|
SSEFv | SSEDv | SSEInt => {
|
||||||
|
let (elts_per_word, elt_ty) = match cls[i] {
|
||||||
|
SSEFv => (2, Type::f32(ccx)),
|
||||||
|
SSEDv => (1, Type::f64(ccx)),
|
||||||
|
// FIXME: need to handle the element types, since
|
||||||
|
// C doesn't distinguish between the contained
|
||||||
|
// types of the vector at all; normalise to u8,
|
||||||
|
// maybe?
|
||||||
|
SSEInt => panic!("llregtype: SSEInt not yet supported"),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
let vec_len = llvec_len(&cls[(i + 1u)..]);
|
let vec_len = llvec_len(&cls[(i + 1u)..]);
|
||||||
let vec_ty = Type::vector(&Type::f32(ccx), (vec_len * 2u) as u64);
|
let vec_ty = Type::vector(&elt_ty, (vec_len * elts_per_word) as u64);
|
||||||
tys.push(vec_ty);
|
tys.push(vec_ty);
|
||||||
i += vec_len;
|
i += vec_len;
|
||||||
continue;
|
continue;
|
||||||
@ -337,7 +386,12 @@ fn llreg_ty(ccx: &CrateContext, cls: &[RegClass]) -> Type {
|
|||||||
}
|
}
|
||||||
i += 1u;
|
i += 1u;
|
||||||
}
|
}
|
||||||
return Type::struct_(ccx, tys.as_slice(), false);
|
if tys.len() == 1 && tys[0].kind() == Vector {
|
||||||
|
// if the type contains only a vector, pass it as that vector.
|
||||||
|
tys[0]
|
||||||
|
} else {
|
||||||
|
Type::struct_(ccx, tys.as_slice(), false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute_abi_info(ccx: &CrateContext,
|
pub fn compute_abi_info(ccx: &CrateContext,
|
||||||
|
Loading…
Reference in New Issue
Block a user