comparison gen/abi.cpp @ 1024:9167d492cbc2

Abstracted more (most) ABI details out of the normal codegen.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 03 Mar 2009 02:51:21 +0100
parents e8c6dbcd33d1
children 0477f98d357e
comparison
equal deleted inserted replaced
1023:ca191c141cec 1024:9167d492cbc2
1 #include "gen/llvm.h" 1 #include "gen/llvm.h"
2
3 #include <algorithm>
2 4
3 #include "mars.h" 5 #include "mars.h"
4 6
5 #include "gen/irstate.h" 7 #include "gen/irstate.h"
6 #include "gen/llvmhelpers.h" 8 #include "gen/llvmhelpers.h"
7 #include "gen/tollvm.h" 9 #include "gen/tollvm.h"
8 #include "gen/abi.h" 10 #include "gen/abi.h"
9 #include "gen/logger.h" 11 #include "gen/logger.h"
10 12
11 ////////////////////////////////////////////////////////////////////////////// 13 #include "ir/irfunction.h"
12 //////////////////////////////////////////////////////////////////////////////
13 ///////////////////// baseclass ////////////////////////////
14 //////////////////////////////////////////////////////////////////////////////
15 //////////////////////////////////////////////////////////////////////////////
16
17 // FIXME: Would be nice to come up a better and faster way to do this, right
18 // now I'm more worried about actually making this abstraction work at all ...
19 // It's definitely way overkill with the amount of return value rewrites we
20 // have right now, but I expect this to change with proper x86-64 abi support
21
22 TargetABI::TargetABI()
23 {
24 }
25
26 llvm::Value* TargetABI::getRet(TypeFunction* tf, llvm::Value* io)
27 {
28 if (ABIRetRewrite* r = findRetRewrite(tf))
29 {
30 return r->get(io);
31 }
32 return io;
33 }
34
35 llvm::Value* TargetABI::putRet(TypeFunction* tf, llvm::Value* io)
36 {
37 if (ABIRetRewrite* r = findRetRewrite(tf))
38 {
39 return r->put(io);
40 }
41 return io;
42 }
43
44 const llvm::Type* TargetABI::getRetType(TypeFunction* tf, const llvm::Type* t)
45 {
46 if (ABIRetRewrite* r = findRetRewrite(tf))
47 {
48 return r->type(t);
49 }
50 return t;
51 }
52
53 ABIRetRewrite * TargetABI::findRetRewrite(TypeFunction * tf)
54 {
55 size_t n = retOps.size();
56 if (n)
57 for (size_t i = 0; i < n; i++)
58 {
59 if (retOps[i]->test(tf))
60 return retOps[i];
61 }
62 return NULL;
63 }
64 14
65 ////////////////////////////////////////////////////////////////////////////// 15 //////////////////////////////////////////////////////////////////////////////
66 ////////////////////////////////////////////////////////////////////////////// 16 //////////////////////////////////////////////////////////////////////////////
67 ///////////////////// X86 //////////////////////////// 17 ///////////////////// X86 ////////////////////////////
68 ////////////////////////////////////////////////////////////////////////////// 18 //////////////////////////////////////////////////////////////////////////////
69 ////////////////////////////////////////////////////////////////////////////// 19 //////////////////////////////////////////////////////////////////////////////
70 20
71 // simply swap of real/imag parts for proper x87 complex abi 21 // simply swap of real/imag parts for proper x87 complex abi
72 struct X87_complex_swap : ABIRetRewrite 22 struct X87_complex_swap : ABIRewrite
73 { 23 {
74 LLValue* get(LLValue* v) 24 LLValue* get(Type*, LLValue* v)
75 { 25 {
76 return DtoAggrPairSwap(v); 26 return DtoAggrPairSwap(v);
77 } 27 }
78 LLValue* put(LLValue* v) 28 LLValue* put(Type*, LLValue* v)
79 { 29 {
80 return DtoAggrPairSwap(v); 30 return DtoAggrPairSwap(v);
81 } 31 }
82 const LLType* type(const LLType* t) 32 const LLType* type(Type*, const LLType* t)
83 { 33 {
84 return t; 34 return t;
85 } 35 }
86 bool test(TypeFunction* tf) 36 };
87 { 37
88 // extern(D) && is(T:creal) 38 //////////////////////////////////////////////////////////////////////////////
89 return (tf->linkage == LINKd && tf->next->toBasetype()->iscomplex()); 39
90 } 40 struct X86_cfloat_rewrite : ABIRewrite
91 };
92
93 //////////////////////////////////////////////////////////////////////////////
94
95 struct X86_cfloat_rewrite : ABIRetRewrite
96 { 41 {
97 // i64 -> {float,float} 42 // i64 -> {float,float}
98 LLValue* get(LLValue* in) 43 LLValue* get(Type*, LLValue* in)
99 { 44 {
100 // extract real part 45 // extract real part
101 LLValue* rpart = gIR->ir->CreateTrunc(in, LLType::Int32Ty); 46 LLValue* rpart = gIR->ir->CreateTrunc(in, LLType::Int32Ty);
102 rpart = gIR->ir->CreateBitCast(rpart, LLType::FloatTy, ".re"); 47 rpart = gIR->ir->CreateBitCast(rpart, LLType::FloatTy, ".re");
103 48
109 // return {float,float} aggr pair with same bits 54 // return {float,float} aggr pair with same bits
110 return DtoAggrPair(rpart, ipart, ".final_cfloat"); 55 return DtoAggrPair(rpart, ipart, ".final_cfloat");
111 } 56 }
112 57
113 // {float,float} -> i64 58 // {float,float} -> i64
114 LLValue* put(LLValue* v) 59 LLValue* put(Type*, LLValue* v)
115 { 60 {
116 // extract real 61 // extract real
117 LLValue* r = gIR->ir->CreateExtractValue(v, 0); 62 LLValue* r = gIR->ir->CreateExtractValue(v, 0);
118 // cast to i32 63 // cast to i32
119 r = gIR->ir->CreateBitCast(r, LLType::Int32Ty); 64 r = gIR->ir->CreateBitCast(r, LLType::Int32Ty);
132 // combine and return 77 // combine and return
133 return v = gIR->ir->CreateOr(r, i); 78 return v = gIR->ir->CreateOr(r, i);
134 } 79 }
135 80
136 // {float,float} -> i64 81 // {float,float} -> i64
137 const LLType* type(const LLType* t) 82 const LLType* type(Type*, const LLType* t)
138 { 83 {
139 return LLType::Int64Ty; 84 return LLType::Int64Ty;
140 } 85 }
141 86 };
142 // test if rewrite applies to function 87
143 bool test(TypeFunction* tf) 88 //////////////////////////////////////////////////////////////////////////////
144 { 89
145 return (tf->linkage != LINKd) 90 // FIXME: try into eliminating the alloca or if at least check
146 && (tf->next->toBasetype() == Type::tcomplex32); 91 // if it gets optimized away
92
93 // convert byval struct
94 // when
95 struct X86_struct_to_register : ABIRewrite
96 {
97 // int -> struct
98 LLValue* get(Type* dty, LLValue* v)
99 {
100 Logger::println("rewriting int -> struct");
101 LLValue* mem = DtoAlloca(DtoType(dty), ".int_to_struct");
102 DtoStore(v, DtoBitCast(mem, getPtrToType(v->getType())));
103 return DtoLoad(mem);
104 }
105 // struct -> int
106 LLValue* put(Type* dty, LLValue* v)
107 {
108 Logger::println("rewriting struct -> int");
109 LLValue* mem = DtoAlloca(v->getType(), ".struct_to_int");
110 DtoStore(v, mem);
111 DtoLoad(DtoBitCast(mem, getPtrToType(type(dty, v->getType()))));
112 }
113 const LLType* type(Type*, const LLType* t)
114 {
115 size_t sz = getTypePaddedSize(t)*8;
116 return LLIntegerType::get(sz);
147 } 117 }
148 }; 118 };
149 119
150 ////////////////////////////////////////////////////////////////////////////// 120 //////////////////////////////////////////////////////////////////////////////
151 121
152 struct X86TargetABI : TargetABI 122 struct X86TargetABI : TargetABI
153 { 123 {
154 X86TargetABI() 124 X87_complex_swap swapComplex;
155 { 125 X86_cfloat_rewrite cfloatToInt;
156 retOps.push_back(new X87_complex_swap); 126 X86_struct_to_register structToReg;
157 retOps.push_back(new X86_cfloat_rewrite);
158 }
159 127
160 bool returnInArg(TypeFunction* tf) 128 bool returnInArg(TypeFunction* tf)
161 { 129 {
162 Type* rt = tf->next->toBasetype(); 130 Type* rt = tf->next->toBasetype();
163 // D only returns structs on the stack 131 // D only returns structs on the stack
166 // other ABI's follow C, which is cdouble and creal returned on the stack 134 // other ABI's follow C, which is cdouble and creal returned on the stack
167 // as well as structs 135 // as well as structs
168 else 136 else
169 return (rt->ty == Tstruct || rt->ty == Tcomplex64 || rt->ty == Tcomplex80); 137 return (rt->ty == Tstruct || rt->ty == Tcomplex64 || rt->ty == Tcomplex80);
170 } 138 }
139
140 bool passByVal(Type* t)
141 {
142 return t->toBasetype()->ty == Tstruct;
143 }
144
145 void rewriteFunctionType(TypeFunction* tf)
146 {
147 IrFuncTy* fty = tf->fty;
148 Type* rt = fty->ret->type->toBasetype();
149
150 // extern(D)
151 if (tf->linkage == LINKd)
152 {
153 // RETURN VALUE
154
155 // complex {re,im} -> {im,re}
156 if (rt->iscomplex())
157 {
158 fty->ret->rewrite = &swapComplex;
159 }
160
161 // IMPLICIT PARAMETERS
162
163 // mark this/nested params inreg
164 if (fty->arg_this)
165 {
166 fty->arg_this->attrs = llvm::Attribute::InReg;
167 }
168 else if (fty->arg_nest)
169 {
170 fty->arg_nest->attrs = llvm::Attribute::InReg;
171 }
172 // otherwise try to mark the last param inreg
173 else if (!fty->arg_sret && !fty->args.empty())
174 {
175 // The last parameter is passed in EAX rather than being pushed on the stack if the following conditions are met:
176 // * It fits in EAX.
177 // * It is not a 3 byte struct.
178 // * It is not a floating point type.
179
180 IrFuncTyArg* last = fty->args.back();
181 Type* lastTy = last->type->toBasetype();
182 unsigned sz = lastTy->size();
183
184 if (last->byref && !last->isByVal())
185 {
186 last->attrs = llvm::Attribute::InReg;
187 }
188 else if (!lastTy->isfloating() && (sz == 1 || sz == 2 || sz == 4)) // right?
189 {
190 // rewrite the struct into an integer to make inreg work
191 if (lastTy->ty == Tstruct)
192 {
193 last->rewrite = &structToReg;
194 last->ltype = structToReg.type(last->type, last->ltype);
195 last->byref = false;
196 }
197 last->attrs = llvm::Attribute::InReg;
198 }
199 }
200
201 // FIXME: tf->varargs == 1 need to use C calling convention and vararg mechanism to live up to the spec:
202 // "The caller is expected to clean the stack. _argptr is not passed, it is computed by the callee."
203
204 // EXPLICIT PARAMETERS
205
206 // reverse parameter order
207 // for non variadics
208 if (!fty->args.empty() && tf->varargs != 1)
209 {
210 fty->reverseParams = true;
211 }
212 }
213
214 // extern(C) and all others
215 else
216 {
217 // RETURN VALUE
218
219 // cfloat -> i64
220 if (tf->next->toBasetype() == Type::tcomplex32)
221 {
222 fty->ret->rewrite = &cfloatToInt;
223 fty->ret->ltype = LLType::Int64Ty;
224 }
225
226 // IMPLICIT PARAMETERS
227
228 // EXPLICIT PARAMETERS
229 }
230 }
171 }; 231 };
172 232
173 ////////////////////////////////////////////////////////////////////////////// 233 //////////////////////////////////////////////////////////////////////////////
174 ////////////////////////////////////////////////////////////////////////////// 234 //////////////////////////////////////////////////////////////////////////////
175 /////////////////// X86-64 ////////////////////////// 235 /////////////////// X86-64 //////////////////////////
176 ////////////////////////////////////////////////////////////////////////////// 236 //////////////////////////////////////////////////////////////////////////////
177 ////////////////////////////////////////////////////////////////////////////// 237 //////////////////////////////////////////////////////////////////////////////
178 238
179 struct X86_64_cfloat_rewrite : ABIRetRewrite 239 struct X86_64_cfloat_rewrite : ABIRewrite
180 { 240 {
181 // {double} -> {float,float} 241 // {double} -> {float,float}
182 LLValue* get(LLValue* in) 242 LLValue* get(Type*, LLValue* in)
183 { 243 {
184 // extract double 244 // extract double
185 LLValue* v = gIR->ir->CreateExtractValue(in, 0); 245 LLValue* v = gIR->ir->CreateExtractValue(in, 0);
186 // cast to i64 246 // cast to i64
187 v = gIR->ir->CreateBitCast(v, LLType::Int64Ty); 247 v = gIR->ir->CreateBitCast(v, LLType::Int64Ty);
198 // return {float,float} aggr pair with same bits 258 // return {float,float} aggr pair with same bits
199 return DtoAggrPair(rpart, ipart, ".final_cfloat"); 259 return DtoAggrPair(rpart, ipart, ".final_cfloat");
200 } 260 }
201 261
202 // {float,float} -> {double} 262 // {float,float} -> {double}
203 LLValue* put(LLValue* v) 263 LLValue* put(Type*, LLValue* v)
204 { 264 {
205 // extract real 265 // extract real
206 LLValue* r = gIR->ir->CreateExtractValue(v, 0); 266 LLValue* r = gIR->ir->CreateExtractValue(v, 0);
207 // cast to i32 267 // cast to i32
208 r = gIR->ir->CreateBitCast(r, LLType::Int32Ty); 268 r = gIR->ir->CreateBitCast(r, LLType::Int32Ty);
229 LLValue* undef = llvm::UndefValue::get(t); 289 LLValue* undef = llvm::UndefValue::get(t);
230 return gIR->ir->CreateInsertValue(undef, v, 0); 290 return gIR->ir->CreateInsertValue(undef, v, 0);
231 } 291 }
232 292
233 // {float,float} -> {double} 293 // {float,float} -> {double}
234 const LLType* type(const LLType* t) 294 const LLType* type(Type*, const LLType* t)
235 { 295 {
236 return LLStructType::get(LLType::DoubleTy, NULL); 296 return LLStructType::get(LLType::DoubleTy, NULL);
237 } 297 }
238
239 // test if rewrite applies to function
240 bool test(TypeFunction* tf)
241 {
242 return (tf->linkage != LINKd)
243 && (tf->next->toBasetype() == Type::tcomplex32);
244 }
245 }; 298 };
246 299
247 ////////////////////////////////////////////////////////////////////////////// 300 //////////////////////////////////////////////////////////////////////////////
248 301
249 struct X86_64TargetABI : TargetABI 302 struct X86_64TargetABI : TargetABI
250 { 303 {
251 X86_64TargetABI() 304 X86_64_cfloat_rewrite cfloat_rewrite;
252 {
253 retOps.push_back(new X86_64_cfloat_rewrite);
254 }
255 305
256 bool returnInArg(TypeFunction* tf) 306 bool returnInArg(TypeFunction* tf)
257 { 307 {
258 Type* rt = tf->next->toBasetype(); 308 Type* rt = tf->next->toBasetype();
259 return (rt->ty == Tstruct); 309 return (rt->ty == Tstruct);
260 } 310 }
311
312 bool passByVal(Type* t)
313 {
314 return t->toBasetype()->ty == Tstruct;
315 }
316
317 void rewriteFunctionType(TypeFunction* tf)
318 {
319 IrFuncTy* fty = tf->fty;
320 Type* rt = fty->ret->type->toBasetype();
321
322 // rewrite cfloat return for !extern(D)
323 if (tf->linkage != LINKd && rt == Type::tcomplex32)
324 {
325 fty->ret->rewrite = &cfloat_rewrite;
326 fty->ret->ltype = cfloat_rewrite.type(fty->ret->type, fty->ret->ltype);
327 }
328 }
261 }; 329 };
262 330
263 ////////////////////////////////////////////////////////////////////////////// 331 //////////////////////////////////////////////////////////////////////////////
264 ////////////////////////////////////////////////////////////////////////////// 332 //////////////////////////////////////////////////////////////////////////////
265 /////////////////// Unknown targets ////////////////////////// 333 /////////////////// Unknown targets //////////////////////////
267 ////////////////////////////////////////////////////////////////////////////// 335 //////////////////////////////////////////////////////////////////////////////
268 336
269 // Some reasonable defaults for when we don't know what ABI to use. 337 // Some reasonable defaults for when we don't know what ABI to use.
270 struct UnknownTargetABI : TargetABI 338 struct UnknownTargetABI : TargetABI
271 { 339 {
272 UnknownTargetABI()
273 {
274 // Don't push anything into retOps, assume defaults will be fine.
275 }
276
277 bool returnInArg(TypeFunction* tf) 340 bool returnInArg(TypeFunction* tf)
278 { 341 {
279 Type* rt = tf->next->toBasetype(); 342 return (tf->next->toBasetype()->ty == Tstruct);
280 return (rt->ty == Tstruct); 343 }
344
345 bool passByVal(Type* t)
346 {
347 return t->toBasetype()->ty == Tstruct;
348 }
349
350 void rewriteFunctionType(TypeFunction* t)
351 {
352 // why?
281 } 353 }
282 }; 354 };
283 355
284 ////////////////////////////////////////////////////////////////////////////// 356 //////////////////////////////////////////////////////////////////////////////
285 ////////////////////////////////////////////////////////////////////////////// 357 //////////////////////////////////////////////////////////////////////////////