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)