Mercurial > projects > ldc
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 } |