comparison gen/complex.cpp @ 359:926f65e39246 trunk

[svn r380] Improve complex number support.
author ChristianK
date Mon, 14 Jul 2008 17:22:43 +0200
parents 4aa2b6753059
children 8014dbd24605
comparison
equal deleted inserted replaced
358:051f5b550d9c 359:926f65e39246
102 ////////////////////////////////////////////////////////////////////////////////////////// 102 //////////////////////////////////////////////////////////////////////////////////////////
103 103
104 DValue* DtoComplex(Type* to, DValue* val) 104 DValue* DtoComplex(Type* to, DValue* val)
105 { 105 {
106 Type* t = DtoDType(val->getType()); 106 Type* t = DtoDType(val->getType());
107 TY ty = t->ty;
108 107
109 if (val->isComplex() || t->iscomplex()) { 108 if (val->isComplex() || t->iscomplex()) {
110 return DtoCastComplex(val, to); 109 return DtoCastComplex(val, to);
111 } 110 }
112 111
113 const LLType* base = DtoComplexBaseType(to); 112 const LLType* base = DtoComplexBaseType(to);
114 113
115 LLConstant* undef = llvm::UndefValue::get(base); 114 Type* baserety;
116 LLConstant* zero; 115 Type* baseimty;
117 if (ty == Tfloat32 || ty == Timaginary32 || ty == Tcomplex32) 116 TY ty = to->ty;
118 zero = LLConstant::getNullValue(DtoType(Type::tfloat32)); // llvm::ConstantFP::get(llvm::APFloat(0.0f)); 117 if (ty == Tcomplex32) {
119 else if (ty == Tfloat64 || ty == Timaginary64 || ty == Tcomplex64) 118 baserety = Type::tfloat32;
120 zero = LLConstant::getNullValue(DtoType(Type::tfloat64)); 119 baseimty = Type::timaginary32;
121 else if (ty == Tfloat80 || ty == Timaginary80 || ty == Tcomplex80) 120 } else if (ty == Tcomplex64) {
122 zero = LLConstant::getNullValue(DtoType((global.params.useFP80)?Type::tfloat80:Type::tfloat64)); 121 baserety = Type::tfloat64;
122 baseimty = Type::timaginary64;
123 } else if (ty == Tcomplex80) {
124 baserety = global.params.useFP80 ? Type::tfloat80 : Type::tfloat64;
125 baseimty = global.params.useFP80 ? Type::timaginary80 : Type::timaginary64;
126 }
123 127
124 if (t->isimaginary()) { 128 if (t->isimaginary()) {
125 return new DComplexValue(to, zero, val->getRVal()); 129 return new DComplexValue(to, LLConstant::getNullValue(DtoType(baserety)), DtoCastFloat(val, baseimty)->getRVal());
126 } 130 }
127 else if (t->isfloating()) { 131 else if (t->isfloating()) {
128 return new DComplexValue(to, val->getRVal(), zero); 132 return new DComplexValue(to, DtoCastFloat(val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty)));
129 } 133 }
130 else 134 else if (t->isintegral()) {
135 return new DComplexValue(to, DtoCastInt(val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty)));
136 }
131 assert(0); 137 assert(0);
132 } 138 }
133 139
134 ////////////////////////////////////////////////////////////////////////////////////////// 140 //////////////////////////////////////////////////////////////////////////////////////////
135 141
147 153
148 ////////////////////////////////////////////////////////////////////////////////////////// 154 //////////////////////////////////////////////////////////////////////////////////////////
149 155
150 void DtoGetComplexParts(DValue* c, LLValue*& re, LLValue*& im) 156 void DtoGetComplexParts(DValue* c, LLValue*& re, LLValue*& im)
151 { 157 {
152 // lhs values 158 // get LLValues
153 if (DComplexValue* cx = c->isComplex()) { 159 if (DComplexValue* cx = c->isComplex()) {
154 re = cx->re; 160 re = cx->re;
155 im = cx->im; 161 im = cx->im;
156 } 162 }
157 else { 163 else {
158 re = DtoLoad(DtoGEPi(c->getRVal(),0,0,"tmp")); 164 re = DtoLoad(DtoGEPi(c->getRVal(),0,0,"tmp"));
159 im = DtoLoad(DtoGEPi(c->getRVal(),0,1,"tmp")); 165 im = DtoLoad(DtoGEPi(c->getRVal(),0,1,"tmp"));
160 } 166 }
161 } 167 }
162 168
169 DValue* resolveLR(DValue* val, bool getlval)
170 {
171 if (DLRValue* lr = val->isLRValue()) {
172 if (getlval)
173 return lr->lvalue;
174 else
175 return lr->rvalue;
176 }
177 return val;
178 }
179
163 ////////////////////////////////////////////////////////////////////////////////////////// 180 //////////////////////////////////////////////////////////////////////////////////////////
164 181
165 DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs) 182 DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs)
166 { 183 {
167 lhs = DtoComplex(type, lhs); 184 lhs = DtoComplex(type, resolveLR(lhs, true));
168 rhs = DtoComplex(type, rhs); 185 rhs = DtoComplex(type, resolveLR(rhs, false));
169 186
170 llvm::Value *a, *b, *c, *d, *re, *im; 187 llvm::Value *a, *b, *c, *d, *re, *im;
171 188
172 // lhs values 189 // lhs values
173 DtoGetComplexParts(lhs, a, b); 190 DtoGetComplexParts(lhs, a, b);
183 200
184 ////////////////////////////////////////////////////////////////////////////////////////// 201 //////////////////////////////////////////////////////////////////////////////////////////
185 202
186 DValue* DtoComplexSub(Type* type, DValue* lhs, DValue* rhs) 203 DValue* DtoComplexSub(Type* type, DValue* lhs, DValue* rhs)
187 { 204 {
188 lhs = DtoComplex(type, lhs); 205 lhs = DtoComplex(type, resolveLR(lhs, true));
189 rhs = DtoComplex(type, rhs); 206 rhs = DtoComplex(type, resolveLR(rhs, false));
190 207
191 llvm::Value *a, *b, *c, *d, *re, *im; 208 llvm::Value *a, *b, *c, *d, *re, *im;
192 209
193 // lhs values 210 // lhs values
194 DtoGetComplexParts(lhs, a, b); 211 DtoGetComplexParts(lhs, a, b);
204 221
205 ////////////////////////////////////////////////////////////////////////////////////////// 222 //////////////////////////////////////////////////////////////////////////////////////////
206 223
207 DValue* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs) 224 DValue* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs)
208 { 225 {
209 lhs = DtoComplex(type, lhs); 226 lhs = DtoComplex(type, resolveLR(lhs, true));
210 rhs = DtoComplex(type, rhs); 227 rhs = DtoComplex(type, resolveLR(rhs, false));
211 228
212 llvm::Value *a, *b, *c, *d; 229 llvm::Value *a, *b, *c, *d;
213 230
214 // lhs values 231 // lhs values
215 DtoGetComplexParts(lhs, a, b); 232 DtoGetComplexParts(lhs, a, b);
231 248
232 ////////////////////////////////////////////////////////////////////////////////////////// 249 //////////////////////////////////////////////////////////////////////////////////////////
233 250
234 DValue* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs) 251 DValue* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs)
235 { 252 {
236 lhs = DtoComplex(type, lhs); 253 lhs = DtoComplex(type, resolveLR(lhs, true));
237 rhs = DtoComplex(type, rhs); 254 rhs = DtoComplex(type, resolveLR(rhs, false));
238 255
239 llvm::Value *a, *b, *c, *d; 256 llvm::Value *a, *b, *c, *d;
240 257
241 // lhs values 258 // lhs values
242 DtoGetComplexParts(lhs, a, b); 259 DtoGetComplexParts(lhs, a, b);
264 281
265 ////////////////////////////////////////////////////////////////////////////////////////// 282 //////////////////////////////////////////////////////////////////////////////////////////
266 283
267 DValue* DtoComplexNeg(Type* type, DValue* val) 284 DValue* DtoComplexNeg(Type* type, DValue* val)
268 { 285 {
269 val = DtoComplex(type, val); 286 val = DtoComplex(type, resolveLR(val, false));
270 287
271 llvm::Value *a, *b, *re, *im; 288 llvm::Value *a, *b, *re, *im;
272 289
273 // values 290 // values
274 DtoGetComplexParts(val, a, b); 291 DtoGetComplexParts(val, a, b);
284 301
285 LLValue* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs) 302 LLValue* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs)
286 { 303 {
287 Type* type = lhs->getType(); 304 Type* type = lhs->getType();
288 305
289 lhs = DtoComplex(type, lhs); 306 lhs = DtoComplex(type, resolveLR(lhs, false));
290 rhs = DtoComplex(type, rhs); 307 rhs = DtoComplex(type, resolveLR(rhs, false));
291 308
292 llvm::Value *a, *b, *c, *d; 309 llvm::Value *a, *b, *c, *d;
293 310
294 // lhs values 311 // lhs values
295 DtoGetComplexParts(lhs, a, b); 312 DtoGetComplexParts(lhs, a, b);
340 357
341 // unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions. 358 // unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions.
342 // so we need to give it storage, or fix the system that handles this stuff (DLRValue) 359 // so we need to give it storage, or fix the system that handles this stuff (DLRValue)
343 LLValue* mem = new llvm::AllocaInst(DtoType(_to), "castcomplextmp", gIR->topallocapoint()); 360 LLValue* mem = new llvm::AllocaInst(DtoType(_to), "castcomplextmp", gIR->topallocapoint());
344 DtoComplexSet(mem, re, im); 361 DtoComplexSet(mem, re, im);
345 return new DLRValue(val->getType(), val->getRVal(), _to, mem); 362 return new DLRValue(val, new DImValue(_to, mem));
346 } 363 }
347 else if (to->isimaginary()) { 364 else if (to->isimaginary()) {
348 if (val->isComplex()) 365 if (val->isComplex())
349 return new DImValue(to, val->isComplex()->im); 366 return new DImValue(to, val->isComplex()->im);
350 LLValue* v = val->getRVal(); 367 LLValue* v = val->getRVal();