@@ -19,16 +19,23 @@ use trans::type_::Type;
1919
2020use std:: cmp;
2121
22+ pub enum Flavor {
23+ General ,
24+ Ios
25+ }
26+
27+ type TyAlignFn = fn ( ty : Type ) -> uint ;
28+
2229fn align_up_to ( off : uint , a : uint ) -> uint {
2330 return ( off + a - 1 u) / a * a;
2431}
2532
26- fn align ( off : uint , ty : Type ) -> uint {
27- let a = ty_align ( ty) ;
33+ fn align ( off : uint , ty : Type , align_fn : TyAlignFn ) -> uint {
34+ let a = align_fn ( ty) ;
2835 return align_up_to ( off, a) ;
2936}
3037
31- fn ty_align ( ty : Type ) -> uint {
38+ fn general_ty_align ( ty : Type ) -> uint {
3239 match ty. kind ( ) {
3340 Integer => {
3441 unsafe {
@@ -43,18 +50,51 @@ fn ty_align(ty: Type) -> uint {
4350 1
4451 } else {
4552 let str_tys = ty. field_types ( ) ;
46- str_tys. iter ( ) . fold ( 1 , |a, t| cmp:: max ( a, ty_align ( * t) ) )
53+ str_tys. iter ( ) . fold ( 1 , |a, t| cmp:: max ( a, general_ty_align ( * t) ) )
54+ }
55+ }
56+ Array => {
57+ let elt = ty. element_type ( ) ;
58+ general_ty_align ( elt)
59+ }
60+ _ => panic ! ( "ty_align: unhandled type" )
61+ }
62+ }
63+
64+ // For more information see:
65+ // ARMv7
66+ // https://developer.apple.com/library/ios/documentation/Xcode/Conceptual
67+ // /iPhoneOSABIReference/Articles/ARMv7FunctionCallingConventions.html
68+ // ARMv6
69+ // https://developer.apple.com/library/ios/documentation/Xcode/Conceptual
70+ // /iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html
71+ fn ios_ty_align ( ty : Type ) -> uint {
72+ match ty. kind ( ) {
73+ Integer => {
74+ unsafe {
75+ cmp:: min ( 4 , ( ( llvm:: LLVMGetIntTypeWidth ( ty. to_ref ( ) ) as uint ) + 7 ) / 8 )
76+ }
77+ }
78+ Pointer => 4 ,
79+ Float => 4 ,
80+ Double => 4 ,
81+ Struct => {
82+ if ty. is_packed ( ) {
83+ 1
84+ } else {
85+ let str_tys = ty. field_types ( ) ;
86+ str_tys. iter ( ) . fold ( 1 , |a, t| cmp:: max ( a, ios_ty_align ( * t) ) )
4787 }
4888 }
4989 Array => {
5090 let elt = ty. element_type ( ) ;
51- ty_align ( elt)
91+ ios_ty_align ( elt)
5292 }
5393 _ => panic ! ( "ty_align: unhandled type" )
5494 }
5595}
5696
57- fn ty_size ( ty : Type ) -> uint {
97+ fn ty_size ( ty : Type , align_fn : TyAlignFn ) -> uint {
5898 match ty. kind ( ) {
5999 Integer => {
60100 unsafe {
@@ -67,29 +107,32 @@ fn ty_size(ty: Type) -> uint {
67107 Struct => {
68108 if ty. is_packed ( ) {
69109 let str_tys = ty. field_types ( ) ;
70- str_tys. iter ( ) . fold ( 0 , |s, t| s + ty_size ( * t) )
110+ str_tys. iter ( ) . fold ( 0 , |s, t| s + ty_size ( * t, align_fn ) )
71111 } else {
72112 let str_tys = ty. field_types ( ) ;
73- let size = str_tys. iter ( ) . fold ( 0 , |s, t| align ( s, * t) + ty_size ( * t) ) ;
74- align ( size, ty)
113+ let size = str_tys. iter ( )
114+ . fold ( 0 , |s, t| {
115+ align ( s, * t, align_fn) + ty_size ( * t, align_fn)
116+ } ) ;
117+ align ( size, ty, align_fn)
75118 }
76119 }
77120 Array => {
78121 let len = ty. array_length ( ) ;
79122 let elt = ty. element_type ( ) ;
80- let eltsz = ty_size ( elt) ;
123+ let eltsz = ty_size ( elt, align_fn ) ;
81124 len * eltsz
82125 }
83126 _ => panic ! ( "ty_size: unhandled type" )
84127 }
85128}
86129
87- fn classify_ret_ty ( ccx : & CrateContext , ty : Type ) -> ArgType {
130+ fn classify_ret_ty ( ccx : & CrateContext , ty : Type , align_fn : TyAlignFn ) -> ArgType {
88131 if is_reg_ty ( ty) {
89132 let attr = if ty == Type :: i1 ( ccx) { Some ( ZExtAttribute ) } else { None } ;
90133 return ArgType :: direct ( ty, None , None , attr) ;
91134 }
92- let size = ty_size ( ty) ;
135+ let size = ty_size ( ty, align_fn ) ;
93136 if size <= 4 {
94137 let llty = if size <= 1 {
95138 Type :: i8 ( ccx)
@@ -103,13 +146,13 @@ fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
103146 ArgType :: indirect ( ty, Some ( StructRetAttribute ) )
104147}
105148
106- fn classify_arg_ty ( ccx : & CrateContext , ty : Type ) -> ArgType {
149+ fn classify_arg_ty ( ccx : & CrateContext , ty : Type , align_fn : TyAlignFn ) -> ArgType {
107150 if is_reg_ty ( ty) {
108151 let attr = if ty == Type :: i1 ( ccx) { Some ( ZExtAttribute ) } else { None } ;
109152 return ArgType :: direct ( ty, None , None , attr) ;
110153 }
111- let align = ty_align ( ty) ;
112- let size = ty_size ( ty) ;
154+ let align = align_fn ( ty) ;
155+ let size = ty_size ( ty, align_fn ) ;
113156 let llty = if align <= 4 {
114157 Type :: array ( & Type :: i32 ( ccx) , ( ( size + 3 ) / 4 ) as u64 )
115158 } else {
@@ -131,15 +174,21 @@ fn is_reg_ty(ty: Type) -> bool {
131174pub fn compute_abi_info ( ccx : & CrateContext ,
132175 atys : & [ Type ] ,
133176 rty : Type ,
134- ret_def : bool ) -> FnType {
177+ ret_def : bool ,
178+ flavor : Flavor ) -> FnType {
179+ let align_fn = match flavor {
180+ Flavor :: General => general_ty_align as TyAlignFn ,
181+ Flavor :: Ios => ios_ty_align as TyAlignFn ,
182+ } ;
183+
135184 let mut arg_tys = Vec :: new ( ) ;
136185 for & aty in atys. iter ( ) {
137- let ty = classify_arg_ty ( ccx, aty) ;
186+ let ty = classify_arg_ty ( ccx, aty, align_fn ) ;
138187 arg_tys. push ( ty) ;
139188 }
140189
141190 let ret_ty = if ret_def {
142- classify_ret_ty ( ccx, rty)
191+ classify_ret_ty ( ccx, rty, align_fn )
143192 } else {
144193 ArgType :: direct ( Type :: void ( ccx) , None , None , None )
145194 } ;
0 commit comments