提交 ea045d20 编写于 作者: V Valerii Hiora

iOS: cabi fixes

Changed alignment according to official Apple docs
上级 ac0607ac
......@@ -115,8 +115,15 @@ pub fn compute_abi_info(ccx: &CrateContext,
} else {
cabi_x86_64::compute_abi_info(ccx, atys, rty, ret_def)
},
"arm" => cabi_arm::compute_abi_info(ccx, atys, rty, ret_def),
"aarch64" => cabi_aarch64::compute_abi_info(ccx, atys, rty, ret_def),
"arm" => {
let flavor = if ccx.sess().target.target.target_os == "ios" {
cabi_arm::Flavor::Ios
} else {
cabi_arm::Flavor::General
};
cabi_arm::compute_abi_info(ccx, atys, rty, ret_def, flavor)
},
"mips" => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def),
a => ccx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a)
[]),
......
......@@ -19,16 +19,23 @@
use std::cmp;
pub enum Flavor {
General,
Ios
}
type TyAlignFn = fn(ty: Type) -> uint;
fn align_up_to(off: uint, a: uint) -> uint {
return (off + a - 1u) / a * a;
}
fn align(off: uint, ty: Type) -> uint {
let a = ty_align(ty);
fn align(off: uint, ty: Type, align_fn: TyAlignFn) -> uint {
let a = align_fn(ty);
return align_up_to(off, a);
}
fn ty_align(ty: Type) -> uint {
fn general_ty_align(ty: Type) -> uint {
match ty.kind() {
Integer => {
unsafe {
......@@ -43,18 +50,51 @@ fn ty_align(ty: Type) -> uint {
1
} else {
let str_tys = ty.field_types();
str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
str_tys.iter().fold(1, |a, t| cmp::max(a, general_ty_align(*t)))
}
}
Array => {
let elt = ty.element_type();
general_ty_align(elt)
}
_ => panic!("ty_align: unhandled type")
}
}
// For more information see:
// ARMv7
// https://developer.apple.com/library/ios/documentation/Xcode/Conceptual
// /iPhoneOSABIReference/Articles/ARMv7FunctionCallingConventions.html
// ARMv6
// https://developer.apple.com/library/ios/documentation/Xcode/Conceptual
// /iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html
fn ios_ty_align(ty: Type) -> uint {
match ty.kind() {
Integer => {
unsafe {
cmp::min(4, ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8)
}
}
Pointer => 4,
Float => 4,
Double => 4,
Struct => {
if ty.is_packed() {
1
} else {
let str_tys = ty.field_types();
str_tys.iter().fold(1, |a, t| cmp::max(a, ios_ty_align(*t)))
}
}
Array => {
let elt = ty.element_type();
ty_align(elt)
ios_ty_align(elt)
}
_ => panic!("ty_align: unhandled type")
}
}
fn ty_size(ty: Type) -> uint {
fn ty_size(ty: Type, align_fn: TyAlignFn) -> uint {
match ty.kind() {
Integer => {
unsafe {
......@@ -67,29 +107,32 @@ fn ty_size(ty: Type) -> uint {
Struct => {
if ty.is_packed() {
let str_tys = ty.field_types();
str_tys.iter().fold(0, |s, t| s + ty_size(*t))
str_tys.iter().fold(0, |s, t| s + ty_size(*t, align_fn))
} else {
let str_tys = ty.field_types();
let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
align(size, ty)
let size = str_tys.iter()
.fold(0, |s, t| {
align(s, *t, align_fn) + ty_size(*t, align_fn)
});
align(size, ty, align_fn)
}
}
Array => {
let len = ty.array_length();
let elt = ty.element_type();
let eltsz = ty_size(elt);
let eltsz = ty_size(elt, align_fn);
len * eltsz
}
_ => panic!("ty_size: unhandled type")
}
}
fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
fn classify_ret_ty(ccx: &CrateContext, ty: Type, align_fn: TyAlignFn) -> ArgType {
if is_reg_ty(ty) {
let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
return ArgType::direct(ty, None, None, attr);
}
let size = ty_size(ty);
let size = ty_size(ty, align_fn);
if size <= 4 {
let llty = if size <= 1 {
Type::i8(ccx)
......@@ -103,13 +146,13 @@ fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
ArgType::indirect(ty, Some(StructRetAttribute))
}
fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType {
fn classify_arg_ty(ccx: &CrateContext, ty: Type, align_fn: TyAlignFn) -> ArgType {
if is_reg_ty(ty) {
let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
return ArgType::direct(ty, None, None, attr);
}
let align = ty_align(ty);
let size = ty_size(ty);
let align = align_fn(ty);
let size = ty_size(ty, align_fn);
let llty = if align <= 4 {
Type::array(&Type::i32(ccx), ((size + 3) / 4) as u64)
} else {
......@@ -131,15 +174,21 @@ fn is_reg_ty(ty: Type) -> bool {
pub fn compute_abi_info(ccx: &CrateContext,
atys: &[Type],
rty: Type,
ret_def: bool) -> FnType {
ret_def: bool,
flavor: Flavor) -> FnType {
let align_fn = match flavor {
Flavor::General => general_ty_align as TyAlignFn,
Flavor::Ios => ios_ty_align as TyAlignFn,
};
let mut arg_tys = Vec::new();
for &aty in atys.iter() {
let ty = classify_arg_ty(ccx, aty);
let ty = classify_arg_ty(ccx, aty, align_fn);
arg_tys.push(ty);
}
let ret_ty = if ret_def {
classify_ret_ty(ccx, rty)
classify_ret_ty(ccx, rty, align_fn)
} else {
ArgType::direct(Type::void(ccx), None, None, None)
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册