Mercurial > projects > ldc
comparison gen/complex.cpp @ 617:634fbbdec390
Simplify complex number handling. Fixes bug with complex substraction.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Mon, 22 Sep 2008 20:29:18 +0200 |
parents | 192b82878b78 |
children | 7e0a766fef47 |
comparison
equal
deleted
inserted
replaced
616:5ced42a55aa9 | 617:634fbbdec390 |
---|---|
86 | 86 |
87 ////////////////////////////////////////////////////////////////////////////////////////// | 87 ////////////////////////////////////////////////////////////////////////////////////////// |
88 | 88 |
89 DValue* DtoComplex(Loc& loc, Type* to, DValue* val) | 89 DValue* DtoComplex(Loc& loc, Type* to, DValue* val) |
90 { | 90 { |
91 Type* t = val->getType()->toBasetype(); | 91 const LLType* complexTy = DtoType(to); |
92 | |
93 if (t->iscomplex()) { | |
94 return DtoCastComplex(loc, val, to); | |
95 } | |
96 | |
97 const LLType* base = DtoComplexBaseType(to); | |
98 | 92 |
99 Type* baserety; | 93 Type* baserety; |
100 Type* baseimty; | 94 Type* baseimty; |
101 TY ty = to->ty; | 95 TY ty = to->ty; |
102 if (ty == Tcomplex32) { | 96 if (ty == Tcomplex32) { |
111 } | 105 } |
112 else { | 106 else { |
113 assert(0); | 107 assert(0); |
114 } | 108 } |
115 | 109 |
116 const LLType* complexTy = DtoType(to); | 110 LLValue *re, *im; |
117 LLValue* res; | 111 DtoGetComplexParts(loc, to, val, re, im); |
118 | 112 |
119 if (t->isimaginary()) { | 113 if(!re) |
120 res = DtoAggrPair(complexTy, LLConstant::getNullValue(DtoType(baserety)), DtoCastFloat(loc, val, baseimty)->getRVal()); | 114 re = LLConstant::getNullValue(DtoType(baserety)); |
121 } | 115 if(!im) |
122 else if (t->isfloating()) { | 116 im = LLConstant::getNullValue(DtoType(baseimty)); |
123 res = DtoAggrPair(complexTy, DtoCastFloat(loc, val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty))); | 117 |
124 } | 118 LLValue* res = DtoAggrPair(complexTy, re, im); |
125 else if (t->isintegral()) { | 119 |
126 res = DtoAggrPair(complexTy, DtoCastInt(loc, val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty))); | 120 return new DImValue(to, res); |
121 } | |
122 | |
123 ////////////////////////////////////////////////////////////////////////////////////////// | |
124 | |
125 void DtoComplexSet(LLValue* c, LLValue* re, LLValue* im) | |
126 { | |
127 DtoStore(re, DtoGEPi(c,0,0,"tmp")); | |
128 DtoStore(im, DtoGEPi(c,0,1,"tmp")); | |
129 } | |
130 | |
131 ////////////////////////////////////////////////////////////////////////////////////////// | |
132 | |
133 void DtoGetComplexParts(Loc& loc, Type* to, DValue* val, LLValue*& re, LLValue*& im) | |
134 { | |
135 const LLType* base = DtoComplexBaseType(to); | |
136 | |
137 Type* baserety; | |
138 Type* baseimty; | |
139 TY ty = to->ty; | |
140 if (ty == Tcomplex32) { | |
141 baserety = Type::tfloat32; | |
142 baseimty = Type::timaginary32; | |
143 } else if (ty == Tcomplex64) { | |
144 baserety = Type::tfloat64; | |
145 baseimty = Type::timaginary64; | |
146 } else if (ty == Tcomplex80) { | |
147 baserety = Type::tfloat80; | |
148 baseimty = Type::timaginary80; | |
127 } | 149 } |
128 else { | 150 else { |
129 assert(0); | 151 assert(0); |
130 } | 152 } |
131 return new DImValue(to, res); | 153 |
132 } | 154 Type* t = val->getType()->toBasetype(); |
133 | 155 |
134 ////////////////////////////////////////////////////////////////////////////////////////// | 156 if (t->iscomplex()) { |
135 | 157 DValue* v = DtoCastComplex(loc, val, to); |
136 void DtoComplexSet(LLValue* c, LLValue* re, LLValue* im) | 158 if (to->iscomplex()) { |
137 { | 159 re = gIR->ir->CreateExtractValue(v->getRVal(), 0, ".re_part"); |
138 DtoStore(re, DtoGEPi(c,0,0,"tmp")); | 160 im = gIR->ir->CreateExtractValue(v->getRVal(), 1, ".im_part"); |
139 DtoStore(im, DtoGEPi(c,0,1,"tmp")); | 161 } else |
140 } | 162 DtoGetComplexParts(loc, to, v, re, im); |
141 | 163 } |
142 ////////////////////////////////////////////////////////////////////////////////////////// | 164 else if (t->isimaginary()) { |
143 | 165 re = NULL; |
144 void DtoGetComplexParts(DValue* c, LLValue*& re, LLValue*& im) | 166 im = DtoCastFloat(loc, val, baseimty)->getRVal(); |
145 { | 167 } |
146 LLValue* v = c->getRVal(); | 168 else if (t->isfloating()) { |
147 Logger::cout() << "extracting real and imaginary parts from: " << *v << '\n'; | 169 re = DtoCastFloat(loc, val, baserety)->getRVal(); |
148 re = gIR->ir->CreateExtractValue(v, 0, ".re_part"); | 170 im = NULL; |
149 im = gIR->ir->CreateExtractValue(v, 1, ".im_part"); | 171 } |
150 } | 172 else if (t->isintegral()) { |
151 | 173 re = DtoCastInt(loc, val, baserety)->getRVal(); |
152 DValue* resolveLR(DValue* val, bool getlval) | 174 im = NULL; |
153 { | 175 } |
154 if (DLRValue* lr = val->isLRValue()) { | 176 else { |
155 if (getlval) | 177 assert(0); |
156 return lr->lvalue; | 178 } |
157 else | |
158 return lr->rvalue; | |
159 } | |
160 return val; | |
161 } | |
162 | |
163 ////////////////////////////////////////////////////////////////////////////////////////// | |
164 | |
165 bool hasRe(Type* t) | |
166 { | |
167 return | |
168 (t->ty != Timaginary32 && | |
169 t->ty != Timaginary64 && | |
170 t->ty != Timaginary80); | |
171 } | |
172 | |
173 bool hasIm(Type* t) | |
174 { | |
175 return | |
176 (t->ty == Timaginary32 || | |
177 t->ty == Timaginary64 || | |
178 t->ty == Timaginary80 || | |
179 t->ty == Tcomplex32 || | |
180 t->ty == Tcomplex64 || | |
181 t->ty == Tcomplex80); | |
182 } | 179 } |
183 | 180 |
184 ////////////////////////////////////////////////////////////////////////////////////////// | 181 ////////////////////////////////////////////////////////////////////////////////////////// |
185 | 182 |
186 DValue* DtoComplexAdd(Loc& loc, Type* type, DValue* lhs, DValue* rhs) | 183 DValue* DtoComplexAdd(Loc& loc, Type* type, DValue* lhs, DValue* rhs) |
187 { | 184 { |
188 DValue* clhs = DtoComplex(loc, type, resolveLR(lhs, true)); | |
189 DValue* crhs = DtoComplex(loc, type, resolveLR(rhs, false)); | |
190 | |
191 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; | 185 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; |
192 | 186 |
193 // lhs values | 187 // lhs values |
194 DtoGetComplexParts(clhs, lhs_re, lhs_im); | 188 DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im); |
195 // rhs values | 189 // rhs values |
196 DtoGetComplexParts(crhs, rhs_re, rhs_im); | 190 DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im); |
197 | 191 |
198 // add up | 192 // add up |
199 Type* lhstype = lhs->getType(); | 193 if(lhs_re && rhs_re) |
200 Type* rhstype = rhs->getType(); | |
201 if(hasRe(lhstype) && hasRe(rhstype)) | |
202 res_re = gIR->ir->CreateAdd(lhs_re, rhs_re, "tmp"); | 194 res_re = gIR->ir->CreateAdd(lhs_re, rhs_re, "tmp"); |
203 else if(hasRe(lhstype)) | 195 else if(lhs_re) |
204 res_re = lhs_re; | 196 res_re = lhs_re; |
205 else // either hasRe(rhstype) or no re at all (then use any) | 197 else // either rhs_re or no re at all (then use any) |
206 res_re = rhs_re; | 198 res_re = rhs_re; |
207 | 199 |
208 if(hasIm(lhstype) && hasIm(rhstype)) | 200 if(lhs_im && rhs_im) |
209 res_im = gIR->ir->CreateAdd(lhs_im, rhs_im, "tmp"); | 201 res_im = gIR->ir->CreateAdd(lhs_im, rhs_im, "tmp"); |
210 else if(hasIm(lhstype)) | 202 else if(lhs_im) |
211 res_im = lhs_im; | 203 res_im = lhs_im; |
212 else // either hasIm(rhstype) or no im at all (then use any) | 204 else // either rhs_im or no im at all (then use any) |
213 res_im = rhs_im; | 205 res_im = rhs_im; |
214 | 206 |
215 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); | 207 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); |
216 return new DImValue(type, res); | 208 return new DImValue(type, res); |
217 } | 209 } |
218 | 210 |
219 ////////////////////////////////////////////////////////////////////////////////////////// | 211 ////////////////////////////////////////////////////////////////////////////////////////// |
220 | 212 |
221 DValue* DtoComplexSub(Loc& loc, Type* type, DValue* lhs, DValue* rhs) | 213 DValue* DtoComplexSub(Loc& loc, Type* type, DValue* lhs, DValue* rhs) |
222 { | 214 { |
223 DValue* clhs = DtoComplex(loc, type, resolveLR(lhs, true)); | |
224 DValue* crhs = DtoComplex(loc, type, resolveLR(rhs, false)); | |
225 | |
226 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; | 215 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; |
227 | 216 |
228 // lhs values | 217 // lhs values |
229 DtoGetComplexParts(clhs, lhs_re, lhs_im); | 218 DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im); |
230 // rhs values | 219 // rhs values |
231 DtoGetComplexParts(crhs, rhs_re, rhs_im); | 220 DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im); |
232 | 221 |
233 // sub up | 222 // add up |
234 Type* lhstype = lhs->getType(); | 223 if(lhs_re && rhs_re) |
235 Type* rhstype = rhs->getType(); | |
236 if(hasRe(rhstype)) | |
237 res_re = gIR->ir->CreateSub(lhs_re, rhs_re, "tmp"); | 224 res_re = gIR->ir->CreateSub(lhs_re, rhs_re, "tmp"); |
238 else | 225 else if(lhs_re) |
239 res_re = lhs_re; | 226 res_re = lhs_re; |
227 else // either rhs_re or no re at all (then use any) | |
228 res_re = gIR->ir->CreateNeg(rhs_re, "neg"); | |
240 | 229 |
241 if(hasIm(rhstype)) | 230 if(lhs_im && rhs_im) |
242 res_im = gIR->ir->CreateSub(lhs_im, rhs_im, "tmp"); | 231 res_im = gIR->ir->CreateSub(lhs_im, rhs_im, "tmp"); |
243 else | 232 else if(lhs_im) |
244 res_im = lhs_im; | 233 res_im = lhs_im; |
234 else // either rhs_im or no im at all (then use any) | |
235 res_im = gIR->ir->CreateNeg(rhs_im, "neg"); | |
245 | 236 |
246 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); | 237 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); |
247 return new DImValue(type, res); | 238 return new DImValue(type, res); |
248 } | 239 } |
249 | 240 |
250 ////////////////////////////////////////////////////////////////////////////////////////// | 241 ////////////////////////////////////////////////////////////////////////////////////////// |
251 | 242 |
252 DValue* DtoComplexMul(Loc& loc, Type* type, DValue* lhs, DValue* rhs) | 243 DValue* DtoComplexMul(Loc& loc, Type* type, DValue* lhs, DValue* rhs) |
253 { | 244 { |
254 DValue* clhs = DtoComplex(loc, type, resolveLR(lhs, true)); | |
255 DValue* crhs = DtoComplex(loc, type, resolveLR(rhs, false)); | |
256 | |
257 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; | 245 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; |
258 | 246 |
259 // lhs values | 247 // lhs values |
260 DtoGetComplexParts(clhs, lhs_re, lhs_im); | 248 DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im); |
261 // rhs values | 249 // rhs values |
262 DtoGetComplexParts(crhs, rhs_re, rhs_im); | 250 DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im); |
263 | 251 |
264 // mul up | 252 // mul up |
265 llvm::Value *rere = NULL; | 253 llvm::Value *rere = NULL; |
266 llvm::Value *reim = NULL; | 254 llvm::Value *reim = NULL; |
267 llvm::Value *imre = NULL; | 255 llvm::Value *imre = NULL; |
268 llvm::Value *imim = NULL; | 256 llvm::Value *imim = NULL; |
269 Type* lhstype = lhs->getType(); | 257 |
270 Type* rhstype = rhs->getType(); | 258 if(lhs_re && rhs_re) |
271 | |
272 if(hasRe(lhstype) && hasRe(rhstype)) | |
273 rere = gIR->ir->CreateMul(lhs_re, rhs_re, "rere_mul"); | 259 rere = gIR->ir->CreateMul(lhs_re, rhs_re, "rere_mul"); |
274 if(hasRe(lhstype) && hasIm(rhstype)) | 260 if(lhs_re && rhs_im) |
275 reim = gIR->ir->CreateMul(lhs_re, rhs_im, "reim_mul"); | 261 reim = gIR->ir->CreateMul(lhs_re, rhs_im, "reim_mul"); |
276 if(hasIm(lhstype) && hasRe(rhstype)) | 262 if(lhs_im && rhs_re) |
277 imre = gIR->ir->CreateMul(lhs_im, rhs_re, "imre_mul"); | 263 imre = gIR->ir->CreateMul(lhs_im, rhs_re, "imre_mul"); |
278 if(hasIm(lhstype) && hasIm(rhstype)) | 264 if(lhs_im && rhs_im) |
279 imim = gIR->ir->CreateMul(lhs_im, rhs_im, "imim_mul"); | 265 imim = gIR->ir->CreateMul(lhs_im, rhs_im, "imim_mul"); |
280 | 266 |
281 if(rere && imim) | 267 if(rere && imim) |
282 res_re = gIR->ir->CreateSub(rere, imim, "rere_imim_sub"); | 268 res_re = gIR->ir->CreateSub(rere, imim, "rere_imim_sub"); |
283 else if(rere) | 269 else if(rere) |
284 res_re = rere; | 270 res_re = rere; |
285 else if(imim) | 271 else if(imim) |
286 res_re = gIR->ir->CreateNeg(imim, "imim_neg"); | 272 res_re = gIR->ir->CreateNeg(imim, "imim_neg"); |
287 else | 273 else |
288 res_re = hasRe(lhstype) ? rhs_re : lhs_re; // null! | 274 res_re = lhs_re ? rhs_re : lhs_re; // null! |
289 | 275 |
290 if(reim && imre) | 276 if(reim && imre) |
291 res_im = gIR->ir->CreateAdd(reim, imre, "reim_imre_add"); | 277 res_im = gIR->ir->CreateAdd(reim, imre, "reim_imre_add"); |
292 else if(reim) | 278 else if(reim) |
293 res_im = reim; | 279 res_im = reim; |
294 else if(imre) | 280 else if(imre) |
295 res_im = imre; | 281 res_im = imre; |
296 else | 282 else |
297 res_im = hasRe(lhstype) ? rhs_im : lhs_re; // null! | 283 res_im = lhs_re ? rhs_im : lhs_re; // null! |
298 | 284 |
299 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); | 285 LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); |
300 return new DImValue(type, res); | 286 return new DImValue(type, res); |
301 } | 287 } |
302 | 288 |
303 ////////////////////////////////////////////////////////////////////////////////////////// | 289 ////////////////////////////////////////////////////////////////////////////////////////// |
304 | 290 |
305 DValue* DtoComplexDiv(Loc& loc, Type* type, DValue* lhs, DValue* rhs) | 291 DValue* DtoComplexDiv(Loc& loc, Type* type, DValue* lhs, DValue* rhs) |
306 { | 292 { |
307 DValue* clhs = DtoComplex(loc, type, resolveLR(lhs, true)); | |
308 DValue* crhs = DtoComplex(loc, type, resolveLR(rhs, false)); | |
309 | |
310 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; | 293 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; |
311 | 294 |
312 // lhs values | 295 // lhs values |
313 DtoGetComplexParts(clhs, lhs_re, lhs_im); | 296 DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im); |
314 // rhs values | 297 // rhs values |
315 DtoGetComplexParts(crhs, rhs_re, rhs_im); | 298 DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im); |
316 | |
317 Type* lhstype = lhs->getType(); | |
318 Type* rhstype = rhs->getType(); | |
319 | 299 |
320 // if divisor is only real, division is simple | 300 // if divisor is only real, division is simple |
321 if(hasRe(rhstype) && !hasIm(rhstype)) { | 301 if(rhs_re && !rhs_im) { |
322 if(hasRe(lhstype)) | 302 if(lhs_re) |
323 res_re = gIR->ir->CreateFDiv(lhs_re, rhs_re, "re_divby_re"); | 303 res_re = gIR->ir->CreateFDiv(lhs_re, rhs_re, "re_divby_re"); |
324 else | 304 else |
325 res_re = lhs_re; | 305 res_re = lhs_re; |
326 if(hasIm(lhstype)) | 306 if(lhs_im) |
327 res_im = gIR->ir->CreateFDiv(lhs_im, rhs_re, "im_divby_re"); | 307 res_im = gIR->ir->CreateFDiv(lhs_im, rhs_re, "im_divby_re"); |
328 else | 308 else |
329 res_im = lhs_im; | 309 res_im = lhs_im; |
330 } | 310 } |
331 // if divisor is only imaginary, division is simple too | 311 // if divisor is only imaginary, division is simple too |
332 else if(!hasRe(rhstype) && hasIm(rhstype)) { | 312 else if(!rhs_re && rhs_im) { |
333 if(hasRe(lhstype)) | 313 if(lhs_re) |
334 res_im = gIR->ir->CreateNeg(gIR->ir->CreateFDiv(lhs_re, rhs_im, "re_divby_im"), "neg"); | 314 res_im = gIR->ir->CreateNeg(gIR->ir->CreateFDiv(lhs_re, rhs_im, "re_divby_im"), "neg"); |
335 else | 315 else |
336 res_im = lhs_re; | 316 res_im = lhs_re; |
337 if(hasIm(lhstype)) | 317 if(lhs_im) |
338 res_re = gIR->ir->CreateFDiv(lhs_im, rhs_im, "im_divby_im"); | 318 res_re = gIR->ir->CreateFDiv(lhs_im, rhs_im, "im_divby_im"); |
339 else | 319 else |
340 res_re = lhs_im; | 320 res_re = lhs_im; |
341 } | 321 } |
342 // full division | 322 // full division |
343 else { | 323 else { |
344 llvm::Value *tmp1, *tmp2, *denom; | 324 llvm::Value *tmp1, *tmp2, *denom; |
345 | 325 |
346 if(hasRe(lhstype) && hasIm(lhstype)) { | 326 if(lhs_re && lhs_im) { |
347 tmp1 = gIR->ir->CreateMul(lhs_re, rhs_re, "rere"); | 327 tmp1 = gIR->ir->CreateMul(lhs_re, rhs_re, "rere"); |
348 tmp2 = gIR->ir->CreateMul(lhs_im, rhs_im, "imim"); | 328 tmp2 = gIR->ir->CreateMul(lhs_im, rhs_im, "imim"); |
349 res_re = gIR->ir->CreateAdd(tmp1, tmp2, "rere_plus_imim"); | 329 res_re = gIR->ir->CreateAdd(tmp1, tmp2, "rere_plus_imim"); |
350 | 330 |
351 tmp1 = gIR->ir->CreateMul(lhs_re, rhs_im, "reim"); | 331 tmp1 = gIR->ir->CreateMul(lhs_re, rhs_im, "reim"); |
352 tmp2 = gIR->ir->CreateMul(lhs_im, rhs_re, "imre"); | 332 tmp2 = gIR->ir->CreateMul(lhs_im, rhs_re, "imre"); |
353 res_im = gIR->ir->CreateSub(tmp2, tmp1, "imre_sub_reim"); | 333 res_im = gIR->ir->CreateSub(tmp2, tmp1, "imre_sub_reim"); |
354 } | 334 } |
355 else if(hasRe(lhstype)) { | 335 else if(lhs_re) { |
356 res_re = gIR->ir->CreateMul(lhs_re, rhs_re, "rere"); | 336 res_re = gIR->ir->CreateMul(lhs_re, rhs_re, "rere"); |
357 | 337 |
358 res_im = gIR->ir->CreateMul(lhs_re, rhs_im, "reim"); | 338 res_im = gIR->ir->CreateMul(lhs_re, rhs_im, "reim"); |
359 res_im = gIR->ir->CreateNeg(res_im); | 339 res_im = gIR->ir->CreateNeg(res_im); |
360 } | 340 } |
361 else if(hasIm(lhstype)) { | 341 else if(lhs_im) { |
362 res_re = gIR->ir->CreateMul(lhs_im, rhs_im, "imim"); | 342 res_re = gIR->ir->CreateMul(lhs_im, rhs_im, "imim"); |
363 res_im = gIR->ir->CreateMul(lhs_im, rhs_re, "imre"); | 343 res_im = gIR->ir->CreateMul(lhs_im, rhs_re, "imre"); |
364 } | 344 } |
365 else | 345 else |
366 assert(0 && "lhs has neither real nor imaginary part"); | 346 assert(0 && "lhs has neither real nor imaginary part"); |
379 | 359 |
380 ////////////////////////////////////////////////////////////////////////////////////////// | 360 ////////////////////////////////////////////////////////////////////////////////////////// |
381 | 361 |
382 DValue* DtoComplexNeg(Loc& loc, Type* type, DValue* val) | 362 DValue* DtoComplexNeg(Loc& loc, Type* type, DValue* val) |
383 { | 363 { |
384 val = DtoComplex(loc, type, resolveLR(val, false)); | |
385 | |
386 llvm::Value *a, *b, *re, *im; | 364 llvm::Value *a, *b, *re, *im; |
387 | 365 |
388 // values | 366 // values |
389 DtoGetComplexParts(val, a, b); | 367 DtoGetComplexParts(loc, type, val, a, b); |
390 | 368 |
391 // sub up | 369 // neg up |
370 assert(a && b); | |
392 re = gIR->ir->CreateNeg(a, "tmp"); | 371 re = gIR->ir->CreateNeg(a, "tmp"); |
393 im = gIR->ir->CreateNeg(b, "tmp"); | 372 im = gIR->ir->CreateNeg(b, "tmp"); |
394 | 373 |
395 LLValue* res = DtoAggrPair(DtoType(type), re, im); | 374 LLValue* res = DtoAggrPair(DtoType(type), re, im); |
396 return new DImValue(type, res); | 375 return new DImValue(type, res); |
400 | 379 |
401 LLValue* DtoComplexEquals(Loc& loc, TOK op, DValue* lhs, DValue* rhs) | 380 LLValue* DtoComplexEquals(Loc& loc, TOK op, DValue* lhs, DValue* rhs) |
402 { | 381 { |
403 Type* type = lhs->getType(); | 382 Type* type = lhs->getType(); |
404 | 383 |
405 lhs = DtoComplex(loc, type, resolveLR(lhs, false)); | 384 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; |
406 rhs = DtoComplex(loc, type, resolveLR(rhs, false)); | |
407 | |
408 llvm::Value *a, *b, *c, *d; | |
409 | 385 |
410 // lhs values | 386 // lhs values |
411 DtoGetComplexParts(lhs, a, b); | 387 DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im); |
412 // rhs values | 388 // rhs values |
413 DtoGetComplexParts(rhs, c, d); | 389 DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im); |
414 | 390 |
415 // select predicate | 391 // select predicate |
416 llvm::FCmpInst::Predicate cmpop; | 392 llvm::FCmpInst::Predicate cmpop; |
417 if (op == TOKequal) | 393 if (op == TOKequal) |
418 cmpop = llvm::FCmpInst::FCMP_OEQ; | 394 cmpop = llvm::FCmpInst::FCMP_OEQ; |
419 else | 395 else |
420 cmpop = llvm::FCmpInst::FCMP_UNE; | 396 cmpop = llvm::FCmpInst::FCMP_UNE; |
421 | 397 |
422 // (l.re==r.re && l.im==r.im) or (l.re!=r.re || l.im!=r.im) | 398 // (l.re==r.re && l.im==r.im) or (l.re!=r.re || l.im!=r.im) |
423 LLValue* b1 = new llvm::FCmpInst(cmpop, a, c, "tmp", gIR->scopebb()); | 399 LLValue* b1 = new llvm::FCmpInst(cmpop, lhs_re, rhs_re, "tmp", gIR->scopebb()); |
424 LLValue* b2 = new llvm::FCmpInst(cmpop, b, d, "tmp", gIR->scopebb()); | 400 LLValue* b2 = new llvm::FCmpInst(cmpop, lhs_im, rhs_im, "tmp", gIR->scopebb()); |
425 | 401 |
426 if (op == TOKequal) | 402 if (op == TOKequal) |
427 return gIR->ir->CreateAnd(b1,b2,"tmp"); | 403 return gIR->ir->CreateAnd(b1,b2,"tmp"); |
428 else | 404 else |
429 return gIR->ir->CreateOr(b1,b2,"tmp"); | 405 return gIR->ir->CreateOr(b1,b2,"tmp"); |
438 if (to->iscomplex()) { | 414 if (to->iscomplex()) { |
439 if (vty->size() == to->size()) | 415 if (vty->size() == to->size()) |
440 return val; | 416 return val; |
441 | 417 |
442 llvm::Value *re, *im; | 418 llvm::Value *re, *im; |
443 DtoGetComplexParts(val, re, im); | 419 DtoGetComplexParts(loc, val->getType(), val, re, im); |
444 const LLType* toty = DtoComplexBaseType(to); | 420 const LLType* toty = DtoComplexBaseType(to); |
445 | 421 |
446 if (to->size() < vty->size()) { | 422 if (to->size() < vty->size()) { |
447 re = gIR->ir->CreateFPTrunc(re, toty, "tmp"); | 423 re = gIR->ir->CreateFPTrunc(re, toty, "tmp"); |
448 im = gIR->ir->CreateFPTrunc(im, toty, "tmp"); | 424 im = gIR->ir->CreateFPTrunc(im, toty, "tmp"); |