Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

root/gen/complex.cpp

Revision 1586:7f728c52e63c, 13.8 kB (checked in by Christian Kamm <kamm incasoftware de>, 3 years ago)

Fix several 'reaches end of function' warnings by making fatal noreturn.

The warnings also pointed out a few genuine bugs. Replace some tabs with
spaces.

Line 
1 #include "gen/llvm.h"
2
3 #include "mtype.h"
4 #include "declaration.h"
5
6 #include "gen/complex.h"
7 #include "gen/tollvm.h"
8 #include "gen/llvmhelpers.h"
9 #include "gen/irstate.h"
10 #include "gen/dvalue.h"
11 #include "gen/logger.h"
12
13 //////////////////////////////////////////////////////////////////////////////////////////
14
15 const llvm::StructType* DtoComplexType(Type* type)
16 {
17     Type* t = type->toBasetype();
18     const LLType* base = DtoComplexBaseType(t);
19     return llvm::StructType::get(gIR->context(), base, base, NULL);
20 }
21
22 const LLType* DtoComplexBaseType(Type* t)
23 {
24     TY ty = t->toBasetype()->ty;
25     const LLType* base;
26     if (ty == Tcomplex32) {
27         return LLType::getFloatTy(gIR->context());
28     }
29     else if (ty == Tcomplex64) {
30         return LLType::getDoubleTy(gIR->context());
31     }
32     else if (ty == Tcomplex80) {
33         if ((global.params.cpu == ARCHx86) || (global.params.cpu == ARCHx86_64))
34             return LLType::getX86_FP80Ty(gIR->context());
35         else
36             return LLType::getDoubleTy(gIR->context());
37     }
38     else {
39         assert(0);
40     }
41 }
42
43 //////////////////////////////////////////////////////////////////////////////////////////
44
45 LLConstant* DtoConstComplex(Type* _ty, long double re, long double im)
46 {
47     TY ty = _ty->toBasetype()->ty;
48
49     llvm::ConstantFP* fre;
50     llvm::ConstantFP* fim;
51
52     Type* base = 0;
53
54     if (ty == Tcomplex32) {
55         base = Type::tfloat32;
56     }
57     else if (ty == Tcomplex64) {
58         base = Type::tfloat64;
59     }
60     else if (ty == Tcomplex80) {
61         base = Type::tfloat80;
62     }
63
64     std::vector<LLConstant*> inits;
65     inits.push_back(DtoConstFP(base, re));
66     inits.push_back(DtoConstFP(base, im));
67
68     return llvm::ConstantStruct::get(DtoComplexType(_ty), inits);
69 }
70
71 //////////////////////////////////////////////////////////////////////////////////////////
72
73 LLValue* DtoRealPart(DValue* val)
74 {
75     assert(0);
76     return gIR->ir->CreateExtractElement(val->getRVal(), DtoConstUint(0), "tmp");
77 }
78
79 //////////////////////////////////////////////////////////////////////////////////////////
80
81 LLValue* DtoImagPart(DValue* val)
82 {
83     assert(0);
84     return gIR->ir->CreateExtractElement(val->getRVal(), DtoConstUint(1), "tmp");
85 }
86
87 //////////////////////////////////////////////////////////////////////////////////////////
88
89 DValue* DtoComplex(Loc& loc, Type* to, DValue* val)
90 {
91     const LLType* complexTy = DtoType(to);
92
93     Type* baserety;
94     Type* baseimty;
95     TY ty = to->toBasetype()->ty;
96     if (ty == Tcomplex32) {
97         baserety = Type::tfloat32;
98         baseimty = Type::timaginary32;
99     } else if (ty == Tcomplex64) {
100         baserety = Type::tfloat64;
101         baseimty = Type::timaginary64;
102     } else if (ty == Tcomplex80) {
103         baserety = Type::tfloat80;
104         baseimty = Type::timaginary80;
105     }
106     else {
107         assert(0);
108     }
109
110     LLValue *re, *im;
111     DtoGetComplexParts(loc, to, val, re, im);
112
113     if(!re)
114         re = LLConstant::getNullValue(DtoType(baserety));
115     if(!im)
116         im = LLConstant::getNullValue(DtoType(baseimty));
117
118     LLValue* res = DtoAggrPair(complexTy, re, im);
119
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->toBasetype()->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;
149     }
150     else {
151         assert(0);
152     }
153
154     Type* t = val->getType()->toBasetype();
155
156     if (t->iscomplex()) {
157         DValue* v = DtoCastComplex(loc, val, to);
158         if (to->iscomplex()) {
159             re = gIR->ir->CreateExtractValue(v->getRVal(), 0, ".re_part");
160             im = gIR->ir->CreateExtractValue(v->getRVal(), 1, ".im_part");
161         } else
162             DtoGetComplexParts(loc, to, v, re, im);
163     }
164     else if (t->isimaginary()) {
165         re = NULL;
166         im = DtoCastFloat(loc, val, baseimty)->getRVal();
167     }
168     else if (t->isfloating()) {
169         re = DtoCastFloat(loc, val, baserety)->getRVal();
170         im = NULL;
171     }
172     else if (t->isintegral()) {
173         re = DtoCastInt(loc, val, baserety)->getRVal();
174         im = NULL;
175     }
176     else {
177         assert(0);
178     }
179 }
180
181 //////////////////////////////////////////////////////////////////////////////////////////
182
183 DValue* DtoComplexAdd(Loc& loc, Type* type, DValue* lhs, DValue* rhs)
184 {
185     llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
186
187     // lhs values
188     DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im);
189     // rhs values
190     DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im);
191
192     // add up
193     if(lhs_re && rhs_re)
194         res_re = gIR->ir->CreateAdd(lhs_re, rhs_re, "tmp");
195     else if(lhs_re)
196         res_re = lhs_re;
197     else // either rhs_re or no re at all (then use any)
198         res_re = rhs_re;
199    
200     if(lhs_im && rhs_im)
201         res_im = gIR->ir->CreateAdd(lhs_im, rhs_im, "tmp");
202     else if(lhs_im)
203         res_im = lhs_im;
204     else // either rhs_im or no im at all (then use any)
205         res_im = rhs_im;
206
207     LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im);
208     return new DImValue(type, res);
209 }
210
211 //////////////////////////////////////////////////////////////////////////////////////////
212
213 DValue* DtoComplexSub(Loc& loc, Type* type, DValue* lhs, DValue* rhs)
214 {
215     llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
216
217     // lhs values
218     DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im);
219     // rhs values
220     DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im);
221
222     // add up
223     if(lhs_re && rhs_re)
224         res_re = gIR->ir->CreateSub(lhs_re, rhs_re, "tmp");
225     else if(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");
229    
230     if(lhs_im && rhs_im)
231         res_im = gIR->ir->CreateSub(lhs_im, rhs_im, "tmp");
232     else if(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");
236
237     LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im);
238     return new DImValue(type, res);
239 }
240
241 //////////////////////////////////////////////////////////////////////////////////////////
242
243 DValue* DtoComplexMul(Loc& loc, Type* type, DValue* lhs, DValue* rhs)
244 {
245     llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
246
247     // lhs values
248     DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im);
249     // rhs values
250     DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im);
251
252     // mul up
253     llvm::Value *rere = NULL;
254     llvm::Value *reim = NULL;
255     llvm::Value *imre = NULL;
256     llvm::Value *imim = NULL;
257
258     if(lhs_re && rhs_re)
259         rere = gIR->ir->CreateMul(lhs_re, rhs_re, "rere_mul");
260     if(lhs_re && rhs_im)
261         reim = gIR->ir->CreateMul(lhs_re, rhs_im, "reim_mul");
262     if(lhs_im && rhs_re)
263         imre = gIR->ir->CreateMul(lhs_im, rhs_re, "imre_mul");
264     if(lhs_im && rhs_im)
265         imim = gIR->ir->CreateMul(lhs_im, rhs_im, "imim_mul");
266
267     if(rere && imim)
268         res_re = gIR->ir->CreateSub(rere, imim, "rere_imim_sub");
269     else if(rere)
270         res_re = rere;
271     else if(imim)
272         res_re = gIR->ir->CreateNeg(imim, "imim_neg");
273     else
274         res_re = lhs_re ? rhs_re : lhs_re; // null!
275
276     if(reim && imre)
277         res_im = gIR->ir->CreateAdd(reim, imre, "reim_imre_add");
278     else if(reim)
279         res_im = reim;
280     else if(imre)
281         res_im = imre;
282     else
283         res_im = lhs_re ? rhs_im : lhs_re; // null!
284
285     LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im);
286     return new DImValue(type, res);
287 }
288
289 //////////////////////////////////////////////////////////////////////////////////////////
290
291 DValue* DtoComplexDiv(Loc& loc, Type* type, DValue* lhs, DValue* rhs)
292 {
293     llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
294
295     // lhs values
296     DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im);
297     // rhs values
298     DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im);
299
300     // if divisor is only real, division is simple
301     if(rhs_re && !rhs_im) {
302         if(lhs_re)
303             res_re = gIR->ir->CreateFDiv(lhs_re, rhs_re, "re_divby_re");
304         else
305             res_re = lhs_re;
306         if(lhs_im)
307             res_im = gIR->ir->CreateFDiv(lhs_im, rhs_re, "im_divby_re");
308         else
309             res_im = lhs_im;
310     }
311     // if divisor is only imaginary, division is simple too
312     else if(!rhs_re && rhs_im) {
313         if(lhs_re)
314             res_im = gIR->ir->CreateNeg(gIR->ir->CreateFDiv(lhs_re, rhs_im, "re_divby_im"), "neg");
315         else
316             res_im = lhs_re;
317         if(lhs_im)
318             res_re = gIR->ir->CreateFDiv(lhs_im, rhs_im, "im_divby_im");
319         else
320             res_re = lhs_im;
321     }
322     // full division
323     else {
324         llvm::Value *tmp1, *tmp2, *denom;
325
326         if(lhs_re && lhs_im) {
327             tmp1 = gIR->ir->CreateMul(lhs_re, rhs_re, "rere");
328             tmp2 = gIR->ir->CreateMul(lhs_im, rhs_im, "imim");
329             res_re = gIR->ir->CreateAdd(tmp1, tmp2, "rere_plus_imim");
330
331             tmp1 = gIR->ir->CreateMul(lhs_re, rhs_im, "reim");
332             tmp2 = gIR->ir->CreateMul(lhs_im, rhs_re, "imre");
333             res_im = gIR->ir->CreateSub(tmp2, tmp1, "imre_sub_reim");
334         }
335         else if(lhs_re) {
336             res_re = gIR->ir->CreateMul(lhs_re, rhs_re, "rere");
337
338             res_im = gIR->ir->CreateMul(lhs_re, rhs_im, "reim");
339             res_im = gIR->ir->CreateNeg(res_im);
340         }
341         else if(lhs_im) {
342             res_re = gIR->ir->CreateMul(lhs_im, rhs_im, "imim");
343             res_im = gIR->ir->CreateMul(lhs_im, rhs_re, "imre");
344         }
345         else
346             assert(0 && "lhs has neither real nor imaginary part");
347
348         tmp1 = gIR->ir->CreateMul(rhs_re, rhs_re, "rhs_resq");
349         tmp2 = gIR->ir->CreateMul(rhs_im, rhs_im, "rhs_imsq");
350         denom = gIR->ir->CreateAdd(tmp1, tmp2, "denom");
351
352         res_re = gIR->ir->CreateFDiv(res_re, denom, "res_re");
353         res_im = gIR->ir->CreateFDiv(res_im, denom, "res_im");
354     }
355
356     LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im);
357     return new DImValue(type, res);
358 }
359
360 //////////////////////////////////////////////////////////////////////////////////////////
361
362 DValue* DtoComplexNeg(Loc& loc, Type* type, DValue* val)
363 {
364     llvm::Value *a, *b, *re, *im;
365
366     // values
367     DtoGetComplexParts(loc, type, val, a, b);
368
369     // neg up
370     assert(a && b);
371     re = gIR->ir->CreateNeg(a, "tmp");
372     im = gIR->ir->CreateNeg(b, "tmp");
373
374     LLValue* res = DtoAggrPair(DtoType(type), re, im);
375     return new DImValue(type, res);
376 }
377
378 //////////////////////////////////////////////////////////////////////////////////////////
379
380 LLValue* DtoComplexEquals(Loc& loc, TOK op, DValue* lhs, DValue* rhs)
381 {
382     Type* type = lhs->getType();
383
384     llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
385
386     // lhs values
387     DtoGetComplexParts(loc, type, lhs, lhs_re, lhs_im);
388     // rhs values
389     DtoGetComplexParts(loc, type, rhs, rhs_re, rhs_im);
390
391     // select predicate
392     llvm::FCmpInst::Predicate cmpop;
393     if (op == TOKequal || op == TOKidentity)
394         cmpop = llvm::FCmpInst::FCMP_OEQ;
395     else
396         cmpop = llvm::FCmpInst::FCMP_UNE;
397
398     // (l.re==r.re && l.im==r.im) or (l.re!=r.re || l.im!=r.im)
399     LLValue* b1 = gIR->ir->CreateFCmp(cmpop, lhs_re, rhs_re, "tmp");
400     LLValue* b2 = gIR->ir->CreateFCmp(cmpop, lhs_im, rhs_im, "tmp");
401
402     if (op == TOKequal)
403         return gIR->ir->CreateAnd(b1,b2,"tmp");
404     else
405         return gIR->ir->CreateOr(b1,b2,"tmp");
406 }
407
408 //////////////////////////////////////////////////////////////////////////////////////////
409
410 DValue* DtoCastComplex(Loc& loc, DValue* val, Type* _to)
411 {
412     Type* to = _to->toBasetype();
413     Type* vty = val->getType()->toBasetype();
414     if (to->iscomplex()) {
415         if (vty->size() == to->size())
416             return val;
417
418         llvm::Value *re, *im;
419         DtoGetComplexParts(loc, val->getType(), val, re, im);
420         const LLType* toty = DtoComplexBaseType(to);
421
422         if (to->size() < vty->size()) {
423             re = gIR->ir->CreateFPTrunc(re, toty, "tmp");
424             im = gIR->ir->CreateFPTrunc(im, toty, "tmp");
425         }
426         else {
427             re = gIR->ir->CreateFPExt(re, toty, "tmp");
428             im = gIR->ir->CreateFPExt(im, toty, "tmp");
429         }
430
431         LLValue* pair = DtoAggrPair(DtoType(_to), re, im);
432         return new DImValue(_to, pair);
433     }
434     else if (to->isimaginary()) {
435         // FIXME: this loads both values, even when we only need one
436         LLValue* v = val->getRVal();
437         LLValue* impart = gIR->ir->CreateExtractValue(v, 1, ".im_part");
438         DImValue* im = new DImValue(to, impart);
439         return DtoCastFloat(loc, im, to);
440     }
441     else if (to->ty == Tbool) {
442         return new DImValue(_to, DtoComplexEquals(loc, TOKnotequal, val, DtoNullValue(vty)));
443     }
444     else if (to->isfloating() || to->isintegral()) {
445         // FIXME: this loads both values, even when we only need one
446         LLValue* v = val->getRVal();
447         LLValue* repart = gIR->ir->CreateExtractValue(v, 0, ".re_part");
448         Type *extractty;
449         if (vty->ty == Tcomplex32) {
450             extractty = Type::tfloat32;
451         } else if (vty->ty == Tcomplex64) {
452             extractty = Type::tfloat64;
453         } else if (vty->ty == Tcomplex80) {
454             extractty = Type::tfloat80;
455         }
456         DImValue* re = new DImValue(extractty, repart);
457         return DtoCastFloat(loc, re, to);
458     }
459     else {
460         error(loc, "Don't know how to cast %s to %s", vty->toChars(), to->toChars());
461         fatal();
462     }
463 }
Note: See TracBrowser for help on using the browser.
Copyright © 2008, LDC Development Team.