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;
|
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) \
|
#define DEF_SIMPLE_MSASM(STR) \
|
||||||
MSAsmStmt *NS = \
|
MSAsmStmt *NS = \
|
||||||
new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true, \
|
new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true, \
|
||||||
|
@ -558,92 +580,80 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
|
||||||
|
|
||||||
// Match the MCInstr.
|
// Match the MCInstr.
|
||||||
unsigned Kind;
|
unsigned Kind;
|
||||||
|
unsigned Opcode;
|
||||||
unsigned ErrorInfo;
|
unsigned ErrorInfo;
|
||||||
SmallVector<llvm::MCInst, 2> Instrs;
|
SmallVector<std::pair< unsigned, std::string >, 4> MapAndConstraints;
|
||||||
HadError = TargetParser->MatchInstruction(IDLoc, Kind, Operands, Instrs,
|
HadError = TargetParser->MatchInstruction(IDLoc, Operands, *Str.get(), Kind,
|
||||||
|
Opcode, MapAndConstraints,
|
||||||
ErrorInfo,
|
ErrorInfo,
|
||||||
/*matchingInlineAsm*/ true);
|
/*matchingInlineAsm*/ true);
|
||||||
// If we had an error parsing the operands, fail gracefully.
|
// If we had an error parsing the operands, fail gracefully.
|
||||||
if (HadError) { DEF_SIMPLE_MSASM(EmptyAsmStr); return Owned(NS); }
|
if (HadError) { DEF_SIMPLE_MSASM(EmptyAsmStr); return Owned(NS); }
|
||||||
|
|
||||||
// Get the instruction descriptor.
|
// Get the instruction descriptor.
|
||||||
llvm::MCInst Inst = Instrs.back();
|
|
||||||
const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo();
|
const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo();
|
||||||
const llvm::MCInstrDesc &Desc = MII->get(Inst.getOpcode());
|
const llvm::MCInstrDesc &Desc = MII->get(Opcode);
|
||||||
llvm::MCInstPrinter *IP =
|
llvm::MCInstPrinter *IP =
|
||||||
TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI);
|
TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI);
|
||||||
|
|
||||||
// Build the list of clobbers, outputs and inputs.
|
// Build the list of clobbers, outputs and inputs.
|
||||||
unsigned NumDefs = Desc.getNumDefs();
|
unsigned NumDefs = Desc.getNumDefs();
|
||||||
for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
|
for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
|
||||||
if (Operands[i]->isToken() || Operands[i]->isImm())
|
// Skip immediates.
|
||||||
|
if (Operands[i]->isImm())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// FIXME: The getMCInstOperandNum() function does not work with tied
|
// Register.
|
||||||
// operands or custom converters.
|
if (Operands[i]->isReg()) {
|
||||||
unsigned NumMCOperands;
|
// Clobber.
|
||||||
unsigned MCIdx = TargetParser->getMCInstOperandNum(Kind, Operands, i,
|
if (NumDefs && (MapAndConstraints[i-1].first < NumDefs)) {
|
||||||
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)) {
|
|
||||||
std::string Reg;
|
std::string Reg;
|
||||||
llvm::raw_string_ostream OS(Reg);
|
llvm::raw_string_ostream OS(Reg);
|
||||||
IP->printRegName(OS, Op.getReg());
|
IP->printRegName(OS, Operands[i]->getReg());
|
||||||
|
|
||||||
StringRef Clobber(OS.str());
|
StringRef Clobber(OS.str());
|
||||||
if (!Context.getTargetInfo().isValidClobber(Clobber))
|
if (!Context.getTargetInfo().isValidClobber(Clobber))
|
||||||
return StmtError(
|
return StmtError(
|
||||||
Diag(AsmLoc, diag::err_asm_unknown_register_name) << Clobber);
|
Diag(AsmLoc, diag::err_asm_unknown_register_name) << Clobber);
|
||||||
ClobberRegs.insert(Reg);
|
ClobberRegs.insert(Reg);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
// Expr/Input or Output.
|
continue;
|
||||||
if (Op.isExpr()) {
|
}
|
||||||
const llvm::MCExpr *Expr = Op.getExpr();
|
|
||||||
const llvm::MCSymbolRefExpr *SymRef;
|
// Expr/Input or Output.
|
||||||
if ((SymRef = dyn_cast<llvm::MCSymbolRefExpr>(Expr))) {
|
StringRef Name = getMSInlineAsmExprName(Pieces[StrIdx][i]);
|
||||||
StringRef Name = SymRef->getSymbol().getName();
|
|
||||||
IdentifierInfo *II = getIdentifierInfo(Name, AsmToks,
|
// The expr may be a register.
|
||||||
AsmTokRanges[StrIdx].first,
|
// E.g., DWORD PTR [eax]
|
||||||
AsmTokRanges[StrIdx].second);
|
if (Context.getTargetInfo().isValidGCCRegisterName(Name))
|
||||||
if (II) {
|
continue;
|
||||||
CXXScopeSpec SS;
|
|
||||||
UnqualifiedId Id;
|
IdentifierInfo *II = getIdentifierInfo(Name, AsmToks,
|
||||||
SourceLocation Loc;
|
AsmTokRanges[StrIdx].first,
|
||||||
Id.setIdentifier(II, AsmLoc);
|
AsmTokRanges[StrIdx].second);
|
||||||
ExprResult Result = ActOnIdExpression(getCurScope(), SS, Loc, Id,
|
if (II) {
|
||||||
false, false);
|
CXXScopeSpec SS;
|
||||||
if (!Result.isInvalid()) {
|
UnqualifiedId Id;
|
||||||
// FIXME: Determine the proper constraints.
|
SourceLocation Loc;
|
||||||
bool isMemDef = (i == 1) && Desc.mayStore();
|
Id.setIdentifier(II, AsmLoc);
|
||||||
if (isMemDef) {
|
ExprResult Result = ActOnIdExpression(getCurScope(), SS, Loc, Id,
|
||||||
Outputs.push_back(II);
|
false, false);
|
||||||
OutputExprs.push_back(Result.take());
|
if (!Result.isInvalid()) {
|
||||||
OutputExprNames.push_back(Name.str());
|
// FIXME: Determine the proper constraints.
|
||||||
OutputExprStrIdx.push_back(StrIdx);
|
bool isMemDef = (i == 1) && Desc.mayStore();
|
||||||
OutputConstraints.push_back("=r");
|
if (isMemDef) {
|
||||||
} else {
|
Outputs.push_back(II);
|
||||||
Inputs.push_back(II);
|
OutputExprs.push_back(Result.take());
|
||||||
InputExprs.push_back(Result.take());
|
OutputExprNames.push_back(Name.str());
|
||||||
InputExprNames.push_back(Name.str());
|
OutputExprStrIdx.push_back(StrIdx);
|
||||||
InputExprStrIdx.push_back(StrIdx);
|
|
||||||
InputConstraints.push_back("r");
|
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