forked from OSchip/llvm-project
[ms-inline asm] Use the convertToMapAndConstraints() function in the front-end.
Rework the logic to account for the fact that we no longer create a MCInst. llvm-svn: 164980
This commit is contained in:
parent
f4e35dc672
commit
bb90c414c4
|
@ -458,6 +458,28 @@ static bool buildMSAsmStrings(Sema &SemaRef,
|
|||
return false;
|
||||
}
|
||||
|
||||
// Check to see if the expression is a substring of the asm operand.
|
||||
static StringRef getMSInlineAsmExprName(StringRef Name) {
|
||||
// Strip off the size directives.
|
||||
// E.g., DWORD PTR [V] -> V
|
||||
if (Name.startswith("BYTE") || Name.startswith("byte") ||
|
||||
Name.startswith("WORD") || Name.startswith("word") ||
|
||||
Name.startswith("DWORD") || Name.startswith("dword") ||
|
||||
Name.startswith("QWORD") || Name.startswith("qword") ||
|
||||
Name.startswith("XWORD") || Name.startswith("xword") ||
|
||||
Name.startswith("XMMWORD") || Name.startswith("xmmword") ||
|
||||
Name.startswith("YMMWORD") || Name.startswith("ymmword")) {
|
||||
std::pair< StringRef, StringRef > SplitName = Name.split(' ');
|
||||
assert((SplitName.second.startswith("PTR") ||
|
||||
SplitName.second.startswith("ptr")) &&
|
||||
"Expected PTR/ptr!");
|
||||
SplitName = SplitName.second.split('[');
|
||||
SplitName = SplitName.second.split(']');
|
||||
return SplitName.first;
|
||||
}
|
||||
return Name;
|
||||
}
|
||||
|
||||
#define DEF_SIMPLE_MSASM(STR) \
|
||||
MSAsmStmt *NS = \
|
||||
new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true, \
|
||||
|
@ -558,92 +580,80 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
|
|||
|
||||
// Match the MCInstr.
|
||||
unsigned Kind;
|
||||
unsigned Opcode;
|
||||
unsigned ErrorInfo;
|
||||
SmallVector<llvm::MCInst, 2> Instrs;
|
||||
HadError = TargetParser->MatchInstruction(IDLoc, Kind, Operands, Instrs,
|
||||
SmallVector<std::pair< unsigned, std::string >, 4> MapAndConstraints;
|
||||
HadError = TargetParser->MatchInstruction(IDLoc, Operands, *Str.get(), Kind,
|
||||
Opcode, MapAndConstraints,
|
||||
ErrorInfo,
|
||||
/*matchingInlineAsm*/ true);
|
||||
// If we had an error parsing the operands, fail gracefully.
|
||||
if (HadError) { DEF_SIMPLE_MSASM(EmptyAsmStr); return Owned(NS); }
|
||||
|
||||
// Get the instruction descriptor.
|
||||
llvm::MCInst Inst = Instrs.back();
|
||||
const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo();
|
||||
const llvm::MCInstrDesc &Desc = MII->get(Inst.getOpcode());
|
||||
const llvm::MCInstrDesc &Desc = MII->get(Opcode);
|
||||
llvm::MCInstPrinter *IP =
|
||||
TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI);
|
||||
|
||||
// Build the list of clobbers, outputs and inputs.
|
||||
unsigned NumDefs = Desc.getNumDefs();
|
||||
for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
|
||||
if (Operands[i]->isToken() || Operands[i]->isImm())
|
||||
// Skip immediates.
|
||||
if (Operands[i]->isImm())
|
||||
continue;
|
||||
|
||||
// FIXME: The getMCInstOperandNum() function does not work with tied
|
||||
// operands or custom converters.
|
||||
unsigned NumMCOperands;
|
||||
unsigned MCIdx = TargetParser->getMCInstOperandNum(Kind, Operands, i,
|
||||
NumMCOperands);
|
||||
assert (NumMCOperands && "Expected at least 1 MCOperand!");
|
||||
|
||||
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)) {
|
||||
// Register.
|
||||
if (Operands[i]->isReg()) {
|
||||
// Clobber.
|
||||
if (NumDefs && (MapAndConstraints[i-1].first < NumDefs)) {
|
||||
std::string Reg;
|
||||
llvm::raw_string_ostream OS(Reg);
|
||||
IP->printRegName(OS, Op.getReg());
|
||||
|
||||
IP->printRegName(OS, Operands[i]->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()) {
|
||||
// FIXME: Determine the proper constraints.
|
||||
bool isMemDef = (i == 1) && Desc.mayStore();
|
||||
if (isMemDef) {
|
||||
Outputs.push_back(II);
|
||||
OutputExprs.push_back(Result.take());
|
||||
OutputExprNames.push_back(Name.str());
|
||||
OutputExprStrIdx.push_back(StrIdx);
|
||||
OutputConstraints.push_back("=r");
|
||||
} else {
|
||||
Inputs.push_back(II);
|
||||
InputExprs.push_back(Result.take());
|
||||
InputExprNames.push_back(Name.str());
|
||||
InputExprStrIdx.push_back(StrIdx);
|
||||
InputConstraints.push_back("r");
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Expr/Input or Output.
|
||||
StringRef Name = getMSInlineAsmExprName(Pieces[StrIdx][i]);
|
||||
|
||||
// The expr may be a register.
|
||||
// E.g., DWORD PTR [eax]
|
||||
if (Context.getTargetInfo().isValidGCCRegisterName(Name))
|
||||
continue;
|
||||
|
||||
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()) {
|
||||
// FIXME: Determine the proper constraints.
|
||||
bool isMemDef = (i == 1) && Desc.mayStore();
|
||||
if (isMemDef) {
|
||||
Outputs.push_back(II);
|
||||
OutputExprs.push_back(Result.take());
|
||||
OutputExprNames.push_back(Name.str());
|
||||
OutputExprStrIdx.push_back(StrIdx);
|
||||
|
||||
std::string Constraint = "=" + MapAndConstraints[i-1].second;
|
||||
OutputConstraints.push_back(Constraint);
|
||||
} else {
|
||||
Inputs.push_back(II);
|
||||
InputExprs.push_back(Result.take());
|
||||
InputExprNames.push_back(Name.str());
|
||||
InputExprStrIdx.push_back(StrIdx);
|
||||
InputConstraints.push_back(MapAndConstraints[i-1].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue