13d45a7739bae1e9c53c94ebb38c4339bd8ec0ca6Chad Rosier//===--- SemaStmtAsm.cpp - Semantic Analysis for Asm Statements -----------===// 24b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// 34b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// The LLVM Compiler Infrastructure 44b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// 54b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// This file is distributed under the University of Illinois Open Source 64b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// License. See LICENSE.TXT for details. 74b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// 84b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier//===----------------------------------------------------------------------===// 94b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// 104b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// This file implements semantic analysis for inline asm statements. 114b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// 124b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier//===----------------------------------------------------------------------===// 134b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 144b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "clang/Sema/SemaInternal.h" 154b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "clang/Sema/Scope.h" 164b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "clang/Sema/ScopeInfo.h" 174b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "clang/Sema/Initialization.h" 184b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "clang/Sema/Lookup.h" 194b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "clang/AST/TypeLoc.h" 204b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "clang/Lex/Preprocessor.h" 214b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "clang/Basic/TargetInfo.h" 224b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/ADT/ArrayRef.h" 234b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/ADT/BitVector.h" 244b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/ADT/SmallString.h" 254b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/MC/MCAsmInfo.h" 264b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/MC/MCContext.h" 276e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier#include "llvm/MC/MCExpr.h" 284b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/MC/MCInst.h" 294b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/MC/MCInstPrinter.h" 304b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/MC/MCInstrInfo.h" 314b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/MC/MCObjectFileInfo.h" 324b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/MC/MCRegisterInfo.h" 334b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/MC/MCStreamer.h" 344b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/MC/MCSubtargetInfo.h" 356e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier#include "llvm/MC/MCSymbol.h" 364b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/MC/MCTargetAsmParser.h" 374b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/MC/MCParser/MCAsmLexer.h" 384b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/MC/MCParser/MCAsmParser.h" 394b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/Support/SourceMgr.h" 404b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/Support/TargetRegistry.h" 414b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/Support/TargetSelect.h" 424b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosierusing namespace clang; 434b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosierusing namespace sema; 444b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 454b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// CheckAsmLValue - GNU C has an extremely ugly extension whereby they silently 464b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// ignore "noop" casts in places where an lvalue is required by an inline asm. 474b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// We emulate this behavior when -fheinous-gnu-extensions is specified, but 484b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// provide a strong guidance to not use it. 494b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// 504b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// This method checks to see if the argument is an acceptable l-value and 514b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// returns false if it is a case we can handle. 524b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosierstatic bool CheckAsmLValue(const Expr *E, Sema &S) { 534b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Type dependent expressions will be checked during instantiation. 544b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (E->isTypeDependent()) 554b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return false; 564b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 574b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (E->isLValue()) 584b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return false; // Cool, this is an lvalue. 594b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 604b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Okay, this is not an lvalue, but perhaps it is the result of a cast that we 614b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // are supposed to allow. 624b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier const Expr *E2 = E->IgnoreParenNoopCasts(S.Context); 634b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (E != E2 && E2->isLValue()) { 644b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!S.getLangOpts().HeinousExtensions) 654b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier S.Diag(E2->getLocStart(), diag::err_invalid_asm_cast_lvalue) 664b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << E->getSourceRange(); 674b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier else 684b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier S.Diag(E2->getLocStart(), diag::warn_invalid_asm_cast_lvalue) 694b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << E->getSourceRange(); 704b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Accept, even if we emitted an error diagnostic. 714b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return false; 724b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 734b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 744b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // None of the above, just randomly invalid non-lvalue. 754b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return true; 764b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier} 774b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 784b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// isOperandMentioned - Return true if the specified operand # is mentioned 794b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// anywhere in the decomposed asm string. 804b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosierstatic bool isOperandMentioned(unsigned OpNo, 81df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier ArrayRef<GCCAsmStmt::AsmStringPiece> AsmStrPieces) { 824b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier for (unsigned p = 0, e = AsmStrPieces.size(); p != e; ++p) { 83df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier const GCCAsmStmt::AsmStringPiece &Piece = AsmStrPieces[p]; 844b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Piece.isOperand()) continue; 854b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 864b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // If this is a reference to the input and if the input was the smaller 874b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // one, then we have to reject this asm. 884b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (Piece.getOperandNo() == OpNo) 894b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return true; 904b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 914b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return false; 924b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier} 934b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 94df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad RosierStmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, 95df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier bool IsVolatile, unsigned NumOutputs, 96df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier unsigned NumInputs, IdentifierInfo **Names, 97df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier MultiExprArg constraints, MultiExprArg exprs, 98df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier Expr *asmString, MultiExprArg clobbers, 99df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier SourceLocation RParenLoc) { 1004b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier unsigned NumClobbers = clobbers.size(); 1014b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringLiteral **Constraints = 1025354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer reinterpret_cast<StringLiteral**>(constraints.data()); 1035354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer Expr **Exprs = exprs.data(); 1044b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringLiteral *AsmString = cast<StringLiteral>(asmString); 1055354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer StringLiteral **Clobbers = reinterpret_cast<StringLiteral**>(clobbers.data()); 1064b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1074b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos; 1084b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1094b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // The parser verifies that there is a string literal here. 1104b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!AsmString->isAscii()) 1114b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(AsmString->getLocStart(),diag::err_asm_wide_character) 1124b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << AsmString->getSourceRange()); 1134b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1144b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier for (unsigned i = 0; i != NumOutputs; i++) { 1154b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringLiteral *Literal = Constraints[i]; 1164b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Literal->isAscii()) 1174b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) 1184b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << Literal->getSourceRange()); 1194b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1204b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringRef OutputName; 1214b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (Names[i]) 1224b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OutputName = Names[i]->getName(); 1234b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1244b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName); 1254b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Context.getTargetInfo().validateOutputConstraint(Info)) 1264b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(Literal->getLocStart(), 1274b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier diag::err_asm_invalid_output_constraint) 1284b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << Info.getConstraintStr()); 1294b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1304b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Check that the output exprs are valid lvalues. 1314b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Expr *OutputExpr = Exprs[i]; 1324b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (CheckAsmLValue(OutputExpr, *this)) { 1334b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(OutputExpr->getLocStart(), 1344b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier diag::err_asm_invalid_lvalue_in_output) 1354b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << OutputExpr->getSourceRange()); 1364b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 1374b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1384b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OutputConstraintInfos.push_back(Info); 1394b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 1404b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1414b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos; 1424b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1434b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) { 1444b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringLiteral *Literal = Constraints[i]; 1454b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Literal->isAscii()) 1464b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) 1474b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << Literal->getSourceRange()); 1484b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1494b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringRef InputName; 1504b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (Names[i]) 1514b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputName = Names[i]->getName(); 1524b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1534b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier TargetInfo::ConstraintInfo Info(Literal->getString(), InputName); 1544b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos.data(), 1554b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier NumOutputs, Info)) { 1564b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(Literal->getLocStart(), 1574b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier diag::err_asm_invalid_input_constraint) 1584b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << Info.getConstraintStr()); 1594b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 1604b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1614b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Expr *InputExpr = Exprs[i]; 1624b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1634b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Only allow void types for memory constraints. 1644b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (Info.allowsMemory() && !Info.allowsRegister()) { 1654b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (CheckAsmLValue(InputExpr, *this)) 1664b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(InputExpr->getLocStart(), 1674b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier diag::err_asm_invalid_lvalue_in_input) 1684b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << Info.getConstraintStr() 1694b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << InputExpr->getSourceRange()); 1704b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 1714b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1724b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (Info.allowsRegister()) { 1734b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (InputExpr->getType()->isVoidType()) { 1744b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(InputExpr->getLocStart(), 1754b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier diag::err_asm_invalid_type_in_input) 1764b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << InputExpr->getType() << Info.getConstraintStr() 1774b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << InputExpr->getSourceRange()); 1784b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 1794b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 1804b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1814b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier ExprResult Result = DefaultFunctionArrayLvalueConversion(Exprs[i]); 1824b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (Result.isInvalid()) 1834b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(); 1844b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1854b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Exprs[i] = Result.take(); 1864b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputConstraintInfos.push_back(Info); 1874b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 1884b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1894b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Check that the clobbers are valid. 1904b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier for (unsigned i = 0; i != NumClobbers; i++) { 1914b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringLiteral *Literal = Clobbers[i]; 1924b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Literal->isAscii()) 1934b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) 1944b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << Literal->getSourceRange()); 1954b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1964b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringRef Clobber = Literal->getString(); 1974b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1984b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Context.getTargetInfo().isValidClobber(Clobber)) 1994b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(Literal->getLocStart(), 2004b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier diag::err_asm_unknown_register_name) << Clobber); 2014b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 2024b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 203df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier GCCAsmStmt *NS = 204df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier new (Context) GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, 205df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier NumInputs, Names, Constraints, Exprs, AsmString, 206df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier NumClobbers, Clobbers, RParenLoc); 2074b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Validate the asm string, ensuring it makes sense given the operands we 2084b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // have. 209df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier SmallVector<GCCAsmStmt::AsmStringPiece, 8> Pieces; 2104b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier unsigned DiagOffs; 2114b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (unsigned DiagID = NS->AnalyzeAsmString(Pieces, Context, DiagOffs)) { 2124b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Diag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID) 2134b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << AsmString->getSourceRange(); 2144b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(); 2154b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 2164b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2174b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Validate tied input operands for type mismatches. 2184b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) { 2194b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i]; 2204b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2214b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // If this is a tied constraint, verify that the output and input have 2224b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // either exactly the same type, or that they are int/ptr operands with the 2234b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // same size (int/long, int*/long, are ok etc). 2244b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Info.hasTiedOperand()) continue; 2254b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2264b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier unsigned TiedTo = Info.getTiedOperand(); 2274b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier unsigned InputOpNo = i+NumOutputs; 2284b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Expr *OutputExpr = Exprs[TiedTo]; 2294b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Expr *InputExpr = Exprs[InputOpNo]; 2304b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2314b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (OutputExpr->isTypeDependent() || InputExpr->isTypeDependent()) 2324b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier continue; 2334b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2344b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier QualType InTy = InputExpr->getType(); 2354b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier QualType OutTy = OutputExpr->getType(); 2364b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (Context.hasSameType(InTy, OutTy)) 2374b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier continue; // All types can be tied to themselves. 2384b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2394b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Decide if the input and output are in the same domain (integer/ptr or 2404b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // floating point. 2414b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier enum AsmDomain { 2424b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier AD_Int, AD_FP, AD_Other 2434b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } InputDomain, OutputDomain; 2444b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2454b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (InTy->isIntegerType() || InTy->isPointerType()) 2464b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputDomain = AD_Int; 2474b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier else if (InTy->isRealFloatingType()) 2484b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputDomain = AD_FP; 2494b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier else 2504b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputDomain = AD_Other; 2514b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2524b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (OutTy->isIntegerType() || OutTy->isPointerType()) 2534b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OutputDomain = AD_Int; 2544b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier else if (OutTy->isRealFloatingType()) 2554b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OutputDomain = AD_FP; 2564b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier else 2574b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OutputDomain = AD_Other; 2584b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2594b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // They are ok if they are the same size and in the same domain. This 2604b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // allows tying things like: 2614b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // void* to int* 2624b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // void* to int if they are the same size. 2634b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // double to long double if they are the same size. 2644b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // 2654b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier uint64_t OutSize = Context.getTypeSize(OutTy); 2664b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier uint64_t InSize = Context.getTypeSize(InTy); 2674b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (OutSize == InSize && InputDomain == OutputDomain && 2684b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputDomain != AD_Other) 2694b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier continue; 2704b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2714b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // If the smaller input/output operand is not mentioned in the asm string, 2724b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // then we can promote the smaller one to a larger input and the asm string 2734b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // won't notice. 2744b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier bool SmallerValueMentioned = false; 2754b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2764b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // If this is a reference to the input and if the input was the smaller 2774b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // one, then we have to reject this asm. 2784b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (isOperandMentioned(InputOpNo, Pieces)) { 2794b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // This is a use in the asm string of the smaller operand. Since we 2804b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // codegen this by promoting to a wider value, the asm will get printed 2814b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // "wrong". 2824b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SmallerValueMentioned |= InSize < OutSize; 2834b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 2844b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (isOperandMentioned(TiedTo, Pieces)) { 2854b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // If this is a reference to the output, and if the output is the larger 2864b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // value, then it's ok because we'll promote the input to the larger type. 2874b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SmallerValueMentioned |= OutSize < InSize; 2884b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 2894b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2904b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // If the smaller value wasn't mentioned in the asm string, and if the 2914b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // output was a register, just extend the shorter one to the size of the 2924b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // larger one. 2934b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!SmallerValueMentioned && InputDomain != AD_Other && 2944b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OutputConstraintInfos[TiedTo].allowsRegister()) 2954b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier continue; 2964b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2974b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Either both of the operands were mentioned or the smaller one was 2984b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // mentioned. One more special case that we'll allow: if the tied input is 2994b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // integer, unmentioned, and is a constant, then we'll allow truncating it 3004b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // down to the size of the destination. 3014b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (InputDomain == AD_Int && OutputDomain == AD_Int && 3024b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier !isOperandMentioned(InputOpNo, Pieces) && 3034b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputExpr->isEvaluatable(Context)) { 3044b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier CastKind castKind = 3054b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier (OutTy->isBooleanType() ? CK_IntegralToBoolean : CK_IntegralCast); 3064b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputExpr = ImpCastExprToType(InputExpr, OutTy, castKind).take(); 3074b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Exprs[InputOpNo] = InputExpr; 3084b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier NS->setInputExpr(i, InputExpr); 3094b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier continue; 3104b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 3114b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 3124b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Diag(InputExpr->getLocStart(), 3134b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier diag::err_asm_tying_incompatible_types) 3144b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << InTy << OutTy << OutputExpr->getSourceRange() 3154b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << InputExpr->getSourceRange(); 3164b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(); 3174b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 3184b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 3194b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return Owned(NS); 3204b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier} 3214b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 3224b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// isMSAsmKeyword - Return true if this is an MS-style inline asm keyword. These 3234b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// require special handling. 3244b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosierstatic bool isMSAsmKeyword(StringRef Name) { 3254b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier bool Ret = llvm::StringSwitch<bool>(Name) 3264b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier .Cases("EVEN", "ALIGN", true) // Alignment directives. 3274b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier .Cases("LENGTH", "SIZE", "TYPE", true) // Type and variable sizes. 3284b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier .Case("_emit", true) // _emit Pseudoinstruction. 3294b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier .Default(false); 3304b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return Ret; 3314b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier} 3324b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 3336e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier// getIdentifierInfo - Given a Name and a range of tokens, find the associated 3346e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier// IdentifierInfo*. 3356e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosierstatic IdentifierInfo *getIdentifierInfo(StringRef Name, 3366e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier ArrayRef<Token> AsmToks, 3376e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier unsigned Begin, unsigned End) { 3386e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier for (unsigned i = Begin; i <= End; ++i) { 3396e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier IdentifierInfo *II = AsmToks[i].getIdentifierInfo(); 3406e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier if (II && II->getName() == Name) 3416e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier return II; 3426e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier } 3436e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier return 0; 3446e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier} 3456e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier 346358ab765f36f70d0744ede7dc35ce74c0911e77dChad Rosier// getSpelling - Get the spelling of the AsmTok token. 3474b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosierstatic StringRef getSpelling(Sema &SemaRef, Token AsmTok) { 3484b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringRef Asm; 3494b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SmallString<512> TokenBuf; 3504b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier TokenBuf.resize(512); 3514b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier bool StringInvalid = false; 3524b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Asm = SemaRef.PP.getSpelling(AsmTok, TokenBuf, &StringInvalid); 3534b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier assert (!StringInvalid && "Expected valid string!"); 3544b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return Asm; 3554b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier} 3564b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 357358ab765f36f70d0744ede7dc35ce74c0911e77dChad Rosier// Determine if we should bail on this MSAsm instruction. 3582735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosierstatic bool bailOnMSAsm(std::vector<StringRef> Piece) { 3592735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier for (unsigned i = 0, e = Piece.size(); i != e; ++i) 3602735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier if (isMSAsmKeyword(Piece[i])) 3612735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier return true; 3622735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier return false; 3632735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier} 3642735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier 365358ab765f36f70d0744ede7dc35ce74c0911e77dChad Rosier// Determine if we should bail on this MSAsm block. 3662735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosierstatic bool bailOnMSAsm(std::vector<std::vector<StringRef> > Pieces) { 3672735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier for (unsigned i = 0, e = Pieces.size(); i != e; ++i) 3682735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier if (bailOnMSAsm(Pieces[i])) 3692735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier return true; 3702735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier return false; 3712735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier} 3722735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier 373358ab765f36f70d0744ede7dc35ce74c0911e77dChad Rosier// Determine if this is a simple MSAsm instruction. 37498ac608c79fb46e73715121018f0659fb3bbe3e8Chad Rosierstatic bool isSimpleMSAsm(std::vector<StringRef> &Pieces, 37598ac608c79fb46e73715121018f0659fb3bbe3e8Chad Rosier const TargetInfo &TI) { 37698ac608c79fb46e73715121018f0659fb3bbe3e8Chad Rosier if (isMSAsmKeyword(Pieces[0])) 37798ac608c79fb46e73715121018f0659fb3bbe3e8Chad Rosier return false; 3784b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 37998ac608c79fb46e73715121018f0659fb3bbe3e8Chad Rosier for (unsigned i = 1, e = Pieces.size(); i != e; ++i) 38098ac608c79fb46e73715121018f0659fb3bbe3e8Chad Rosier if (!TI.isValidGCCRegisterName(Pieces[i])) 38198ac608c79fb46e73715121018f0659fb3bbe3e8Chad Rosier return false; 382153f8ecb5169347e41a0734ee1698498d88b96c5Chad Rosier return true; 383153f8ecb5169347e41a0734ee1698498d88b96c5Chad Rosier} 3844b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 385358ab765f36f70d0744ede7dc35ce74c0911e77dChad Rosier// Determine if this is a simple MSAsm block. 386153f8ecb5169347e41a0734ee1698498d88b96c5Chad Rosierstatic bool isSimpleMSAsm(std::vector<std::vector<StringRef> > Pieces, 387153f8ecb5169347e41a0734ee1698498d88b96c5Chad Rosier const TargetInfo &TI) { 388153f8ecb5169347e41a0734ee1698498d88b96c5Chad Rosier for (unsigned i = 0, e = Pieces.size(); i != e; ++i) 389153f8ecb5169347e41a0734ee1698498d88b96c5Chad Rosier if (!isSimpleMSAsm(Pieces[i], TI)) 390153f8ecb5169347e41a0734ee1698498d88b96c5Chad Rosier return false; 39198ac608c79fb46e73715121018f0659fb3bbe3e8Chad Rosier return true; 3924b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier} 3934b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 394358ab765f36f70d0744ede7dc35ce74c0911e77dChad Rosier// Break the AsmSting into pieces (i.e., mnemonic and operands). 39538c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosierstatic void buildMSAsmPieces(StringRef Asm, std::vector<StringRef> &Pieces) { 39638c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier std::pair<StringRef,StringRef> Split = Asm.split(' '); 39738c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier 39838c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier // Mnemonic 39938c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier Pieces.push_back(Split.first); 40038c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier Asm = Split.second; 40138c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier 40238c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier // Operands 40338c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier while (!Asm.empty()) { 40438c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier Split = Asm.split(", "); 40538c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier Pieces.push_back(Split.first); 40638c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier Asm = Split.second; 40738c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier } 40838c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier} 40938c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier 410f0fbd776df77bc4b8b3e6ff3542b2e9117b2b905Chad Rosierstatic void buildMSAsmPieces(std::vector<std::string> &AsmStrings, 411f0fbd776df77bc4b8b3e6ff3542b2e9117b2b905Chad Rosier std::vector<std::vector<StringRef> > &Pieces) { 412f0fbd776df77bc4b8b3e6ff3542b2e9117b2b905Chad Rosier for (unsigned i = 0, e = AsmStrings.size(); i != e; ++i) 413f0fbd776df77bc4b8b3e6ff3542b2e9117b2b905Chad Rosier buildMSAsmPieces(AsmStrings[i], Pieces[i]); 414f0fbd776df77bc4b8b3e6ff3542b2e9117b2b905Chad Rosier} 415f0fbd776df77bc4b8b3e6ff3542b2e9117b2b905Chad Rosier 416682ad162f144ff8e8e5303d30bc48b6a6a41d0d6Chad Rosier// Build the unmodified AsmString used by the IR. Also build the individual 417682ad162f144ff8e8e5303d30bc48b6a6a41d0d6Chad Rosier// asm instruction(s) and place them in the AsmStrings vector; these are fed 418682ad162f144ff8e8e5303d30bc48b6a6a41d0d6Chad Rosier// to the AsmParser. 4199072a026a111726022b4f1c7f0a925d642ae8991Chad Rosierstatic std::string buildMSAsmString(Sema &SemaRef, ArrayRef<Token> AsmToks, 4209072a026a111726022b4f1c7f0a925d642ae8991Chad Rosier std::vector<std::string> &AsmStrings, 4219072a026a111726022b4f1c7f0a925d642ae8991Chad Rosier std::vector<std::pair<unsigned,unsigned> > &AsmTokRanges) { 4224b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier assert (!AsmToks.empty() && "Didn't expect an empty AsmToks!"); 4234b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 42438c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier SmallString<512> Res; 4254b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SmallString<512> Asm; 4269072a026a111726022b4f1c7f0a925d642ae8991Chad Rosier unsigned startTok = 0; 4274b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) { 4284b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier bool isNewAsm = i == 0 || AsmToks[i].isAtStartOfLine() || 4294b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier AsmToks[i].is(tok::kw_asm); 4304b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 4314b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (isNewAsm) { 43238c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier if (i) { 43332f3acc0103055b1ef171fa94d1ee6d1deb0223eBenjamin Kramer AsmStrings.push_back(Asm.str()); 4349072a026a111726022b4f1c7f0a925d642ae8991Chad Rosier AsmTokRanges.push_back(std::make_pair(startTok, i-1)); 4359072a026a111726022b4f1c7f0a925d642ae8991Chad Rosier startTok = i; 43638c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier Res += Asm; 43738c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier Asm.clear(); 43838c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier Res += '\n'; 43938c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier } 4404b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (AsmToks[i].is(tok::kw_asm)) { 4414b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier i++; // Skip __asm 4424b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier assert (i != e && "Expected another token"); 4434b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 4444b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 4454b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 4464b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (i && AsmToks[i].hasLeadingSpace() && !isNewAsm) 4474b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Asm += ' '; 4484b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 4494b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Asm += getSpelling(SemaRef, AsmToks[i]); 4504b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 45132f3acc0103055b1ef171fa94d1ee6d1deb0223eBenjamin Kramer AsmStrings.push_back(Asm.str()); 4529072a026a111726022b4f1c7f0a925d642ae8991Chad Rosier AsmTokRanges.push_back(std::make_pair(startTok, AsmToks.size()-1)); 45338c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier Res += Asm; 45432f3acc0103055b1ef171fa94d1ee6d1deb0223eBenjamin Kramer return Res.str(); 4554b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier} 4564b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 457c69164917460ff717fd0b02649a3d7b0c5096088Chad Rosier#define DEF_SIMPLE_MSASM(STR) \ 45889fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier MSAsmStmt *NS = \ 45989fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true, \ 46089fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier /*IsVolatile*/ true, AsmToks, Inputs, Outputs, \ 461c69164917460ff717fd0b02649a3d7b0c5096088Chad Rosier InputExprs, OutputExprs, STR, Constraints, \ 46289fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier Clobbers, EndLoc); 4632735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier 4644b5e48d39eb94ee12f3d89df60525053d8b0275eChad RosierStmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, 4654b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SourceLocation LBraceLoc, 4664b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier ArrayRef<Token> AsmToks, 4674b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SourceLocation EndLoc) { 46889fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier SmallVector<StringRef, 4> Constraints; 46989fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier std::vector<std::string> InputConstraints; 47089fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier std::vector<std::string> OutputConstraints; 4714112a4c001c0ffe83962e5c6755c8b3e0d74b74cChad Rosier SmallVector<StringRef, 4> Clobbers; 4724b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier std::set<std::string> ClobberRegs; 4734b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SmallVector<IdentifierInfo*, 4> Inputs; 4744b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SmallVector<IdentifierInfo*, 4> Outputs; 475633abb0ea01d37ab9c8e4ce1ee9e48894a12dfcaChad Rosier SmallVector<Expr*, 4> InputExprs; 476633abb0ea01d37ab9c8e4ce1ee9e48894a12dfcaChad Rosier SmallVector<Expr*, 4> OutputExprs; 477acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier SmallVector<std::string, 4> InputExprNames; 478acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier SmallVector<std::string, 4> OutputExprNames; 4794b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 4804b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Empty asm statements don't need to instantiate the AsmParser, etc. 481c69164917460ff717fd0b02649a3d7b0c5096088Chad Rosier StringRef EmptyAsmStr; 482c69164917460ff717fd0b02649a3d7b0c5096088Chad Rosier if (AsmToks.empty()) { DEF_SIMPLE_MSASM(EmptyAsmStr); return Owned(NS); } 4834b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 48438c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier std::vector<std::string> AsmStrings; 4859072a026a111726022b4f1c7f0a925d642ae8991Chad Rosier std::vector<std::pair<unsigned,unsigned> > AsmTokRanges; 4868a30e7735a5c2b8b105734fc9b131cc43c56d765Chad Rosier std::string AsmString = buildMSAsmString(*this, AsmToks, AsmStrings, 4878a30e7735a5c2b8b105734fc9b131cc43c56d765Chad Rosier AsmTokRanges); 48838c71d38e1b2a5f71c086b9c2efa9e8e69fa1bb5Chad Rosier 489e78460f4335766b55c3da6a43fcd072671076458Chad Rosier std::vector<std::vector<StringRef> > Pieces(AsmStrings.size()); 490f0fbd776df77bc4b8b3e6ff3542b2e9117b2b905Chad Rosier buildMSAsmPieces(AsmStrings, Pieces); 491153f8ecb5169347e41a0734ee1698498d88b96c5Chad Rosier 492153f8ecb5169347e41a0734ee1698498d88b96c5Chad Rosier bool IsSimple = isSimpleMSAsm(Pieces, Context.getTargetInfo()); 4934b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 4942735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier // AsmParser doesn't fully support these asm statements. 495c69164917460ff717fd0b02649a3d7b0c5096088Chad Rosier if (bailOnMSAsm(Pieces)) { DEF_SIMPLE_MSASM(EmptyAsmStr); return Owned(NS); } 4964b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 4974b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Initialize targets and assembly printers/parsers. 4984b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier llvm::InitializeAllTargetInfos(); 4994b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier llvm::InitializeAllTargetMCs(); 5004b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier llvm::InitializeAllAsmParsers(); 5014b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 5024b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Get the target specific parser. 5034b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier std::string Error; 5044b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier const std::string &TT = Context.getTargetInfo().getTriple().getTriple(); 5054b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier const llvm::Target *TheTarget(llvm::TargetRegistry::lookupTarget(TT, Error)); 5064b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 5074b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OwningPtr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TT)); 5084b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OwningPtr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT)); 5094b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OwningPtr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo()); 5104b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OwningPtr<llvm::MCSubtargetInfo> 5114b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier STI(TheTarget->createMCSubtargetInfo(TT, "", "")); 5124b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 51325bd2986db1c7b8ced84fe835f5465007de47892Chad Rosier for (unsigned StrIdx = 0, e = AsmStrings.size(); StrIdx != e; ++StrIdx) { 5144b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier llvm::SourceMgr SrcMgr; 5154b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier llvm::MCContext Ctx(*MAI, *MRI, MOFI.get(), &SrcMgr); 5164b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier llvm::MemoryBuffer *Buffer = 51725bd2986db1c7b8ced84fe835f5465007de47892Chad Rosier llvm::MemoryBuffer::getMemBuffer(AsmStrings[StrIdx], "<inline asm>"); 5184b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 5194b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Tell SrcMgr about this buffer, which is what the parser will pick up. 5204b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SrcMgr.AddNewSourceBuffer(Buffer, llvm::SMLoc()); 5214b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 5224b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OwningPtr<llvm::MCStreamer> Str(createNullStreamer(Ctx)); 5234b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OwningPtr<llvm::MCAsmParser> 5244b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Parser(createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI)); 5254b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OwningPtr<llvm::MCTargetAsmParser> 5264b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier TargetParser(TheTarget->createMCAsmParser(*STI, *Parser)); 5274b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Change to the Intel dialect. 5284b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Parser->setAssemblerDialect(1); 5294b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Parser->setTargetParser(*TargetParser.get()); 5304b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 5314b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Prime the lexer. 5324b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Parser->Lex(); 5334b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 5344b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Parse the opcode. 5354b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringRef IDVal; 5364b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Parser->ParseIdentifier(IDVal); 5374b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 5384b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Canonicalize the opcode to lower case. 539be5c3fbec3a430bab2524e9315f58f64815bfeafChad Rosier SmallString<128> OpcodeStr; 540b706d9027cd8bbbaffa8b359a501cba52ace4c09Chad Rosier for (unsigned i = 0, e = IDVal.size(); i != e; ++i) 541be5c3fbec3a430bab2524e9315f58f64815bfeafChad Rosier OpcodeStr.push_back(tolower(IDVal[i])); 5424b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 5434b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Parse the operands. 5444b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier llvm::SMLoc IDLoc; 5454b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SmallVector<llvm::MCParsedAsmOperand*, 8> Operands; 546be5c3fbec3a430bab2524e9315f58f64815bfeafChad Rosier bool HadError = TargetParser->ParseInstruction(OpcodeStr.str(), IDLoc, 5474b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Operands); 5482735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier // If we had an error parsing the operands, fail gracefully. 549c69164917460ff717fd0b02649a3d7b0c5096088Chad Rosier if (HadError) { DEF_SIMPLE_MSASM(EmptyAsmStr); return Owned(NS); } 5504b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 5514b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Match the MCInstr. 552be5c3fbec3a430bab2524e9315f58f64815bfeafChad Rosier unsigned Kind; 55383591b6d3f20ee84f4abe1c2574e90736aa84b11Chad Rosier unsigned ErrorInfo; 5544b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SmallVector<llvm::MCInst, 2> Instrs; 5557065c52fc53ec3106a97b7c8d373df431f3bd4f3Chad Rosier HadError = TargetParser->MatchInstruction(IDLoc, Kind, Operands, Instrs, 5567065c52fc53ec3106a97b7c8d373df431f3bd4f3Chad Rosier ErrorInfo, 55751a6b3f58b0dbbc51a77b8f4a509720954406cebChad Rosier /*matchingInlineAsm*/ true); 5582735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier // If we had an error parsing the operands, fail gracefully. 559c69164917460ff717fd0b02649a3d7b0c5096088Chad Rosier if (HadError) { DEF_SIMPLE_MSASM(EmptyAsmStr); return Owned(NS); } 5604b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 5614b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Get the instruction descriptor. 5624b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier llvm::MCInst Inst = Instrs[0]; 5634b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo(); 5644b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier const llvm::MCInstrDesc &Desc = MII->get(Inst.getOpcode()); 5654b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier llvm::MCInstPrinter *IP = 5664b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI); 5674b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 5686e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier // Build the list of clobbers, outputs and inputs. 569fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier unsigned NumDefs = Desc.getNumDefs(); 5701b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier for (unsigned i = 1, e = Operands.size(); i != e; ++i) { 5711b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier unsigned NumMCOperands; 5728cdd8a9f19146582aeadae3fe38ae21ffbe3deebChad Rosier unsigned MCIdx = TargetParser->getMCInstOperandNum(Kind, Inst, Operands, 573d5eb585a02d6905b5e6f83fd03a90d583a39ac82Chad Rosier i, NumMCOperands); 5741b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier assert (NumMCOperands && "Expected at least 1 MCOperand!"); 5751b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier // If we have a one-to-many mapping, then search for the MCExpr. 5761b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier if (NumMCOperands > 1) { 5771b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier bool foundExpr = false; 5781b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier for (unsigned j = MCIdx, e = MCIdx + NumMCOperands; j != e; ++j) { 5791b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier if (Inst.getOperand(j).isExpr()) { 5801b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier foundExpr = true; 5811b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier MCIdx = j; 5821b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier break; 5831b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier } 5841b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier } 5851b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier assert (foundExpr && "Expected for find an expression!"); 5861b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier } 5871b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier 5881b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier const llvm::MCOperand &Op = Inst.getOperand(MCIdx); 589fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier 590fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier // Immediate. 591fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier if (Op.isImm() || Op.isFPImm()) 5924b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier continue; 5934b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 5941b497f26ab7861b22383b22f35cf799c0b312c9bChad Rosier bool isDef = NumDefs && (MCIdx < NumDefs); 595fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier 596fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier // Register/Clobber. 597fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier if (Op.isReg() && isDef) { 598fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier std::string Reg; 599fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier llvm::raw_string_ostream OS(Reg); 600fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier IP->printRegName(OS, Op.getReg()); 6014b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 602fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier StringRef Clobber(OS.str()); 603fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier if (!Context.getTargetInfo().isValidClobber(Clobber)) 604fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier return StmtError(Diag(AsmLoc, diag::err_asm_unknown_register_name) << 605fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier Clobber); 606fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier ClobberRegs.insert(Reg); 6076e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier continue; 6086e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier } 6096e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier // Expr/Input or Output. 6106e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier if (Op.isExpr()) { 6116e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier const llvm::MCExpr *Expr = Op.getExpr(); 6126e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier const llvm::MCSymbolRefExpr *SymRef; 6136e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier if ((SymRef = dyn_cast<llvm::MCSymbolRefExpr>(Expr))) { 6146e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier StringRef Name = SymRef->getSymbol().getName(); 61560ce584e35503af623e14eeab8fd81df9f215dcdChad Rosier IdentifierInfo *II = getIdentifierInfo(Name, AsmToks, 61625bd2986db1c7b8ced84fe835f5465007de47892Chad Rosier AsmTokRanges[StrIdx].first, 61725bd2986db1c7b8ced84fe835f5465007de47892Chad Rosier AsmTokRanges[StrIdx].second); 618633abb0ea01d37ab9c8e4ce1ee9e48894a12dfcaChad Rosier if (II) { 6191016bdf939fd4a7b65793904610a7e647ec9d89fChad Rosier CXXScopeSpec SS; 6201016bdf939fd4a7b65793904610a7e647ec9d89fChad Rosier UnqualifiedId Id; 6211016bdf939fd4a7b65793904610a7e647ec9d89fChad Rosier SourceLocation Loc; 6221016bdf939fd4a7b65793904610a7e647ec9d89fChad Rosier Id.setIdentifier(II, AsmLoc); 6231016bdf939fd4a7b65793904610a7e647ec9d89fChad Rosier ExprResult Result = ActOnIdExpression(getCurScope(), SS, Loc, Id, 6241016bdf939fd4a7b65793904610a7e647ec9d89fChad Rosier false, false); 6251016bdf939fd4a7b65793904610a7e647ec9d89fChad Rosier if (!Result.isInvalid()) { 62621a37047e56d717c7979fa653c9f30aae468608dChad Rosier bool isMemDef = (i == 1) && Desc.mayStore(); 62721a37047e56d717c7979fa653c9f30aae468608dChad Rosier if (isDef || isMemDef) { 6281016bdf939fd4a7b65793904610a7e647ec9d89fChad Rosier Outputs.push_back(II); 6291016bdf939fd4a7b65793904610a7e647ec9d89fChad Rosier OutputExprs.push_back(Result.take()); 630acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier OutputExprNames.push_back(Name.str()); 63189fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier OutputConstraints.push_back("=r"); 6321016bdf939fd4a7b65793904610a7e647ec9d89fChad Rosier } else { 6331016bdf939fd4a7b65793904610a7e647ec9d89fChad Rosier Inputs.push_back(II); 6341016bdf939fd4a7b65793904610a7e647ec9d89fChad Rosier InputExprs.push_back(Result.take()); 635acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier InputExprNames.push_back(Name.str()); 63689fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier InputConstraints.push_back("r"); 6371016bdf939fd4a7b65793904610a7e647ec9d89fChad Rosier } 638633abb0ea01d37ab9c8e4ce1ee9e48894a12dfcaChad Rosier } 639633abb0ea01d37ab9c8e4ce1ee9e48894a12dfcaChad Rosier } 6406e97be719edb4e3b9ac15353e79c60406b3dc429Chad Rosier } 641fd5e56e35404cb44130b17546b6b5c1b33709d23Chad Rosier } 6424b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 6434b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 6444b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier for (std::set<std::string>::iterator I = ClobberRegs.begin(), 6454b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier E = ClobberRegs.end(); I != E; ++I) 6464b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Clobbers.push_back(*I); 6474b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 64889fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier // Merge the output and input constraints. Output constraints are expected 64989fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier // first. 65089fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier for (std::vector<std::string>::iterator I = OutputConstraints.begin(), 65189fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier E = OutputConstraints.end(); I != E; ++I) 65289fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier Constraints.push_back(*I); 65389fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier 65489fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier for (std::vector<std::string>::iterator I = InputConstraints.begin(), 65589fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier E = InputConstraints.end(); I != E; ++I) 65689fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier Constraints.push_back(*I); 65789fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier 658acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier // Enumerate the AsmString expressions. 659acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier // FIXME: This isn't going to work if: 660acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier // 1. The symbol name and an opcode/reg share the same, or are a substring of 661acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier // the, name. 662acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier // 2. The symbol name appears more then once in the asm string. 663acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier unsigned OpNum = 0; 664acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier for (unsigned i = 0, e = OutputExprNames.size(); i != e; ++i, ++OpNum) { 665acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier size_t found = AsmString.find(OutputExprNames[i]); 666acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier SmallString<32> Res; 667acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier llvm::raw_svector_ostream OS(Res); 668acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier OS << '$' << OpNum; 669acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier AsmString.replace(found, OutputExprNames[i].size(), OS.str()); 670acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier } 671acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier for (unsigned i = 0, e = InputExprNames.size(); i != e; ++i, ++OpNum) { 672acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier size_t found = AsmString.find(InputExprNames[i]); 673acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier SmallString<32> Res; 674acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier llvm::raw_svector_ostream OS(Res); 675acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier OS << '$' << OpNum; 676acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier AsmString.replace(found, InputExprNames[i].size(), OS.str()); 677acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier } 678acc22b6b5a8ba501f896fb0d00afdff5c5a3f090Chad Rosier 6794b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier MSAsmStmt *NS = 6804b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple, 6814b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier /*IsVolatile*/ true, AsmToks, Inputs, Outputs, 68289fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier InputExprs, OutputExprs, AsmString, Constraints, 68389fb6d7eba51c7864ec544e07accd23b24057122Chad Rosier Clobbers, EndLoc); 6844b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return Owned(NS); 6854b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier} 686