comparison gen/complex.cpp @ 585:fbb1a366cfbc

Complex number should now follow the D ABI on x86. They're also treated as first class values now. Big change.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 09 Sep 2008 16:49:47 -0700
parents a34078905d01
children 192b82878b78
comparison
equal deleted inserted replaced
584:c7d7e2282ba3 585:fbb1a366cfbc
6 #include "gen/complex.h" 6 #include "gen/complex.h"
7 #include "gen/tollvm.h" 7 #include "gen/tollvm.h"
8 #include "gen/llvmhelpers.h" 8 #include "gen/llvmhelpers.h"
9 #include "gen/irstate.h" 9 #include "gen/irstate.h"
10 #include "gen/dvalue.h" 10 #include "gen/dvalue.h"
11 #include "gen/logger.h"
11 12
12 ////////////////////////////////////////////////////////////////////////////////////////// 13 //////////////////////////////////////////////////////////////////////////////////////////
13 14
14 const llvm::StructType* DtoComplexType(Type* type) 15 const llvm::StructType* DtoComplexType(Type* type)
15 { 16 {
16 Type* t = type->toBasetype(); 17 Type* t = type->toBasetype();
17
18 const LLType* base = DtoComplexBaseType(t); 18 const LLType* base = DtoComplexBaseType(t);
19 19 return llvm::StructType::get(base, base, NULL);
20 std::vector<const LLType*> types;
21 types.push_back(base);
22 types.push_back(base);
23
24 return llvm::StructType::get(types);
25 } 20 }
26 21
27 const LLType* DtoComplexBaseType(Type* t) 22 const LLType* DtoComplexBaseType(Type* t)
28 { 23 {
29 TY ty = t->toBasetype()->ty; 24 TY ty = t->toBasetype()->ty;
45 } 40 }
46 } 41 }
47 42
48 ////////////////////////////////////////////////////////////////////////////////////////// 43 //////////////////////////////////////////////////////////////////////////////////////////
49 44
50 LLConstant* DtoConstComplex(Type* ty, LLConstant* re, LLConstant* im)
51 {
52 assert(0);
53 const LLType* base = DtoComplexBaseType(ty);
54
55 std::vector<LLConstant*> inits;
56 inits.push_back(re);
57 inits.push_back(im);
58
59 const llvm::VectorType* vt = llvm::VectorType::get(base, 2);
60 return llvm::ConstantVector::get(vt, inits);
61 }
62
63 LLConstant* DtoConstComplex(Type* _ty, long double re, long double im) 45 LLConstant* DtoConstComplex(Type* _ty, long double re, long double im)
64 { 46 {
65 TY ty = _ty->toBasetype()->ty; 47 TY ty = _ty->toBasetype()->ty;
66 48
67 llvm::ConstantFP* fre; 49 llvm::ConstantFP* fre;
106 88
107 DValue* DtoComplex(Loc& loc, Type* to, DValue* val) 89 DValue* DtoComplex(Loc& loc, Type* to, DValue* val)
108 { 90 {
109 Type* t = val->getType()->toBasetype(); 91 Type* t = val->getType()->toBasetype();
110 92
111 if (val->isComplex() || t->iscomplex()) { 93 if (t->iscomplex()) {
112 return DtoCastComplex(loc, val, to); 94 return DtoCastComplex(loc, val, to);
113 } 95 }
114 96
115 const LLType* base = DtoComplexBaseType(to); 97 const LLType* base = DtoComplexBaseType(to);
116 98
125 baseimty = Type::timaginary64; 107 baseimty = Type::timaginary64;
126 } else if (ty == Tcomplex80) { 108 } else if (ty == Tcomplex80) {
127 baserety = Type::tfloat80; 109 baserety = Type::tfloat80;
128 baseimty = Type::timaginary80; 110 baseimty = Type::timaginary80;
129 } 111 }
112 else {
113 assert(0);
114 }
115
116 const LLType* complexTy = DtoType(to);
117 LLValue* res;
130 118
131 if (t->isimaginary()) { 119 if (t->isimaginary()) {
132 return new DComplexValue(to, LLConstant::getNullValue(DtoType(baserety)), DtoCastFloat(loc, val, baseimty)->getRVal()); 120 res = DtoAggrPair(complexTy, LLConstant::getNullValue(DtoType(baserety)), DtoCastFloat(loc, val, baseimty)->getRVal());
133 } 121 }
134 else if (t->isfloating()) { 122 else if (t->isfloating() || t->isintegral()) {
135 return new DComplexValue(to, DtoCastFloat(loc, val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty))); 123 res = DtoAggrPair(complexTy, DtoCastFloat(loc, val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty)));
136 } 124 }
137 else if (t->isintegral()) { 125 else {
138 return new DComplexValue(to, DtoCastInt(loc, val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty))); 126 assert(0);
139 } 127 }
140 assert(0); 128 return new DImValue(to, res);
141 } 129 }
142 130
143 ////////////////////////////////////////////////////////////////////////////////////////// 131 //////////////////////////////////////////////////////////////////////////////////////////
144
145 void DtoComplexAssign(LLValue* l, LLValue* r)
146 {
147 DtoStore(DtoLoad(DtoGEPi(r, 0,0, "tmp")), DtoGEPi(l,0,0,"tmp"));
148 DtoStore(DtoLoad(DtoGEPi(r, 0,1, "tmp")), DtoGEPi(l,0,1,"tmp"));
149 }
150 132
151 void DtoComplexSet(LLValue* c, LLValue* re, LLValue* im) 133 void DtoComplexSet(LLValue* c, LLValue* re, LLValue* im)
152 { 134 {
153 DtoStore(re, DtoGEPi(c,0,0,"tmp")); 135 DtoStore(re, DtoGEPi(c,0,0,"tmp"));
154 DtoStore(im, DtoGEPi(c,0,1,"tmp")); 136 DtoStore(im, DtoGEPi(c,0,1,"tmp"));
156 138
157 ////////////////////////////////////////////////////////////////////////////////////////// 139 //////////////////////////////////////////////////////////////////////////////////////////
158 140
159 void DtoGetComplexParts(DValue* c, LLValue*& re, LLValue*& im) 141 void DtoGetComplexParts(DValue* c, LLValue*& re, LLValue*& im)
160 { 142 {
161 // get LLValues 143 LLValue* v = c->getRVal();
162 if (DComplexValue* cx = c->isComplex()) { 144 Logger::cout() << "extracting real and imaginary parts from: " << *v << '\n';
163 re = cx->re; 145 re = gIR->ir->CreateExtractValue(v, 0, ".re_part");
164 im = cx->im; 146 im = gIR->ir->CreateExtractValue(v, 1, ".im_part");
165 }
166 else {
167 re = DtoLoad(DtoGEPi(c->getRVal(),0,0,"tmp"));
168 im = DtoLoad(DtoGEPi(c->getRVal(),0,1,"tmp"));
169 }
170 } 147 }
171 148
172 DValue* resolveLR(DValue* val, bool getlval) 149 DValue* resolveLR(DValue* val, bool getlval)
173 { 150 {
174 if (DLRValue* lr = val->isLRValue()) { 151 if (DLRValue* lr = val->isLRValue()) {
230 else if(hasIm(lhstype)) 207 else if(hasIm(lhstype))
231 res_im = lhs_im; 208 res_im = lhs_im;
232 else // either hasIm(rhstype) or no im at all (then use any) 209 else // either hasIm(rhstype) or no im at all (then use any)
233 res_im = rhs_im; 210 res_im = rhs_im;
234 211
235 return new DComplexValue(type, res_re, res_im); 212 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im);
213 return new DImValue(type, res);
236 } 214 }
237 215
238 ////////////////////////////////////////////////////////////////////////////////////////// 216 //////////////////////////////////////////////////////////////////////////////////////////
239 217
240 DValue* DtoComplexSub(Loc& loc, Type* type, DValue* lhs, DValue* rhs) 218 DValue* DtoComplexSub(Loc& loc, Type* type, DValue* lhs, DValue* rhs)
260 if(hasIm(rhstype)) 238 if(hasIm(rhstype))
261 res_im = gIR->ir->CreateSub(lhs_im, rhs_im, "tmp"); 239 res_im = gIR->ir->CreateSub(lhs_im, rhs_im, "tmp");
262 else 240 else
263 res_im = lhs_im; 241 res_im = lhs_im;
264 242
265 return new DComplexValue(type, res_re, res_im); 243 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im);
244 return new DImValue(type, res);
266 } 245 }
267 246
268 ////////////////////////////////////////////////////////////////////////////////////////// 247 //////////////////////////////////////////////////////////////////////////////////////////
269 248
270 DValue* DtoComplexMul(Loc& loc, Type* type, DValue* lhs, DValue* rhs) 249 DValue* DtoComplexMul(Loc& loc, Type* type, DValue* lhs, DValue* rhs)
312 else if(imre) 291 else if(imre)
313 res_im = imre; 292 res_im = imre;
314 else 293 else
315 res_im = hasRe(lhstype) ? rhs_im : lhs_re; // null! 294 res_im = hasRe(lhstype) ? rhs_im : lhs_re; // null!
316 295
317 return new DComplexValue(type, res_re, res_im); 296 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im);
297 return new DImValue(type, res);
318 } 298 }
319 299
320 ////////////////////////////////////////////////////////////////////////////////////////// 300 //////////////////////////////////////////////////////////////////////////////////////////
321 301
322 DValue* DtoComplexDiv(Loc& loc, Type* type, DValue* lhs, DValue* rhs) 302 DValue* DtoComplexDiv(Loc& loc, Type* type, DValue* lhs, DValue* rhs)
388 368
389 res_re = gIR->ir->CreateFDiv(res_re, denom, "res_re"); 369 res_re = gIR->ir->CreateFDiv(res_re, denom, "res_re");
390 res_im = gIR->ir->CreateFDiv(res_im, denom, "res_im"); 370 res_im = gIR->ir->CreateFDiv(res_im, denom, "res_im");
391 } 371 }
392 372
393 return new DComplexValue(type, res_re, res_im); 373 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im);
374 return new DImValue(type, res);
394 } 375 }
395 376
396 ////////////////////////////////////////////////////////////////////////////////////////// 377 //////////////////////////////////////////////////////////////////////////////////////////
397 378
398 DValue* DtoComplexNeg(Loc& loc, Type* type, DValue* val) 379 DValue* DtoComplexNeg(Loc& loc, Type* type, DValue* val)
406 387
407 // sub up 388 // sub up
408 re = gIR->ir->CreateNeg(a, "tmp"); 389 re = gIR->ir->CreateNeg(a, "tmp");
409 im = gIR->ir->CreateNeg(b, "tmp"); 390 im = gIR->ir->CreateNeg(b, "tmp");
410 391
411 return new DComplexValue(type, re, im); 392 LLValue* res = DtoAggrPair(DtoType(type), re, im);
393 return new DImValue(type, res);
412 } 394 }
413 395
414 ////////////////////////////////////////////////////////////////////////////////////////// 396 //////////////////////////////////////////////////////////////////////////////////////////
415 397
416 LLValue* DtoComplexEquals(Loc& loc, TOK op, DValue* lhs, DValue* rhs) 398 LLValue* DtoComplexEquals(Loc& loc, TOK op, DValue* lhs, DValue* rhs)
460 442
461 if (to->size() < vty->size()) { 443 if (to->size() < vty->size()) {
462 re = gIR->ir->CreateFPTrunc(re, toty, "tmp"); 444 re = gIR->ir->CreateFPTrunc(re, toty, "tmp");
463 im = gIR->ir->CreateFPTrunc(im, toty, "tmp"); 445 im = gIR->ir->CreateFPTrunc(im, toty, "tmp");
464 } 446 }
465 else if (to->size() > vty->size()) { 447 else {
466 re = gIR->ir->CreateFPExt(re, toty, "tmp"); 448 re = gIR->ir->CreateFPExt(re, toty, "tmp");
467 im = gIR->ir->CreateFPExt(im, toty, "tmp"); 449 im = gIR->ir->CreateFPExt(im, toty, "tmp");
468 } 450 }
469 else { 451
470 return val; 452 LLValue* pair = DtoAggrPair(DtoType(_to), re, im);
471 } 453 DValue* rval = new DImValue(_to, pair);
472 454
473 if (val->isComplex()) 455 // if the value we're casting is not a lvalue, the cast value can't be either
474 return new DComplexValue(_to, re, im); 456 if (!val->isLVal()) {
457 return rval;
458 }
475 459
476 // unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions. 460 // unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions.
477 // so we need to give it storage, or fix the system that handles this stuff (DLRValue) 461 // so we need to maintain the storage
478 LLValue* mem = DtoAlloca(DtoType(_to), "castcomplextmp"); 462 return new DLRValue(val, rval);
479 DtoComplexSet(mem, re, im);
480 return new DLRValue(val, new DImValue(_to, mem));
481 } 463 }
482 else if (to->isimaginary()) { 464 else if (to->isimaginary()) {
483 if (val->isComplex()) 465 // FIXME: this loads both values, even when we only need one
484 return new DImValue(to, val->isComplex()->im);
485 LLValue* v = val->getRVal(); 466 LLValue* v = val->getRVal();
486 DImValue* im = new DImValue(to, DtoLoad(DtoGEPi(v,0,1,"tmp"))); 467 LLValue* impart = gIR->ir->CreateExtractValue(v, 1, ".im_part");
468 DImValue* im = new DImValue(to, impart);
487 return DtoCastFloat(loc, im, to); 469 return DtoCastFloat(loc, im, to);
488 } 470 }
489 else if (to->isfloating()) { 471 else if (to->isfloating()) {
490 if (val->isComplex()) 472 // FIXME: this loads both values, even when we only need one
491 return new DImValue(to, val->isComplex()->re);
492 LLValue* v = val->getRVal(); 473 LLValue* v = val->getRVal();
493 DImValue* re = new DImValue(to, DtoLoad(DtoGEPi(v,0,0,"tmp"))); 474 LLValue* repart = gIR->ir->CreateExtractValue(v, 0, ".re_part");
475 DImValue* re = new DImValue(to, repart);
494 return DtoCastFloat(loc, re, to); 476 return DtoCastFloat(loc, re, to);
495 } 477 }
496 else 478 else
497 assert(0); 479 assert(0);
498 } 480 }