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