comparison gen/complex.cpp @ 104:4d1e9eb001e0 trunk

[svn r108] Now basic suppport for complex types. =,+,-,*,/ are supported.
author lindquist
date Mon, 19 Nov 2007 02:58:58 +0100
parents
children 3efbcc81ba45
comparison
equal deleted inserted replaced
103:855adfdb8d38 104:4d1e9eb001e0
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/irstate.h"
9 #include "gen/dvalue.h"
10
11 //////////////////////////////////////////////////////////////////////////////////////////
12
13 const llvm::StructType* DtoComplexType(Type* type)
14 {
15 Type* t = DtoDType(type);
16
17 const llvm::Type* base = DtoComplexBaseType(t);
18
19 std::vector<const llvm::Type*> types;
20 types.push_back(base);
21 types.push_back(base);
22
23 return llvm::StructType::get(types);
24 }
25
26 const llvm::Type* DtoComplexBaseType(Type* t)
27 {
28 TY ty = DtoDType(t)->ty;
29 const llvm::Type* base;
30 if (ty == Tcomplex32) {
31 return llvm::Type::FloatTy;
32 }
33 else if (ty == Tcomplex64 || ty == Tcomplex80) {
34 return llvm::Type::DoubleTy;
35 }
36 else {
37 assert(0);
38 }
39 }
40
41 //////////////////////////////////////////////////////////////////////////////////////////
42
43 llvm::Constant* DtoConstComplex(Type* ty, llvm::Constant* re, llvm::Constant* im)
44 {
45 assert(0);
46 const llvm::Type* base = DtoComplexBaseType(ty);
47
48 std::vector<llvm::Constant*> inits;
49 inits.push_back(re);
50 inits.push_back(im);
51
52 const llvm::VectorType* vt = llvm::VectorType::get(base, 2);
53 return llvm::ConstantVector::get(vt, inits);
54 }
55
56 llvm::Constant* DtoConstComplex(Type* _ty, long double re, long double im)
57 {
58 TY ty = DtoDType(_ty)->ty;
59
60 llvm::ConstantFP* fre;
61 llvm::ConstantFP* fim;
62
63 const llvm::Type* base;
64
65 if (ty == Tcomplex32) {
66 fre = DtoConstFP(Type::tfloat32, re);
67 fim = DtoConstFP(Type::tfloat32, im);
68 base = llvm::Type::FloatTy;
69 }
70 else if (ty == Tcomplex64 || ty == Tcomplex80) {
71 fre = DtoConstFP(Type::tfloat64, re);
72 fim = DtoConstFP(Type::tfloat64, im);
73 base = llvm::Type::DoubleTy;
74 }
75 else
76 assert(0);
77
78 std::vector<llvm::Constant*> inits;
79 inits.push_back(fre);
80 inits.push_back(fim);
81 return llvm::ConstantStruct::get(DtoComplexType(_ty), inits);
82 }
83
84 llvm::Constant* DtoUndefComplex(Type* _ty)
85 {
86 assert(0);
87 TY ty = DtoDType(_ty)->ty;
88 const llvm::Type* base;
89 if (ty == Tcomplex32) {
90 base = llvm::Type::FloatTy;
91 }
92 else if (ty == Tcomplex64 || ty == Tcomplex80) {
93 base = llvm::Type::DoubleTy;
94 }
95 else
96 assert(0);
97
98 std::vector<llvm::Constant*> inits;
99 inits.push_back(llvm::UndefValue::get(base));
100 inits.push_back(llvm::UndefValue::get(base));
101
102 const llvm::VectorType* vt = llvm::VectorType::get(base, 2);
103 return llvm::ConstantVector::get(vt, inits);
104 }
105
106 //////////////////////////////////////////////////////////////////////////////////////////
107
108 llvm::Value* DtoRealPart(DValue* val)
109 {
110 assert(0);
111 return gIR->ir->CreateExtractElement(val->getRVal(), DtoConstUint(0), "tmp");
112 }
113
114 //////////////////////////////////////////////////////////////////////////////////////////
115
116 llvm::Value* DtoImagPart(DValue* val)
117 {
118 assert(0);
119 return gIR->ir->CreateExtractElement(val->getRVal(), DtoConstUint(1), "tmp");
120 }
121
122 //////////////////////////////////////////////////////////////////////////////////////////
123
124 DValue* DtoComplex(Type* to, DValue* val)
125 {
126 Type* t = DtoDType(val->getType());
127 TY ty = t->ty;
128
129 if (val->isComplex() || t->iscomplex()) {
130 assert(DtoDType(to) == t);
131 return val;
132 }
133
134 const llvm::Type* base = DtoComplexBaseType(to);
135
136 llvm::Constant* undef = llvm::UndefValue::get(base);
137 llvm::Constant* zero;
138 if (ty == Tfloat32 || ty == Timaginary32 || ty == Tcomplex32)
139 zero = llvm::ConstantFP::get(llvm::Type::FloatTy, float(0));
140 else if (ty == Tfloat64 || ty == Timaginary64 || ty == Tcomplex64 || ty == Tfloat80 || ty == Timaginary80 || ty == Tcomplex80)
141 zero = llvm::ConstantFP::get(llvm::Type::DoubleTy, double(0));
142
143 if (t->isimaginary()) {
144 return new DComplexValue(to, zero, val->getRVal());
145 }
146 else if (t->isfloating()) {
147 return new DComplexValue(to, val->getRVal(), zero);
148 }
149 else
150 assert(0);
151 }
152
153 //////////////////////////////////////////////////////////////////////////////////////////
154
155 void DtoComplexAssign(llvm::Value* l, llvm::Value* r)
156 {
157 DtoStore(DtoLoad(DtoGEPi(r, 0,0, "tmp")), DtoGEPi(l,0,0,"tmp"));
158 DtoStore(DtoLoad(DtoGEPi(r, 0,1, "tmp")), DtoGEPi(l,0,1,"tmp"));
159 }
160
161 void DtoComplexSet(llvm::Value* c, llvm::Value* re, llvm::Value* im)
162 {
163 DtoStore(re, DtoGEPi(c,0,0,"tmp"));
164 DtoStore(im, DtoGEPi(c,0,1,"tmp"));
165 }
166
167 //////////////////////////////////////////////////////////////////////////////////////////
168
169 DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs)
170 {
171 lhs = DtoComplex(type, lhs);
172 rhs = DtoComplex(type, rhs);
173
174 llvm::Value *a, *b, *c, *d, *re, *im;
175
176 // lhs values
177 if (DComplexValue* cx = lhs->isComplex()) {
178 a = cx->re;
179 b = cx->im;
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
196 // add up
197 re = gIR->ir->CreateAdd(a, c, "tmp");
198 im = gIR->ir->CreateAdd(b, d, "tmp");
199
200 return new DComplexValue(type, re, im);
201 }
202
203 //////////////////////////////////////////////////////////////////////////////////////////
204
205 DValue* DtoComplexSub(Type* type, DValue* lhs, DValue* rhs)
206 {
207 lhs = DtoComplex(type, lhs);
208 rhs = DtoComplex(type, rhs);
209
210 llvm::Value *a, *b, *c, *d, *re, *im;
211
212 // lhs values
213 if (DComplexValue* cx = lhs->isComplex()) {
214 a = cx->re;
215 b = cx->im;
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
232 // add up
233 re = gIR->ir->CreateSub(a, c, "tmp");
234 im = gIR->ir->CreateSub(b, d, "tmp");
235
236 return new DComplexValue(type, re, im);
237 }
238
239 //////////////////////////////////////////////////////////////////////////////////////////
240
241 DValue* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs)
242 {
243 lhs = DtoComplex(type, lhs);
244 rhs = DtoComplex(type, rhs);
245
246 llvm::Value *a, *b, *c, *d, *re, *im;
247
248 // lhs values
249 if (DComplexValue* cx = lhs->isComplex()) {
250 a = cx->re;
251 b = cx->im;
252 }
253 else {
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
270 tmp1 = gIR->ir->CreateMul(a, c, "tmp");
271 tmp2 = gIR->ir->CreateMul(b, d, "tmp");
272 re = gIR->ir->CreateSub(tmp1, tmp2, "tmp");
273
274 tmp1 = gIR->ir->CreateMul(b, c, "tmp");
275 tmp2 = gIR->ir->CreateMul(a, d, "tmp");
276 im = gIR->ir->CreateAdd(tmp1, tmp2, "tmp");
277
278 return new DComplexValue(type, re, im);
279 }
280
281 //////////////////////////////////////////////////////////////////////////////////////////
282
283 DValue* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs)
284 {
285 lhs = DtoComplex(type, lhs);
286 rhs = DtoComplex(type, rhs);
287
288 llvm::Value *a, *b, *c, *d, *re, *im;
289
290 // lhs values
291 if (DComplexValue* cx = lhs->isComplex()) {
292 a = cx->re;
293 b = cx->im;
294 }
295 else {
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
312 tmp1 = gIR->ir->CreateMul(c, c, "tmp");
313 tmp2 = gIR->ir->CreateMul(d, d, "tmp");
314 denom = gIR->ir->CreateAdd(tmp1, tmp2, "tmp");
315
316 tmp1 = gIR->ir->CreateMul(a, c, "tmp");
317 tmp2 = gIR->ir->CreateMul(b, d, "tmp");
318 re = gIR->ir->CreateAdd(tmp1, tmp2, "tmp");
319 re = gIR->ir->CreateFDiv(re, denom, "tmp");
320
321 tmp1 = gIR->ir->CreateMul(b, c, "tmp");
322 tmp2 = gIR->ir->CreateMul(a, d, "tmp");
323 im = gIR->ir->CreateSub(tmp1, tmp2, "tmp");
324 im = gIR->ir->CreateFDiv(im, denom, "tmp");
325
326 return new DComplexValue(type, re, im);
327 }
328
329 //////////////////////////////////////////////////////////////////////////////////////////
330
331 llvm::Value* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs)
332 {
333 llvm::Value* lvec = lhs->getRVal();
334 llvm::Value* rvec = rhs->getRVal();
335
336 llvm::FCmpInst::Predicate cmpop;
337 switch(op)
338 {
339 case TOKequal:
340 cmpop = llvm::FCmpInst::FCMP_OEQ;
341 break;
342 case TOKnotequal:
343 cmpop = llvm::FCmpInst::FCMP_UNE;
344 break;
345 default:
346 assert(0);
347 }
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");
358 }