Mercurial > projects > ldc
comparison gen/complex.cpp @ 412:798ee94a0be7
Rework complex addition, substraction and multiplication. Division may need the same.
Fixes run/c/cdouble_09_A,C,D and run/c/cfloat_09_A,C,D.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sun, 27 Jul 2008 17:53:49 +0200 |
parents | 0e6b4d65d3f8 |
children | 3c133dd1eda3 |
comparison
equal
deleted
inserted
replaced
411:3545f9eddbfc | 412:798ee94a0be7 |
---|---|
177 return val; | 177 return val; |
178 } | 178 } |
179 | 179 |
180 ////////////////////////////////////////////////////////////////////////////////////////// | 180 ////////////////////////////////////////////////////////////////////////////////////////// |
181 | 181 |
182 bool hasRe(Type* t) | |
183 { | |
184 return | |
185 (t->ty != Timaginary32 && | |
186 t->ty != Timaginary64 && | |
187 t->ty != Timaginary80); | |
188 } | |
189 | |
190 bool hasIm(Type* t) | |
191 { | |
192 return | |
193 (t->ty == Timaginary32 || | |
194 t->ty == Timaginary64 || | |
195 t->ty == Timaginary80 || | |
196 t->ty == Tcomplex32 || | |
197 t->ty == Tcomplex64 || | |
198 t->ty == Tcomplex80); | |
199 } | |
200 | |
201 ////////////////////////////////////////////////////////////////////////////////////////// | |
202 | |
182 DValue* DtoComplexAdd(Loc& loc, Type* type, DValue* lhs, DValue* rhs) | 203 DValue* DtoComplexAdd(Loc& loc, Type* type, DValue* lhs, DValue* rhs) |
183 { | 204 { |
184 lhs = DtoComplex(loc, type, resolveLR(lhs, true)); | 205 DValue* clhs = DtoComplex(loc, type, resolveLR(lhs, true)); |
185 rhs = DtoComplex(loc, type, resolveLR(rhs, false)); | 206 DValue* crhs = DtoComplex(loc, type, resolveLR(rhs, false)); |
186 | 207 |
187 llvm::Value *a, *b, *c, *d, *re, *im; | 208 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; |
188 | 209 |
189 // lhs values | 210 // lhs values |
190 DtoGetComplexParts(lhs, a, b); | 211 DtoGetComplexParts(clhs, lhs_re, lhs_im); |
191 // rhs values | 212 // rhs values |
192 DtoGetComplexParts(rhs, c, d); | 213 DtoGetComplexParts(crhs, rhs_re, rhs_im); |
193 | 214 |
194 // add up | 215 // add up |
195 re = gIR->ir->CreateAdd(a, c, "tmp"); | 216 Type* lhstype = lhs->getType(); |
196 im = gIR->ir->CreateAdd(b, d, "tmp"); | 217 Type* rhstype = rhs->getType(); |
197 | 218 if(hasRe(lhstype) && hasRe(rhstype)) |
198 return new DComplexValue(type, re, im); | 219 res_re = gIR->ir->CreateAdd(lhs_re, rhs_re, "tmp"); |
220 else if(hasRe(lhstype)) | |
221 res_re = lhs_re; | |
222 else // either hasRe(rhstype) or no re at all (then use any) | |
223 res_re = rhs_re; | |
224 | |
225 if(hasIm(lhstype) && hasIm(rhstype)) | |
226 res_im = gIR->ir->CreateAdd(lhs_im, rhs_im, "tmp"); | |
227 else if(hasIm(lhstype)) | |
228 res_im = lhs_im; | |
229 else // either hasIm(rhstype) or no im at all (then use any) | |
230 res_im = rhs_im; | |
231 | |
232 return new DComplexValue(type, res_re, res_im); | |
199 } | 233 } |
200 | 234 |
201 ////////////////////////////////////////////////////////////////////////////////////////// | 235 ////////////////////////////////////////////////////////////////////////////////////////// |
202 | 236 |
203 DValue* DtoComplexSub(Loc& loc, Type* type, DValue* lhs, DValue* rhs) | 237 DValue* DtoComplexSub(Loc& loc, Type* type, DValue* lhs, DValue* rhs) |
204 { | 238 { |
205 lhs = DtoComplex(loc, type, resolveLR(lhs, true)); | 239 DValue* clhs = DtoComplex(loc, type, resolveLR(lhs, true)); |
206 rhs = DtoComplex(loc, type, resolveLR(rhs, false)); | 240 DValue* crhs = DtoComplex(loc, type, resolveLR(rhs, false)); |
207 | 241 |
208 llvm::Value *a, *b, *c, *d, *re, *im; | 242 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; |
209 | 243 |
210 // lhs values | 244 // lhs values |
211 DtoGetComplexParts(lhs, a, b); | 245 DtoGetComplexParts(clhs, lhs_re, lhs_im); |
212 // rhs values | 246 // rhs values |
213 DtoGetComplexParts(rhs, c, d); | 247 DtoGetComplexParts(crhs, rhs_re, rhs_im); |
214 | 248 |
215 // add up | 249 // sub up |
216 re = gIR->ir->CreateSub(a, c, "tmp"); | 250 Type* lhstype = lhs->getType(); |
217 im = gIR->ir->CreateSub(b, d, "tmp"); | 251 Type* rhstype = rhs->getType(); |
218 | 252 if(hasRe(rhstype)) |
219 return new DComplexValue(type, re, im); | 253 res_re = gIR->ir->CreateSub(lhs_re, rhs_re, "tmp"); |
254 else | |
255 res_re = lhs_re; | |
256 | |
257 if(hasIm(rhstype)) | |
258 res_im = gIR->ir->CreateSub(lhs_im, rhs_im, "tmp"); | |
259 else | |
260 res_im = lhs_im; | |
261 | |
262 return new DComplexValue(type, res_re, res_im); | |
220 } | 263 } |
221 | 264 |
222 ////////////////////////////////////////////////////////////////////////////////////////// | 265 ////////////////////////////////////////////////////////////////////////////////////////// |
223 | 266 |
224 DValue* DtoComplexMul(Loc& loc, Type* type, DValue* lhs, DValue* rhs) | 267 DValue* DtoComplexMul(Loc& loc, Type* type, DValue* lhs, DValue* rhs) |
225 { | 268 { |
226 lhs = DtoComplex(loc, type, resolveLR(lhs, true)); | 269 DValue* clhs = DtoComplex(loc, type, resolveLR(lhs, true)); |
227 rhs = DtoComplex(loc, type, resolveLR(rhs, false)); | 270 DValue* crhs = DtoComplex(loc, type, resolveLR(rhs, false)); |
228 | 271 |
229 llvm::Value *a, *b, *c, *d; | 272 llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im; |
230 | 273 |
231 // lhs values | 274 // lhs values |
232 DtoGetComplexParts(lhs, a, b); | 275 DtoGetComplexParts(clhs, lhs_re, lhs_im); |
233 // rhs values | 276 // rhs values |
234 DtoGetComplexParts(rhs, c, d); | 277 DtoGetComplexParts(crhs, rhs_re, rhs_im); |
235 | 278 |
236 llvm::Value *tmp1, *tmp2, *re, *im; | 279 // mul up |
237 | 280 llvm::Value *rere = NULL; |
238 tmp1 = gIR->ir->CreateMul(a, c, "tmp"); | 281 llvm::Value *reim = NULL; |
239 tmp2 = gIR->ir->CreateMul(b, d, "tmp"); | 282 llvm::Value *imre = NULL; |
240 re = gIR->ir->CreateSub(tmp1, tmp2, "tmp"); | 283 llvm::Value *imim = NULL; |
241 | 284 Type* lhstype = lhs->getType(); |
242 tmp1 = gIR->ir->CreateMul(b, c, "tmp"); | 285 Type* rhstype = rhs->getType(); |
243 tmp2 = gIR->ir->CreateMul(a, d, "tmp"); | 286 |
244 im = gIR->ir->CreateAdd(tmp1, tmp2, "tmp"); | 287 if(hasRe(lhstype) && hasRe(rhstype)) |
245 | 288 rere = gIR->ir->CreateMul(lhs_re, rhs_re, "rere_mul"); |
246 return new DComplexValue(type, re, im); | 289 if(hasRe(lhstype) && hasIm(rhstype)) |
290 reim = gIR->ir->CreateMul(lhs_re, rhs_im, "reim_mul"); | |
291 if(hasIm(lhstype) && hasRe(rhstype)) | |
292 imre = gIR->ir->CreateMul(lhs_im, rhs_re, "imre_mul"); | |
293 if(hasIm(lhstype) && hasIm(rhstype)) | |
294 imim = gIR->ir->CreateMul(lhs_im, rhs_im, "imim_mul"); | |
295 | |
296 if(rere && imim) | |
297 res_re = gIR->ir->CreateSub(rere, imim, "rere_imim_sub"); | |
298 else if(rere) | |
299 res_re = rere; | |
300 else if(imim) | |
301 res_re = gIR->ir->CreateNeg(imim, "imim_neg"); | |
302 else | |
303 res_re = hasRe(lhstype) ? rhs_re : lhs_re; // null! | |
304 | |
305 if(reim && imre) | |
306 res_im = gIR->ir->CreateAdd(reim, imre, "reim_imre_add"); | |
307 else if(reim) | |
308 res_im = reim; | |
309 else if(imre) | |
310 res_im = imre; | |
311 else | |
312 res_im = hasRe(lhstype) ? rhs_im : lhs_re; // null! | |
313 | |
314 return new DComplexValue(type, res_re, res_im); | |
247 } | 315 } |
248 | 316 |
249 ////////////////////////////////////////////////////////////////////////////////////////// | 317 ////////////////////////////////////////////////////////////////////////////////////////// |
250 | 318 |
251 DValue* DtoComplexDiv(Loc& loc, Type* type, DValue* lhs, DValue* rhs) | 319 DValue* DtoComplexDiv(Loc& loc, Type* type, DValue* lhs, DValue* rhs) |