blob: 5aa6b974931bcbe669aab0e254088a5f80b5015d [file] [log] [blame]
Chris Lattner820dce82007-08-24 02:22:53 +00001//===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===//
Chris Lattner8d0cc2f2007-08-21 05:54:00 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This contains code to emit Expr nodes with complex types as LLVM code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenFunction.h"
15#include "CodeGenModule.h"
16#include "clang/AST/AST.h"
17#include "llvm/Constants.h"
18#include "llvm/Function.h"
19#include "llvm/Support/Compiler.h"
20using namespace clang;
21using namespace CodeGen;
22
23//===----------------------------------------------------------------------===//
Chris Lattneredb3bf02007-08-21 05:54:53 +000024// Complex Expression Emitter
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000025//===----------------------------------------------------------------------===//
26
Chris Lattner5280c5f2007-08-21 16:57:55 +000027typedef CodeGenFunction::ComplexPairTy ComplexPairTy;
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000028
29namespace {
30class VISIBILITY_HIDDEN ComplexExprEmitter
31 : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
32 CodeGenFunction &CGF;
Chris Lattner950b5d92007-08-21 17:39:38 +000033 llvm::LLVMBuilder &Builder;
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000034public:
Chris Lattner950b5d92007-08-21 17:39:38 +000035 ComplexExprEmitter(CodeGenFunction &cgf) : CGF(cgf), Builder(CGF.Builder) {
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000036 }
37
38
39 //===--------------------------------------------------------------------===//
40 // Utilities
41 //===--------------------------------------------------------------------===//
42
43 /// EmitLoadOfLValue - Given an expression with complex type that represents a
44 /// value l-value, this method emits the address of the l-value, then loads
45 /// and returns the result.
Chris Lattner1cd8f5c2007-08-21 17:28:34 +000046 ComplexPairTy EmitLoadOfLValue(const Expr *E) {
Chris Lattner689bfe42007-08-21 18:02:02 +000047 LValue LV = CGF.EmitLValue(E);
48 // FIXME: Volatile
49 return EmitLoadOfComplex(LV.getAddress(), false);
Chris Lattner1cd8f5c2007-08-21 17:28:34 +000050 }
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000051
Chris Lattner1cd8f5c2007-08-21 17:28:34 +000052 /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load
53 /// the real and imaginary pieces.
Chris Lattner689bfe42007-08-21 18:02:02 +000054 ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr, bool isVolatile);
Chris Lattner1cd8f5c2007-08-21 17:28:34 +000055
56 /// EmitStoreOfComplex - Store the specified real/imag parts into the
57 /// specified value pointer.
Chris Lattner689bfe42007-08-21 18:02:02 +000058 void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol);
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000059
Chris Lattnerb4cd7872007-08-26 22:09:01 +000060 /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
61 ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
62 QualType DestType);
63
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000064 //===--------------------------------------------------------------------===//
65 // Visitor Methods
66 //===--------------------------------------------------------------------===//
Chris Lattner7cff5302007-08-21 18:51:13 +000067
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000068 ComplexPairTy VisitStmt(Stmt *S) {
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000069 S->dump();
Chris Lattner7cff5302007-08-21 18:51:13 +000070 assert(0 && "Stmt can't have complex result type!");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000071 return ComplexPairTy();
72 }
Chris Lattner7cff5302007-08-21 18:51:13 +000073 ComplexPairTy VisitExpr(Expr *S);
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000074 ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}
Chris Lattner97d71832007-08-26 05:57:57 +000075 ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL);
Chris Lattnerb1f5ebc2007-08-26 03:51:12 +000076
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000077 // l-values.
Chris Lattner97d71832007-08-26 05:57:57 +000078 ComplexPairTy VisitDeclRefExpr(const Expr *E) { return EmitLoadOfLValue(E); }
Chris Lattner55029ed2007-08-21 18:03:58 +000079 ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
Chris Lattner97d71832007-08-26 05:57:57 +000080 ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); }
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000081
Chris Lattner385d4b72007-08-21 22:33:41 +000082 // FIXME: CompoundLiteralExpr
Chris Lattner97d71832007-08-26 05:57:57 +000083
84 ComplexPairTy EmitCast(Expr *Op, QualType DestTy);
85 ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) {
86 // Unlike for scalars, we don't have to worry about function->ptr demotion
87 // here.
88 return EmitCast(E->getSubExpr(), E->getType());
89 }
90 ComplexPairTy VisitCastExpr(CastExpr *E) {
91 return EmitCast(E->getSubExpr(), E->getType());
92 }
Chris Lattner84363b72007-08-23 21:38:16 +000093 ComplexPairTy VisitCallExpr(const CallExpr *E);
Chris Lattner385d4b72007-08-21 22:33:41 +000094
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000095 // Operators.
Chris Lattner63213e22007-08-21 22:25:29 +000096 ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,
97 bool isInc, bool isPre);
98 ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) {
99 return VisitPrePostIncDec(E, false, false);
100 }
101 ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) {
102 return VisitPrePostIncDec(E, true, false);
103 }
104 ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) {
105 return VisitPrePostIncDec(E, false, true);
106 }
107 ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) {
108 return VisitPrePostIncDec(E, true, true);
109 }
110 ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
Chris Lattnerd4aae9b2007-08-21 20:08:23 +0000111 ComplexPairTy VisitUnaryPlus (const UnaryOperator *E) {
112 return Visit(E->getSubExpr());
113 }
114 ComplexPairTy VisitUnaryMinus (const UnaryOperator *E);
Chris Lattner2d0f4de2007-08-21 20:41:44 +0000115 ComplexPairTy VisitUnaryNot (const UnaryOperator *E);
116 // LNot,SizeOf,AlignOf,Real,Imag never return complex.
117 ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) {
118 return Visit(E->getSubExpr());
119 }
120
Chris Lattnerb4cd7872007-08-26 22:09:01 +0000121 struct BinOpInfo {
122 ComplexPairTy LHS;
123 ComplexPairTy RHS;
124 QualType Ty; // Computation Type.
125 };
126
127 BinOpInfo EmitBinOps(const BinaryOperator *E);
128 ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
129 ComplexPairTy (ComplexExprEmitter::*Func)
130 (const BinOpInfo &));
131
132 ComplexPairTy EmitBinAdd(const BinOpInfo &Op);
133 ComplexPairTy EmitBinSub(const BinOpInfo &Op);
134 ComplexPairTy EmitBinMul(const BinOpInfo &Op);
135 ComplexPairTy EmitBinDiv(const BinOpInfo &Op);
136
137 ComplexPairTy VisitBinMul(const BinaryOperator *E) {
138 return EmitBinMul(EmitBinOps(E));
139 }
140 ComplexPairTy VisitBinAdd(const BinaryOperator *E) {
141 return EmitBinAdd(EmitBinOps(E));
142 }
143 ComplexPairTy VisitBinSub(const BinaryOperator *E) {
144 return EmitBinSub(EmitBinOps(E));
145 }
146 ComplexPairTy VisitBinDiv(const BinaryOperator *E) {
147 return EmitBinDiv(EmitBinOps(E));
148 }
149
150 // Compound assignments.
151 ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) {
152 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
153 }
154 ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) {
155 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
156 }
157 ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) {
158 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
159 }
160 ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) {
161 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
162 }
163
Chris Lattner7e1b81f2007-08-26 21:27:07 +0000164 // GCC rejects rem/and/or/xor for integer complex.
Chris Lattner7c257f42007-08-21 17:12:50 +0000165 // Logical and/or always return int, never complex.
Chris Lattner5280c5f2007-08-21 16:57:55 +0000166
167 // No comparisons produce a complex result.
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000168 ComplexPairTy VisitBinAssign (const BinaryOperator *E);
Chris Lattnerc15b0db2007-08-21 17:15:50 +0000169 ComplexPairTy VisitBinComma (const BinaryOperator *E);
170
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000171
172 ComplexPairTy VisitConditionalOperator(const ConditionalOperator *CO);
Chris Lattner53375682007-08-24 02:18:47 +0000173 ComplexPairTy VisitChooseExpr(ChooseExpr *CE);
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000174};
175} // end anonymous namespace.
176
177//===----------------------------------------------------------------------===//
178// Utilities
179//===----------------------------------------------------------------------===//
180
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000181/// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to
182/// load the real and imaginary pieces, returning them as Real/Imag.
Chris Lattner689bfe42007-08-21 18:02:02 +0000183ComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr,
184 bool isVolatile) {
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000185 llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
186 llvm::Constant *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
187 // FIXME: It would be nice to make this "Ptr->getName()+realp"
Chris Lattner950b5d92007-08-21 17:39:38 +0000188 llvm::Value *RealPtr = Builder.CreateGEP(SrcPtr, Zero, Zero, "realp");
189 llvm::Value *ImagPtr = Builder.CreateGEP(SrcPtr, Zero, One, "imagp");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000190
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000191 // FIXME: It would be nice to make this "Ptr->getName()+real"
Chris Lattner689bfe42007-08-21 18:02:02 +0000192 llvm::Value *Real = Builder.CreateLoad(RealPtr, isVolatile, "real");
193 llvm::Value *Imag = Builder.CreateLoad(ImagPtr, isVolatile, "imag");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000194 return ComplexPairTy(Real, Imag);
195}
196
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000197/// EmitStoreOfComplex - Store the specified real/imag parts into the
198/// specified value pointer.
Chris Lattner689bfe42007-08-21 18:02:02 +0000199void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr,
200 bool isVolatile) {
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000201 llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
202 llvm::Constant *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
Chris Lattner950b5d92007-08-21 17:39:38 +0000203 llvm::Value *RealPtr = Builder.CreateGEP(Ptr, Zero, Zero, "real");
204 llvm::Value *ImagPtr = Builder.CreateGEP(Ptr, Zero, One, "imag");
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000205
Chris Lattner689bfe42007-08-21 18:02:02 +0000206 Builder.CreateStore(Val.first, RealPtr, isVolatile);
207 Builder.CreateStore(Val.second, ImagPtr, isVolatile);
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000208}
209
210
211
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000212//===----------------------------------------------------------------------===//
213// Visitor Methods
214//===----------------------------------------------------------------------===//
215
Chris Lattner7cff5302007-08-21 18:51:13 +0000216ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) {
217 fprintf(stderr, "Unimplemented complex expr!\n");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000218 E->dump();
Chris Lattner7cff5302007-08-21 18:51:13 +0000219 const llvm::Type *EltTy =
220 CGF.ConvertType(E->getType()->getAsComplexType()->getElementType());
221 llvm::Value *U = llvm::UndefValue::get(EltTy);
222 return ComplexPairTy(U, U);
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000223}
224
Chris Lattner97d71832007-08-26 05:57:57 +0000225ComplexPairTy ComplexExprEmitter::
226VisitImaginaryLiteral(const ImaginaryLiteral *IL) {
Chris Lattnerb1f5ebc2007-08-26 03:51:12 +0000227 llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr());
228 return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
229}
230
231
Chris Lattner84363b72007-08-23 21:38:16 +0000232ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {
233 llvm::Value *AggPtr = CGF.EmitCallExpr(E).getAggregateAddr();
234 return EmitLoadOfComplex(AggPtr, false);
235}
236
Chris Lattnerb4cd7872007-08-26 22:09:01 +0000237/// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
238ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
239 QualType SrcType,
240 QualType DestType) {
241 // Get the src/dest element type.
242 SrcType = cast<ComplexType>(SrcType.getCanonicalType())->getElementType();
243 DestType = cast<ComplexType>(DestType.getCanonicalType())->getElementType();
Chris Lattner97d71832007-08-26 05:57:57 +0000244
Chris Lattnerb4cd7872007-08-26 22:09:01 +0000245 // C99 6.3.1.6: When a value of complextype is converted to another
246 // complex type, both the real and imaginary parts followthe conversion
247 // rules for the corresponding real types.
248 Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType);
249 Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType);
250 return Val;
251}
252
253ComplexPairTy ComplexExprEmitter::EmitCast(Expr *Op, QualType DestTy) {
Chris Lattner97d71832007-08-26 05:57:57 +0000254 // Two cases here: cast from (complex to complex) and (scalar to complex).
Chris Lattnerb4cd7872007-08-26 22:09:01 +0000255 if (Op->getType()->isComplexType())
256 return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy);
257
Chris Lattner97d71832007-08-26 05:57:57 +0000258 // C99 6.3.1.7: When a value of real type is converted to a complex type, the
259 // real part of the complex result value is determined by the rules of
260 // conversion to the corresponding real type and the imaginary part of the
261 // complex result value is a positive zero or an unsigned zero.
262 llvm::Value *Elt = CGF.EmitScalarExpr(Op);
263
264 // Convert the input element to the element type of the complex.
Chris Lattnerb4cd7872007-08-26 22:09:01 +0000265 DestTy = cast<ComplexType>(DestTy.getCanonicalType())->getElementType();
Chris Lattner4e05d1e2007-08-26 06:48:56 +0000266 Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy);
Chris Lattner97d71832007-08-26 05:57:57 +0000267
268 // Return (realval, 0).
269 return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType()));
270}
271
Chris Lattner63213e22007-08-21 22:25:29 +0000272ComplexPairTy ComplexExprEmitter::VisitPrePostIncDec(const UnaryOperator *E,
273 bool isInc, bool isPre) {
274 LValue LV = CGF.EmitLValue(E->getSubExpr());
275 // FIXME: Handle volatile!
276 ComplexPairTy InVal = EmitLoadOfComplex(LV.getAddress(), false);
277
278 int AmountVal = isInc ? 1 : -1;
279
280 llvm::Value *NextVal;
281 if (isa<llvm::IntegerType>(InVal.first->getType()))
282 NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal);
283 else
284 NextVal = llvm::ConstantFP::get(InVal.first->getType(), AmountVal);
285
286 // Add the inc/dec to the real part.
287 NextVal = Builder.CreateAdd(InVal.first, NextVal, isInc ? "inc" : "dec");
288
289 ComplexPairTy IncVal(NextVal, InVal.second);
290
291 // Store the updated result through the lvalue.
292 EmitStoreOfComplex(IncVal, LV.getAddress(), false); /* FIXME: Volatile */
293
294 // If this is a postinc, return the value read from memory, otherwise use the
295 // updated value.
296 return isPre ? IncVal : InVal;
297}
298
Chris Lattnerd4aae9b2007-08-21 20:08:23 +0000299ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
300 ComplexPairTy Op = Visit(E->getSubExpr());
301 llvm::Value *ResR = Builder.CreateNeg(Op.first, "neg.r");
302 llvm::Value *ResI = Builder.CreateNeg(Op.second, "neg.i");
303 return ComplexPairTy(ResR, ResI);
304}
305
Chris Lattner2d0f4de2007-08-21 20:41:44 +0000306ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
307 // ~(a+ib) = a + i*-b
308 ComplexPairTy Op = Visit(E->getSubExpr());
309 llvm::Value *ResI = Builder.CreateNeg(Op.second, "conj.i");
310 return ComplexPairTy(Op.first, ResI);
311}
Chris Lattnerd4aae9b2007-08-21 20:08:23 +0000312
Chris Lattnerb4cd7872007-08-26 22:09:01 +0000313ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) {
314 llvm::Value *ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r");
315 llvm::Value *ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000316 return ComplexPairTy(ResR, ResI);
317}
318
Chris Lattnerb4cd7872007-08-26 22:09:01 +0000319ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) {
320 llvm::Value *ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r");
321 llvm::Value *ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i");
Chris Lattner41c0c852007-08-23 23:46:33 +0000322 return ComplexPairTy(ResR, ResI);
323}
324
325
Chris Lattnerb4cd7872007-08-26 22:09:01 +0000326ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {
327 llvm::Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl");
328 llvm::Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,"mul.rr");
Chris Lattner950b5d92007-08-21 17:39:38 +0000329 llvm::Value *ResR = Builder.CreateSub(ResRl, ResRr, "mul.r");
Chris Lattner9a4e2c62007-08-21 16:34:16 +0000330
Chris Lattnerb4cd7872007-08-26 22:09:01 +0000331 llvm::Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il");
332 llvm::Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir");
Chris Lattner950b5d92007-08-21 17:39:38 +0000333 llvm::Value *ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i");
Chris Lattner9a4e2c62007-08-21 16:34:16 +0000334 return ComplexPairTy(ResR, ResI);
335}
336
Chris Lattnerb4cd7872007-08-26 22:09:01 +0000337ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
338 llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
339 llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
Chris Lattner9843d9e2007-08-26 21:24:19 +0000340
341 // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
342 llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr, "tmp"); // a*c
343 llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi, "tmp"); // b*d
344 llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2, "tmp"); // ac+bd
345
346 llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr, "tmp"); // c*c
347 llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi, "tmp"); // d*d
348 llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5, "tmp"); // cc+dd
349
350 llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr, "tmp"); // b*c
351 llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi, "tmp"); // a*d
352 llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8, "tmp"); // bc-ad
353
354 llvm::Value *DSTr, *DSTi;
355 if (Tmp3->getType()->isFloatingPoint()) {
356 DSTr = Builder.CreateFDiv(Tmp3, Tmp6, "tmp");
357 DSTi = Builder.CreateFDiv(Tmp9, Tmp6, "tmp");
358 } else {
Chris Lattnerb4cd7872007-08-26 22:09:01 +0000359 if (Op.Ty->getAsComplexType()->getElementType()->isUnsignedIntegerType()) {
Chris Lattner9843d9e2007-08-26 21:24:19 +0000360 DSTr = Builder.CreateUDiv(Tmp3, Tmp6, "tmp");
361 DSTi = Builder.CreateUDiv(Tmp9, Tmp6, "tmp");
362 } else {
363 DSTr = Builder.CreateSDiv(Tmp3, Tmp6, "tmp");
364 DSTi = Builder.CreateSDiv(Tmp9, Tmp6, "tmp");
365 }
366 }
367
368 return ComplexPairTy(DSTr, DSTi);
369}
370
Chris Lattnerb4cd7872007-08-26 22:09:01 +0000371ComplexExprEmitter::BinOpInfo
372ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) {
373 BinOpInfo Ops;
374 Ops.LHS = Visit(E->getLHS());
375 Ops.RHS = Visit(E->getRHS());
376 Ops.Ty = E->getType();
377 return Ops;
378}
379
380
381// Compound assignments.
382ComplexPairTy ComplexExprEmitter::
383EmitCompoundAssign(const CompoundAssignOperator *E,
384 ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
385 QualType LHSTy = E->getLHS()->getType(), RHSTy = E->getRHS()->getType();
386
387 // Load the LHS and RHS operands.
388 LValue LHSLV = CGF.EmitLValue(E->getLHS());
389
390 BinOpInfo OpInfo;
391 OpInfo.Ty = E->getComputationType();
392
393 // We know the LHS is a complex lvalue.
394 OpInfo.LHS = EmitLoadOfComplex(LHSLV.getAddress(), false);// FIXME: Volatile.
395 OpInfo.LHS = EmitComplexToComplexCast(OpInfo.LHS, LHSTy, OpInfo.Ty);
396
397 // It is possible for the RHS to be complex or scalar.
398 OpInfo.RHS = EmitCast(E->getRHS(), OpInfo.Ty);
399
400 // Expand the binary operator.
401 ComplexPairTy Result = (this->*Func)(OpInfo);
402
403 // Truncate the result back to the LHS type.
404 Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
405
406 // Store the result value into the LHS lvalue.
407 EmitStoreOfComplex(Result, LHSLV.getAddress(), false); // FIXME: VOLATILE
408 return Result;
409}
Chris Lattner9843d9e2007-08-26 21:24:19 +0000410
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000411ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
412 assert(E->getLHS()->getType().getCanonicalType() ==
413 E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
414 // Emit the RHS.
415 ComplexPairTy Val = Visit(E->getRHS());
416
417 // Compute the address to store into.
418 LValue LHS = CGF.EmitLValue(E->getLHS());
419
420 // Store into it.
421 // FIXME: Volatility!
Chris Lattner689bfe42007-08-21 18:02:02 +0000422 EmitStoreOfComplex(Val, LHS.getAddress(), false);
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000423 return Val;
424}
425
Chris Lattnerc15b0db2007-08-21 17:15:50 +0000426ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
427 CGF.EmitStmt(E->getLHS());
428 return Visit(E->getRHS());
429}
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000430
431ComplexPairTy ComplexExprEmitter::
432VisitConditionalOperator(const ConditionalOperator *E) {
433 llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
434 llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
435 llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
436
437 llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
Chris Lattner950b5d92007-08-21 17:39:38 +0000438 Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000439
440 CGF.EmitBlock(LHSBlock);
441
442 // Handle the GNU extension for missing LHS.
Chris Lattneredb3bf02007-08-21 05:54:53 +0000443 assert(E->getLHS() && "Must have LHS for complex value");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000444
445 ComplexPairTy LHS = Visit(E->getLHS());
Chris Lattner950b5d92007-08-21 17:39:38 +0000446 Builder.CreateBr(ContBlock);
447 LHSBlock = Builder.GetInsertBlock();
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000448
449 CGF.EmitBlock(RHSBlock);
450
451 ComplexPairTy RHS = Visit(E->getRHS());
Chris Lattner950b5d92007-08-21 17:39:38 +0000452 Builder.CreateBr(ContBlock);
453 RHSBlock = Builder.GetInsertBlock();
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000454
455 CGF.EmitBlock(ContBlock);
456
457 // Create a PHI node for the real part.
Chris Lattner950b5d92007-08-21 17:39:38 +0000458 llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), "cond.r");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000459 RealPN->reserveOperandSpace(2);
460 RealPN->addIncoming(LHS.first, LHSBlock);
461 RealPN->addIncoming(RHS.first, RHSBlock);
462
463 // Create a PHI node for the imaginary part.
Chris Lattner950b5d92007-08-21 17:39:38 +0000464 llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), "cond.i");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000465 ImagPN->reserveOperandSpace(2);
466 ImagPN->addIncoming(LHS.second, LHSBlock);
467 ImagPN->addIncoming(RHS.second, RHSBlock);
468
469 return ComplexPairTy(RealPN, ImagPN);
470}
471
Chris Lattner53375682007-08-24 02:18:47 +0000472ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) {
473 llvm::APSInt CondVal(32);
474 bool IsConst = E->getCond()->isIntegerConstantExpr(CondVal, CGF.getContext());
475 assert(IsConst && "Condition of choose expr must be i-c-e"); IsConst=IsConst;
476
477 // Emit the LHS or RHS as appropriate.
478 return Visit(CondVal != 0 ? E->getLHS() : E->getRHS());
479}
480
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000481//===----------------------------------------------------------------------===//
482// Entry Point into this File
483//===----------------------------------------------------------------------===//
484
485/// EmitComplexExpr - Emit the computation of the specified expression of
486/// complex type, ignoring the result.
Chris Lattner5280c5f2007-08-21 16:57:55 +0000487ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E) {
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000488 assert(E && E->getType()->isComplexType() &&
489 "Invalid complex expression to emit");
490
Chris Lattner5280c5f2007-08-21 16:57:55 +0000491 return ComplexExprEmitter(*this).Visit(const_cast<Expr*>(E));
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000492}
493
Chris Lattner348c8a22007-08-23 23:43:33 +0000494/// EmitComplexExprIntoAddr - Emit the computation of the specified expression
495/// of complex type, storing into the specified Value*.
496void CodeGenFunction::EmitComplexExprIntoAddr(const Expr *E,
Chris Lattner8e1f6e02007-08-26 16:22:13 +0000497 llvm::Value *DestAddr,
498 bool DestIsVolatile) {
Chris Lattner348c8a22007-08-23 23:43:33 +0000499 assert(E && E->getType()->isComplexType() &&
500 "Invalid complex expression to emit");
501 ComplexExprEmitter Emitter(*this);
502 ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E));
Chris Lattner8e1f6e02007-08-26 16:22:13 +0000503 Emitter.EmitStoreOfComplex(Val, DestAddr, DestIsVolatile);
Chris Lattner348c8a22007-08-23 23:43:33 +0000504}