comparison gen/complex.cpp @ 107:3efbcc81ba45 trunk

[svn r111] Fixed most problems with complex number support and added typeinfo for them. Added typeinfo ti_C. Did some changes to the way expressions that have both lvalue and rvalue LLVM values are handled.
author lindquist
date Tue, 20 Nov 2007 00:02:35 +0100
parents 4d1e9eb001e0
children 44a95ac7368a
comparison
equal deleted inserted replaced
106:5b5194b25f33 107:3efbcc81ba45
125 { 125 {
126 Type* t = DtoDType(val->getType()); 126 Type* t = DtoDType(val->getType());
127 TY ty = t->ty; 127 TY ty = t->ty;
128 128
129 if (val->isComplex() || t->iscomplex()) { 129 if (val->isComplex() || t->iscomplex()) {
130 assert(DtoDType(to) == t); 130 return DtoCastComplex(val, to);
131 return val;
132 } 131 }
133 132
134 const llvm::Type* base = DtoComplexBaseType(to); 133 const llvm::Type* base = DtoComplexBaseType(to);
135 134
136 llvm::Constant* undef = llvm::UndefValue::get(base); 135 llvm::Constant* undef = llvm::UndefValue::get(base);
164 DtoStore(im, DtoGEPi(c,0,1,"tmp")); 163 DtoStore(im, DtoGEPi(c,0,1,"tmp"));
165 } 164 }
166 165
167 ////////////////////////////////////////////////////////////////////////////////////////// 166 //////////////////////////////////////////////////////////////////////////////////////////
168 167
168 void DtoGetComplexParts(DValue* c, llvm::Value*& re, llvm::Value*& im)
169 {
170 // lhs values
171 if (DComplexValue* cx = c->isComplex()) {
172 re = cx->re;
173 im = cx->im;
174 }
175 else {
176 re = DtoLoad(DtoGEPi(c->getRVal(),0,0,"tmp"));
177 im = DtoLoad(DtoGEPi(c->getRVal(),0,1,"tmp"));
178 }
179 }
180
181 //////////////////////////////////////////////////////////////////////////////////////////
182
169 DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs) 183 DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs)
170 { 184 {
171 lhs = DtoComplex(type, lhs); 185 lhs = DtoComplex(type, lhs);
172 rhs = DtoComplex(type, rhs); 186 rhs = DtoComplex(type, rhs);
173 187
174 llvm::Value *a, *b, *c, *d, *re, *im; 188 llvm::Value *a, *b, *c, *d, *re, *im;
175 189
176 // lhs values 190 // lhs values
177 if (DComplexValue* cx = lhs->isComplex()) { 191 DtoGetComplexParts(lhs, a, b);
178 a = cx->re; 192 // rhs values
179 b = cx->im; 193 DtoGetComplexParts(rhs, c, d);
180 }
181 else {
182 a = DtoLoad(DtoGEPi(lhs->getRVal(),0,0,"tmp"));
183 b = DtoLoad(DtoGEPi(lhs->getRVal(),0,1,"tmp"));
184 }
185
186 // rhs values
187 if (DComplexValue* cx = rhs->isComplex()) {
188 c = cx->re;
189 d = cx->im;
190 }
191 else {
192 c = DtoLoad(DtoGEPi(rhs->getRVal(),0,0,"tmp"));
193 d = DtoLoad(DtoGEPi(rhs->getRVal(),0,1,"tmp"));
194 }
195 194
196 // add up 195 // add up
197 re = gIR->ir->CreateAdd(a, c, "tmp"); 196 re = gIR->ir->CreateAdd(a, c, "tmp");
198 im = gIR->ir->CreateAdd(b, d, "tmp"); 197 im = gIR->ir->CreateAdd(b, d, "tmp");
199 198
208 rhs = DtoComplex(type, rhs); 207 rhs = DtoComplex(type, rhs);
209 208
210 llvm::Value *a, *b, *c, *d, *re, *im; 209 llvm::Value *a, *b, *c, *d, *re, *im;
211 210
212 // lhs values 211 // lhs values
213 if (DComplexValue* cx = lhs->isComplex()) { 212 DtoGetComplexParts(lhs, a, b);
214 a = cx->re; 213 // rhs values
215 b = cx->im; 214 DtoGetComplexParts(rhs, c, d);
216 }
217 else {
218 a = DtoLoad(DtoGEPi(lhs->getRVal(),0,0,"tmp"));
219 b = DtoLoad(DtoGEPi(lhs->getRVal(),0,1,"tmp"));
220 }
221
222 // rhs values
223 if (DComplexValue* cx = rhs->isComplex()) {
224 c = cx->re;
225 d = cx->im;
226 }
227 else {
228 c = DtoLoad(DtoGEPi(rhs->getRVal(),0,0,"tmp"));
229 d = DtoLoad(DtoGEPi(rhs->getRVal(),0,1,"tmp"));
230 }
231 215
232 // add up 216 // add up
233 re = gIR->ir->CreateSub(a, c, "tmp"); 217 re = gIR->ir->CreateSub(a, c, "tmp");
234 im = gIR->ir->CreateSub(b, d, "tmp"); 218 im = gIR->ir->CreateSub(b, d, "tmp");
235 219
241 DValue* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs) 225 DValue* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs)
242 { 226 {
243 lhs = DtoComplex(type, lhs); 227 lhs = DtoComplex(type, lhs);
244 rhs = DtoComplex(type, rhs); 228 rhs = DtoComplex(type, rhs);
245 229
246 llvm::Value *a, *b, *c, *d, *re, *im; 230 llvm::Value *a, *b, *c, *d;
247 231
248 // lhs values 232 // lhs values
249 if (DComplexValue* cx = lhs->isComplex()) { 233 DtoGetComplexParts(lhs, a, b);
250 a = cx->re; 234 // rhs values
251 b = cx->im; 235 DtoGetComplexParts(rhs, c, d);
252 } 236
253 else { 237 llvm::Value *tmp1, *tmp2, *re, *im;
254 a = DtoLoad(DtoGEPi(lhs->getRVal(),0,0,"tmp"));
255 b = DtoLoad(DtoGEPi(lhs->getRVal(),0,1,"tmp"));
256 }
257
258 // rhs values
259 if (DComplexValue* cx = rhs->isComplex()) {
260 c = cx->re;
261 d = cx->im;
262 }
263 else {
264 c = DtoLoad(DtoGEPi(rhs->getRVal(),0,0,"tmp"));
265 d = DtoLoad(DtoGEPi(rhs->getRVal(),0,1,"tmp"));
266 }
267
268 llvm::Value *tmp1, *tmp2;
269 238
270 tmp1 = gIR->ir->CreateMul(a, c, "tmp"); 239 tmp1 = gIR->ir->CreateMul(a, c, "tmp");
271 tmp2 = gIR->ir->CreateMul(b, d, "tmp"); 240 tmp2 = gIR->ir->CreateMul(b, d, "tmp");
272 re = gIR->ir->CreateSub(tmp1, tmp2, "tmp"); 241 re = gIR->ir->CreateSub(tmp1, tmp2, "tmp");
273 242
283 DValue* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs) 252 DValue* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs)
284 { 253 {
285 lhs = DtoComplex(type, lhs); 254 lhs = DtoComplex(type, lhs);
286 rhs = DtoComplex(type, rhs); 255 rhs = DtoComplex(type, rhs);
287 256
288 llvm::Value *a, *b, *c, *d, *re, *im; 257 llvm::Value *a, *b, *c, *d;
289 258
290 // lhs values 259 // lhs values
291 if (DComplexValue* cx = lhs->isComplex()) { 260 DtoGetComplexParts(lhs, a, b);
292 a = cx->re; 261 // rhs values
293 b = cx->im; 262 DtoGetComplexParts(rhs, c, d);
294 } 263
295 else { 264 llvm::Value *tmp1, *tmp2, *denom, *re, *im;
296 a = DtoLoad(DtoGEPi(lhs->getRVal(),0,0,"tmp"));
297 b = DtoLoad(DtoGEPi(lhs->getRVal(),0,1,"tmp"));
298 }
299
300 // rhs values
301 if (DComplexValue* cx = rhs->isComplex()) {
302 c = cx->re;
303 d = cx->im;
304 }
305 else {
306 c = DtoLoad(DtoGEPi(rhs->getRVal(),0,0,"tmp"));
307 d = DtoLoad(DtoGEPi(rhs->getRVal(),0,1,"tmp"));
308 }
309
310 llvm::Value *tmp1, *tmp2, *denom;
311 265
312 tmp1 = gIR->ir->CreateMul(c, c, "tmp"); 266 tmp1 = gIR->ir->CreateMul(c, c, "tmp");
313 tmp2 = gIR->ir->CreateMul(d, d, "tmp"); 267 tmp2 = gIR->ir->CreateMul(d, d, "tmp");
314 denom = gIR->ir->CreateAdd(tmp1, tmp2, "tmp"); 268 denom = gIR->ir->CreateAdd(tmp1, tmp2, "tmp");
315 269
328 282
329 ////////////////////////////////////////////////////////////////////////////////////////// 283 //////////////////////////////////////////////////////////////////////////////////////////
330 284
331 llvm::Value* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs) 285 llvm::Value* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs)
332 { 286 {
333 llvm::Value* lvec = lhs->getRVal(); 287 Type* type = lhs->getType();
334 llvm::Value* rvec = rhs->getRVal(); 288
335 289 lhs = DtoComplex(type, lhs);
290 rhs = DtoComplex(type, rhs);
291
292 llvm::Value *a, *b, *c, *d;
293
294 // lhs values
295 DtoGetComplexParts(lhs, a, b);
296 // rhs values
297 DtoGetComplexParts(rhs, c, d);
298
299 // select predicate
336 llvm::FCmpInst::Predicate cmpop; 300 llvm::FCmpInst::Predicate cmpop;
337 switch(op) 301 if (op == TOKequal)
338 {
339 case TOKequal:
340 cmpop = llvm::FCmpInst::FCMP_OEQ; 302 cmpop = llvm::FCmpInst::FCMP_OEQ;
341 break; 303 else
342 case TOKnotequal:
343 cmpop = llvm::FCmpInst::FCMP_UNE; 304 cmpop = llvm::FCmpInst::FCMP_UNE;
344 break; 305
345 default: 306 // (l.re==r.re && l.im==r.im)
346 assert(0); 307 llvm::Value* b1 = new llvm::FCmpInst(cmpop, a, c, "tmp", gIR->scopebb());
347 } 308 llvm::Value* b2 = new llvm::FCmpInst(cmpop, b, d, "tmp", gIR->scopebb());
348
349 llvm::Value* l1 = gIR->ir->CreateExtractElement(lvec, DtoConstUint(0), "re");
350 llvm::Value* r1 = gIR->ir->CreateExtractElement(rvec, DtoConstUint(0), "re");
351 llvm::Value* b1 = new llvm::FCmpInst(cmpop, l1, r1, "tmp", gIR->scopebb());
352
353 llvm::Value* l2 = gIR->ir->CreateExtractElement(lvec, DtoConstUint(1), "im");
354 llvm::Value* r2 = gIR->ir->CreateExtractElement(rvec, DtoConstUint(1), "im");
355 llvm::Value* b2 = new llvm::FCmpInst(cmpop, l2, r2, "tmp", gIR->scopebb());
356
357 return gIR->ir->CreateAnd(b1,b2,"tmp"); 309 return gIR->ir->CreateAnd(b1,b2,"tmp");
358 } 310 }