Mercurial > projects > ldc
comparison gen/complex.cpp @ 359:926f65e39246 trunk
[svn r380] Improve complex number support.
author | ChristianK |
---|---|
date | Mon, 14 Jul 2008 17:22:43 +0200 |
parents | 4aa2b6753059 |
children | 8014dbd24605 |
comparison
equal
deleted
inserted
replaced
358:051f5b550d9c | 359:926f65e39246 |
---|---|
102 ////////////////////////////////////////////////////////////////////////////////////////// | 102 ////////////////////////////////////////////////////////////////////////////////////////// |
103 | 103 |
104 DValue* DtoComplex(Type* to, DValue* val) | 104 DValue* DtoComplex(Type* to, DValue* val) |
105 { | 105 { |
106 Type* t = DtoDType(val->getType()); | 106 Type* t = DtoDType(val->getType()); |
107 TY ty = t->ty; | |
108 | 107 |
109 if (val->isComplex() || t->iscomplex()) { | 108 if (val->isComplex() || t->iscomplex()) { |
110 return DtoCastComplex(val, to); | 109 return DtoCastComplex(val, to); |
111 } | 110 } |
112 | 111 |
113 const LLType* base = DtoComplexBaseType(to); | 112 const LLType* base = DtoComplexBaseType(to); |
114 | 113 |
115 LLConstant* undef = llvm::UndefValue::get(base); | 114 Type* baserety; |
116 LLConstant* zero; | 115 Type* baseimty; |
117 if (ty == Tfloat32 || ty == Timaginary32 || ty == Tcomplex32) | 116 TY ty = to->ty; |
118 zero = LLConstant::getNullValue(DtoType(Type::tfloat32)); // llvm::ConstantFP::get(llvm::APFloat(0.0f)); | 117 if (ty == Tcomplex32) { |
119 else if (ty == Tfloat64 || ty == Timaginary64 || ty == Tcomplex64) | 118 baserety = Type::tfloat32; |
120 zero = LLConstant::getNullValue(DtoType(Type::tfloat64)); | 119 baseimty = Type::timaginary32; |
121 else if (ty == Tfloat80 || ty == Timaginary80 || ty == Tcomplex80) | 120 } else if (ty == Tcomplex64) { |
122 zero = LLConstant::getNullValue(DtoType((global.params.useFP80)?Type::tfloat80:Type::tfloat64)); | 121 baserety = Type::tfloat64; |
122 baseimty = Type::timaginary64; | |
123 } else if (ty == Tcomplex80) { | |
124 baserety = global.params.useFP80 ? Type::tfloat80 : Type::tfloat64; | |
125 baseimty = global.params.useFP80 ? Type::timaginary80 : Type::timaginary64; | |
126 } | |
123 | 127 |
124 if (t->isimaginary()) { | 128 if (t->isimaginary()) { |
125 return new DComplexValue(to, zero, val->getRVal()); | 129 return new DComplexValue(to, LLConstant::getNullValue(DtoType(baserety)), DtoCastFloat(val, baseimty)->getRVal()); |
126 } | 130 } |
127 else if (t->isfloating()) { | 131 else if (t->isfloating()) { |
128 return new DComplexValue(to, val->getRVal(), zero); | 132 return new DComplexValue(to, DtoCastFloat(val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty))); |
129 } | 133 } |
130 else | 134 else if (t->isintegral()) { |
135 return new DComplexValue(to, DtoCastInt(val, baserety)->getRVal(), LLConstant::getNullValue(DtoType(baseimty))); | |
136 } | |
131 assert(0); | 137 assert(0); |
132 } | 138 } |
133 | 139 |
134 ////////////////////////////////////////////////////////////////////////////////////////// | 140 ////////////////////////////////////////////////////////////////////////////////////////// |
135 | 141 |
147 | 153 |
148 ////////////////////////////////////////////////////////////////////////////////////////// | 154 ////////////////////////////////////////////////////////////////////////////////////////// |
149 | 155 |
150 void DtoGetComplexParts(DValue* c, LLValue*& re, LLValue*& im) | 156 void DtoGetComplexParts(DValue* c, LLValue*& re, LLValue*& im) |
151 { | 157 { |
152 // lhs values | 158 // get LLValues |
153 if (DComplexValue* cx = c->isComplex()) { | 159 if (DComplexValue* cx = c->isComplex()) { |
154 re = cx->re; | 160 re = cx->re; |
155 im = cx->im; | 161 im = cx->im; |
156 } | 162 } |
157 else { | 163 else { |
158 re = DtoLoad(DtoGEPi(c->getRVal(),0,0,"tmp")); | 164 re = DtoLoad(DtoGEPi(c->getRVal(),0,0,"tmp")); |
159 im = DtoLoad(DtoGEPi(c->getRVal(),0,1,"tmp")); | 165 im = DtoLoad(DtoGEPi(c->getRVal(),0,1,"tmp")); |
160 } | 166 } |
161 } | 167 } |
162 | 168 |
169 DValue* resolveLR(DValue* val, bool getlval) | |
170 { | |
171 if (DLRValue* lr = val->isLRValue()) { | |
172 if (getlval) | |
173 return lr->lvalue; | |
174 else | |
175 return lr->rvalue; | |
176 } | |
177 return val; | |
178 } | |
179 | |
163 ////////////////////////////////////////////////////////////////////////////////////////// | 180 ////////////////////////////////////////////////////////////////////////////////////////// |
164 | 181 |
165 DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs) | 182 DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs) |
166 { | 183 { |
167 lhs = DtoComplex(type, lhs); | 184 lhs = DtoComplex(type, resolveLR(lhs, true)); |
168 rhs = DtoComplex(type, rhs); | 185 rhs = DtoComplex(type, resolveLR(rhs, false)); |
169 | 186 |
170 llvm::Value *a, *b, *c, *d, *re, *im; | 187 llvm::Value *a, *b, *c, *d, *re, *im; |
171 | 188 |
172 // lhs values | 189 // lhs values |
173 DtoGetComplexParts(lhs, a, b); | 190 DtoGetComplexParts(lhs, a, b); |
183 | 200 |
184 ////////////////////////////////////////////////////////////////////////////////////////// | 201 ////////////////////////////////////////////////////////////////////////////////////////// |
185 | 202 |
186 DValue* DtoComplexSub(Type* type, DValue* lhs, DValue* rhs) | 203 DValue* DtoComplexSub(Type* type, DValue* lhs, DValue* rhs) |
187 { | 204 { |
188 lhs = DtoComplex(type, lhs); | 205 lhs = DtoComplex(type, resolveLR(lhs, true)); |
189 rhs = DtoComplex(type, rhs); | 206 rhs = DtoComplex(type, resolveLR(rhs, false)); |
190 | 207 |
191 llvm::Value *a, *b, *c, *d, *re, *im; | 208 llvm::Value *a, *b, *c, *d, *re, *im; |
192 | 209 |
193 // lhs values | 210 // lhs values |
194 DtoGetComplexParts(lhs, a, b); | 211 DtoGetComplexParts(lhs, a, b); |
204 | 221 |
205 ////////////////////////////////////////////////////////////////////////////////////////// | 222 ////////////////////////////////////////////////////////////////////////////////////////// |
206 | 223 |
207 DValue* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs) | 224 DValue* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs) |
208 { | 225 { |
209 lhs = DtoComplex(type, lhs); | 226 lhs = DtoComplex(type, resolveLR(lhs, true)); |
210 rhs = DtoComplex(type, rhs); | 227 rhs = DtoComplex(type, resolveLR(rhs, false)); |
211 | 228 |
212 llvm::Value *a, *b, *c, *d; | 229 llvm::Value *a, *b, *c, *d; |
213 | 230 |
214 // lhs values | 231 // lhs values |
215 DtoGetComplexParts(lhs, a, b); | 232 DtoGetComplexParts(lhs, a, b); |
231 | 248 |
232 ////////////////////////////////////////////////////////////////////////////////////////// | 249 ////////////////////////////////////////////////////////////////////////////////////////// |
233 | 250 |
234 DValue* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs) | 251 DValue* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs) |
235 { | 252 { |
236 lhs = DtoComplex(type, lhs); | 253 lhs = DtoComplex(type, resolveLR(lhs, true)); |
237 rhs = DtoComplex(type, rhs); | 254 rhs = DtoComplex(type, resolveLR(rhs, false)); |
238 | 255 |
239 llvm::Value *a, *b, *c, *d; | 256 llvm::Value *a, *b, *c, *d; |
240 | 257 |
241 // lhs values | 258 // lhs values |
242 DtoGetComplexParts(lhs, a, b); | 259 DtoGetComplexParts(lhs, a, b); |
264 | 281 |
265 ////////////////////////////////////////////////////////////////////////////////////////// | 282 ////////////////////////////////////////////////////////////////////////////////////////// |
266 | 283 |
267 DValue* DtoComplexNeg(Type* type, DValue* val) | 284 DValue* DtoComplexNeg(Type* type, DValue* val) |
268 { | 285 { |
269 val = DtoComplex(type, val); | 286 val = DtoComplex(type, resolveLR(val, false)); |
270 | 287 |
271 llvm::Value *a, *b, *re, *im; | 288 llvm::Value *a, *b, *re, *im; |
272 | 289 |
273 // values | 290 // values |
274 DtoGetComplexParts(val, a, b); | 291 DtoGetComplexParts(val, a, b); |
284 | 301 |
285 LLValue* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs) | 302 LLValue* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs) |
286 { | 303 { |
287 Type* type = lhs->getType(); | 304 Type* type = lhs->getType(); |
288 | 305 |
289 lhs = DtoComplex(type, lhs); | 306 lhs = DtoComplex(type, resolveLR(lhs, false)); |
290 rhs = DtoComplex(type, rhs); | 307 rhs = DtoComplex(type, resolveLR(rhs, false)); |
291 | 308 |
292 llvm::Value *a, *b, *c, *d; | 309 llvm::Value *a, *b, *c, *d; |
293 | 310 |
294 // lhs values | 311 // lhs values |
295 DtoGetComplexParts(lhs, a, b); | 312 DtoGetComplexParts(lhs, a, b); |
340 | 357 |
341 // unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions. | 358 // unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions. |
342 // so we need to give it storage, or fix the system that handles this stuff (DLRValue) | 359 // so we need to give it storage, or fix the system that handles this stuff (DLRValue) |
343 LLValue* mem = new llvm::AllocaInst(DtoType(_to), "castcomplextmp", gIR->topallocapoint()); | 360 LLValue* mem = new llvm::AllocaInst(DtoType(_to), "castcomplextmp", gIR->topallocapoint()); |
344 DtoComplexSet(mem, re, im); | 361 DtoComplexSet(mem, re, im); |
345 return new DLRValue(val->getType(), val->getRVal(), _to, mem); | 362 return new DLRValue(val, new DImValue(_to, mem)); |
346 } | 363 } |
347 else if (to->isimaginary()) { | 364 else if (to->isimaginary()) { |
348 if (val->isComplex()) | 365 if (val->isComplex()) |
349 return new DImValue(to, val->isComplex()->im); | 366 return new DImValue(to, val->isComplex()->im); |
350 LLValue* v = val->getRVal(); | 367 LLValue* v = val->getRVal(); |