Mercurial > projects > ldc
comparison gen/abi.cpp @ 1042:45af482e3832
Updated ABI handling to be more flexible with regard to reusing lvalues and allocating fewer temporaries.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Wed, 04 Mar 2009 17:24:25 +0100 |
parents | 0477f98d357e |
children | 0485751a40ae |
comparison
equal
deleted
inserted
replaced
1041:9dca7182aa75 | 1042:45af482e3832 |
---|---|
7 #include "gen/irstate.h" | 7 #include "gen/irstate.h" |
8 #include "gen/llvmhelpers.h" | 8 #include "gen/llvmhelpers.h" |
9 #include "gen/tollvm.h" | 9 #include "gen/tollvm.h" |
10 #include "gen/abi.h" | 10 #include "gen/abi.h" |
11 #include "gen/logger.h" | 11 #include "gen/logger.h" |
12 #include "gen/dvalue.h" | |
12 | 13 |
13 #include "ir/irfunction.h" | 14 #include "ir/irfunction.h" |
15 | |
16 ////////////////////////////////////////////////////////////////////////////// | |
17 | |
18 void ABIRewrite::getL(Type* dty, DValue* v, llvm::Value* lval) | |
19 { | |
20 LLValue* rval = v->getRVal(); | |
21 assert(rval->getType() == lval->getType()->getContainedType(0)); | |
22 DtoStore(rval, lval); | |
23 } | |
14 | 24 |
15 ////////////////////////////////////////////////////////////////////////////// | 25 ////////////////////////////////////////////////////////////////////////////// |
16 ////////////////////////////////////////////////////////////////////////////// | 26 ////////////////////////////////////////////////////////////////////////////// |
17 ///////////////////// X86 //////////////////////////// | 27 ///////////////////// X86 //////////////////////////// |
18 ////////////////////////////////////////////////////////////////////////////// | 28 ////////////////////////////////////////////////////////////////////////////// |
19 ////////////////////////////////////////////////////////////////////////////// | 29 ////////////////////////////////////////////////////////////////////////////// |
20 | 30 |
21 // simply swap of real/imag parts for proper x87 complex abi | 31 // simply swap of real/imag parts for proper x87 complex abi |
22 struct X87_complex_swap : ABIRewrite | 32 struct X87_complex_swap : ABIRewrite |
23 { | 33 { |
24 LLValue* get(Type*, LLValue* v) | 34 LLValue* get(Type*, DValue* v) |
25 { | 35 { |
26 return DtoAggrPairSwap(v); | 36 return DtoAggrPairSwap(v->getRVal()); |
27 } | 37 } |
28 LLValue* put(Type*, LLValue* v) | 38 LLValue* put(Type*, DValue* v) |
29 { | 39 { |
30 return DtoAggrPairSwap(v); | 40 return DtoAggrPairSwap(v->getRVal()); |
31 } | 41 } |
32 const LLType* type(Type*, const LLType* t) | 42 const LLType* type(Type*, const LLType* t) |
33 { | 43 { |
34 return t; | 44 return t; |
35 } | 45 } |
38 ////////////////////////////////////////////////////////////////////////////// | 48 ////////////////////////////////////////////////////////////////////////////// |
39 | 49 |
40 struct X86_cfloat_rewrite : ABIRewrite | 50 struct X86_cfloat_rewrite : ABIRewrite |
41 { | 51 { |
42 // i64 -> {float,float} | 52 // i64 -> {float,float} |
43 LLValue* get(Type*, LLValue* in) | 53 LLValue* get(Type*, DValue* dv) |
44 { | 54 { |
55 LLValue* in = dv->getRVal(); | |
56 | |
45 // extract real part | 57 // extract real part |
46 LLValue* rpart = gIR->ir->CreateTrunc(in, LLType::Int32Ty); | 58 LLValue* rpart = gIR->ir->CreateTrunc(in, LLType::Int32Ty); |
47 rpart = gIR->ir->CreateBitCast(rpart, LLType::FloatTy, ".re"); | 59 rpart = gIR->ir->CreateBitCast(rpart, LLType::FloatTy, ".re"); |
48 | 60 |
49 // extract imag part | 61 // extract imag part |
54 // return {float,float} aggr pair with same bits | 66 // return {float,float} aggr pair with same bits |
55 return DtoAggrPair(rpart, ipart, ".final_cfloat"); | 67 return DtoAggrPair(rpart, ipart, ".final_cfloat"); |
56 } | 68 } |
57 | 69 |
58 // {float,float} -> i64 | 70 // {float,float} -> i64 |
59 LLValue* put(Type*, LLValue* v) | 71 LLValue* put(Type*, DValue* dv) |
60 { | 72 { |
73 LLValue* v = dv->getRVal(); | |
74 | |
61 // extract real | 75 // extract real |
62 LLValue* r = gIR->ir->CreateExtractValue(v, 0); | 76 LLValue* r = gIR->ir->CreateExtractValue(v, 0); |
63 // cast to i32 | 77 // cast to i32 |
64 r = gIR->ir->CreateBitCast(r, LLType::Int32Ty); | 78 r = gIR->ir->CreateBitCast(r, LLType::Int32Ty); |
65 // zext to i64 | 79 // zext to i64 |
93 // convert byval struct | 107 // convert byval struct |
94 // when | 108 // when |
95 struct X86_struct_to_register : ABIRewrite | 109 struct X86_struct_to_register : ABIRewrite |
96 { | 110 { |
97 // int -> struct | 111 // int -> struct |
98 LLValue* get(Type* dty, LLValue* v) | 112 LLValue* get(Type* dty, DValue* dv) |
99 { | 113 { |
100 Logger::println("rewriting int -> struct"); | 114 Logger::println("rewriting int -> struct"); |
101 LLValue* mem = DtoAlloca(DtoType(dty), ".int_to_struct"); | 115 LLValue* mem = DtoAlloca(DtoType(dty), ".int_to_struct"); |
116 LLValue* v = dv->getRVal(); | |
102 DtoStore(v, DtoBitCast(mem, getPtrToType(v->getType()))); | 117 DtoStore(v, DtoBitCast(mem, getPtrToType(v->getType()))); |
103 return DtoLoad(mem); | 118 return DtoLoad(mem); |
104 } | 119 } |
120 // int -> struct (with dst lvalue given) | |
121 void getL(Type* dty, DValue* dv, llvm::Value* lval) | |
122 { | |
123 Logger::println("rewriting int -> struct"); | |
124 LLValue* v = dv->getRVal(); | |
125 DtoStore(v, DtoBitCast(lval, getPtrToType(v->getType()))); | |
126 } | |
105 // struct -> int | 127 // struct -> int |
106 LLValue* put(Type* dty, LLValue* v) | 128 LLValue* put(Type* dty, DValue* dv) |
107 { | 129 { |
108 Logger::println("rewriting struct -> int"); | 130 Logger::println("rewriting struct -> int"); |
109 LLValue* mem = DtoAlloca(v->getType(), ".struct_to_int"); | 131 assert(dv->isLVal()); |
110 DtoStore(v, mem); | 132 LLValue* mem = dv->getLVal(); |
111 DtoLoad(DtoBitCast(mem, getPtrToType(type(dty, v->getType())))); | 133 const LLType* t = LLIntegerType::get(dty->size()*8); |
134 DtoLoad(DtoBitCast(mem, getPtrToType(t))); | |
112 } | 135 } |
113 const LLType* type(Type*, const LLType* t) | 136 const LLType* type(Type*, const LLType* t) |
114 { | 137 { |
115 size_t sz = getTypePaddedSize(t)*8; | 138 size_t sz = getTypePaddedSize(t)*8; |
116 return LLIntegerType::get(sz); | 139 return LLIntegerType::get(sz); |
239 ////////////////////////////////////////////////////////////////////////////// | 262 ////////////////////////////////////////////////////////////////////////////// |
240 | 263 |
241 struct X86_64_cfloat_rewrite : ABIRewrite | 264 struct X86_64_cfloat_rewrite : ABIRewrite |
242 { | 265 { |
243 // {double} -> {float,float} | 266 // {double} -> {float,float} |
244 LLValue* get(Type*, LLValue* in) | 267 LLValue* get(Type*, DValue* dv) |
245 { | 268 { |
269 LLValue* in = dv->getRVal(); | |
270 | |
246 // extract double | 271 // extract double |
247 LLValue* v = gIR->ir->CreateExtractValue(in, 0); | 272 LLValue* v = gIR->ir->CreateExtractValue(in, 0); |
248 // cast to i64 | 273 // cast to i64 |
249 v = gIR->ir->CreateBitCast(v, LLType::Int64Ty); | 274 v = gIR->ir->CreateBitCast(v, LLType::Int64Ty); |
250 | 275 |
260 // return {float,float} aggr pair with same bits | 285 // return {float,float} aggr pair with same bits |
261 return DtoAggrPair(rpart, ipart, ".final_cfloat"); | 286 return DtoAggrPair(rpart, ipart, ".final_cfloat"); |
262 } | 287 } |
263 | 288 |
264 // {float,float} -> {double} | 289 // {float,float} -> {double} |
265 LLValue* put(Type*, LLValue* v) | 290 LLValue* put(Type*, DValue* dv) |
266 { | 291 { |
292 LLValue* v = dv->getRVal(); | |
293 | |
267 // extract real | 294 // extract real |
268 LLValue* r = gIR->ir->CreateExtractValue(v, 0); | 295 LLValue* r = gIR->ir->CreateExtractValue(v, 0); |
269 // cast to i32 | 296 // cast to i32 |
270 r = gIR->ir->CreateBitCast(r, LLType::Int32Ty); | 297 r = gIR->ir->CreateBitCast(r, LLType::Int32Ty); |
271 // zext to i64 | 298 // zext to i64 |