CGExprComplex.cpp revision 154440e6a8fa6ac5bca395876d79b530b39a2c1c
19f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner//===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===// 29f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner// 39f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner// The LLVM Compiler Infrastructure 49f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner// 59f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner// This file is distributed under the University of Illinois Open Source 69f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner// License. See LICENSE.TXT for details. 79f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner// 89f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner//===----------------------------------------------------------------------===// 99f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner// 109f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner// This contains code to emit Expr nodes with complex types as LLVM code. 114cd2ad15b43f21d641330b4b09961af08646445eDuncan Sands// 124cd2ad15b43f21d641330b4b09961af08646445eDuncan Sands//===----------------------------------------------------------------------===// 134cd2ad15b43f21d641330b4b09961af08646445eDuncan Sands 14ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands#include "CodeGenFunction.h" 15ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands#include "CodeGenModule.h" 16ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands#include "clang/AST/ASTContext.h" 179f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner#include "clang/AST/StmtVisitor.h" 189f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner#include "llvm/Constants.h" 199f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattner#include "llvm/Function.h" 20a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands#include "llvm/ADT/SmallString.h" 21a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands#include "llvm/Support/Compiler.h" 229f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattnerusing namespace clang; 239f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattnerusing namespace CodeGen; 241845009290e4d804ad377927bd8a08cca3036adcDuncan Sands 25d70d1a5c44609af091f6fc3e29193f9f4756a74fDuncan Sands//===----------------------------------------------------------------------===// 26d06094f0682f2ede03caff4892b1a57469896d48Chris Lattner// Complex Expression Emitter 271845009290e4d804ad377927bd8a08cca3036adcDuncan Sands//===----------------------------------------------------------------------===// 28e60d79faf7ef7bc4847f9e5d067af00b98dced7bDuncan Sands 299f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattnertypedef CodeGenFunction::ComplexPairTy ComplexPairTy; 30d06094f0682f2ede03caff4892b1a57469896d48Chris Lattner 319f3c25aeb3df77a336693308dc0f19a4983c99afChris Lattnernamespace { 32124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sandsclass VISIBILITY_HIDDEN ComplexExprEmitter 33a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> { 34a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands CodeGenFunction &CGF; 35a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands CGBuilderTy &Builder; 36a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands // True is we should ignore the value of a 37a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands bool IgnoreReal; 3882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands bool IgnoreImag; 3982fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands // True if we should ignore the value of a=b 40a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands bool IgnoreRealAssign; 411845009290e4d804ad377927bd8a08cca3036adcDuncan Sands bool IgnoreImagAssign; 42a74a58c83be492b7d5b7383656f049909394cff4Duncan Sandspublic: 431845009290e4d804ad377927bd8a08cca3036adcDuncan Sands ComplexExprEmitter(CodeGenFunction &cgf, bool ir=false, bool ii=false, 4482fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands bool irn=false, bool iin=false) 4582fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii), 4682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands IgnoreRealAssign(irn), IgnoreImagAssign(iin) { 4782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands } 481845009290e4d804ad377927bd8a08cca3036adcDuncan Sands 491845009290e4d804ad377927bd8a08cca3036adcDuncan Sands 501845009290e4d804ad377927bd8a08cca3036adcDuncan Sands //===--------------------------------------------------------------------===// 511845009290e4d804ad377927bd8a08cca3036adcDuncan Sands // Utilities 521845009290e4d804ad377927bd8a08cca3036adcDuncan Sands //===--------------------------------------------------------------------===// 531845009290e4d804ad377927bd8a08cca3036adcDuncan Sands 541845009290e4d804ad377927bd8a08cca3036adcDuncan Sands bool TestAndClearIgnoreReal() { 551845009290e4d804ad377927bd8a08cca3036adcDuncan Sands bool I = IgnoreReal; 561845009290e4d804ad377927bd8a08cca3036adcDuncan Sands IgnoreReal = false; 571845009290e4d804ad377927bd8a08cca3036adcDuncan Sands return I; 581845009290e4d804ad377927bd8a08cca3036adcDuncan Sands } 591845009290e4d804ad377927bd8a08cca3036adcDuncan Sands bool TestAndClearIgnoreImag() { 601845009290e4d804ad377927bd8a08cca3036adcDuncan Sands bool I = IgnoreImag; 611845009290e4d804ad377927bd8a08cca3036adcDuncan Sands IgnoreImag = false; 621845009290e4d804ad377927bd8a08cca3036adcDuncan Sands return I; 631845009290e4d804ad377927bd8a08cca3036adcDuncan Sands } 641845009290e4d804ad377927bd8a08cca3036adcDuncan Sands bool TestAndClearIgnoreRealAssign() { 651845009290e4d804ad377927bd8a08cca3036adcDuncan Sands bool I = IgnoreRealAssign; 661845009290e4d804ad377927bd8a08cca3036adcDuncan Sands IgnoreRealAssign = false; 671845009290e4d804ad377927bd8a08cca3036adcDuncan Sands return I; 68a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands } 693421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands bool TestAndClearIgnoreImagAssign() { 703421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands bool I = IgnoreImagAssign; 713421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands IgnoreImagAssign = false; 723421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return I; 733421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands } 743421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 75e21083aa3a79506f896d95d7147c3c4627a77ef0Benjamin Kramer /// EmitLoadOfLValue - Given an expression with complex type that represents a 763421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands /// value l-value, this method emits the address of the l-value, then loads 77e21083aa3a79506f896d95d7147c3c4627a77ef0Benjamin Kramer /// and returns the result. 783421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy EmitLoadOfLValue(const Expr *E) { 793421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands LValue LV = CGF.EmitLValue(E); 803421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands if (LV.isSimple()) 813421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified()); 823421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 833421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands if (LV.isPropertyRef()) 843421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return CGF.EmitObjCPropertyGet(LV.getPropertyRefExpr()).getComplexVal(); 853421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 863421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands assert(LV.isKVCRef() && "Unknown LValue type!"); 873421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return CGF.EmitObjCPropertyGet(LV.getKVCRefExpr()).getComplexVal(); 883421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands } 893421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 903421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load 913421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands /// the real and imaginary pieces. 92124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr, bool isVolatile); 93124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands 94a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands /// EmitStoreOfComplex - Store the specified real/imag parts into the 953421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands /// specified value pointer. 96a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol); 973421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 98a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType. 99a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType, 100a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands QualType DestType); 1013421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 102a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands //===--------------------------------------------------------------------===// 1033421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands // Visitor Methods 1043421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands //===--------------------------------------------------------------------===// 1053421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 1063421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitStmt(Stmt *S) { 1073421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands S->dump(CGF.getContext().getSourceManager()); 1083421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands assert(0 && "Stmt can't have complex result type!"); 1093421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return ComplexPairTy(); 1103421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands } 1113421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitExpr(Expr *S); 1123421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());} 1133421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL); 1143421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 1153421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands // l-values. 116124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands ComplexPairTy VisitDeclRefExpr(const Expr *E) { return EmitLoadOfLValue(E); } 117124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 118a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands return EmitLoadOfLValue(E); 1193421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands } 120a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands ComplexPairTy VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { 1213421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return EmitLoadOfLValue(E); 122a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands } 123a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands ComplexPairTy VisitObjCImplctSetterGetterRefExpr( 124a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands ObjCImplctSetterGetterRefExpr *E) { 1253421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return EmitLoadOfLValue(E); 126a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands } 1273421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) { 1283421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return CGF.EmitObjCMessageExpr(E).getComplexVal(); 1293421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands } 1303421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); } 1313421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); } 1323421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 1333421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands // FIXME: CompoundLiteralExpr 1343421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 1353421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy EmitCast(Expr *Op, QualType DestTy); 1363421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) { 1373421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands // Unlike for scalars, we don't have to worry about function->ptr demotion 138e21083aa3a79506f896d95d7147c3c4627a77ef0Benjamin Kramer // here. 1393421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return EmitCast(E->getSubExpr(), E->getType()); 140e21083aa3a79506f896d95d7147c3c4627a77ef0Benjamin Kramer } 1413421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitCastExpr(CastExpr *E) { 1423421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return EmitCast(E->getSubExpr(), E->getType()); 1433421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands } 1443421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitCallExpr(const CallExpr *E); 1453421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitStmtExpr(const StmtExpr *E); 1463421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 1473421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands // Operators. 1483421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E, 1493421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands bool isInc, bool isPre); 1503421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) { 1513421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return VisitPrePostIncDec(E, false, false); 1523421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands } 15382fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) { 15482fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands return VisitPrePostIncDec(E, true, false); 1553421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands } 1563421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) { 1573421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return VisitPrePostIncDec(E, false, true); 1583421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands } 159124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) { 160124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands return VisitPrePostIncDec(E, true, true); 1613421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands } 1623421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); } 1633421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitUnaryPlus (const UnaryOperator *E) { 1643421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands TestAndClearIgnoreReal(); 1651cd05bb605e3c3eee9197d3f10b628c60d0cc07aDuncan Sands TestAndClearIgnoreImag(); 1661cd05bb605e3c3eee9197d3f10b628c60d0cc07aDuncan Sands TestAndClearIgnoreRealAssign(); 167124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands TestAndClearIgnoreImagAssign(); 168a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands return Visit(E->getSubExpr()); 169124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands } 170a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands ComplexPairTy VisitUnaryMinus (const UnaryOperator *E); 1713421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitUnaryNot (const UnaryOperator *E); 172a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands // LNot,Real,Imag never return complex. 173a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) { 1743421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return Visit(E->getSubExpr()); 175a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands } 1763421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) { 1773421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return Visit(DAE->getExpr()); 1783421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands } 1793421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) { 1803421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return CGF.EmitCXXExprWithTemporaries(E).getComplexVal(); 1813421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands } 182124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands ComplexPairTy VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) { 183124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands assert(E->getType()->isAnyComplexType() && "Expected complex type!"); 1843421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands QualType Elem = E->getType()->getAsComplexType()->getElementType(); 1853421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands llvm::Constant *Null = 1863421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands llvm::Constant::getNullValue(CGF.ConvertType(Elem)); 1873421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return ComplexPairTy(Null, Null); 1881cd05bb605e3c3eee9197d3f10b628c60d0cc07aDuncan Sands } 1891cd05bb605e3c3eee9197d3f10b628c60d0cc07aDuncan Sands ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { 190124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands assert(E->getType()->isAnyComplexType() && "Expected complex type!"); 191a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands QualType Elem = E->getType()->getAsComplexType()->getElementType(); 192124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands llvm::Constant *Null = 193a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands llvm::Constant::getNullValue(CGF.ConvertType(Elem)); 1943421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return ComplexPairTy(Null, Null); 195a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands } 196a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands 1973421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands struct BinOpInfo { 198a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands ComplexPairTy LHS; 1993421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy RHS; 2003421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands QualType Ty; // Computation Type. 2013421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands }; 2023421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 2033421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands BinOpInfo EmitBinOps(const BinaryOperator *E); 2043421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E, 2053421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy (ComplexExprEmitter::*Func) 2063421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands (const BinOpInfo &)); 207e21083aa3a79506f896d95d7147c3c4627a77ef0Benjamin Kramer 208566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands ComplexPairTy EmitBinAdd(const BinOpInfo &Op); 209566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands ComplexPairTy EmitBinSub(const BinOpInfo &Op); 210566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands ComplexPairTy EmitBinMul(const BinOpInfo &Op); 211e21083aa3a79506f896d95d7147c3c4627a77ef0Benjamin Kramer ComplexPairTy EmitBinDiv(const BinOpInfo &Op); 212566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 213566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands ComplexPairTy VisitBinMul(const BinaryOperator *E) { 214566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands return EmitBinMul(EmitBinOps(E)); 215566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands } 216566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands ComplexPairTy VisitBinAdd(const BinaryOperator *E) { 217566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands return EmitBinAdd(EmitBinOps(E)); 218566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands } 219566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands ComplexPairTy VisitBinSub(const BinaryOperator *E) { 220566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands return EmitBinSub(EmitBinOps(E)); 221566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands } 222566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands ComplexPairTy VisitBinDiv(const BinaryOperator *E) { 223566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands return EmitBinDiv(EmitBinOps(E)); 224566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands } 225566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 226566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands // Compound assignments. 227566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) { 228566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd); 229566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands } 230566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) { 231124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub); 232566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands } 233a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) { 234a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul); 235566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands } 236a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) { 237566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv); 238566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands } 239566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 240566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands // GCC rejects rem/and/or/xor for integer complex. 241566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands // Logical and/or always return int, never complex. 242566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 243566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands // No comparisons produce a complex result. 244566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands ComplexPairTy VisitBinAssign (const BinaryOperator *E); 245566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands ComplexPairTy VisitBinComma (const BinaryOperator *E); 246566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 247566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 248566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands ComplexPairTy VisitConditionalOperator(const ConditionalOperator *CO); 249566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands ComplexPairTy VisitChooseExpr(ChooseExpr *CE); 250124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands 251566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands ComplexPairTy VisitInitListExpr(InitListExpr *E); 252a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands 253a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands ComplexPairTy VisitVAArgExpr(VAArgExpr *E); 254566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands}; 255a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands} // end anonymous namespace. 256566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 257566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands//===----------------------------------------------------------------------===// 258566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands// Utilities 259566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands//===----------------------------------------------------------------------===// 260566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 261566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands/// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to 262566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands/// load the real and imaginary pieces, returning them as Real/Imag. 263566edb04b890cebca8f2eefa37af7371a1e756c9Duncan SandsComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr, 264566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands bool isVolatile) { 265566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands llvm::SmallString<64> Name(SrcPtr->getName().begin(), 266566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands SrcPtr->getName().end()); 267566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 268566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands llvm::Value *Real=0, *Imag=0; 269566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 270566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands if (!IgnoreReal) { 271566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands Name += ".realp"; 272566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands llvm::Value *RealPtr = Builder.CreateStructGEP(SrcPtr, 0, Name.c_str()); 273124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands 274566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands Name.pop_back(); // .realp -> .real 275a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands Real = Builder.CreateLoad(RealPtr, isVolatile, Name.c_str()); 276a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands Name.resize(Name.size()-4); // .real -> .imagp 277566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands } 278a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands 279566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands if (!IgnoreImag) { 280566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands Name += "imagp"; 281566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 282566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands llvm::Value *ImagPtr = Builder.CreateStructGEP(SrcPtr, 1, Name.c_str()); 283566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 284566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands Name.pop_back(); // .imagp -> .imag 285566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands Imag = Builder.CreateLoad(ImagPtr, isVolatile, Name.c_str()); 286566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands } 287566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands return ComplexPairTy(Real, Imag); 288566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands} 289566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 290566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands/// EmitStoreOfComplex - Store the specified real/imag parts into the 291566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands/// specified value pointer. 292124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sandsvoid ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr, 293566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands bool isVolatile) { 294a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands llvm::Value *RealPtr = Builder.CreateStructGEP(Ptr, 0, "real"); 295a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands llvm::Value *ImagPtr = Builder.CreateStructGEP(Ptr, 1, "imag"); 296566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 297a3c44a5280042dbc0cde995675c225ede4528c6eDuncan Sands Builder.CreateStore(Val.first, RealPtr, isVolatile); 298566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands Builder.CreateStore(Val.second, ImagPtr, isVolatile); 299566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands} 300566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 301566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 302566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands 303566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands//===----------------------------------------------------------------------===// 304b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands// Visitor Methods 305b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands//===----------------------------------------------------------------------===// 306b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 307b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan SandsComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) { 308b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands CGF.ErrorUnsupported(E, "complex expression"); 3091845009290e4d804ad377927bd8a08cca3036adcDuncan Sands const llvm::Type *EltTy = 3101845009290e4d804ad377927bd8a08cca3036adcDuncan Sands CGF.ConvertType(E->getType()->getAsComplexType()->getElementType()); 3111845009290e4d804ad377927bd8a08cca3036adcDuncan Sands llvm::Value *U = llvm::UndefValue::get(EltTy); 3120312a93693abc2eb682b2b101c889959888fd883Duncan Sands return ComplexPairTy(U, U); 3130312a93693abc2eb682b2b101c889959888fd883Duncan Sands} 3140312a93693abc2eb682b2b101c889959888fd883Duncan Sands 3150312a93693abc2eb682b2b101c889959888fd883Duncan SandsComplexPairTy ComplexExprEmitter:: 316b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan SandsVisitImaginaryLiteral(const ImaginaryLiteral *IL) { 317b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr()); 318b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands return 319b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag); 320b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands} 321b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 322b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 323b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan SandsComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) { 324b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands if (E->getCallReturnType()->isReferenceType()) 325b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands return EmitLoadOfLValue(E); 326b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 327b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands return CGF.EmitCallExpr(E).getComplexVal(); 3281845009290e4d804ad377927bd8a08cca3036adcDuncan Sands} 3291845009290e4d804ad377927bd8a08cca3036adcDuncan Sands 330b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan SandsComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) { 3311845009290e4d804ad377927bd8a08cca3036adcDuncan Sands return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getComplexVal(); 3321845009290e4d804ad377927bd8a08cca3036adcDuncan Sands} 333b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 334b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands/// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType. 3357cf85e74e3885005ca8e5fdb155fa5351e255b85Duncan SandsComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val, 336124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands QualType SrcType, 337124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands QualType DestType) { 338b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands // Get the src/dest element type. 339b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands SrcType = SrcType->getAsComplexType()->getElementType(); 340b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands DestType = DestType->getAsComplexType()->getElementType(); 341b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 342b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands // C99 6.3.1.6: When a value of complex type is converted to another 343b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands // complex type, both the real and imaginary parts follow the conversion 344b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands // rules for the corresponding real types. 345b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType); 346b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType); 347b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands return Val; 348124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands} 349b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 350b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan SandsComplexPairTy ComplexExprEmitter::EmitCast(Expr *Op, QualType DestTy) { 351b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands // Two cases here: cast from (complex to complex) and (scalar to complex). 352b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands if (Op->getType()->isAnyComplexType()) 353b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy); 354b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 355b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands // C99 6.3.1.7: When a value of real type is converted to a complex type, the 356b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands // real part of the complex result value is determined by the rules of 357b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands // conversion to the corresponding real type and the imaginary part of the 358b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands // complex result value is a positive zero or an unsigned zero. 359b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands llvm::Value *Elt = CGF.EmitScalarExpr(Op); 360b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 361b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands // Convert the input element to the element type of the complex. 362b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands DestTy = DestTy->getAsComplexType()->getElementType(); 363b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy); 364b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 365124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands // Return (realval, 0). 366124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType())); 367b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands} 368b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 369124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan SandsComplexPairTy ComplexExprEmitter::VisitPrePostIncDec(const UnaryOperator *E, 370124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands bool isInc, bool isPre) { 371b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands LValue LV = CGF.EmitLValue(E->getSubExpr()); 372b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands ComplexPairTy InVal = EmitLoadOfComplex(LV.getAddress(), 373b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands LV.isVolatileQualified()); 374b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 375b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands llvm::Value *NextVal; 376b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands if (isa<llvm::IntegerType>(InVal.first->getType())) { 377b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands uint64_t AmountVal = isInc ? 1 : -1; 378b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal, true); 379b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 380b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands // Add the inc/dec to the real part. 381b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands NextVal = Builder.CreateAdd(InVal.first, NextVal, isInc ? "inc" : "dec"); 382b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands } else { 383a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands QualType ElemTy = E->getType()->getAsComplexType()->getElementType(); 3841845009290e4d804ad377927bd8a08cca3036adcDuncan Sands llvm::APFloat FVal(CGF.getContext().getFloatTypeSemantics(ElemTy), 1); 385a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands if (!isInc) 3860312a93693abc2eb682b2b101c889959888fd883Duncan Sands FVal.changeSign(); 3870312a93693abc2eb682b2b101c889959888fd883Duncan Sands NextVal = llvm::ConstantFP::get(CGF.getLLVMContext(), FVal); 3880312a93693abc2eb682b2b101c889959888fd883Duncan Sands 3890312a93693abc2eb682b2b101c889959888fd883Duncan Sands // Add the inc/dec to the real part. 390b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands NextVal = Builder.CreateFAdd(InVal.first, NextVal, isInc ? "inc" : "dec"); 391b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands } 392b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 393b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands ComplexPairTy IncVal(NextVal, InVal.second); 394b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 395b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands // Store the updated result through the lvalue. 396b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands EmitStoreOfComplex(IncVal, LV.getAddress(), LV.isVolatileQualified()); 397b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 398b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands // If this is a postinc, return the value read from memory, otherwise use the 399b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands // updated value. 4001845009290e4d804ad377927bd8a08cca3036adcDuncan Sands return isPre ? IncVal : InVal; 401a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands} 402b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 4031845009290e4d804ad377927bd8a08cca3036adcDuncan SandsComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { 404a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands TestAndClearIgnoreReal(); 405b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands TestAndClearIgnoreImag(); 406b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands TestAndClearIgnoreRealAssign(); 407124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands TestAndClearIgnoreImagAssign(); 408b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands ComplexPairTy Op = Visit(E->getSubExpr()); 409b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands 410b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands llvm::Value *ResR, *ResI; 411b2cbdc35ba85c04df15b0e991d9be371691ab08cDuncan Sands if (Op.first->getType()->isFloatingPoint()) { 412a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands ResR = Builder.CreateFNeg(Op.first, "neg.r"); 413a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands ResI = Builder.CreateFNeg(Op.second, "neg.i"); 414a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands } else { 415a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands ResR = Builder.CreateNeg(Op.first, "neg.r"); 416a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands ResI = Builder.CreateNeg(Op.second, "neg.i"); 4171845009290e4d804ad377927bd8a08cca3036adcDuncan Sands } 4181845009290e4d804ad377927bd8a08cca3036adcDuncan Sands return ComplexPairTy(ResR, ResI); 4190312a93693abc2eb682b2b101c889959888fd883Duncan Sands} 4200312a93693abc2eb682b2b101c889959888fd883Duncan Sands 4210312a93693abc2eb682b2b101c889959888fd883Duncan SandsComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) { 4220312a93693abc2eb682b2b101c889959888fd883Duncan Sands TestAndClearIgnoreReal(); 423a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands TestAndClearIgnoreImag(); 424a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands TestAndClearIgnoreRealAssign(); 425a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands TestAndClearIgnoreImagAssign(); 4261845009290e4d804ad377927bd8a08cca3036adcDuncan Sands // ~(a+ib) = a + i*-b 4271845009290e4d804ad377927bd8a08cca3036adcDuncan Sands ComplexPairTy Op = Visit(E->getSubExpr()); 4281845009290e4d804ad377927bd8a08cca3036adcDuncan Sands llvm::Value *ResI; 429a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands if (Op.second->getType()->isFloatingPoint()) 430a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands ResI = Builder.CreateFNeg(Op.second, "conj.i"); 431a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands else 4321845009290e4d804ad377927bd8a08cca3036adcDuncan Sands ResI = Builder.CreateNeg(Op.second, "conj.i"); 4331845009290e4d804ad377927bd8a08cca3036adcDuncan Sands 4341845009290e4d804ad377927bd8a08cca3036adcDuncan Sands return ComplexPairTy(Op.first, ResI); 435a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands} 436a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands 437a74a58c83be492b7d5b7383656f049909394cff4Duncan SandsComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) { 438a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands llvm::Value *ResR, *ResI; 439a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands 440552008946530e01efdad15044e1f621883d14a3aDuncan Sands if (Op.LHS.first->getType()->isFloatingPoint()) { 441ff10341183adf74760e6118a55cbd1debf50f90fDuncan Sands ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first, "add.r"); 442552008946530e01efdad15044e1f621883d14a3aDuncan Sands ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i"); 443a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands } else { 4441845009290e4d804ad377927bd8a08cca3036adcDuncan Sands ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r"); 4451845009290e4d804ad377927bd8a08cca3036adcDuncan Sands ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i"); 446a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands } 447a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands return ComplexPairTy(ResR, ResI); 448a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands} 449a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands 450a74a58c83be492b7d5b7383656f049909394cff4Duncan SandsComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) { 451a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands llvm::Value *ResR, *ResI; 452a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands if (Op.LHS.first->getType()->isFloatingPoint()) { 453a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first, "sub.r"); 454a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i"); 455a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands } else { 456a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r"); 457a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i"); 458a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands } 459a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands return ComplexPairTy(ResR, ResI); 460a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands} 4611845009290e4d804ad377927bd8a08cca3036adcDuncan Sands 4621845009290e4d804ad377927bd8a08cca3036adcDuncan Sands 4630312a93693abc2eb682b2b101c889959888fd883Duncan SandsComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) { 4640312a93693abc2eb682b2b101c889959888fd883Duncan Sands using llvm::Value; 4650312a93693abc2eb682b2b101c889959888fd883Duncan Sands Value *ResR, *ResI; 4660312a93693abc2eb682b2b101c889959888fd883Duncan Sands 467a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands if (Op.LHS.first->getType()->isFloatingPoint()) { 468a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands Value *ResRl = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl"); 469a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands Value *ResRr = Builder.CreateFMul(Op.LHS.second, Op.RHS.second,"mul.rr"); 470a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands ResR = Builder.CreateFSub(ResRl, ResRr, "mul.r"); 471a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands 472a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands Value *ResIl = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il"); 473a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands Value *ResIr = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir"); 474a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands ResI = Builder.CreateFAdd(ResIl, ResIr, "mul.i"); 4751845009290e4d804ad377927bd8a08cca3036adcDuncan Sands } else { 4761845009290e4d804ad377927bd8a08cca3036adcDuncan Sands Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl"); 4771845009290e4d804ad377927bd8a08cca3036adcDuncan Sands Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,"mul.rr"); 4781845009290e4d804ad377927bd8a08cca3036adcDuncan Sands ResR = Builder.CreateSub(ResRl, ResRr, "mul.r"); 479a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands 480a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il"); 481a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir"); 482552008946530e01efdad15044e1f621883d14a3aDuncan Sands ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i"); 483ff10341183adf74760e6118a55cbd1debf50f90fDuncan Sands } 484552008946530e01efdad15044e1f621883d14a3aDuncan Sands return ComplexPairTy(ResR, ResI); 4851845009290e4d804ad377927bd8a08cca3036adcDuncan Sands} 486a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands 487a74a58c83be492b7d5b7383656f049909394cff4Duncan SandsComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { 488a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second; 489a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second; 490a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands 491a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands 492a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands llvm::Value *DSTr, *DSTi; 493a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands if (Op.LHS.first->getType()->isFloatingPoint()) { 494a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) 495a74a58c83be492b7d5b7383656f049909394cff4Duncan Sands llvm::Value *Tmp1 = Builder.CreateFMul(LHSr, RHSr, "tmp"); // a*c 4968aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner llvm::Value *Tmp2 = Builder.CreateFMul(LHSi, RHSi, "tmp"); // b*d 497d06094f0682f2ede03caff4892b1a57469896d48Chris Lattner llvm::Value *Tmp3 = Builder.CreateFAdd(Tmp1, Tmp2, "tmp"); // ac+bd 498ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands 499ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands llvm::Value *Tmp4 = Builder.CreateFMul(RHSr, RHSr, "tmp"); // c*c 500ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands llvm::Value *Tmp5 = Builder.CreateFMul(RHSi, RHSi, "tmp"); // d*d 501d06094f0682f2ede03caff4892b1a57469896d48Chris Lattner llvm::Value *Tmp6 = Builder.CreateFAdd(Tmp4, Tmp5, "tmp"); // cc+dd 502d06094f0682f2ede03caff4892b1a57469896d48Chris Lattner 503d06094f0682f2ede03caff4892b1a57469896d48Chris Lattner llvm::Value *Tmp7 = Builder.CreateFMul(LHSi, RHSr, "tmp"); // b*c 5048aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner llvm::Value *Tmp8 = Builder.CreateFMul(LHSr, RHSi, "tmp"); // a*d 5058aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner llvm::Value *Tmp9 = Builder.CreateFSub(Tmp7, Tmp8, "tmp"); // bc-ad 5068aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner 50712a86f5b3199e72e6d967781acc76340f5920e46Duncan Sands DSTr = Builder.CreateFDiv(Tmp3, Tmp6, "tmp"); 5088aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner DSTi = Builder.CreateFDiv(Tmp9, Tmp6, "tmp"); 5098aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner } else { 5108aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) 51112a86f5b3199e72e6d967781acc76340f5920e46Duncan Sands llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr, "tmp"); // a*c 512fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi, "tmp"); // b*d 513fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2, "tmp"); // ac+bd 514fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands 51512a86f5b3199e72e6d967781acc76340f5920e46Duncan Sands llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr, "tmp"); // c*c 516fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi, "tmp"); // d*d 517fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5, "tmp"); // cc+dd 518fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands 519fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr, "tmp"); // b*c 520fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi, "tmp"); // a*d 521fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8, "tmp"); // bc-ad 522ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands 523124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands if (Op.Ty->getAsComplexType()->getElementType()->isUnsignedIntegerType()) { 524124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands DSTr = Builder.CreateUDiv(Tmp3, Tmp6, "tmp"); 525124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands DSTi = Builder.CreateUDiv(Tmp9, Tmp6, "tmp"); 526fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands } else { 527fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands DSTr = Builder.CreateSDiv(Tmp3, Tmp6, "tmp"); 528fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands DSTi = Builder.CreateSDiv(Tmp9, Tmp6, "tmp"); 529124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands } 530124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands } 531fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands 53287689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands return ComplexPairTy(DSTr, DSTi); 53382fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands} 53475d289ed6201e82718343d7a36d2a2fa082f6217Duncan Sands 53507f30fbd734069b80b90c6aeea0ae645ce3880c0Duncan SandsComplexExprEmitter::BinOpInfo 53607f30fbd734069b80b90c6aeea0ae645ce3880c0Duncan SandsComplexExprEmitter::EmitBinOps(const BinaryOperator *E) { 53782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands TestAndClearIgnoreReal(); 538566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands TestAndClearIgnoreImag(); 539566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands TestAndClearIgnoreRealAssign(); 540566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands TestAndClearIgnoreImagAssign(); 541566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands BinOpInfo Ops; 542566edb04b890cebca8f2eefa37af7371a1e756c9Duncan Sands Ops.LHS = Visit(E->getLHS()); 5433421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands Ops.RHS = Visit(E->getRHS()); 5443421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands Ops.Ty = E->getType(); 5453421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands return Ops; 5463421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands} 5473421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 54887689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands 54987689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands// Compound assignments. 55087689cfc54993959adb20b89a56bc58aad18ca56Duncan SandsComplexPairTy ComplexExprEmitter:: 55187689cfc54993959adb20b89a56bc58aad18ca56Duncan SandsEmitCompoundAssign(const CompoundAssignOperator *E, 55287689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){ 55387689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands TestAndClearIgnoreReal(); 55487689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands TestAndClearIgnoreImag(); 55587689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands bool ignreal = TestAndClearIgnoreRealAssign(); 55687689cfc54993959adb20b89a56bc58aad18ca56Duncan Sands bool ignimag = TestAndClearIgnoreImagAssign(); 5578aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner QualType LHSTy = E->getLHS()->getType(), RHSTy = E->getRHS()->getType(); 5588aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner 5598aee8efc0c2e387faa7dae39fdf613a22889b566Chris Lattner BinOpInfo OpInfo; 560ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands 561ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands // Load the RHS and LHS operands. 562ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands // __block variables need to have the rhs evaluated first, plus this should 563ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands // improve codegen a little. It is possible for the RHS to be complex or 564ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands // scalar. 565fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands OpInfo.Ty = E->getComputationResultType(); 566fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands OpInfo.RHS = EmitCast(E->getRHS(), OpInfo.Ty); 567ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands 5683421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands LValue LHSLV = CGF.EmitLValue(E->getLHS()); 569ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands 570fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands 571fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands // We know the LHS is a complex lvalue. 572fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands OpInfo.LHS=EmitLoadOfComplex(LHSLV.getAddress(),LHSLV.isVolatileQualified()); 573fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands OpInfo.LHS=EmitComplexToComplexCast(OpInfo.LHS, LHSTy, OpInfo.Ty); 574fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands 575fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands // Expand the binary operator. 576fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands ComplexPairTy Result = (this->*Func)(OpInfo); 577fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands 578fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands // Truncate the result back to the LHS type. 579fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy); 580fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands 581fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands // Store the result value into the LHS lvalue. 582fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands EmitStoreOfComplex(Result, LHSLV.getAddress(), LHSLV.isVolatileQualified()); 583fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands // And now return the LHS 584fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands IgnoreReal = ignreal; 585fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands IgnoreImag = ignimag; 586fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands IgnoreRealAssign = ignreal; 587124708d9b47cc53cb11d8bfed75b241b6eec86d4Duncan Sands IgnoreImagAssign = ignimag; 588fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands return EmitLoadOfComplex(LHSLV.getAddress(), LHSLV.isVolatileQualified()); 589fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands} 590fe02c69f84ad52d42be934e4fe702f03e4991a6aDuncan Sands 591fe02c69f84ad52d42be934e4fe702f03e4991a6aDuncan SandsComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) { 592b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands TestAndClearIgnoreReal(); 593fe02c69f84ad52d42be934e4fe702f03e4991a6aDuncan Sands TestAndClearIgnoreImag(); 594fe02c69f84ad52d42be934e4fe702f03e4991a6aDuncan Sands bool ignreal = TestAndClearIgnoreRealAssign(); 595fe02c69f84ad52d42be934e4fe702f03e4991a6aDuncan Sands bool ignimag = TestAndClearIgnoreImagAssign(); 596fe02c69f84ad52d42be934e4fe702f03e4991a6aDuncan Sands assert(CGF.getContext().getCanonicalType(E->getLHS()->getType()) == 597b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands CGF.getContext().getCanonicalType(E->getRHS()->getType()) && 598b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands "Invalid assignment"); 599b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands // Emit the RHS. 600b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands ComplexPairTy Val = Visit(E->getRHS()); 601b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands 602b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands // Compute the address to store into. 603b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands LValue LHS = CGF.EmitLValue(E->getLHS()); 604b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands 605b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands // Store into it, if simple. 606b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands if (LHS.isSimple()) { 607b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands EmitStoreOfComplex(Val, LHS.getAddress(), LHS.isVolatileQualified()); 608b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands 609b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands // And now return the LHS 610b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands IgnoreReal = ignreal; 611b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands IgnoreImag = ignimag; 612b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands IgnoreRealAssign = ignreal; 613b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands IgnoreImagAssign = ignimag; 614b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified()); 615b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands } 616b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands 617b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands // Otherwise we must have a property setter (no complex vector/bitfields). 618b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands if (LHS.isPropertyRef()) 619b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(), RValue::getComplex(Val)); 62082fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands else 621b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), RValue::getComplex(Val)); 622b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands 623b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands // There is no reload after a store through a method, but we need to restore 624b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands // the Ignore* flags. 625b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands IgnoreReal = ignreal; 626b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands IgnoreImag = ignimag; 627b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands IgnoreRealAssign = ignreal; 628b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands IgnoreImagAssign = ignimag; 629b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands return Val; 630b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands} 631b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands 632b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan SandsComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { 633b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands CGF.EmitStmt(E->getLHS()); 634b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands CGF.EnsureInsertPoint(); 635b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands return Visit(E->getRHS()); 636b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands} 637b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands 638b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan SandsComplexPairTy ComplexExprEmitter:: 639b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan SandsVisitConditionalOperator(const ConditionalOperator *E) { 640b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands TestAndClearIgnoreReal(); 641b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands TestAndClearIgnoreImag(); 642b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands TestAndClearIgnoreRealAssign(); 643b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands TestAndClearIgnoreImagAssign(); 644b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); 645b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); 646b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); 647b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands 648c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond()); 649c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands Builder.CreateCondBr(Cond, LHSBlock, RHSBlock); 650c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands 651b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands CGF.EmitBlock(LHSBlock); 652c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands 653c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands // Handle the GNU extension for missing LHS. 654c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands assert(E->getLHS() && "Must have LHS for complex value"); 655c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands 656c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands ComplexPairTy LHS = Visit(E->getLHS()); 657c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands LHSBlock = Builder.GetInsertBlock(); 658c087e20331c8a4c3b77d96a73588e80c06d89e3dDuncan Sands CGF.EmitBranch(ContBlock); 6593421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 6603421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands CGF.EmitBlock(RHSBlock); 6613421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands 6623421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands ComplexPairTy RHS = Visit(E->getRHS()); 6633421d908539cc489d2b1dac67d8cbc07160b01dbDuncan Sands RHSBlock = Builder.GetInsertBlock(); 664b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands CGF.EmitBranch(ContBlock); 665b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands 666b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands CGF.EmitBlock(ContBlock); 667b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands 668b2f3c383ec62b959ee27d0a5fb890894c4e49e86Duncan Sands // Create a PHI node for the real part. 669fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), "cond.r"); 670fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands RealPN->reserveOperandSpace(2); 671fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands RealPN->addIncoming(LHS.first, LHSBlock); 672fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands RealPN->addIncoming(RHS.first, RHSBlock); 673fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands 674fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands // Create a PHI node for the imaginary part. 675fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), "cond.i"); 676fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands ImagPN->reserveOperandSpace(2); 677fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands ImagPN->addIncoming(LHS.second, LHSBlock); 678fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands ImagPN->addIncoming(RHS.second, RHSBlock); 679fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands 680fea3b218d61708ea3577f4ef14c8f7677a94db95Duncan Sands return ComplexPairTy(RealPN, ImagPN); 681ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands} 682ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands 683ee9a2e322af96accc9e55ed6373c0057453714b1Duncan SandsComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) { 684ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands return Visit(E->getChosenSubExpr(CGF.getContext())); 685ee9a2e322af96accc9e55ed6373c0057453714b1Duncan Sands} 68682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands 68782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan SandsComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) { 68882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands bool Ignore = TestAndClearIgnoreReal(); 68982fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands (void)Ignore; 69082fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands assert (Ignore == false && "init list ignored"); 69182fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands Ignore = TestAndClearIgnoreImag(); 69282fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands (void)Ignore; 69382fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands assert (Ignore == false && "init list ignored"); 69482fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands if (E->getNumInits()) 69582fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands return Visit(E->getInit(0)); 69682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands 69782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands // Empty init list intializes to null 69882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands QualType Ty = E->getType()->getAsComplexType()->getElementType(); 69982fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands const llvm::Type* LTy = CGF.ConvertType(Ty); 70082fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy); 70182fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands return ComplexPairTy(zeroConstant, zeroConstant); 70282fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands} 70382fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands 70482fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan SandsComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) { 70582fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands llvm::Value *ArgValue = CGF.EmitVAListRef(E->getSubExpr()); 70682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, E->getType()); 70782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands 70882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands if (!ArgPtr) { 70982fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands CGF.ErrorUnsupported(E, "complex va_arg expression"); 71082fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands const llvm::Type *EltTy = 71182fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands CGF.ConvertType(E->getType()->getAsComplexType()->getElementType()); 71282fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands llvm::Value *U = llvm::UndefValue::get(EltTy); 7131895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands return ComplexPairTy(U, U); 7141895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands } 7151895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands 7161895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands // FIXME Volatility. 7171895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands return EmitLoadOfComplex(ArgPtr, false); 7181895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands} 7191895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands 7201895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands//===----------------------------------------------------------------------===// 7211895e98ef38afbe011575cc25f4889d96e37421bDuncan Sands// Entry Point into this File 7225413880654585f01ea9880f24f07f27c8da56ba8Nick Lewycky//===----------------------------------------------------------------------===// 72375d289ed6201e82718343d7a36d2a2fa082f6217Duncan Sands 72407f30fbd734069b80b90c6aeea0ae645ce3880c0Duncan Sands/// EmitComplexExpr - Emit the computation of the specified expression of 72507f30fbd734069b80b90c6aeea0ae645ce3880c0Duncan Sands/// complex type, ignoring the result. 72682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan SandsComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal, 72782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands bool IgnoreImag, bool IgnoreRealAssign, bool IgnoreImagAssign) { 72882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands assert(E && E->getType()->isAnyComplexType() && 72982fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands "Invalid complex expression to emit"); 73082fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands 73182fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag, IgnoreRealAssign, 73282fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands IgnoreImagAssign) 73382fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands .Visit(const_cast<Expr*>(E)); 73482fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands} 73582fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands 73682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands/// EmitComplexExprIntoAddr - Emit the computation of the specified expression 73782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands/// of complex type, storing into the specified Value*. 73882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sandsvoid CodeGenFunction::EmitComplexExprIntoAddr(const Expr *E, 73982fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands llvm::Value *DestAddr, 74082fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands bool DestIsVolatile) { 74182fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands assert(E && E->getType()->isAnyComplexType() && 74282fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands "Invalid complex expression to emit"); 74382fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands ComplexExprEmitter Emitter(*this); 74482fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E)); 74582fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands Emitter.EmitStoreOfComplex(Val, DestAddr, DestIsVolatile); 74682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands} 74782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands 74882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands/// StoreComplexToAddr - Store a complex number into the specified address. 74982fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sandsvoid CodeGenFunction::StoreComplexToAddr(ComplexPairTy V, 75082fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands llvm::Value *DestAddr, 75182fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands bool DestIsVolatile) { 75282fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands ComplexExprEmitter(*this).EmitStoreOfComplex(V, DestAddr, DestIsVolatile); 75382fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands} 75482fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands 75582fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands/// LoadComplexFromAddr - Load a complex number from the specified address. 75682fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan SandsComplexPairTy CodeGenFunction::LoadComplexFromAddr(llvm::Value *SrcAddr, 75782fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands bool SrcIsVolatile) { 75882fdab335881cd90f8f7ab3ad1f1ca0bb3ee886aDuncan Sands return ComplexExprEmitter(*this).EmitLoadOfComplex(SrcAddr, SrcIsVolatile); 759593faa53fa6d89841e601cc4571d143a6a05f0b4Duncan Sands} 760593faa53fa6d89841e601cc4571d143a6a05f0b4Duncan Sands