diff options
author | Chad Rosier <mcrosier@apple.com> | 2012-09-12 18:14:25 +0000 |
---|---|---|
committer | Chad Rosier <mcrosier@apple.com> | 2012-09-12 18:14:25 +0000 |
commit | 57cd91f683d6852b4de8afeb0026e05d83eaaff7 (patch) | |
tree | f6e509741f65d1afc56336cf9220f11c99941117 /clang/lib/Sema/SemaStmtAsm.cpp | |
parent | f6cb1ee75a0f2eb477506ebe0da2cc6e8579991e (diff) | |
download | bcm5719-llvm-57cd91f683d6852b4de8afeb0026e05d83eaaff7.tar.gz bcm5719-llvm-57cd91f683d6852b4de8afeb0026e05d83eaaff7.zip |
[ms-inline asm] If we have a single asm operand that maps to multiple
MCOperands then iterate over all of then when computing clobbers, inputs and
outputs.
On x86 the 1-to-many mapping is a memory operand that includes a BaseReg(reg),
MemScale(imm), MemIndexReg(reg), an Expr(MCExpr or imm) and a MemSegReg(reg).
Invalid register (Op.getReg() == 0) are not considered when computing clobber.
llvm-svn: 163728
Diffstat (limited to 'clang/lib/Sema/SemaStmtAsm.cpp')
-rw-r--r-- | clang/lib/Sema/SemaStmtAsm.cpp | 108 |
1 files changed, 53 insertions, 55 deletions
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index 3f57a6ec035..9109bcb854a 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -581,62 +581,60 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, unsigned MCIdx = TargetParser->getMCInstOperandNum(Kind, Inst, Operands, i, NumMCOperands); assert (NumMCOperands && "Expected at least 1 MCOperand!"); - // If we have a one-to-many mapping, then search for the MCExpr. - if (NumMCOperands > 1) { - bool foundExpr = false; - for (unsigned j = MCIdx, e = MCIdx + NumMCOperands; j != e; ++j) { - if (Inst.getOperand(j).isExpr()) { - foundExpr = true; - MCIdx = j; - break; - } - } - assert (foundExpr && "Expected for find an expression!"); - } - - const llvm::MCOperand &Op = Inst.getOperand(MCIdx); - // Register/Clobber. - if (Op.isReg() && NumDefs && (MCIdx < NumDefs)) { - std::string Reg; - llvm::raw_string_ostream OS(Reg); - IP->printRegName(OS, Op.getReg()); - - StringRef Clobber(OS.str()); - if (!Context.getTargetInfo().isValidClobber(Clobber)) - return StmtError(Diag(AsmLoc, diag::err_asm_unknown_register_name) << - Clobber); - ClobberRegs.insert(Reg); - continue; - } - // Expr/Input or Output. - if (Op.isExpr()) { - const llvm::MCExpr *Expr = Op.getExpr(); - const llvm::MCSymbolRefExpr *SymRef; - if ((SymRef = dyn_cast<llvm::MCSymbolRefExpr>(Expr))) { - StringRef Name = SymRef->getSymbol().getName(); - IdentifierInfo *II = getIdentifierInfo(Name, AsmToks, - AsmTokRanges[StrIdx].first, - AsmTokRanges[StrIdx].second); - if (II) { - CXXScopeSpec SS; - UnqualifiedId Id; - SourceLocation Loc; - Id.setIdentifier(II, AsmLoc); - ExprResult Result = ActOnIdExpression(getCurScope(), SS, Loc, Id, - false, false); - if (!Result.isInvalid()) { - bool isMemDef = (i == 1) && Desc.mayStore(); - if (isMemDef) { - Outputs.push_back(II); - OutputExprs.push_back(Result.take()); - OutputExprNames.push_back(Name.str()); - OutputConstraints.push_back("=r"); - } else { - Inputs.push_back(II); - InputExprs.push_back(Result.take()); - InputExprNames.push_back(Name.str()); - InputConstraints.push_back("r"); + for (unsigned j = MCIdx, e = MCIdx + NumMCOperands; j != e; ++j) { + const llvm::MCOperand &Op = Inst.getOperand(j); + + // Skip immediates. + if (Op.isImm() || Op.isFPImm()) + continue; + + // Skip invalid register operands. + if (Op.isReg() && Op.getReg() == 0) + continue; + + // Register/Clobber. + if (Op.isReg() && NumDefs && (j < NumDefs)) { + std::string Reg; + llvm::raw_string_ostream OS(Reg); + IP->printRegName(OS, Op.getReg()); + + StringRef Clobber(OS.str()); + if (!Context.getTargetInfo().isValidClobber(Clobber)) + return StmtError( + Diag(AsmLoc, diag::err_asm_unknown_register_name) << Clobber); + ClobberRegs.insert(Reg); + continue; + } + // Expr/Input or Output. + if (Op.isExpr()) { + const llvm::MCExpr *Expr = Op.getExpr(); + const llvm::MCSymbolRefExpr *SymRef; + if ((SymRef = dyn_cast<llvm::MCSymbolRefExpr>(Expr))) { + StringRef Name = SymRef->getSymbol().getName(); + IdentifierInfo *II = getIdentifierInfo(Name, AsmToks, + AsmTokRanges[StrIdx].first, + AsmTokRanges[StrIdx].second); + if (II) { + CXXScopeSpec SS; + UnqualifiedId Id; + SourceLocation Loc; + Id.setIdentifier(II, AsmLoc); + ExprResult Result = ActOnIdExpression(getCurScope(), SS, Loc, Id, + false, false); + if (!Result.isInvalid()) { + bool isMemDef = (i == 1) && Desc.mayStore(); + if (isMemDef) { + Outputs.push_back(II); + OutputExprs.push_back(Result.take()); + OutputExprNames.push_back(Name.str()); + OutputConstraints.push_back("=r"); + } else { + Inputs.push_back(II); + InputExprs.push_back(Result.take()); + InputExprNames.push_back(Name.str()); + InputConstraints.push_back("r"); + } } } } |