1f22ef01cSRoman Divacky //===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===// 2f22ef01cSRoman Divacky // 3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure 4f22ef01cSRoman Divacky // 5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source 6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details. 7f22ef01cSRoman Divacky // 8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 9f22ef01cSRoman Divacky // 10f22ef01cSRoman Divacky // This contains code to emit Expr nodes with complex types as LLVM code. 11f22ef01cSRoman Divacky // 12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 13f22ef01cSRoman Divacky 14f22ef01cSRoman Divacky #include "CodeGenFunction.h" 15f22ef01cSRoman Divacky #include "CodeGenModule.h" 16f22ef01cSRoman Divacky #include "clang/AST/ASTContext.h" 17f22ef01cSRoman Divacky #include "clang/AST/StmtVisitor.h" 18f22ef01cSRoman Divacky #include "llvm/ADT/SmallString.h" 19139f7f9bSDimitry Andric #include "llvm/IR/Constants.h" 20139f7f9bSDimitry Andric #include "llvm/IR/Function.h" 21f785676fSDimitry Andric #include <algorithm> 22f22ef01cSRoman Divacky using namespace clang; 23f22ef01cSRoman Divacky using namespace CodeGen; 24f22ef01cSRoman Divacky 25f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 26f22ef01cSRoman Divacky // Complex Expression Emitter 27f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 28f22ef01cSRoman Divacky 29f22ef01cSRoman Divacky typedef CodeGenFunction::ComplexPairTy ComplexPairTy; 30f22ef01cSRoman Divacky 31139f7f9bSDimitry Andric /// Return the complex type that we are meant to emit. 32139f7f9bSDimitry Andric static const ComplexType *getComplexType(QualType type) { 33139f7f9bSDimitry Andric type = type.getCanonicalType(); 34139f7f9bSDimitry Andric if (const ComplexType *comp = dyn_cast<ComplexType>(type)) { 35139f7f9bSDimitry Andric return comp; 36139f7f9bSDimitry Andric } else { 37139f7f9bSDimitry Andric return cast<ComplexType>(cast<AtomicType>(type)->getValueType()); 38139f7f9bSDimitry Andric } 39139f7f9bSDimitry Andric } 40139f7f9bSDimitry Andric 41f22ef01cSRoman Divacky namespace { 42f22ef01cSRoman Divacky class ComplexExprEmitter 43f22ef01cSRoman Divacky : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> { 44f22ef01cSRoman Divacky CodeGenFunction &CGF; 45f22ef01cSRoman Divacky CGBuilderTy &Builder; 46f22ef01cSRoman Divacky bool IgnoreReal; 47f22ef01cSRoman Divacky bool IgnoreImag; 48f22ef01cSRoman Divacky public: 492754fe60SDimitry Andric ComplexExprEmitter(CodeGenFunction &cgf, bool ir=false, bool ii=false) 502754fe60SDimitry Andric : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii) { 51f22ef01cSRoman Divacky } 52f22ef01cSRoman Divacky 53f22ef01cSRoman Divacky 54f22ef01cSRoman Divacky //===--------------------------------------------------------------------===// 55f22ef01cSRoman Divacky // Utilities 56f22ef01cSRoman Divacky //===--------------------------------------------------------------------===// 57f22ef01cSRoman Divacky 58f22ef01cSRoman Divacky bool TestAndClearIgnoreReal() { 59f22ef01cSRoman Divacky bool I = IgnoreReal; 60f22ef01cSRoman Divacky IgnoreReal = false; 61f22ef01cSRoman Divacky return I; 62f22ef01cSRoman Divacky } 63f22ef01cSRoman Divacky bool TestAndClearIgnoreImag() { 64f22ef01cSRoman Divacky bool I = IgnoreImag; 65f22ef01cSRoman Divacky IgnoreImag = false; 66f22ef01cSRoman Divacky return I; 67f22ef01cSRoman Divacky } 68f22ef01cSRoman Divacky 69f22ef01cSRoman Divacky /// EmitLoadOfLValue - Given an expression with complex type that represents a 70f22ef01cSRoman Divacky /// value l-value, this method emits the address of the l-value, then loads 71f22ef01cSRoman Divacky /// and returns the result. 72f22ef01cSRoman Divacky ComplexPairTy EmitLoadOfLValue(const Expr *E) { 73f785676fSDimitry Andric return EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc()); 742754fe60SDimitry Andric } 752754fe60SDimitry Andric 76f785676fSDimitry Andric ComplexPairTy EmitLoadOfLValue(LValue LV, SourceLocation Loc); 772754fe60SDimitry Andric 78f22ef01cSRoman Divacky /// EmitStoreOfComplex - Store the specified real/imag parts into the 79f22ef01cSRoman Divacky /// specified value pointer. 80139f7f9bSDimitry Andric void EmitStoreOfComplex(ComplexPairTy Val, LValue LV, bool isInit); 81f22ef01cSRoman Divacky 82f22ef01cSRoman Divacky /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType. 83f22ef01cSRoman Divacky ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType, 84f22ef01cSRoman Divacky QualType DestType); 85f785676fSDimitry Andric /// EmitComplexToComplexCast - Emit a cast from scalar value Val to DestType. 86f785676fSDimitry Andric ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType, 87f785676fSDimitry Andric QualType DestType); 88f22ef01cSRoman Divacky 89f22ef01cSRoman Divacky //===--------------------------------------------------------------------===// 90f22ef01cSRoman Divacky // Visitor Methods 91f22ef01cSRoman Divacky //===--------------------------------------------------------------------===// 92f22ef01cSRoman Divacky 932754fe60SDimitry Andric ComplexPairTy Visit(Expr *E) { 942754fe60SDimitry Andric return StmtVisitor<ComplexExprEmitter, ComplexPairTy>::Visit(E); 952754fe60SDimitry Andric } 962754fe60SDimitry Andric 97f22ef01cSRoman Divacky ComplexPairTy VisitStmt(Stmt *S) { 98f22ef01cSRoman Divacky S->dump(CGF.getContext().getSourceManager()); 996122f3e6SDimitry Andric llvm_unreachable("Stmt can't have complex result type!"); 100f22ef01cSRoman Divacky } 101f22ef01cSRoman Divacky ComplexPairTy VisitExpr(Expr *S); 102f22ef01cSRoman Divacky ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());} 1033b0f4066SDimitry Andric ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) { 1043b0f4066SDimitry Andric return Visit(GE->getResultExpr()); 1053b0f4066SDimitry Andric } 106f22ef01cSRoman Divacky ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL); 10717a519f9SDimitry Andric ComplexPairTy 10817a519f9SDimitry Andric VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE) { 10917a519f9SDimitry Andric return Visit(PE->getReplacement()); 11017a519f9SDimitry Andric } 111f22ef01cSRoman Divacky 112f22ef01cSRoman Divacky // l-values. 113dff0c46cSDimitry Andric ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) { 114dff0c46cSDimitry Andric if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) { 115dff0c46cSDimitry Andric if (result.isReference()) 116f785676fSDimitry Andric return EmitLoadOfLValue(result.getReferenceLValue(CGF, E), 117f785676fSDimitry Andric E->getExprLoc()); 118dff0c46cSDimitry Andric 119f785676fSDimitry Andric llvm::Constant *pair = result.getValue(); 120f785676fSDimitry Andric return ComplexPairTy(pair->getAggregateElement(0U), 121f785676fSDimitry Andric pair->getAggregateElement(1U)); 122dff0c46cSDimitry Andric } 123f22ef01cSRoman Divacky return EmitLoadOfLValue(E); 124f22ef01cSRoman Divacky } 125dff0c46cSDimitry Andric ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 126f22ef01cSRoman Divacky return EmitLoadOfLValue(E); 127f22ef01cSRoman Divacky } 128f22ef01cSRoman Divacky ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) { 129f22ef01cSRoman Divacky return CGF.EmitObjCMessageExpr(E).getComplexVal(); 130f22ef01cSRoman Divacky } 131f22ef01cSRoman Divacky ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); } 132f22ef01cSRoman Divacky ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); } 1332754fe60SDimitry Andric ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) { 1342754fe60SDimitry Andric if (E->isGLValue()) 135f785676fSDimitry Andric return EmitLoadOfLValue(CGF.getOpaqueLValueMapping(E), E->getExprLoc()); 1362754fe60SDimitry Andric return CGF.getOpaqueRValueMapping(E).getComplexVal(); 1372754fe60SDimitry Andric } 138f22ef01cSRoman Divacky 139dff0c46cSDimitry Andric ComplexPairTy VisitPseudoObjectExpr(PseudoObjectExpr *E) { 140dff0c46cSDimitry Andric return CGF.EmitPseudoObjectRValue(E).getComplexVal(); 141dff0c46cSDimitry Andric } 142dff0c46cSDimitry Andric 143f22ef01cSRoman Divacky // FIXME: CompoundLiteralExpr 144f22ef01cSRoman Divacky 145ffd1746dSEd Schouten ComplexPairTy EmitCast(CastExpr::CastKind CK, Expr *Op, QualType DestTy); 146f22ef01cSRoman Divacky ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) { 147f22ef01cSRoman Divacky // Unlike for scalars, we don't have to worry about function->ptr demotion 148f22ef01cSRoman Divacky // here. 149ffd1746dSEd Schouten return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); 150f22ef01cSRoman Divacky } 151f22ef01cSRoman Divacky ComplexPairTy VisitCastExpr(CastExpr *E) { 152ffd1746dSEd Schouten return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); 153f22ef01cSRoman Divacky } 154f22ef01cSRoman Divacky ComplexPairTy VisitCallExpr(const CallExpr *E); 155f22ef01cSRoman Divacky ComplexPairTy VisitStmtExpr(const StmtExpr *E); 156f22ef01cSRoman Divacky 157f22ef01cSRoman Divacky // Operators. 158f22ef01cSRoman Divacky ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E, 159f22ef01cSRoman Divacky bool isInc, bool isPre) { 160f22ef01cSRoman Divacky LValue LV = CGF.EmitLValue(E->getSubExpr()); 161f22ef01cSRoman Divacky return CGF.EmitComplexPrePostIncDec(E, LV, isInc, isPre); 162f22ef01cSRoman Divacky } 163f22ef01cSRoman Divacky ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) { 164f22ef01cSRoman Divacky return VisitPrePostIncDec(E, false, false); 165f22ef01cSRoman Divacky } 166f22ef01cSRoman Divacky ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) { 167f22ef01cSRoman Divacky return VisitPrePostIncDec(E, true, false); 168f22ef01cSRoman Divacky } 169f22ef01cSRoman Divacky ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) { 170f22ef01cSRoman Divacky return VisitPrePostIncDec(E, false, true); 171f22ef01cSRoman Divacky } 172f22ef01cSRoman Divacky ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) { 173f22ef01cSRoman Divacky return VisitPrePostIncDec(E, true, true); 174f22ef01cSRoman Divacky } 175f22ef01cSRoman Divacky ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); } 176f22ef01cSRoman Divacky ComplexPairTy VisitUnaryPlus (const UnaryOperator *E) { 177f22ef01cSRoman Divacky TestAndClearIgnoreReal(); 178f22ef01cSRoman Divacky TestAndClearIgnoreImag(); 179f22ef01cSRoman Divacky return Visit(E->getSubExpr()); 180f22ef01cSRoman Divacky } 181f22ef01cSRoman Divacky ComplexPairTy VisitUnaryMinus (const UnaryOperator *E); 182f22ef01cSRoman Divacky ComplexPairTy VisitUnaryNot (const UnaryOperator *E); 183f22ef01cSRoman Divacky // LNot,Real,Imag never return complex. 184f22ef01cSRoman Divacky ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) { 185f22ef01cSRoman Divacky return Visit(E->getSubExpr()); 186f22ef01cSRoman Divacky } 187f22ef01cSRoman Divacky ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) { 188f22ef01cSRoman Divacky return Visit(DAE->getExpr()); 189f22ef01cSRoman Divacky } 190284c1978SDimitry Andric ComplexPairTy VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) { 191284c1978SDimitry Andric CodeGenFunction::CXXDefaultInitExprScope Scope(CGF); 192284c1978SDimitry Andric return Visit(DIE->getExpr()); 193284c1978SDimitry Andric } 1942754fe60SDimitry Andric ComplexPairTy VisitExprWithCleanups(ExprWithCleanups *E) { 195dff0c46cSDimitry Andric CGF.enterFullExpression(E); 196dff0c46cSDimitry Andric CodeGenFunction::RunCleanupsScope Scope(CGF); 197dff0c46cSDimitry Andric return Visit(E->getSubExpr()); 198f22ef01cSRoman Divacky } 199ffd1746dSEd Schouten ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { 200f22ef01cSRoman Divacky assert(E->getType()->isAnyComplexType() && "Expected complex type!"); 201139f7f9bSDimitry Andric QualType Elem = E->getType()->castAs<ComplexType>()->getElementType(); 202f22ef01cSRoman Divacky llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem)); 203f22ef01cSRoman Divacky return ComplexPairTy(Null, Null); 204f22ef01cSRoman Divacky } 205f22ef01cSRoman Divacky ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { 206f22ef01cSRoman Divacky assert(E->getType()->isAnyComplexType() && "Expected complex type!"); 207139f7f9bSDimitry Andric QualType Elem = E->getType()->castAs<ComplexType>()->getElementType(); 208f22ef01cSRoman Divacky llvm::Constant *Null = 209f22ef01cSRoman Divacky llvm::Constant::getNullValue(CGF.ConvertType(Elem)); 210f22ef01cSRoman Divacky return ComplexPairTy(Null, Null); 211f22ef01cSRoman Divacky } 212f22ef01cSRoman Divacky 213f22ef01cSRoman Divacky struct BinOpInfo { 214f22ef01cSRoman Divacky ComplexPairTy LHS; 215f22ef01cSRoman Divacky ComplexPairTy RHS; 216f22ef01cSRoman Divacky QualType Ty; // Computation Type. 217f22ef01cSRoman Divacky }; 218f22ef01cSRoman Divacky 219f22ef01cSRoman Divacky BinOpInfo EmitBinOps(const BinaryOperator *E); 2202754fe60SDimitry Andric LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E, 2212754fe60SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func) 2222754fe60SDimitry Andric (const BinOpInfo &), 223f785676fSDimitry Andric RValue &Val); 224f22ef01cSRoman Divacky ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E, 225f22ef01cSRoman Divacky ComplexPairTy (ComplexExprEmitter::*Func) 226f22ef01cSRoman Divacky (const BinOpInfo &)); 227f22ef01cSRoman Divacky 228f22ef01cSRoman Divacky ComplexPairTy EmitBinAdd(const BinOpInfo &Op); 229f22ef01cSRoman Divacky ComplexPairTy EmitBinSub(const BinOpInfo &Op); 230f22ef01cSRoman Divacky ComplexPairTy EmitBinMul(const BinOpInfo &Op); 231f22ef01cSRoman Divacky ComplexPairTy EmitBinDiv(const BinOpInfo &Op); 232f22ef01cSRoman Divacky 233f22ef01cSRoman Divacky ComplexPairTy VisitBinAdd(const BinaryOperator *E) { 234f22ef01cSRoman Divacky return EmitBinAdd(EmitBinOps(E)); 235f22ef01cSRoman Divacky } 236f22ef01cSRoman Divacky ComplexPairTy VisitBinSub(const BinaryOperator *E) { 237f22ef01cSRoman Divacky return EmitBinSub(EmitBinOps(E)); 238f22ef01cSRoman Divacky } 2392754fe60SDimitry Andric ComplexPairTy VisitBinMul(const BinaryOperator *E) { 2402754fe60SDimitry Andric return EmitBinMul(EmitBinOps(E)); 2412754fe60SDimitry Andric } 242f22ef01cSRoman Divacky ComplexPairTy VisitBinDiv(const BinaryOperator *E) { 243f22ef01cSRoman Divacky return EmitBinDiv(EmitBinOps(E)); 244f22ef01cSRoman Divacky } 245f22ef01cSRoman Divacky 246f22ef01cSRoman Divacky // Compound assignments. 247f22ef01cSRoman Divacky ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) { 248f22ef01cSRoman Divacky return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd); 249f22ef01cSRoman Divacky } 250f22ef01cSRoman Divacky ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) { 251f22ef01cSRoman Divacky return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub); 252f22ef01cSRoman Divacky } 253f22ef01cSRoman Divacky ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) { 254f22ef01cSRoman Divacky return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul); 255f22ef01cSRoman Divacky } 256f22ef01cSRoman Divacky ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) { 257f22ef01cSRoman Divacky return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv); 258f22ef01cSRoman Divacky } 259f22ef01cSRoman Divacky 260f22ef01cSRoman Divacky // GCC rejects rem/and/or/xor for integer complex. 261f22ef01cSRoman Divacky // Logical and/or always return int, never complex. 262f22ef01cSRoman Divacky 263f22ef01cSRoman Divacky // No comparisons produce a complex result. 2642754fe60SDimitry Andric 2652754fe60SDimitry Andric LValue EmitBinAssignLValue(const BinaryOperator *E, 2662754fe60SDimitry Andric ComplexPairTy &Val); 267f22ef01cSRoman Divacky ComplexPairTy VisitBinAssign (const BinaryOperator *E); 268f22ef01cSRoman Divacky ComplexPairTy VisitBinComma (const BinaryOperator *E); 269f22ef01cSRoman Divacky 270f22ef01cSRoman Divacky 2712754fe60SDimitry Andric ComplexPairTy 2722754fe60SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO); 273f22ef01cSRoman Divacky ComplexPairTy VisitChooseExpr(ChooseExpr *CE); 274f22ef01cSRoman Divacky 275f22ef01cSRoman Divacky ComplexPairTy VisitInitListExpr(InitListExpr *E); 276f22ef01cSRoman Divacky 277dff0c46cSDimitry Andric ComplexPairTy VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { 278dff0c46cSDimitry Andric return EmitLoadOfLValue(E); 279dff0c46cSDimitry Andric } 280dff0c46cSDimitry Andric 281f22ef01cSRoman Divacky ComplexPairTy VisitVAArgExpr(VAArgExpr *E); 2826122f3e6SDimitry Andric 2836122f3e6SDimitry Andric ComplexPairTy VisitAtomicExpr(AtomicExpr *E) { 2846122f3e6SDimitry Andric return CGF.EmitAtomicExpr(E).getComplexVal(); 2856122f3e6SDimitry Andric } 286f22ef01cSRoman Divacky }; 287f22ef01cSRoman Divacky } // end anonymous namespace. 288f22ef01cSRoman Divacky 289f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 290f22ef01cSRoman Divacky // Utilities 291f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 292f22ef01cSRoman Divacky 293139f7f9bSDimitry Andric /// EmitLoadOfLValue - Given an RValue reference for a complex, emit code to 294f22ef01cSRoman Divacky /// load the real and imaginary pieces, returning them as Real/Imag. 295f785676fSDimitry Andric ComplexPairTy ComplexExprEmitter::EmitLoadOfLValue(LValue lvalue, 296f785676fSDimitry Andric SourceLocation loc) { 297139f7f9bSDimitry Andric assert(lvalue.isSimple() && "non-simple complex l-value?"); 298139f7f9bSDimitry Andric if (lvalue.getType()->isAtomicType()) 299f785676fSDimitry Andric return CGF.EmitAtomicLoad(lvalue, loc).getComplexVal(); 300139f7f9bSDimitry Andric 301139f7f9bSDimitry Andric llvm::Value *SrcPtr = lvalue.getAddress(); 302139f7f9bSDimitry Andric bool isVolatile = lvalue.isVolatileQualified(); 303f785676fSDimitry Andric unsigned AlignR = lvalue.getAlignment().getQuantity(); 304f785676fSDimitry Andric ASTContext &C = CGF.getContext(); 305f785676fSDimitry Andric QualType ComplexTy = lvalue.getType(); 306f785676fSDimitry Andric unsigned ComplexAlign = C.getTypeAlignInChars(ComplexTy).getQuantity(); 307f785676fSDimitry Andric unsigned AlignI = std::min(AlignR, ComplexAlign); 308139f7f9bSDimitry Andric 309f22ef01cSRoman Divacky llvm::Value *Real=0, *Imag=0; 310f22ef01cSRoman Divacky 3112754fe60SDimitry Andric if (!IgnoreReal || isVolatile) { 312f22ef01cSRoman Divacky llvm::Value *RealP = Builder.CreateStructGEP(SrcPtr, 0, 313f22ef01cSRoman Divacky SrcPtr->getName() + ".realp"); 314f785676fSDimitry Andric Real = Builder.CreateAlignedLoad(RealP, AlignR, isVolatile, 315f785676fSDimitry Andric SrcPtr->getName() + ".real"); 316f22ef01cSRoman Divacky } 317f22ef01cSRoman Divacky 3182754fe60SDimitry Andric if (!IgnoreImag || isVolatile) { 319f22ef01cSRoman Divacky llvm::Value *ImagP = Builder.CreateStructGEP(SrcPtr, 1, 320f22ef01cSRoman Divacky SrcPtr->getName() + ".imagp"); 321f785676fSDimitry Andric Imag = Builder.CreateAlignedLoad(ImagP, AlignI, isVolatile, 322f785676fSDimitry Andric SrcPtr->getName() + ".imag"); 323f22ef01cSRoman Divacky } 324f22ef01cSRoman Divacky return ComplexPairTy(Real, Imag); 325f22ef01cSRoman Divacky } 326f22ef01cSRoman Divacky 327f22ef01cSRoman Divacky /// EmitStoreOfComplex - Store the specified real/imag parts into the 328f22ef01cSRoman Divacky /// specified value pointer. 329139f7f9bSDimitry Andric void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, 330139f7f9bSDimitry Andric LValue lvalue, 331139f7f9bSDimitry Andric bool isInit) { 332139f7f9bSDimitry Andric if (lvalue.getType()->isAtomicType()) 333139f7f9bSDimitry Andric return CGF.EmitAtomicStore(RValue::getComplex(Val), lvalue, isInit); 334139f7f9bSDimitry Andric 335139f7f9bSDimitry Andric llvm::Value *Ptr = lvalue.getAddress(); 336f22ef01cSRoman Divacky llvm::Value *RealPtr = Builder.CreateStructGEP(Ptr, 0, "real"); 337f22ef01cSRoman Divacky llvm::Value *ImagPtr = Builder.CreateStructGEP(Ptr, 1, "imag"); 338f785676fSDimitry Andric unsigned AlignR = lvalue.getAlignment().getQuantity(); 339f785676fSDimitry Andric ASTContext &C = CGF.getContext(); 340f785676fSDimitry Andric QualType ComplexTy = lvalue.getType(); 341f785676fSDimitry Andric unsigned ComplexAlign = C.getTypeAlignInChars(ComplexTy).getQuantity(); 342f785676fSDimitry Andric unsigned AlignI = std::min(AlignR, ComplexAlign); 343f22ef01cSRoman Divacky 344f785676fSDimitry Andric Builder.CreateAlignedStore(Val.first, RealPtr, AlignR, 345f785676fSDimitry Andric lvalue.isVolatileQualified()); 346f785676fSDimitry Andric Builder.CreateAlignedStore(Val.second, ImagPtr, AlignI, 347f785676fSDimitry Andric lvalue.isVolatileQualified()); 348f22ef01cSRoman Divacky } 349f22ef01cSRoman Divacky 350f22ef01cSRoman Divacky 351f22ef01cSRoman Divacky 352f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 353f22ef01cSRoman Divacky // Visitor Methods 354f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 355f22ef01cSRoman Divacky 356f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) { 357f22ef01cSRoman Divacky CGF.ErrorUnsupported(E, "complex expression"); 3586122f3e6SDimitry Andric llvm::Type *EltTy = 359139f7f9bSDimitry Andric CGF.ConvertType(getComplexType(E->getType())->getElementType()); 360f22ef01cSRoman Divacky llvm::Value *U = llvm::UndefValue::get(EltTy); 361f22ef01cSRoman Divacky return ComplexPairTy(U, U); 362f22ef01cSRoman Divacky } 363f22ef01cSRoman Divacky 364f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter:: 365f22ef01cSRoman Divacky VisitImaginaryLiteral(const ImaginaryLiteral *IL) { 366f22ef01cSRoman Divacky llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr()); 3672754fe60SDimitry Andric return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag); 368f22ef01cSRoman Divacky } 369f22ef01cSRoman Divacky 370f22ef01cSRoman Divacky 371f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) { 372f22ef01cSRoman Divacky if (E->getCallReturnType()->isReferenceType()) 373f22ef01cSRoman Divacky return EmitLoadOfLValue(E); 374f22ef01cSRoman Divacky 375f22ef01cSRoman Divacky return CGF.EmitCallExpr(E).getComplexVal(); 376f22ef01cSRoman Divacky } 377f22ef01cSRoman Divacky 378f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) { 3792754fe60SDimitry Andric CodeGenFunction::StmtExprEvaluation eval(CGF); 380f785676fSDimitry Andric llvm::Value *RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), true); 381f785676fSDimitry Andric assert(RetAlloca && "Expected complex return value"); 382f785676fSDimitry Andric return EmitLoadOfLValue(CGF.MakeAddrLValue(RetAlloca, E->getType()), 383f785676fSDimitry Andric E->getExprLoc()); 384f22ef01cSRoman Divacky } 385f22ef01cSRoman Divacky 386f22ef01cSRoman Divacky /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType. 387f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val, 388f22ef01cSRoman Divacky QualType SrcType, 389f22ef01cSRoman Divacky QualType DestType) { 390f22ef01cSRoman Divacky // Get the src/dest element type. 391139f7f9bSDimitry Andric SrcType = SrcType->castAs<ComplexType>()->getElementType(); 392139f7f9bSDimitry Andric DestType = DestType->castAs<ComplexType>()->getElementType(); 393f22ef01cSRoman Divacky 394f22ef01cSRoman Divacky // C99 6.3.1.6: When a value of complex type is converted to another 395f22ef01cSRoman Divacky // complex type, both the real and imaginary parts follow the conversion 396f22ef01cSRoman Divacky // rules for the corresponding real types. 397f22ef01cSRoman Divacky Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType); 398f22ef01cSRoman Divacky Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType); 399f22ef01cSRoman Divacky return Val; 400f22ef01cSRoman Divacky } 401f22ef01cSRoman Divacky 402f785676fSDimitry Andric ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val, 403f785676fSDimitry Andric QualType SrcType, 404f785676fSDimitry Andric QualType DestType) { 405f785676fSDimitry Andric // Convert the input element to the element type of the complex. 406f785676fSDimitry Andric DestType = DestType->castAs<ComplexType>()->getElementType(); 407f785676fSDimitry Andric Val = CGF.EmitScalarConversion(Val, SrcType, DestType); 408f785676fSDimitry Andric 409f785676fSDimitry Andric // Return (realval, 0). 410f785676fSDimitry Andric return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType())); 411f785676fSDimitry Andric } 412f785676fSDimitry Andric 413ffd1746dSEd Schouten ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op, 414ffd1746dSEd Schouten QualType DestTy) { 4152754fe60SDimitry Andric switch (CK) { 41617a519f9SDimitry Andric case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!"); 41717a519f9SDimitry Andric 418dff0c46cSDimitry Andric // Atomic to non-atomic casts may be more than a no-op for some platforms and 419dff0c46cSDimitry Andric // for some types. 420dff0c46cSDimitry Andric case CK_AtomicToNonAtomic: 421dff0c46cSDimitry Andric case CK_NonAtomicToAtomic: 4222754fe60SDimitry Andric case CK_NoOp: 4232754fe60SDimitry Andric case CK_LValueToRValue: 42417a519f9SDimitry Andric case CK_UserDefinedConversion: 4252754fe60SDimitry Andric return Visit(Op); 4262754fe60SDimitry Andric 42717a519f9SDimitry Andric case CK_LValueBitCast: { 428139f7f9bSDimitry Andric LValue origLV = CGF.EmitLValue(Op); 429139f7f9bSDimitry Andric llvm::Value *V = origLV.getAddress(); 430ffd1746dSEd Schouten V = Builder.CreateBitCast(V, 431ffd1746dSEd Schouten CGF.ConvertType(CGF.getContext().getPointerType(DestTy))); 432139f7f9bSDimitry Andric return EmitLoadOfLValue(CGF.MakeAddrLValue(V, DestTy, 433f785676fSDimitry Andric origLV.getAlignment()), 434f785676fSDimitry Andric Op->getExprLoc()); 435ffd1746dSEd Schouten } 436ffd1746dSEd Schouten 43717a519f9SDimitry Andric case CK_BitCast: 43817a519f9SDimitry Andric case CK_BaseToDerived: 43917a519f9SDimitry Andric case CK_DerivedToBase: 44017a519f9SDimitry Andric case CK_UncheckedDerivedToBase: 44117a519f9SDimitry Andric case CK_Dynamic: 44217a519f9SDimitry Andric case CK_ToUnion: 44317a519f9SDimitry Andric case CK_ArrayToPointerDecay: 44417a519f9SDimitry Andric case CK_FunctionToPointerDecay: 44517a519f9SDimitry Andric case CK_NullToPointer: 44617a519f9SDimitry Andric case CK_NullToMemberPointer: 44717a519f9SDimitry Andric case CK_BaseToDerivedMemberPointer: 44817a519f9SDimitry Andric case CK_DerivedToBaseMemberPointer: 44917a519f9SDimitry Andric case CK_MemberPointerToBoolean: 450dff0c46cSDimitry Andric case CK_ReinterpretMemberPointer: 45117a519f9SDimitry Andric case CK_ConstructorConversion: 45217a519f9SDimitry Andric case CK_IntegralToPointer: 45317a519f9SDimitry Andric case CK_PointerToIntegral: 45417a519f9SDimitry Andric case CK_PointerToBoolean: 45517a519f9SDimitry Andric case CK_ToVoid: 45617a519f9SDimitry Andric case CK_VectorSplat: 45717a519f9SDimitry Andric case CK_IntegralCast: 45817a519f9SDimitry Andric case CK_IntegralToBoolean: 45917a519f9SDimitry Andric case CK_IntegralToFloating: 46017a519f9SDimitry Andric case CK_FloatingToIntegral: 46117a519f9SDimitry Andric case CK_FloatingToBoolean: 46217a519f9SDimitry Andric case CK_FloatingCast: 4636122f3e6SDimitry Andric case CK_CPointerToObjCPointerCast: 4646122f3e6SDimitry Andric case CK_BlockPointerToObjCPointerCast: 46517a519f9SDimitry Andric case CK_AnyPointerToBlockPointerCast: 46617a519f9SDimitry Andric case CK_ObjCObjectLValueCast: 46717a519f9SDimitry Andric case CK_FloatingComplexToReal: 46817a519f9SDimitry Andric case CK_FloatingComplexToBoolean: 46917a519f9SDimitry Andric case CK_IntegralComplexToReal: 47017a519f9SDimitry Andric case CK_IntegralComplexToBoolean: 4716122f3e6SDimitry Andric case CK_ARCProduceObject: 4726122f3e6SDimitry Andric case CK_ARCConsumeObject: 4736122f3e6SDimitry Andric case CK_ARCReclaimReturnedObject: 4746122f3e6SDimitry Andric case CK_ARCExtendBlockObject: 475dff0c46cSDimitry Andric case CK_CopyAndAutoreleaseBlockObject: 4763861d79fSDimitry Andric case CK_BuiltinFnToFnPtr: 477139f7f9bSDimitry Andric case CK_ZeroToOCLEvent: 47817a519f9SDimitry Andric llvm_unreachable("invalid cast kind for complex value"); 47917a519f9SDimitry Andric 48017a519f9SDimitry Andric case CK_FloatingRealToComplex: 481f785676fSDimitry Andric case CK_IntegralRealToComplex: 482f785676fSDimitry Andric return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op), 483f785676fSDimitry Andric Op->getType(), DestTy); 484f22ef01cSRoman Divacky 48517a519f9SDimitry Andric case CK_FloatingComplexCast: 48617a519f9SDimitry Andric case CK_FloatingComplexToIntegralComplex: 48717a519f9SDimitry Andric case CK_IntegralComplexCast: 48817a519f9SDimitry Andric case CK_IntegralComplexToFloatingComplex: 48917a519f9SDimitry Andric return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy); 49017a519f9SDimitry Andric } 49117a519f9SDimitry Andric 49217a519f9SDimitry Andric llvm_unreachable("unknown cast resulting in complex value"); 49317a519f9SDimitry Andric } 49417a519f9SDimitry Andric 495f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { 496f22ef01cSRoman Divacky TestAndClearIgnoreReal(); 497f22ef01cSRoman Divacky TestAndClearIgnoreImag(); 498f22ef01cSRoman Divacky ComplexPairTy Op = Visit(E->getSubExpr()); 499f22ef01cSRoman Divacky 500f22ef01cSRoman Divacky llvm::Value *ResR, *ResI; 501f22ef01cSRoman Divacky if (Op.first->getType()->isFloatingPointTy()) { 502f22ef01cSRoman Divacky ResR = Builder.CreateFNeg(Op.first, "neg.r"); 503f22ef01cSRoman Divacky ResI = Builder.CreateFNeg(Op.second, "neg.i"); 504f22ef01cSRoman Divacky } else { 505f22ef01cSRoman Divacky ResR = Builder.CreateNeg(Op.first, "neg.r"); 506f22ef01cSRoman Divacky ResI = Builder.CreateNeg(Op.second, "neg.i"); 507f22ef01cSRoman Divacky } 508f22ef01cSRoman Divacky return ComplexPairTy(ResR, ResI); 509f22ef01cSRoman Divacky } 510f22ef01cSRoman Divacky 511f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) { 512f22ef01cSRoman Divacky TestAndClearIgnoreReal(); 513f22ef01cSRoman Divacky TestAndClearIgnoreImag(); 514f22ef01cSRoman Divacky // ~(a+ib) = a + i*-b 515f22ef01cSRoman Divacky ComplexPairTy Op = Visit(E->getSubExpr()); 516f22ef01cSRoman Divacky llvm::Value *ResI; 517f22ef01cSRoman Divacky if (Op.second->getType()->isFloatingPointTy()) 518f22ef01cSRoman Divacky ResI = Builder.CreateFNeg(Op.second, "conj.i"); 519f22ef01cSRoman Divacky else 520f22ef01cSRoman Divacky ResI = Builder.CreateNeg(Op.second, "conj.i"); 521f22ef01cSRoman Divacky 522f22ef01cSRoman Divacky return ComplexPairTy(Op.first, ResI); 523f22ef01cSRoman Divacky } 524f22ef01cSRoman Divacky 525f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) { 526f22ef01cSRoman Divacky llvm::Value *ResR, *ResI; 527f22ef01cSRoman Divacky 528f22ef01cSRoman Divacky if (Op.LHS.first->getType()->isFloatingPointTy()) { 529f22ef01cSRoman Divacky ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first, "add.r"); 530f22ef01cSRoman Divacky ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i"); 531f22ef01cSRoman Divacky } else { 532f22ef01cSRoman Divacky ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r"); 533f22ef01cSRoman Divacky ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i"); 534f22ef01cSRoman Divacky } 535f22ef01cSRoman Divacky return ComplexPairTy(ResR, ResI); 536f22ef01cSRoman Divacky } 537f22ef01cSRoman Divacky 538f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) { 539f22ef01cSRoman Divacky llvm::Value *ResR, *ResI; 540f22ef01cSRoman Divacky if (Op.LHS.first->getType()->isFloatingPointTy()) { 541f22ef01cSRoman Divacky ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first, "sub.r"); 542f22ef01cSRoman Divacky ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i"); 543f22ef01cSRoman Divacky } else { 544f22ef01cSRoman Divacky ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r"); 545f22ef01cSRoman Divacky ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i"); 546f22ef01cSRoman Divacky } 547f22ef01cSRoman Divacky return ComplexPairTy(ResR, ResI); 548f22ef01cSRoman Divacky } 549f22ef01cSRoman Divacky 550f22ef01cSRoman Divacky 551f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) { 552f22ef01cSRoman Divacky using llvm::Value; 553f22ef01cSRoman Divacky Value *ResR, *ResI; 554f22ef01cSRoman Divacky 555f22ef01cSRoman Divacky if (Op.LHS.first->getType()->isFloatingPointTy()) { 556f22ef01cSRoman Divacky Value *ResRl = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl"); 557f22ef01cSRoman Divacky Value *ResRr = Builder.CreateFMul(Op.LHS.second, Op.RHS.second,"mul.rr"); 558f22ef01cSRoman Divacky ResR = Builder.CreateFSub(ResRl, ResRr, "mul.r"); 559f22ef01cSRoman Divacky 560f22ef01cSRoman Divacky Value *ResIl = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il"); 561f22ef01cSRoman Divacky Value *ResIr = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir"); 562f22ef01cSRoman Divacky ResI = Builder.CreateFAdd(ResIl, ResIr, "mul.i"); 563f22ef01cSRoman Divacky } else { 564f22ef01cSRoman Divacky Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl"); 565f22ef01cSRoman Divacky Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,"mul.rr"); 566f22ef01cSRoman Divacky ResR = Builder.CreateSub(ResRl, ResRr, "mul.r"); 567f22ef01cSRoman Divacky 568f22ef01cSRoman Divacky Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il"); 569f22ef01cSRoman Divacky Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir"); 570f22ef01cSRoman Divacky ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i"); 571f22ef01cSRoman Divacky } 572f22ef01cSRoman Divacky return ComplexPairTy(ResR, ResI); 573f22ef01cSRoman Divacky } 574f22ef01cSRoman Divacky 575f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { 576f22ef01cSRoman Divacky llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second; 577f22ef01cSRoman Divacky llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second; 578f22ef01cSRoman Divacky 579f22ef01cSRoman Divacky 580f22ef01cSRoman Divacky llvm::Value *DSTr, *DSTi; 581f22ef01cSRoman Divacky if (Op.LHS.first->getType()->isFloatingPointTy()) { 582f22ef01cSRoman Divacky // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) 5836122f3e6SDimitry Andric llvm::Value *Tmp1 = Builder.CreateFMul(LHSr, RHSr); // a*c 5846122f3e6SDimitry Andric llvm::Value *Tmp2 = Builder.CreateFMul(LHSi, RHSi); // b*d 5856122f3e6SDimitry Andric llvm::Value *Tmp3 = Builder.CreateFAdd(Tmp1, Tmp2); // ac+bd 586f22ef01cSRoman Divacky 5876122f3e6SDimitry Andric llvm::Value *Tmp4 = Builder.CreateFMul(RHSr, RHSr); // c*c 5886122f3e6SDimitry Andric llvm::Value *Tmp5 = Builder.CreateFMul(RHSi, RHSi); // d*d 5896122f3e6SDimitry Andric llvm::Value *Tmp6 = Builder.CreateFAdd(Tmp4, Tmp5); // cc+dd 590f22ef01cSRoman Divacky 5916122f3e6SDimitry Andric llvm::Value *Tmp7 = Builder.CreateFMul(LHSi, RHSr); // b*c 5926122f3e6SDimitry Andric llvm::Value *Tmp8 = Builder.CreateFMul(LHSr, RHSi); // a*d 5936122f3e6SDimitry Andric llvm::Value *Tmp9 = Builder.CreateFSub(Tmp7, Tmp8); // bc-ad 594f22ef01cSRoman Divacky 5956122f3e6SDimitry Andric DSTr = Builder.CreateFDiv(Tmp3, Tmp6); 5966122f3e6SDimitry Andric DSTi = Builder.CreateFDiv(Tmp9, Tmp6); 597f22ef01cSRoman Divacky } else { 598f22ef01cSRoman Divacky // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) 5996122f3e6SDimitry Andric llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr); // a*c 6006122f3e6SDimitry Andric llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi); // b*d 6016122f3e6SDimitry Andric llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2); // ac+bd 602f22ef01cSRoman Divacky 6036122f3e6SDimitry Andric llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr); // c*c 6046122f3e6SDimitry Andric llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi); // d*d 6056122f3e6SDimitry Andric llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5); // cc+dd 606f22ef01cSRoman Divacky 6076122f3e6SDimitry Andric llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr); // b*c 6086122f3e6SDimitry Andric llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi); // a*d 6096122f3e6SDimitry Andric llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8); // bc-ad 610f22ef01cSRoman Divacky 611139f7f9bSDimitry Andric if (Op.Ty->castAs<ComplexType>()->getElementType()->isUnsignedIntegerType()) { 6126122f3e6SDimitry Andric DSTr = Builder.CreateUDiv(Tmp3, Tmp6); 6136122f3e6SDimitry Andric DSTi = Builder.CreateUDiv(Tmp9, Tmp6); 614f22ef01cSRoman Divacky } else { 6156122f3e6SDimitry Andric DSTr = Builder.CreateSDiv(Tmp3, Tmp6); 6166122f3e6SDimitry Andric DSTi = Builder.CreateSDiv(Tmp9, Tmp6); 617f22ef01cSRoman Divacky } 618f22ef01cSRoman Divacky } 619f22ef01cSRoman Divacky 620f22ef01cSRoman Divacky return ComplexPairTy(DSTr, DSTi); 621f22ef01cSRoman Divacky } 622f22ef01cSRoman Divacky 623f22ef01cSRoman Divacky ComplexExprEmitter::BinOpInfo 624f22ef01cSRoman Divacky ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) { 625f22ef01cSRoman Divacky TestAndClearIgnoreReal(); 626f22ef01cSRoman Divacky TestAndClearIgnoreImag(); 627f22ef01cSRoman Divacky BinOpInfo Ops; 628f22ef01cSRoman Divacky Ops.LHS = Visit(E->getLHS()); 629f22ef01cSRoman Divacky Ops.RHS = Visit(E->getRHS()); 630f22ef01cSRoman Divacky Ops.Ty = E->getType(); 631f22ef01cSRoman Divacky return Ops; 632f22ef01cSRoman Divacky } 633f22ef01cSRoman Divacky 634f22ef01cSRoman Divacky 6352754fe60SDimitry Andric LValue ComplexExprEmitter:: 6362754fe60SDimitry Andric EmitCompoundAssignLValue(const CompoundAssignOperator *E, 6372754fe60SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&), 638f785676fSDimitry Andric RValue &Val) { 639f22ef01cSRoman Divacky TestAndClearIgnoreReal(); 640f22ef01cSRoman Divacky TestAndClearIgnoreImag(); 6412754fe60SDimitry Andric QualType LHSTy = E->getLHS()->getType(); 642f22ef01cSRoman Divacky 643f22ef01cSRoman Divacky BinOpInfo OpInfo; 644f22ef01cSRoman Divacky 645f22ef01cSRoman Divacky // Load the RHS and LHS operands. 646f22ef01cSRoman Divacky // __block variables need to have the rhs evaluated first, plus this should 6472754fe60SDimitry Andric // improve codegen a little. 648f22ef01cSRoman Divacky OpInfo.Ty = E->getComputationResultType(); 6492754fe60SDimitry Andric 6502754fe60SDimitry Andric // The RHS should have been converted to the computation type. 6512754fe60SDimitry Andric assert(OpInfo.Ty->isAnyComplexType()); 6522754fe60SDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(OpInfo.Ty, 6532754fe60SDimitry Andric E->getRHS()->getType())); 6542754fe60SDimitry Andric OpInfo.RHS = Visit(E->getRHS()); 655f22ef01cSRoman Divacky 656ffd1746dSEd Schouten LValue LHS = CGF.EmitLValue(E->getLHS()); 6572754fe60SDimitry Andric 658f785676fSDimitry Andric // Load from the l-value and convert it. 659f785676fSDimitry Andric if (LHSTy->isAnyComplexType()) { 660f785676fSDimitry Andric ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, E->getExprLoc()); 661f785676fSDimitry Andric OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty); 662f785676fSDimitry Andric } else { 663f785676fSDimitry Andric llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, E->getExprLoc()); 664f785676fSDimitry Andric OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty); 665f785676fSDimitry Andric } 666f22ef01cSRoman Divacky 667f22ef01cSRoman Divacky // Expand the binary operator. 668f22ef01cSRoman Divacky ComplexPairTy Result = (this->*Func)(OpInfo); 669f22ef01cSRoman Divacky 670f785676fSDimitry Andric // Truncate the result and store it into the LHS lvalue. 671f785676fSDimitry Andric if (LHSTy->isAnyComplexType()) { 672f785676fSDimitry Andric ComplexPairTy ResVal = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy); 673f785676fSDimitry Andric EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false); 674f785676fSDimitry Andric Val = RValue::getComplex(ResVal); 675f785676fSDimitry Andric } else { 676f785676fSDimitry Andric llvm::Value *ResVal = 677f785676fSDimitry Andric CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy); 678f785676fSDimitry Andric CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false); 679f785676fSDimitry Andric Val = RValue::get(ResVal); 680f785676fSDimitry Andric } 681ffd1746dSEd Schouten 6822754fe60SDimitry Andric return LHS; 683f22ef01cSRoman Divacky } 684f22ef01cSRoman Divacky 6852754fe60SDimitry Andric // Compound assignments. 6862754fe60SDimitry Andric ComplexPairTy ComplexExprEmitter:: 6872754fe60SDimitry Andric EmitCompoundAssign(const CompoundAssignOperator *E, 6882754fe60SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){ 689f785676fSDimitry Andric RValue Val; 6902754fe60SDimitry Andric LValue LV = EmitCompoundAssignLValue(E, Func, Val); 6912754fe60SDimitry Andric 6922754fe60SDimitry Andric // The result of an assignment in C is the assigned r-value. 6933861d79fSDimitry Andric if (!CGF.getLangOpts().CPlusPlus) 694f785676fSDimitry Andric return Val.getComplexVal(); 6952754fe60SDimitry Andric 6962754fe60SDimitry Andric // If the lvalue is non-volatile, return the computed value of the assignment. 6972754fe60SDimitry Andric if (!LV.isVolatileQualified()) 698f785676fSDimitry Andric return Val.getComplexVal(); 6992754fe60SDimitry Andric 700f785676fSDimitry Andric return EmitLoadOfLValue(LV, E->getExprLoc()); 7012754fe60SDimitry Andric } 7022754fe60SDimitry Andric 7032754fe60SDimitry Andric LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E, 7042754fe60SDimitry Andric ComplexPairTy &Val) { 705ffd1746dSEd Schouten assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), 706ffd1746dSEd Schouten E->getRHS()->getType()) && 707f22ef01cSRoman Divacky "Invalid assignment"); 7082754fe60SDimitry Andric TestAndClearIgnoreReal(); 7092754fe60SDimitry Andric TestAndClearIgnoreImag(); 7102754fe60SDimitry Andric 7112754fe60SDimitry Andric // Emit the RHS. __block variables need the RHS evaluated first. 7122754fe60SDimitry Andric Val = Visit(E->getRHS()); 713f22ef01cSRoman Divacky 714f22ef01cSRoman Divacky // Compute the address to store into. 715f22ef01cSRoman Divacky LValue LHS = CGF.EmitLValue(E->getLHS()); 716f22ef01cSRoman Divacky 717ffd1746dSEd Schouten // Store the result value into the LHS lvalue. 718139f7f9bSDimitry Andric EmitStoreOfComplex(Val, LHS, /*isInit*/ false); 719f22ef01cSRoman Divacky 7202754fe60SDimitry Andric return LHS; 7212754fe60SDimitry Andric } 722ffd1746dSEd Schouten 7232754fe60SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) { 7242754fe60SDimitry Andric ComplexPairTy Val; 7252754fe60SDimitry Andric LValue LV = EmitBinAssignLValue(E, Val); 7262754fe60SDimitry Andric 7272754fe60SDimitry Andric // The result of an assignment in C is the assigned r-value. 7283861d79fSDimitry Andric if (!CGF.getLangOpts().CPlusPlus) 7292754fe60SDimitry Andric return Val; 7302754fe60SDimitry Andric 7312754fe60SDimitry Andric // If the lvalue is non-volatile, return the computed value of the assignment. 7322754fe60SDimitry Andric if (!LV.isVolatileQualified()) 7332754fe60SDimitry Andric return Val; 7342754fe60SDimitry Andric 735f785676fSDimitry Andric return EmitLoadOfLValue(LV, E->getExprLoc()); 736f22ef01cSRoman Divacky } 737f22ef01cSRoman Divacky 738f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { 7392754fe60SDimitry Andric CGF.EmitIgnoredExpr(E->getLHS()); 740f22ef01cSRoman Divacky return Visit(E->getRHS()); 741f22ef01cSRoman Divacky } 742f22ef01cSRoman Divacky 743f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter:: 7442754fe60SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { 745f22ef01cSRoman Divacky TestAndClearIgnoreReal(); 746f22ef01cSRoman Divacky TestAndClearIgnoreImag(); 747f22ef01cSRoman Divacky llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); 748f22ef01cSRoman Divacky llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); 749f22ef01cSRoman Divacky llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); 750f22ef01cSRoman Divacky 7512754fe60SDimitry Andric // Bind the common expression if necessary. 7522754fe60SDimitry Andric CodeGenFunction::OpaqueValueMapping binding(CGF, E); 7532754fe60SDimitry Andric 7542754fe60SDimitry Andric CodeGenFunction::ConditionalEvaluation eval(CGF); 755f22ef01cSRoman Divacky CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock); 756f22ef01cSRoman Divacky 7572754fe60SDimitry Andric eval.begin(CGF); 758f22ef01cSRoman Divacky CGF.EmitBlock(LHSBlock); 7592754fe60SDimitry Andric ComplexPairTy LHS = Visit(E->getTrueExpr()); 760f22ef01cSRoman Divacky LHSBlock = Builder.GetInsertBlock(); 761f22ef01cSRoman Divacky CGF.EmitBranch(ContBlock); 7622754fe60SDimitry Andric eval.end(CGF); 763f22ef01cSRoman Divacky 7642754fe60SDimitry Andric eval.begin(CGF); 765f22ef01cSRoman Divacky CGF.EmitBlock(RHSBlock); 7662754fe60SDimitry Andric ComplexPairTy RHS = Visit(E->getFalseExpr()); 767f22ef01cSRoman Divacky RHSBlock = Builder.GetInsertBlock(); 768f22ef01cSRoman Divacky CGF.EmitBlock(ContBlock); 7692754fe60SDimitry Andric eval.end(CGF); 770f22ef01cSRoman Divacky 771f22ef01cSRoman Divacky // Create a PHI node for the real part. 7723b0f4066SDimitry Andric llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.r"); 773f22ef01cSRoman Divacky RealPN->addIncoming(LHS.first, LHSBlock); 774f22ef01cSRoman Divacky RealPN->addIncoming(RHS.first, RHSBlock); 775f22ef01cSRoman Divacky 776f22ef01cSRoman Divacky // Create a PHI node for the imaginary part. 7773b0f4066SDimitry Andric llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.i"); 778f22ef01cSRoman Divacky ImagPN->addIncoming(LHS.second, LHSBlock); 779f22ef01cSRoman Divacky ImagPN->addIncoming(RHS.second, RHSBlock); 780f22ef01cSRoman Divacky 781f22ef01cSRoman Divacky return ComplexPairTy(RealPN, ImagPN); 782f22ef01cSRoman Divacky } 783f22ef01cSRoman Divacky 784f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) { 785f785676fSDimitry Andric return Visit(E->getChosenSubExpr()); 786f22ef01cSRoman Divacky } 787f22ef01cSRoman Divacky 788f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) { 789f22ef01cSRoman Divacky bool Ignore = TestAndClearIgnoreReal(); 790f22ef01cSRoman Divacky (void)Ignore; 791f22ef01cSRoman Divacky assert (Ignore == false && "init list ignored"); 792f22ef01cSRoman Divacky Ignore = TestAndClearIgnoreImag(); 793f22ef01cSRoman Divacky (void)Ignore; 794f22ef01cSRoman Divacky assert (Ignore == false && "init list ignored"); 7956122f3e6SDimitry Andric 7966122f3e6SDimitry Andric if (E->getNumInits() == 2) { 7976122f3e6SDimitry Andric llvm::Value *Real = CGF.EmitScalarExpr(E->getInit(0)); 7986122f3e6SDimitry Andric llvm::Value *Imag = CGF.EmitScalarExpr(E->getInit(1)); 7996122f3e6SDimitry Andric return ComplexPairTy(Real, Imag); 8006122f3e6SDimitry Andric } else if (E->getNumInits() == 1) { 801f22ef01cSRoman Divacky return Visit(E->getInit(0)); 8026122f3e6SDimitry Andric } 803f22ef01cSRoman Divacky 804f22ef01cSRoman Divacky // Empty init list intializes to null 8056122f3e6SDimitry Andric assert(E->getNumInits() == 0 && "Unexpected number of inits"); 806139f7f9bSDimitry Andric QualType Ty = E->getType()->castAs<ComplexType>()->getElementType(); 8076122f3e6SDimitry Andric llvm::Type* LTy = CGF.ConvertType(Ty); 808f22ef01cSRoman Divacky llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy); 809f22ef01cSRoman Divacky return ComplexPairTy(zeroConstant, zeroConstant); 810f22ef01cSRoman Divacky } 811f22ef01cSRoman Divacky 812f22ef01cSRoman Divacky ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) { 813f22ef01cSRoman Divacky llvm::Value *ArgValue = CGF.EmitVAListRef(E->getSubExpr()); 814f22ef01cSRoman Divacky llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, E->getType()); 815f22ef01cSRoman Divacky 816f22ef01cSRoman Divacky if (!ArgPtr) { 817f22ef01cSRoman Divacky CGF.ErrorUnsupported(E, "complex va_arg expression"); 8186122f3e6SDimitry Andric llvm::Type *EltTy = 819139f7f9bSDimitry Andric CGF.ConvertType(E->getType()->castAs<ComplexType>()->getElementType()); 820f22ef01cSRoman Divacky llvm::Value *U = llvm::UndefValue::get(EltTy); 821f22ef01cSRoman Divacky return ComplexPairTy(U, U); 822f22ef01cSRoman Divacky } 823f22ef01cSRoman Divacky 824f785676fSDimitry Andric return EmitLoadOfLValue(CGF.MakeNaturalAlignAddrLValue(ArgPtr, E->getType()), 825f785676fSDimitry Andric E->getExprLoc()); 826f22ef01cSRoman Divacky } 827f22ef01cSRoman Divacky 828f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 829f22ef01cSRoman Divacky // Entry Point into this File 830f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 831f22ef01cSRoman Divacky 832f22ef01cSRoman Divacky /// EmitComplexExpr - Emit the computation of the specified expression of 833f22ef01cSRoman Divacky /// complex type, ignoring the result. 834f22ef01cSRoman Divacky ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal, 8352754fe60SDimitry Andric bool IgnoreImag) { 836139f7f9bSDimitry Andric assert(E && getComplexType(E->getType()) && 837f22ef01cSRoman Divacky "Invalid complex expression to emit"); 838f22ef01cSRoman Divacky 8392754fe60SDimitry Andric return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag) 840f22ef01cSRoman Divacky .Visit(const_cast<Expr*>(E)); 841f22ef01cSRoman Divacky } 842f22ef01cSRoman Divacky 843139f7f9bSDimitry Andric void CodeGenFunction::EmitComplexExprIntoLValue(const Expr *E, LValue dest, 844139f7f9bSDimitry Andric bool isInit) { 845139f7f9bSDimitry Andric assert(E && getComplexType(E->getType()) && 846f22ef01cSRoman Divacky "Invalid complex expression to emit"); 847f22ef01cSRoman Divacky ComplexExprEmitter Emitter(*this); 848f22ef01cSRoman Divacky ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E)); 849139f7f9bSDimitry Andric Emitter.EmitStoreOfComplex(Val, dest, isInit); 850f22ef01cSRoman Divacky } 851f22ef01cSRoman Divacky 852139f7f9bSDimitry Andric /// EmitStoreOfComplex - Store a complex number into the specified l-value. 853139f7f9bSDimitry Andric void CodeGenFunction::EmitStoreOfComplex(ComplexPairTy V, LValue dest, 854139f7f9bSDimitry Andric bool isInit) { 855139f7f9bSDimitry Andric ComplexExprEmitter(*this).EmitStoreOfComplex(V, dest, isInit); 856f22ef01cSRoman Divacky } 857f22ef01cSRoman Divacky 858139f7f9bSDimitry Andric /// EmitLoadOfComplex - Load a complex number from the specified address. 859f785676fSDimitry Andric ComplexPairTy CodeGenFunction::EmitLoadOfComplex(LValue src, 860f785676fSDimitry Andric SourceLocation loc) { 861f785676fSDimitry Andric return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc); 862f22ef01cSRoman Divacky } 8632754fe60SDimitry Andric 8642754fe60SDimitry Andric LValue CodeGenFunction::EmitComplexAssignmentLValue(const BinaryOperator *E) { 8652754fe60SDimitry Andric assert(E->getOpcode() == BO_Assign); 8662754fe60SDimitry Andric ComplexPairTy Val; // ignored 8672754fe60SDimitry Andric return ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val); 8682754fe60SDimitry Andric } 8692754fe60SDimitry Andric 870f785676fSDimitry Andric typedef ComplexPairTy (ComplexExprEmitter::*CompoundFunc)( 871f785676fSDimitry Andric const ComplexExprEmitter::BinOpInfo &); 8722754fe60SDimitry Andric 873f785676fSDimitry Andric static CompoundFunc getComplexOp(BinaryOperatorKind Op) { 874f785676fSDimitry Andric switch (Op) { 875f785676fSDimitry Andric case BO_MulAssign: return &ComplexExprEmitter::EmitBinMul; 876f785676fSDimitry Andric case BO_DivAssign: return &ComplexExprEmitter::EmitBinDiv; 877f785676fSDimitry Andric case BO_SubAssign: return &ComplexExprEmitter::EmitBinSub; 878f785676fSDimitry Andric case BO_AddAssign: return &ComplexExprEmitter::EmitBinAdd; 8792754fe60SDimitry Andric default: 8802754fe60SDimitry Andric llvm_unreachable("unexpected complex compound assignment"); 8812754fe60SDimitry Andric } 882f785676fSDimitry Andric } 8832754fe60SDimitry Andric 884f785676fSDimitry Andric LValue CodeGenFunction:: 885f785676fSDimitry Andric EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) { 886f785676fSDimitry Andric CompoundFunc Op = getComplexOp(E->getOpcode()); 887f785676fSDimitry Andric RValue Val; 8882754fe60SDimitry Andric return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val); 8892754fe60SDimitry Andric } 890f785676fSDimitry Andric 891f785676fSDimitry Andric LValue CodeGenFunction:: 892f785676fSDimitry Andric EmitScalarCompooundAssignWithComplex(const CompoundAssignOperator *E, 893f785676fSDimitry Andric llvm::Value *&Result) { 894f785676fSDimitry Andric CompoundFunc Op = getComplexOp(E->getOpcode()); 895f785676fSDimitry Andric RValue Val; 896f785676fSDimitry Andric LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val); 897f785676fSDimitry Andric Result = Val.getScalarVal(); 898f785676fSDimitry Andric return Ret; 899f785676fSDimitry Andric } 900