CGStmt.cpp revision 64d5d6c5903157c521af496479d06dc26032d718
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- CGStmt.cpp - Emit LLVM Code from Statements ----------------------===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This contains code to emit Stmt nodes as LLVM code. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 14e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta#include "CGDebugInfo.h" 15e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta#include "CodeGenModule.h" 165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "CodeGenFunction.h" 17de7fb8413b13651fd85b7125d08b3c9ac2816d9dDaniel Dunbar#include "clang/AST/StmtVisitor.h" 18fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson#include "clang/Basic/TargetInfo.h" 19fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson#include "llvm/InlineAsm.h" 20fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson#include "llvm/ADT/StringExtras.h" 215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace CodeGen; 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Statement Emission 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitStmt(const Stmt *S) { 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(S && "Null statement?"); 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 31e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta // Generate stoppoints if we are emitting debug info. 32e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta // Beginning of a Compound Statement (e.g. an opening '{') does not produce 33e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta // executable code. So do not generate a stoppoint for that. 34e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta CGDebugInfo *DI = CGM.getDebugInfo(); 35e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta if (DI && S->getStmtClass() != Stmt::CompoundStmtClass) { 36e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta if (S->getLocStart().isValid()) { 37e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta DI->setLocation(S->getLocStart()); 38e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta } 39e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta 40e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta DI->EmitStopPoint(CurFn, Builder); 41e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta } 42e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta 435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (S->getStmtClass()) { 445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: 451e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner // Must be an expression in a stmt context. Emit the value (to get 461e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner // side-effects) and ignore the result. 475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (const Expr *E = dyn_cast<Expr>(S)) { 481e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner if (!hasAggregateLLVMType(E->getType())) 491e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner EmitScalarExpr(E); 509b2dc287177394a8f73833e2ad4f7ca8cd6f22bbChris Lattner else if (E->getType()->isAnyComplexType()) 511e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner EmitComplexExpr(E); 521e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner else 531e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner EmitAggExpr(E, 0, false); 545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 55488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar ErrorUnsupported(S, "statement"); 565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::NullStmtClass: break; 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break; 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break; 615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break; 620ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar case Stmt::IndirectGotoStmtClass: 630ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar EmitIndirectGotoStmt(cast<IndirectGotoStmt>(*S)); break; 645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break; 665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break; 675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::DoStmtClass: EmitDoStmt(cast<DoStmt>(*S)); break; 685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::ForStmtClass: EmitForStmt(cast<ForStmt>(*S)); break; 695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break; 715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break; 72da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 73da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner case Stmt::BreakStmtClass: EmitBreakStmt(); break; 74da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner case Stmt::ContinueStmtClass: EmitContinueStmt(); break; 7551b09f2c528c8460b5465c676173324e44176d62Devang Patel case Stmt::SwitchStmtClass: EmitSwitchStmt(cast<SwitchStmt>(*S)); break; 7651b09f2c528c8460b5465c676173324e44176d62Devang Patel case Stmt::DefaultStmtClass: EmitDefaultStmt(cast<DefaultStmt>(*S)); break; 7751b09f2c528c8460b5465c676173324e44176d62Devang Patel case Stmt::CaseStmtClass: EmitCaseStmt(cast<CaseStmt>(*S)); break; 78fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case Stmt::AsmStmtClass: EmitAsmStmt(cast<AsmStmt>(*S)); break; 790a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar 800a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtTryStmtClass: 8164d5d6c5903157c521af496479d06dc26032d718Anders Carlsson EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S)); 8264d5d6c5903157c521af496479d06dc26032d718Anders Carlsson break; 830a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtCatchStmtClass: 8464d5d6c5903157c521af496479d06dc26032d718Anders Carlsson assert(0 && "@catch statements should be handled by EmitObjCAtTryStmt"); 850a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 860a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtFinallyStmtClass: 8764d5d6c5903157c521af496479d06dc26032d718Anders Carlsson assert(0 && "@finally statements should be handled by EmitObjCAtTryStmt"); 880a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 890a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtThrowStmtClass: 9064d5d6c5903157c521af496479d06dc26032d718Anders Carlsson EmitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(*S)); 910a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 920a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtSynchronizedStmtClass: 930a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar ErrorUnsupported(S, "@synchronized statement"); 940a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 953d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson case Stmt::ObjCForCollectionStmtClass: 963d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson EmitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(*S)); 970a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1013379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true, 1023379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// this captures the expression result of the last sub-statement and returns it 1033379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// (for use by the statement expression extension). 1049b65551d0b387a7597fb39356a4d8ef10046445eChris LattnerRValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, 1059b65551d0b387a7597fb39356a4d8ef10046445eChris Lattner llvm::Value *AggLoc, bool isAggVol) { 1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FIXME: handle vla's etc. 1071c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta CGDebugInfo *DI = CGM.getDebugInfo(); 1081c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta if (DI) { 109345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner if (S.getLBracLoc().isValid()) 1101c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta DI->setLocation(S.getLBracLoc()); 1111c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta DI->EmitRegionStart(CurFn, Builder); 1121c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta } 1131c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta 1143379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner for (CompoundStmt::const_body_iterator I = S.body_begin(), 1153379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner E = S.body_end()-GetLast; I != E; ++I) 1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(*I); 117e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta 1181c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta if (DI) { 119345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner if (S.getRBracLoc().isValid()) 1201c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta DI->setLocation(S.getRBracLoc()); 1211c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta DI->EmitRegionEnd(CurFn, Builder); 1221c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta } 1231c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta 1243379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner if (!GetLast) 1253379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner return RValue::get(0); 1269b65551d0b387a7597fb39356a4d8ef10046445eChris Lattner 12791d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner // We have to special case labels here. They are statements, but when put at 12891d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner // the end of a statement expression, they yield the value of their 12991d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner // subexpression. Handle this by walking through all labels we encounter, 13091d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner // emitting them before we evaluate the subexpr. 13191d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner const Stmt *LastStmt = S.body_back(); 13291d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner while (const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) { 13391d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner EmitLabel(*LS); 13491d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner LastStmt = LS->getSubStmt(); 13591d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner } 13691d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner 13791d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner return EmitAnyExpr(cast<Expr>(LastStmt), AggLoc); 1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitBlock(llvm::BasicBlock *BB) { 1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit a branch from this block to the next one if this was a real block. If 1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // this was just a fall-through block after a terminator, don't emit it. 1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::BasicBlock *LastBB = Builder.GetInsertBlock(); 1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (LastBB->getTerminator()) { 1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the previous block is already terminated, don't touch it. 14716f23570999cac1fa13597386938450843003840Daniel Dunbar } else if (LastBB->empty() && isDummyBlock(LastBB)) { 1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the last block was an empty placeholder, remove it now. 1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // TODO: cache and reuse these. 15016f23570999cac1fa13597386938450843003840Daniel Dunbar LastBB->eraseFromParent(); 1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 1525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, create a fall-through branch. 1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Builder.CreateBr(BB); 1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CurFn->getBasicBlockList().push_back(BB); 1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Builder.SetInsertPoint(BB); 1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 15991d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattnervoid CodeGenFunction::EmitLabel(const LabelStmt &S) { 1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S); 1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(NextBB); 16291d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner} 16391d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner 16491d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner 16591d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattnervoid CodeGenFunction::EmitLabelStmt(const LabelStmt &S) { 16691d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner EmitLabel(S); 1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getSubStmt()); 1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitGotoStmt(const GotoStmt &S) { 1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Builder.CreateBr(getBasicBlockForLabel(S.getLabel())); 1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit a block after the branch so that dead code after a goto has some place 1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // to go. 175984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif Builder.SetInsertPoint(llvm::BasicBlock::Create("", CurFn)); 1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1780ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbarvoid CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) { 1790ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // Emit initial switch which will be patched up later by 1800ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // EmitIndirectSwitches(). We need a default dest, so we use the 1810ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // current BB, but this is overwritten. 1820ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar llvm::Value *V = Builder.CreatePtrToInt(EmitScalarExpr(S.getTarget()), 1830ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar llvm::Type::Int32Ty, 1840ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar "addr"); 1850ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar llvm::SwitchInst *I = Builder.CreateSwitch(V, Builder.GetInsertBlock()); 1860ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar IndirectSwitches.push_back(I); 1870ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar 1880ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // Emit a block after the branch so that dead code after a goto has some place 1890ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // to go. 1900ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar Builder.SetInsertPoint(llvm::BasicBlock::Create("", CurFn)); 1910ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar} 1920ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar 1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitIfStmt(const IfStmt &S) { 1940ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // FIXME: It would probably be nice for us to skip emission of if 1950ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // (0) code here. 1960ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar 1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.4.1: The first substatement is executed if the expression compares 1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // unequal to 0. The condition must be a scalar type. 1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 201984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *ContBlock = llvm::BasicBlock::Create("ifend"); 202984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *ThenBlock = llvm::BasicBlock::Create("ifthen"); 2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::BasicBlock *ElseBlock = ContBlock; 2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getElse()) 206984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif ElseBlock = llvm::BasicBlock::Create("ifelse"); 2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Insert the conditional branch. 2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Builder.CreateCondBr(BoolCondVal, ThenBlock, ElseBlock); 2105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the 'then' code. 2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ThenBlock); 2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getThen()); 214d9363c3a80168283b3da518b4e17f545a6246857Devang Patel llvm::BasicBlock *BB = Builder.GetInsertBlock(); 215d9363c3a80168283b3da518b4e17f545a6246857Devang Patel if (isDummyBlock(BB)) { 216d9363c3a80168283b3da518b4e17f545a6246857Devang Patel BB->eraseFromParent(); 217d9363c3a80168283b3da518b4e17f545a6246857Devang Patel Builder.SetInsertPoint(ThenBlock); 218345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner } else { 219d9363c3a80168283b3da518b4e17f545a6246857Devang Patel Builder.CreateBr(ContBlock); 220345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner } 2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the 'else' code if present. 2235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (const Stmt *Else = S.getElse()) { 2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ElseBlock); 2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(Else); 226d9363c3a80168283b3da518b4e17f545a6246857Devang Patel llvm::BasicBlock *BB = Builder.GetInsertBlock(); 227d9363c3a80168283b3da518b4e17f545a6246857Devang Patel if (isDummyBlock(BB)) { 228d9363c3a80168283b3da518b4e17f545a6246857Devang Patel BB->eraseFromParent(); 229d9363c3a80168283b3da518b4e17f545a6246857Devang Patel Builder.SetInsertPoint(ElseBlock); 230345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner } else { 231d9363c3a80168283b3da518b4e17f545a6246857Devang Patel Builder.CreateBr(ContBlock); 232345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner } 2335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the continuation block for code after the if. 2365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ContBlock); 2375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitWhileStmt(const WhileStmt &S) { 2405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the header for the loop, insert it, which will create an uncond br to 2415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // it. 242984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *LoopHeader = llvm::BasicBlock::Create("whilecond"); 2435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(LoopHeader); 2445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the conditional in the while header. C99 6.8.5.1: The evaluation 2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // of the controlling expression takes place before each execution of the loop 2475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // body. 2485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 2492c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel 2502c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel // while(1) is common, avoid extra exit blocks. Be sure 2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // to correctly handle break/continue though. 2522c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel bool EmitBoolCondBranch = true; 2532c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) 2542c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (C->isOne()) 2552c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel EmitBoolCondBranch = false; 2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Create an exit block for when the condition fails, create a block for the 2585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // body of the loop. 259984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *ExitBlock = llvm::BasicBlock::Create("whileexit"); 260984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *LoopBody = llvm::BasicBlock::Create("whilebody"); 2615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // As long as the condition is true, go to the loop body. 2632c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (EmitBoolCondBranch) 2642c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock); 265da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 266da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 267da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader)); 2685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the loop body. 2705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(LoopBody); 2715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getBody()); 272da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 273da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.pop_back(); 2745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Cycle to the condition. 2765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Builder.CreateBr(LoopHeader); 2775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the exit block. 2795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ExitBlock); 2802c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel 2812c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel // If LoopHeader is a simple forwarding block then eliminate it. 2822c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (!EmitBoolCondBranch 2832c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel && &LoopHeader->front() == LoopHeader->getTerminator()) { 2842c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel LoopHeader->replaceAllUsesWith(LoopBody); 2852c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel LoopHeader->getTerminator()->eraseFromParent(); 2862c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel LoopHeader->eraseFromParent(); 2872c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel } 2885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitDoStmt(const DoStmt &S) { 2915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the body for the loop, insert it, which will create an uncond br to 2925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // it. 293984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *LoopBody = llvm::BasicBlock::Create("dobody"); 294984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *AfterDo = llvm::BasicBlock::Create("afterdo"); 2955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(LoopBody); 296da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 297984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *DoCond = llvm::BasicBlock::Create("docond"); 298da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 299da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 300da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.push_back(BreakContinue(AfterDo, DoCond)); 3015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the body of the loop into the block. 3035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getBody()); 3045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 305da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.pop_back(); 306da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 307da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner EmitBlock(DoCond); 308da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 3095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5.2: "The evaluation of the controlling expression takes place 3105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // after each execution of the loop body." 3115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the conditional in the while header. 3135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5p2/p4: The first substatement is executed if the expression 3145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // compares unequal to 0. The condition must be a scalar type. 3155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 31605f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 31705f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // "do {} while (0)" is common in macros, avoid extra blocks. Be sure 31805f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // to correctly handle break/continue though. 31905f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel bool EmitBoolCondBranch = true; 32005f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) 32105f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (C->isZero()) 32205f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel EmitBoolCondBranch = false; 32305f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 3245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // As long as the condition is true, iterate the loop. 32505f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (EmitBoolCondBranch) 32605f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo); 3275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the exit block. 3295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(AfterDo); 33005f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 33105f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // If DoCond is a simple forwarding block then eliminate it. 33205f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (!EmitBoolCondBranch && &DoCond->front() == DoCond->getTerminator()) { 33305f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel DoCond->replaceAllUsesWith(AfterDo); 33405f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel DoCond->getTerminator()->eraseFromParent(); 33505f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel DoCond->eraseFromParent(); 33605f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel } 3375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitForStmt(const ForStmt &S) { 3405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FIXME: What do we do if the increment (f.e.) contains a stmt expression, 3415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // which contains a continue/break? 342da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // TODO: We could keep track of whether the loop body contains any 343da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // break/continue statements and not create unnecessary blocks (like 344da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // "afterfor" for a condless loop) if it doesn't. 345da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 3465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the first part before the loop. 3475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getInit()) 3485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getInit()); 3495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Start the loop with a block that tests the condition. 351984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *CondBlock = llvm::BasicBlock::Create("forcond"); 352984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *AfterFor = llvm::BasicBlock::Create("afterfor"); 353da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 3545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(CondBlock); 3555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the condition if present. If not, treat it as a non-zero-constant 3575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // according to 6.8.5.3p2, aka, true. 3585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getCond()) { 3595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5p2/p4: The first substatement is executed if the expression 3605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // compares unequal to 0. The condition must be a scalar type. 3615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 3625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // As long as the condition is true, iterate the loop. 364984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *ForBody = llvm::BasicBlock::Create("forbody"); 3655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Builder.CreateCondBr(BoolCondVal, ForBody, AfterFor); 3665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ForBody); 3675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 3685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Treat it as a non-zero constant. Don't even create a new block for the 3695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // body, just fall into it. 3705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 3715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 372da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // If the for loop doesn't have an increment we can just use the 373da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // condition as the continue block. 374da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner llvm::BasicBlock *ContinueBlock; 375da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner if (S.getInc()) 376984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif ContinueBlock = llvm::BasicBlock::Create("forinc"); 377da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner else 378da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner ContinueBlock = CondBlock; 379da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 380da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 381da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.push_back(BreakContinue(AfterFor, ContinueBlock)); 382da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 3835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the condition is true, execute the body of the for stmt. 3845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getBody()); 385da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 386da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.pop_back(); 387da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 388da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner if (S.getInc()) 389da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner EmitBlock(ContinueBlock); 3905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If there is an increment, emit it next. 3925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getInc()) 393883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner EmitStmt(S.getInc()); 3945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Finally, branch back up to the condition for the next iteration. 3965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Builder.CreateBr(CondBlock); 3975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 398da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Emit the fall-through block. 399da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner EmitBlock(AfterFor); 4005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand 4035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// if the function returns void, or may be missing one if the function returns 4045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// non-void. Fun stuff :). 4055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { 4065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the result value, even if unused, to evalute the side effects. 4075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const Expr *RV = S.getRetValue(); 4084b0029d5f8742760981a3bd58004f75454090a61Chris Lattner 409144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman llvm::Value* RetValue = 0; 4105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FnRetTy->isVoidType()) { 411144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman // Make sure not to return anything 412144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman if (RV) { 413144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman // Evaluate the expression for side effects 414144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman EmitAnyExpr(RV); 415144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman } 4165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else if (RV == 0) { 4175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const llvm::Type *RetTy = CurFn->getFunctionType()->getReturnType(); 418144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman if (RetTy != llvm::Type::VoidTy) { 419144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman // Handle "return;" in a function that returns a value. 420144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman RetValue = llvm::UndefValue::get(RetTy); 421144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman } 4224b0029d5f8742760981a3bd58004f75454090a61Chris Lattner } else if (!hasAggregateLLVMType(RV->getType())) { 423144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman RetValue = EmitScalarExpr(RV); 4249b2dc287177394a8f73833e2ad4f7ca8cd6f22bbChris Lattner } else if (RV->getType()->isAnyComplexType()) { 425345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner EmitComplexExprIntoAddr(RV, CurFn->arg_begin(), false); 4265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 427345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner EmitAggExpr(RV, CurFn->arg_begin(), false); 4285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 429144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman 430144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman if (RetValue) { 431144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman Builder.CreateRet(RetValue); 432144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman } else { 433144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman Builder.CreateRetVoid(); 434144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman } 4355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit a block after the branch so that dead code after a return has some 4375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // place to go. 438984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif EmitBlock(llvm::BasicBlock::Create()); 4395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitDeclStmt(const DeclStmt &S) { 4429474504790f11617479b8d6ef8b64e32d071f251Steve Naroff for (const ScopedDecl *Decl = S.getDecl(); Decl; 4439474504790f11617479b8d6ef8b64e32d071f251Steve Naroff Decl = Decl->getNextDeclarator()) 4445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitDecl(*Decl); 4456fa5f0943a84233b2e1ec9716eae55643225bfd4Chris Lattner} 446da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 447da13870e99fe33934b2122f06528a5063f78ae4cChris Lattnervoid CodeGenFunction::EmitBreakStmt() { 448da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!"); 449da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 450da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock; 451da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner Builder.CreateBr(Block); 452984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif EmitBlock(llvm::BasicBlock::Create()); 453da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner} 454da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 455da13870e99fe33934b2122f06528a5063f78ae4cChris Lattnervoid CodeGenFunction::EmitContinueStmt() { 456da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 457da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 458da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock; 459da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner Builder.CreateBr(Block); 460984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif EmitBlock(llvm::BasicBlock::Create()); 461da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner} 46251b09f2c528c8460b5465c676173324e44176d62Devang Patel 463c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// EmitCaseStmtRange - If case statement range is not too big then 464c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// add multiple cases to switch instruction, one for each value within 465c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// the range. If range is too big then emit "if" condition check. 466c049e4f406a7f7179eba98659044a32508e53289Devang Patelvoid CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) { 467662174c82ef46b19a2329c7d37208e1d12dfb7b3Daniel Dunbar // FIXME: kill me with param - ddunbar 4684efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar assert(S.getRHS() && "Expected RHS value in CaseStmt"); 469c049e4f406a7f7179eba98659044a32508e53289Devang Patel 4704efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar llvm::APSInt LHS = S.getLHS()->getIntegerConstantExprValue(getContext()); 4714efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar llvm::APSInt RHS = S.getRHS()->getIntegerConstantExprValue(getContext()); 4724efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar 47316f23570999cac1fa13597386938450843003840Daniel Dunbar // Emit the code for this case. We do this first to make sure it is 47416f23570999cac1fa13597386938450843003840Daniel Dunbar // properly chained from our predecessor before generating the 47516f23570999cac1fa13597386938450843003840Daniel Dunbar // switch machinery to enter this block. 47616f23570999cac1fa13597386938450843003840Daniel Dunbar StartBlock("sw.bb"); 47716f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *CaseDest = Builder.GetInsertBlock(); 47816f23570999cac1fa13597386938450843003840Daniel Dunbar EmitStmt(S.getSubStmt()); 47916f23570999cac1fa13597386938450843003840Daniel Dunbar 4804efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar // If range is empty, do nothing. 4814efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar if (LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS)) 4824efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar return; 483c049e4f406a7f7179eba98659044a32508e53289Devang Patel 484c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::APInt Range = RHS - LHS; 48516f23570999cac1fa13597386938450843003840Daniel Dunbar // FIXME: parameters such as this should not be hardcoded. 486c049e4f406a7f7179eba98659044a32508e53289Devang Patel if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) { 487c049e4f406a7f7179eba98659044a32508e53289Devang Patel // Range is small enough to add multiple switch instruction cases. 4884efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar for (unsigned i = 0, e = Range.getZExtValue() + 1; i != e; ++i) { 4892d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel SwitchInsn->addCase(llvm::ConstantInt::get(LHS), CaseDest); 4902d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel LHS++; 4912d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel } 492c049e4f406a7f7179eba98659044a32508e53289Devang Patel return; 493c049e4f406a7f7179eba98659044a32508e53289Devang Patel } 494c049e4f406a7f7179eba98659044a32508e53289Devang Patel 49516f23570999cac1fa13597386938450843003840Daniel Dunbar // The range is too big. Emit "if" condition into a new block, 49616f23570999cac1fa13597386938450843003840Daniel Dunbar // making sure to save and restore the current insertion point. 49716f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *RestoreBB = Builder.GetInsertBlock(); 49816f23570999cac1fa13597386938450843003840Daniel Dunbar 49916f23570999cac1fa13597386938450843003840Daniel Dunbar // Push this test onto the chain of range checks (which terminates 50016f23570999cac1fa13597386938450843003840Daniel Dunbar // in the default basic block). The switch's default will be changed 50116f23570999cac1fa13597386938450843003840Daniel Dunbar // to the top of this chain after switch emission is complete. 50216f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *FalseDest = CaseRangeBlock; 50316f23570999cac1fa13597386938450843003840Daniel Dunbar CaseRangeBlock = llvm::BasicBlock::Create("sw.caserange"); 50416f23570999cac1fa13597386938450843003840Daniel Dunbar 50516f23570999cac1fa13597386938450843003840Daniel Dunbar CurFn->getBasicBlockList().push_back(CaseRangeBlock); 50616f23570999cac1fa13597386938450843003840Daniel Dunbar Builder.SetInsertPoint(CaseRangeBlock); 507c049e4f406a7f7179eba98659044a32508e53289Devang Patel 508c049e4f406a7f7179eba98659044a32508e53289Devang Patel // Emit range check. 509c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::Value *Diff = 5104efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar Builder.CreateSub(SwitchInsn->getCondition(), llvm::ConstantInt::get(LHS), 5114efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar "tmp"); 512c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::Value *Cond = 513c049e4f406a7f7179eba98659044a32508e53289Devang Patel Builder.CreateICmpULE(Diff, llvm::ConstantInt::get(Range), "tmp"); 514c049e4f406a7f7179eba98659044a32508e53289Devang Patel Builder.CreateCondBr(Cond, CaseDest, FalseDest); 515c049e4f406a7f7179eba98659044a32508e53289Devang Patel 51616f23570999cac1fa13597386938450843003840Daniel Dunbar // Restore the appropriate insertion point. 51716f23570999cac1fa13597386938450843003840Daniel Dunbar Builder.SetInsertPoint(RestoreBB); 518c049e4f406a7f7179eba98659044a32508e53289Devang Patel} 5192d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel 520c049e4f406a7f7179eba98659044a32508e53289Devang Patelvoid CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { 521c049e4f406a7f7179eba98659044a32508e53289Devang Patel if (S.getRHS()) { 522c049e4f406a7f7179eba98659044a32508e53289Devang Patel EmitCaseStmtRange(S); 523c049e4f406a7f7179eba98659044a32508e53289Devang Patel return; 524c049e4f406a7f7179eba98659044a32508e53289Devang Patel } 525c049e4f406a7f7179eba98659044a32508e53289Devang Patel 526c049e4f406a7f7179eba98659044a32508e53289Devang Patel StartBlock("sw.bb"); 527c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::BasicBlock *CaseDest = Builder.GetInsertBlock(); 5284efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar llvm::APSInt CaseVal = S.getLHS()->getIntegerConstantExprValue(getContext()); 5294efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar SwitchInsn->addCase(llvm::ConstantInt::get(CaseVal), 5304efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar CaseDest); 53151b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getSubStmt()); 53251b09f2c528c8460b5465c676173324e44176d62Devang Patel} 53351b09f2c528c8460b5465c676173324e44176d62Devang Patel 53451b09f2c528c8460b5465c676173324e44176d62Devang Patelvoid CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) { 53516f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest(); 53616f23570999cac1fa13597386938450843003840Daniel Dunbar assert(DefaultBlock->empty() && "EmitDefaultStmt: Default block already defined?"); 53716f23570999cac1fa13597386938450843003840Daniel Dunbar EmitBlock(DefaultBlock); 53851b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getSubStmt()); 53951b09f2c528c8460b5465c676173324e44176d62Devang Patel} 54051b09f2c528c8460b5465c676173324e44176d62Devang Patel 54151b09f2c528c8460b5465c676173324e44176d62Devang Patelvoid CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { 54251b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::Value *CondV = EmitScalarExpr(S.getCond()); 54351b09f2c528c8460b5465c676173324e44176d62Devang Patel 54451b09f2c528c8460b5465c676173324e44176d62Devang Patel // Handle nested switch statements. 54551b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::SwitchInst *SavedSwitchInsn = SwitchInsn; 546c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::BasicBlock *SavedCRBlock = CaseRangeBlock; 54751b09f2c528c8460b5465c676173324e44176d62Devang Patel 54816f23570999cac1fa13597386938450843003840Daniel Dunbar // Create basic block to hold stuff that comes after switch 54916f23570999cac1fa13597386938450843003840Daniel Dunbar // statement. We also need to create a default block now so that 55016f23570999cac1fa13597386938450843003840Daniel Dunbar // explicit case ranges tests can have a place to jump to on 55116f23570999cac1fa13597386938450843003840Daniel Dunbar // failure. 55216f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *NextBlock = llvm::BasicBlock::Create("sw.epilog"); 55316f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *DefaultBlock = llvm::BasicBlock::Create("sw.default"); 55416f23570999cac1fa13597386938450843003840Daniel Dunbar SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock); 55516f23570999cac1fa13597386938450843003840Daniel Dunbar CaseRangeBlock = DefaultBlock; 55651b09f2c528c8460b5465c676173324e44176d62Devang Patel 557d28a80d64616b66c91d28bb4c08ca2d8c594de4eEli Friedman // Create basic block for body of switch 55816f23570999cac1fa13597386938450843003840Daniel Dunbar StartBlock("sw.body"); 559d28a80d64616b66c91d28bb4c08ca2d8c594de4eEli Friedman 560e9b8c0a38549692f1b8f688c05c35442fc620865Devang Patel // All break statements jump to NextBlock. If BreakContinueStack is non empty 561e9b8c0a38549692f1b8f688c05c35442fc620865Devang Patel // then reuse last ContinueBlock. 56251b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::BasicBlock *ContinueBlock = NULL; 56351b09f2c528c8460b5465c676173324e44176d62Devang Patel if (!BreakContinueStack.empty()) 56451b09f2c528c8460b5465c676173324e44176d62Devang Patel ContinueBlock = BreakContinueStack.back().ContinueBlock; 56551b09f2c528c8460b5465c676173324e44176d62Devang Patel BreakContinueStack.push_back(BreakContinue(NextBlock, ContinueBlock)); 56651b09f2c528c8460b5465c676173324e44176d62Devang Patel 56751b09f2c528c8460b5465c676173324e44176d62Devang Patel // Emit switch body. 56851b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getBody()); 56951b09f2c528c8460b5465c676173324e44176d62Devang Patel BreakContinueStack.pop_back(); 57051b09f2c528c8460b5465c676173324e44176d62Devang Patel 57116f23570999cac1fa13597386938450843003840Daniel Dunbar // Update the default block in case explicit case range tests have 57216f23570999cac1fa13597386938450843003840Daniel Dunbar // been chained on top. 57316f23570999cac1fa13597386938450843003840Daniel Dunbar SwitchInsn->setSuccessor(0, CaseRangeBlock); 574c049e4f406a7f7179eba98659044a32508e53289Devang Patel 57516f23570999cac1fa13597386938450843003840Daniel Dunbar // If a default was never emitted then reroute any jumps to it and 57616f23570999cac1fa13597386938450843003840Daniel Dunbar // discard. 57716f23570999cac1fa13597386938450843003840Daniel Dunbar if (!DefaultBlock->getParent()) { 57816f23570999cac1fa13597386938450843003840Daniel Dunbar DefaultBlock->replaceAllUsesWith(NextBlock); 57916f23570999cac1fa13597386938450843003840Daniel Dunbar delete DefaultBlock; 58016f23570999cac1fa13597386938450843003840Daniel Dunbar } 58116f23570999cac1fa13597386938450843003840Daniel Dunbar 58216f23570999cac1fa13597386938450843003840Daniel Dunbar // Emit continuation. 58316f23570999cac1fa13597386938450843003840Daniel Dunbar EmitBlock(NextBlock); 58451b09f2c528c8460b5465c676173324e44176d62Devang Patel 58551b09f2c528c8460b5465c676173324e44176d62Devang Patel SwitchInsn = SavedSwitchInsn; 586c049e4f406a7f7179eba98659044a32508e53289Devang Patel CaseRangeBlock = SavedCRBlock; 58751b09f2c528c8460b5465c676173324e44176d62Devang Patel} 588fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 589345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattnerstatic std::string ConvertAsmString(const char *Start, unsigned NumOperands, 590345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner bool IsSimple) { 591fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson static unsigned AsmCounter = 0; 592fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson AsmCounter++; 593fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Result; 5942abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson if (IsSimple) { 5952abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson while (*Start) { 5962abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson switch (*Start) { 5972abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson default: 5982abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Result += *Start; 5992abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson break; 6002abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson case '$': 6012abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Result += "$$"; 6022abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson break; 6032abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 6042abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Start++; 6052abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 6062abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson 6072abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson return Result; 6082abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 609fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 610fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson while (*Start) { 611fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson switch (*Start) { 612fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson default: 613fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += *Start; 614fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 615fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '$': 616fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += "$$"; 617fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 618fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '%': 619fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Escaped character 620fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Start++; 621fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (!*Start) { 622fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // FIXME: This should be caught during Sema. 623fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(0 && "Trailing '%' in asm string."); 624fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 625fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 626fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson char EscapedChar = *Start; 627fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (EscapedChar == '%') { 628fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Escaped percentage sign. 629fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += '%'; 630345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner } else if (EscapedChar == '=') { 631fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Generate an unique ID. 632fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += llvm::utostr(AsmCounter); 633fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else if (isdigit(EscapedChar)) { 634fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // %n - Assembler operand n 635fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson char *End; 636fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson unsigned long n = strtoul(Start, &End, 10); 637fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (Start == End) { 638fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // FIXME: This should be caught during Sema. 639fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(0 && "Missing operand!"); 640fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else if (n >= NumOperands) { 641fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // FIXME: This should be caught during Sema. 642fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(0 && "Operand number out of range!"); 643fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 644fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 645fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += '$' + llvm::utostr(n); 6467695f70bbd3e4d42adaa1ef2ff5e1b9ab3d9c345Lauro Ramos Venancio Start = End - 1; 6472abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } else if (isalpha(EscapedChar)) { 6482abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson char *End; 6492abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson 6502abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson unsigned long n = strtoul(Start + 1, &End, 10); 6512abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson if (Start == End) { 6522abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson // FIXME: This should be caught during Sema. 6532abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson assert(0 && "Missing operand!"); 6542abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } else if (n >= NumOperands) { 6552abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson // FIXME: This should be caught during Sema. 6562abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson assert(0 && "Operand number out of range!"); 6572abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 6582abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson 6592abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Result += "${" + llvm::utostr(n) + ':' + EscapedChar + '}'; 6607695f70bbd3e4d42adaa1ef2ff5e1b9ab3d9c345Lauro Ramos Venancio Start = End - 1; 661fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 662fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(0 && "Unhandled asm escaped character!"); 663fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 664fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 665fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Start++; 666fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 667fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 668fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson return Result; 669fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 670fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 671a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venanciostatic std::string SimplifyConstraint(const char* Constraint, 672a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio TargetInfo &Target) { 673fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Result; 674fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 675fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson while (*Constraint) { 676fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson switch (*Constraint) { 677fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson default: 678a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio Result += Target.convertConstraint(*Constraint); 679fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 680fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Ignore these 681fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '*': 682fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '?': 683fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '!': 684fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 685fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case 'g': 686fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += "imr"; 687fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 688fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 689fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 690fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraint++; 691fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 692fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 693fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson return Result; 694fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 695fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 696fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlssonvoid CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { 697fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string AsmString = 698fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ConvertAsmString(std::string(S.getAsmString()->getStrData(), 699fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.getAsmString()->getByteLength()).c_str(), 7002abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson S.getNumOutputs() + S.getNumInputs(), S.isSimple()); 701fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 702fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Constraints; 703fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 704fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::Value *ResultAddr = 0; 705fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const llvm::Type *ResultType = llvm::Type::VoidTy; 706fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 707fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::vector<const llvm::Type*> ArgTypes; 708fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::vector<llvm::Value*> Args; 709f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 710f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // Keep track of inout constraints. 711f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::string InOutConstraints; 712f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::vector<llvm::Value*> InOutArgs; 713f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::vector<const llvm::Type*> InOutArgTypes; 714fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 715fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) { 716fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string OutputConstraint(S.getOutputConstraint(i)->getStrData(), 717fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.getOutputConstraint(i)->getByteLength()); 718fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 719fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson TargetInfo::ConstraintInfo Info; 720fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson bool result = Target.validateOutputConstraint(OutputConstraint.c_str(), 721fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Info); 722fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(result && "Failed to parse output constraint"); 723fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 724fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Simplify the output constraint. 725a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1, Target); 726fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 727fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson LValue Dest = EmitLValue(S.getOutputExpr(i)); 728fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const llvm::Type *DestValueType = 729fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson cast<llvm::PointerType>(Dest.getAddress()->getType())->getElementType(); 730fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 731fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // If the first output operand is not a memory dest, we'll 732fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // make it the return value. 733fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (i == 0 && !(Info & TargetInfo::CI_AllowsMemory) && 734d79a726dc3c8af61b486948c97a183c7fe5b0179Dan Gohman DestValueType->isSingleValueType()) { 735fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ResultAddr = Dest.getAddress(); 736fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ResultType = DestValueType; 737fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += "=" + OutputConstraint; 738fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 739fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ArgTypes.push_back(Dest.getAddress()->getType()); 740cad3ab611ebd3bee3ce6395d649640047f904cdeAnders Carlsson Args.push_back(Dest.getAddress()); 741fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (i != 0) 742fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 743f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Constraints += "=*"; 744fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += OutputConstraint; 745f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 746f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 747f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson if (Info & TargetInfo::CI_ReadWrite) { 748f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // FIXME: This code should be shared with the code that handles inputs. 749f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutConstraints += ','; 750f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 751f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson const Expr *InputExpr = S.getOutputExpr(i); 752f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson llvm::Value *Arg; 753f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson if ((Info & TargetInfo::CI_AllowsRegister) || 754f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson !(Info & TargetInfo::CI_AllowsMemory)) { 755d79a726dc3c8af61b486948c97a183c7fe5b0179Dan Gohman if (ConvertType(InputExpr->getType())->isSingleValueType()) { 756f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Arg = EmitScalarExpr(InputExpr); 757f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } else { 758662174c82ef46b19a2329c7d37208e1d12dfb7b3Daniel Dunbar ErrorUnsupported(&S, "asm statement passing multiple-value types as inputs"); 759f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 760f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } else { 761f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson LValue Dest = EmitLValue(InputExpr); 762f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Arg = Dest.getAddress(); 763f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutConstraints += '*'; 764f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 765f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 766f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutArgTypes.push_back(Arg->getType()); 767f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutArgs.push_back(Arg); 768f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutConstraints += OutputConstraint; 769f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 770fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 771fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 772fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson unsigned NumConstraints = S.getNumOutputs() + S.getNumInputs(); 773fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 774fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) { 775fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const Expr *InputExpr = S.getInputExpr(i); 776fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 777fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string InputConstraint(S.getInputConstraint(i)->getStrData(), 778fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.getInputConstraint(i)->getByteLength()); 779fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 780fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson TargetInfo::ConstraintInfo Info; 781fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson bool result = Target.validateInputConstraint(InputConstraint.c_str(), 782fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson NumConstraints, 783fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Info); 784fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(result && "Failed to parse input constraint"); 785fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 786fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (i != 0 || S.getNumOutputs() > 0) 787fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 788fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 789fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Simplify the input constraint. 790a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio InputConstraint = SimplifyConstraint(InputConstraint.c_str(), Target); 791fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 792fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::Value *Arg; 793fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 794fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if ((Info & TargetInfo::CI_AllowsRegister) || 795fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson !(Info & TargetInfo::CI_AllowsMemory)) { 796d79a726dc3c8af61b486948c97a183c7fe5b0179Dan Gohman if (ConvertType(InputExpr->getType())->isSingleValueType()) { 797fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Arg = EmitScalarExpr(InputExpr); 798fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 799662174c82ef46b19a2329c7d37208e1d12dfb7b3Daniel Dunbar ErrorUnsupported(&S, "asm statement passing multiple-value types as inputs"); 800fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 801fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 802fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson LValue Dest = EmitLValue(InputExpr); 803fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Arg = Dest.getAddress(); 804fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += '*'; 805fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 806fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 807fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ArgTypes.push_back(Arg->getType()); 808fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Args.push_back(Arg); 809fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += InputConstraint; 810fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 811fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 812f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // Append the "input" part of inout constraints last. 813f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { 814f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson ArgTypes.push_back(InOutArgTypes[i]); 815f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Args.push_back(InOutArgs[i]); 816f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 817f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Constraints += InOutConstraints; 818f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 819fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Clobbers 820fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) { 821fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Clobber(S.getClobber(i)->getStrData(), 822fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.getClobber(i)->getByteLength()); 823fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 824fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Clobber = Target.getNormalizedGCCRegisterName(Clobber.c_str()); 825fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 826ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson if (i != 0 || NumConstraints != 0) 827fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 828ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson 829ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson Constraints += "~{"; 830fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += Clobber; 831ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson Constraints += '}'; 832fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 833fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 834fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Add machine specific clobbers 835fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (const char *C = Target.getClobbers()) { 836fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (!Constraints.empty()) 837fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 838fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += C; 839fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 840f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 841fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const llvm::FunctionType *FTy = 842fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::FunctionType::get(ResultType, ArgTypes, false); 843fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 844fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::InlineAsm *IA = 845fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::InlineAsm::get(FTy, AsmString, Constraints, 846fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.isVolatile() || S.getNumOutputs() == 0); 847fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::Value *Result = Builder.CreateCall(IA, Args.begin(), Args.end(), ""); 8481e692ace08959399794363e77499b73da5494af9Eli Friedman if (ResultAddr) // FIXME: volatility 849fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Builder.CreateStore(Result, ResultAddr); 850fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 851