diff --git a/src/librustc_trans/trans/cabi_aarch64.rs b/src/librustc_trans/trans/cabi_aarch64.rs index 66308503b818d..ca9b3791ea980 100644 --- a/src/librustc_trans/trans/cabi_aarch64.rs +++ b/src/librustc_trans/trans/cabi_aarch64.rs @@ -11,7 +11,7 @@ #![allow(non_upper_case_globals)] use llvm; -use llvm::{Integer, Pointer, Float, Double, Struct, Array}; +use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector}; use llvm::{StructRetAttribute, ZExtAttribute}; use trans::cabi::{FnType, ArgType}; use trans::context::CrateContext; @@ -50,6 +50,11 @@ fn ty_align(ty: Type) -> uint { let elt = ty.element_type(); ty_align(elt) } + 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); 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") } } diff --git a/src/librustc_trans/trans/cabi_arm.rs b/src/librustc_trans/trans/cabi_arm.rs index 830771d7397e2..2da0c3787e8c5 100644 --- a/src/librustc_trans/trans/cabi_arm.rs +++ b/src/librustc_trans/trans/cabi_arm.rs @@ -11,7 +11,7 @@ #![allow(non_upper_case_globals)] use llvm; -use llvm::{Integer, Pointer, Float, Double, Struct, Array}; +use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector}; use llvm::{StructRetAttribute, ZExtAttribute}; use trans::cabi::{FnType, ArgType}; use trans::context::CrateContext; @@ -57,6 +57,11 @@ fn general_ty_align(ty: Type) -> uint { let elt = ty.element_type(); 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") } } @@ -90,6 +95,11 @@ fn ios_ty_align(ty: Type) -> uint { let elt = ty.element_type(); 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") } } @@ -123,6 +133,12 @@ fn ty_size(ty: Type, align_fn: TyAlignFn) -> uint { let eltsz = ty_size(elt, align_fn); 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") } } diff --git a/src/librustc_trans/trans/cabi_mips.rs b/src/librustc_trans/trans/cabi_mips.rs index 4dfe8daf33946..0a0ab784f57fc 100644 --- a/src/librustc_trans/trans/cabi_mips.rs +++ b/src/librustc_trans/trans/cabi_mips.rs @@ -13,7 +13,7 @@ use libc::c_uint; use std::cmp; use llvm; -use llvm::{Integer, Pointer, Float, Double, Struct, Array}; +use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector}; use llvm::{StructRetAttribute, ZExtAttribute}; use trans::cabi::{ArgType, FnType}; use trans::context::CrateContext; @@ -50,7 +50,12 @@ fn ty_align(ty: Type) -> uint { let elt = ty.element_type(); 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); 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") } } diff --git a/src/librustc_trans/trans/cabi_x86_64.rs b/src/librustc_trans/trans/cabi_x86_64.rs index c0e80ff08a22e..72ace5f95617d 100644 --- a/src/librustc_trans/trans/cabi_x86_64.rs +++ b/src/librustc_trans/trans/cabi_x86_64.rs @@ -16,7 +16,7 @@ use self::RegClass::*; use llvm; use llvm::{Integer, Pointer, Float, Double}; -use llvm::{Struct, Array, Attribute}; +use llvm::{Struct, Array, Attribute, Vector}; use llvm::{StructRetAttribute, ByValAttribute, ZExtAttribute}; use trans::cabi::{ArgType, FnType}; use trans::context::CrateContext; @@ -114,7 +114,12 @@ fn classify_ty(ty: Type) -> Vec { let elt = ty.element_type(); 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 { let eltsz = ty_size(elt); 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") } } @@ -175,6 +187,12 @@ fn classify_ty(ty: Type) -> Vec { (_, X87Up) | (_, ComplexX87) => Memory, + (SSEFv, SSEUp) | + (SSEFs, SSEUp) | + (SSEDv, SSEUp) | + (SSEDs, SSEUp) | + (SSEInt(_), SSEUp) => return, + (_, _) => newv }; cls[i] = to_write; @@ -240,6 +258,27 @@ fn classify_ty(ty: Type) -> Vec { 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") } } @@ -248,7 +287,7 @@ fn classify_ty(ty: Type) -> Vec { let mut i = 0u; let ty_kind = ty.kind(); 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() { i += 1u; while i < e { @@ -320,9 +359,19 @@ fn llreg_ty(ccx: &CrateContext, cls: &[RegClass]) -> Type { Int => { 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_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); i += vec_len; continue; @@ -337,7 +386,12 @@ fn llreg_ty(ccx: &CrateContext, cls: &[RegClass]) -> Type { } 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,