mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-25 20:59:51 +00:00
Replace the old algorithm that emitted the "print the alias for an instruction"
with the newer, cleaner model. It uses the IAPrinter class to hold the information that is needed to match an instruction with its alias. This also takes into account the available features of the platform. There is one bit of ugliness. The way the logic determines if a pattern is unique is O(N**2), which is gross. But in reality, the number of items it's checking against isn't large. So while it's N**2, it shouldn't be a massive time sink. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129110 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e578252c27
commit
44dcfd3625
@ -25,9 +25,12 @@ protected:
|
|||||||
/// assembly emission is disable.
|
/// assembly emission is disable.
|
||||||
raw_ostream *CommentStream;
|
raw_ostream *CommentStream;
|
||||||
const MCAsmInfo &MAI;
|
const MCAsmInfo &MAI;
|
||||||
|
|
||||||
|
/// The current set of available features.
|
||||||
|
unsigned AvailableFeatures;
|
||||||
public:
|
public:
|
||||||
MCInstPrinter(const MCAsmInfo &mai)
|
MCInstPrinter(const MCAsmInfo &mai)
|
||||||
: CommentStream(0), MAI(mai) {}
|
: CommentStream(0), MAI(mai), AvailableFeatures(0) {}
|
||||||
|
|
||||||
virtual ~MCInstPrinter();
|
virtual ~MCInstPrinter();
|
||||||
|
|
||||||
@ -44,6 +47,9 @@ public:
|
|||||||
|
|
||||||
/// getRegName - Return the assembler register name.
|
/// getRegName - Return the assembler register name.
|
||||||
virtual StringRef getRegName(unsigned RegNo) const;
|
virtual StringRef getRegName(unsigned RegNo) const;
|
||||||
|
|
||||||
|
unsigned getAvailableFeatures() const { return AvailableFeatures; }
|
||||||
|
void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace llvm
|
} // namespace llvm
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#define DEBUG_TYPE "asm-printer"
|
#define DEBUG_TYPE "asm-printer"
|
||||||
#include "X86ATTInstPrinter.h"
|
#include "X86ATTInstPrinter.h"
|
||||||
#include "X86InstComments.h"
|
#include "X86InstComments.h"
|
||||||
|
#include "X86Subtarget.h"
|
||||||
#include "llvm/MC/MCInst.h"
|
#include "llvm/MC/MCInst.h"
|
||||||
#include "llvm/MC/MCAsmInfo.h"
|
#include "llvm/MC/MCAsmInfo.h"
|
||||||
#include "llvm/MC/MCExpr.h"
|
#include "llvm/MC/MCExpr.h"
|
||||||
@ -22,11 +23,23 @@
|
|||||||
#include "llvm/Support/Format.h"
|
#include "llvm/Support/Format.h"
|
||||||
#include "llvm/Support/FormattedStream.h"
|
#include "llvm/Support/FormattedStream.h"
|
||||||
#include "X86GenInstrNames.inc"
|
#include "X86GenInstrNames.inc"
|
||||||
|
#include <map>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
// Include the auto-generated portion of the assembly writer.
|
// Include the auto-generated portion of the assembly writer.
|
||||||
#define GET_INSTRUCTION_NAME
|
#define GET_INSTRUCTION_NAME
|
||||||
|
#define PRINT_ALIAS_INSTR
|
||||||
|
#include "X86GenRegisterNames.inc"
|
||||||
#include "X86GenAsmWriter.inc"
|
#include "X86GenAsmWriter.inc"
|
||||||
|
#undef PRINT_ALIAS_INSTR
|
||||||
|
#undef GET_INSTRUCTION_NAME
|
||||||
|
|
||||||
|
X86ATTInstPrinter::X86ATTInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI)
|
||||||
|
: MCInstPrinter(MAI) {
|
||||||
|
// Initialize the set of available features.
|
||||||
|
setAvailableFeatures(ComputeAvailableFeatures(
|
||||||
|
&TM.getSubtarget<X86Subtarget>()));
|
||||||
|
}
|
||||||
|
|
||||||
void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS) {
|
void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS) {
|
||||||
printInstruction(MI, OS);
|
printInstruction(MI, OS);
|
||||||
@ -35,11 +48,11 @@ void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS) {
|
|||||||
if (CommentStream)
|
if (CommentStream)
|
||||||
EmitAnyX86InstComments(MI, *CommentStream, getRegisterName);
|
EmitAnyX86InstComments(MI, *CommentStream, getRegisterName);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef X86ATTInstPrinter::getOpcodeName(unsigned Opcode) const {
|
StringRef X86ATTInstPrinter::getOpcodeName(unsigned Opcode) const {
|
||||||
return getInstructionName(Opcode);
|
return getInstructionName(Opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
|
void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
|
||||||
raw_ostream &O) {
|
raw_ostream &O) {
|
||||||
switch (MI->getOperand(Op).getImm()) {
|
switch (MI->getOperand(Op).getImm()) {
|
||||||
|
@ -19,16 +19,20 @@
|
|||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class MCOperand;
|
class MCOperand;
|
||||||
|
class X86Subtarget;
|
||||||
class TargetMachine;
|
class TargetMachine;
|
||||||
|
|
||||||
class X86ATTInstPrinter : public MCInstPrinter {
|
class X86ATTInstPrinter : public MCInstPrinter {
|
||||||
public:
|
public:
|
||||||
X86ATTInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI)
|
X86ATTInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI);
|
||||||
: MCInstPrinter(MAI) {}
|
|
||||||
|
|
||||||
virtual void printInst(const MCInst *MI, raw_ostream &OS);
|
virtual void printInst(const MCInst *MI, raw_ostream &OS);
|
||||||
virtual StringRef getOpcodeName(unsigned Opcode) const;
|
virtual StringRef getOpcodeName(unsigned Opcode) const;
|
||||||
|
|
||||||
|
// Methods used to print the alias of an instruction.
|
||||||
|
unsigned ComputeAvailableFeatures(const X86Subtarget *Subtarget) const;
|
||||||
|
bool printAliasInstr(const MCInst *MI, raw_ostream &OS);
|
||||||
|
|
||||||
// Autogenerated by tblgen.
|
// Autogenerated by tblgen.
|
||||||
void printInstruction(const MCInst *MI, raw_ostream &OS);
|
void printInstruction(const MCInst *MI, raw_ostream &OS);
|
||||||
static const char *getRegisterName(unsigned RegNo);
|
static const char *getRegisterName(unsigned RegNo);
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#define DEBUG_TYPE "asm-printer"
|
#define DEBUG_TYPE "asm-printer"
|
||||||
#include "X86IntelInstPrinter.h"
|
#include "X86IntelInstPrinter.h"
|
||||||
#include "X86InstComments.h"
|
#include "X86InstComments.h"
|
||||||
|
#include "X86Subtarget.h"
|
||||||
#include "llvm/MC/MCInst.h"
|
#include "llvm/MC/MCInst.h"
|
||||||
#include "llvm/MC/MCAsmInfo.h"
|
#include "llvm/MC/MCAsmInfo.h"
|
||||||
#include "llvm/MC/MCExpr.h"
|
#include "llvm/MC/MCExpr.h"
|
||||||
|
@ -26,7 +26,7 @@ class X86IntelInstPrinter : public MCInstPrinter {
|
|||||||
public:
|
public:
|
||||||
X86IntelInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI)
|
X86IntelInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI)
|
||||||
: MCInstPrinter(MAI) {}
|
: MCInstPrinter(MAI) {}
|
||||||
|
|
||||||
virtual void printInst(const MCInst *MI, raw_ostream &OS);
|
virtual void printInst(const MCInst *MI, raw_ostream &OS);
|
||||||
virtual StringRef getOpcodeName(unsigned Opcode) const;
|
virtual StringRef getOpcodeName(unsigned Opcode) const;
|
||||||
|
|
||||||
@ -35,7 +35,6 @@ public:
|
|||||||
static const char *getRegisterName(unsigned RegNo);
|
static const char *getRegisterName(unsigned RegNo);
|
||||||
static const char *getInstructionName(unsigned Opcode);
|
static const char *getInstructionName(unsigned Opcode);
|
||||||
|
|
||||||
|
|
||||||
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||||
void printMemReference(const MCInst *MI, unsigned Op, raw_ostream &O);
|
void printMemReference(const MCInst *MI, unsigned Op, raw_ostream &O);
|
||||||
void printSSECC(const MCInst *MI, unsigned Op, raw_ostream &O);
|
void printSSECC(const MCInst *MI, unsigned Op, raw_ostream &O);
|
||||||
|
@ -626,26 +626,30 @@ public:
|
|||||||
bool isOpMapped(StringRef Op) { return OpMap.find(Op) != OpMap.end(); }
|
bool isOpMapped(StringRef Op) { return OpMap.find(Op) != OpMap.end(); }
|
||||||
|
|
||||||
void print(raw_ostream &O) {
|
void print(raw_ostream &O) {
|
||||||
unsigned Indent = 8;
|
if (Conds.empty() && ReqFeatures.empty()) {
|
||||||
|
O.indent(6) << "return true;\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!Conds.empty())
|
O << "if (";
|
||||||
O << "if (";
|
|
||||||
|
|
||||||
for (std::vector<std::string>::iterator
|
for (std::vector<std::string>::iterator
|
||||||
I = Conds.begin(), E = Conds.end(); I != E; ++I) {
|
I = Conds.begin(), E = Conds.end(); I != E; ++I) {
|
||||||
if (I != Conds.begin()) {
|
if (I != Conds.begin()) {
|
||||||
O << " &&\n";
|
O << " &&\n";
|
||||||
O.indent(Indent);
|
O.indent(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
O << *I;
|
O << *I;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ReqFeatures.empty()) {
|
if (!ReqFeatures.empty()) {
|
||||||
if (Conds.begin() != Conds.end())
|
if (Conds.begin() != Conds.end()) {
|
||||||
O << " &&\n";
|
O << " &&\n";
|
||||||
else
|
O.indent(8);
|
||||||
|
} else {
|
||||||
O << "if (";
|
O << "if (";
|
||||||
|
}
|
||||||
|
|
||||||
std::string Req;
|
std::string Req;
|
||||||
raw_string_ostream ReqO(Req);
|
raw_string_ostream ReqO(Req);
|
||||||
@ -656,28 +660,21 @@ public:
|
|||||||
ReqO << AWI.getFeatureInfo(*I)->getEnumName();
|
ReqO << AWI.getFeatureInfo(*I)->getEnumName();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Conds.begin() != Conds.end()) O.indent(Indent);
|
|
||||||
O << "(AvailableFeatures & (" << ReqO.str() << ")) == ("
|
O << "(AvailableFeatures & (" << ReqO.str() << ")) == ("
|
||||||
<< ReqO.str() << ')';
|
<< ReqO.str() << ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Conds.empty() || !ReqFeatures.empty()) {
|
O << ") {\n";
|
||||||
O << ") {\n";
|
O.indent(6) << "// " << Result << "\n";
|
||||||
Indent = 6;
|
O.indent(6) << "AsmString = \"" << AsmString << "\";\n";
|
||||||
} else {
|
|
||||||
Indent = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
O.indent(Indent) << "// " << Result << "\n";
|
|
||||||
O.indent(Indent) << "AsmString = \"" << AsmString << "\";\n";
|
|
||||||
|
|
||||||
for (std::map<StringRef, unsigned>::iterator
|
for (std::map<StringRef, unsigned>::iterator
|
||||||
I = OpMap.begin(), E = OpMap.end(); I != E; ++I)
|
I = OpMap.begin(), E = OpMap.end(); I != E; ++I)
|
||||||
O.indent(Indent) << "OpMap[\"" << I->first << "\"] = "
|
O.indent(6) << "OpMap[\"" << I->first << "\"] = "
|
||||||
<< I->second << ";\n";
|
<< I->second << ";\n";
|
||||||
|
|
||||||
if (!Conds.empty() || !ReqFeatures.empty())
|
O.indent(6) << "break;\n";
|
||||||
O.indent(4) << '}';
|
O.indent(4) << '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const IAPrinter &RHS) {
|
bool operator==(const IAPrinter &RHS) {
|
||||||
@ -727,7 +724,7 @@ static void EmitSubtargetFeatureFlagEnumeration(AsmWriterInfo &Info,
|
|||||||
|
|
||||||
O << " Feature_None = 0\n";
|
O << " Feature_None = 0\n";
|
||||||
O << "};\n\n";
|
O << "};\n\n";
|
||||||
O << "} // end anonymous namespace\n";
|
O << "} // end anonymous namespace\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitComputeAvailableFeatures - Emit the function to compute the list of
|
/// EmitComputeAvailableFeatures - Emit the function to compute the list of
|
||||||
@ -928,156 +925,72 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
|
|||||||
|
|
||||||
if (CantHandle) continue;
|
if (CantHandle) continue;
|
||||||
IAPrinterMap[I->first].push_back(IAP);
|
IAPrinterMap[I->first].push_back(IAP);
|
||||||
|
|
||||||
#if 0
|
|
||||||
O.indent(4) << "// " << I->first << '\n';
|
|
||||||
O.indent(4);
|
|
||||||
IAP->print(O);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
O << "#if 0\n";
|
|
||||||
EmitSubtargetFeatureFlagEnumeration(AWI, O);
|
EmitSubtargetFeatureFlagEnumeration(AWI, O);
|
||||||
EmitComputeAvailableFeatures(AWI, AsmWriter, Target, O);
|
EmitComputeAvailableFeatures(AWI, AsmWriter, Target, O);
|
||||||
O << "#endif\n\n";
|
|
||||||
|
|
||||||
O << "bool " << Target.getName() << ClassName
|
O << "bool " << Target.getName() << ClassName
|
||||||
<< "::printAliasInstr(const " << MachineInstrClassName
|
<< "::printAliasInstr(const " << MachineInstrClassName
|
||||||
<< " *MI, raw_ostream &OS) {\n";
|
<< " *MI, raw_ostream &OS) {\n";
|
||||||
|
|
||||||
if (AliasMap.empty() || !isMC) {
|
std::string Cases;
|
||||||
// FIXME: Support MachineInstr InstAliases?
|
raw_string_ostream CasesO(Cases);
|
||||||
|
|
||||||
|
for (std::map<std::string, std::vector<IAPrinter*> >::iterator
|
||||||
|
I = IAPrinterMap.begin(), E = IAPrinterMap.end(); I != E; ++I) {
|
||||||
|
std::vector<IAPrinter*> &IAPs = I->second;
|
||||||
|
std::vector<IAPrinter*> UniqueIAPs;
|
||||||
|
|
||||||
|
for (std::vector<IAPrinter*>::iterator
|
||||||
|
II = IAPs.begin(), IE = IAPs.end(); II != IE; ++II) {
|
||||||
|
IAPrinter *LHS = *II;
|
||||||
|
bool IsDup = false;
|
||||||
|
for (std::vector<IAPrinter*>::iterator
|
||||||
|
III = IAPs.begin(), IIE = IAPs.end(); III != IIE; ++III) {
|
||||||
|
IAPrinter *RHS = *III;
|
||||||
|
if (LHS != RHS && *LHS == *RHS) {
|
||||||
|
IsDup = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsDup) UniqueIAPs.push_back(LHS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UniqueIAPs.empty()) continue;
|
||||||
|
|
||||||
|
CasesO.indent(2) << "case " << I->first << ":\n";
|
||||||
|
|
||||||
|
for (std::vector<IAPrinter*>::iterator
|
||||||
|
II = UniqueIAPs.begin(), IE = UniqueIAPs.end(); II != IE; ++II) {
|
||||||
|
IAPrinter *IAP = *II;
|
||||||
|
CasesO.indent(4);
|
||||||
|
IAP->print(CasesO);
|
||||||
|
CasesO << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
CasesO.indent(4) << "return true;\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CasesO.str().empty() || !isMC) {
|
||||||
O << " return true;\n";
|
O << " return true;\n";
|
||||||
O << "}\n\n";
|
O << "}\n\n";
|
||||||
O << "#endif // PRINT_ALIAS_INSTR\n";
|
O << "#endif // PRINT_ALIAS_INSTR\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
O << " StringRef AsmString;\n";
|
O.indent(2) << "StringRef AsmString;\n";
|
||||||
O << " std::map<StringRef, unsigned> OpMap;\n";
|
O.indent(2) << "std::map<StringRef, unsigned> OpMap;\n";
|
||||||
O << " switch (MI->getOpcode()) {\n";
|
O.indent(2) << "unsigned AvailableFeatures = getAvailableFeatures();\n\n";
|
||||||
O << " default: return true;\n";
|
O.indent(2) << "switch (MI->getOpcode()) {\n";
|
||||||
|
O.indent(2) << "default: return true;\n";
|
||||||
for (std::map<std::string, std::vector<CodeGenInstAlias*> >::iterator
|
O << CasesO.str();
|
||||||
I = AliasMap.begin(), E = AliasMap.end(); I != E; ++I) {
|
O.indent(2) << "}\n\n";
|
||||||
std::vector<CodeGenInstAlias*> &Aliases = I->second;
|
|
||||||
|
|
||||||
std::map<std::string, unsigned> CondCount;
|
|
||||||
std::map<std::string, std::string> BodyMap;
|
|
||||||
|
|
||||||
std::string AsmString = "";
|
|
||||||
|
|
||||||
for (std::vector<CodeGenInstAlias*>::iterator
|
|
||||||
II = Aliases.begin(), IE = Aliases.end(); II != IE; ++II) {
|
|
||||||
const CodeGenInstAlias *CGA = *II;
|
|
||||||
AsmString = CGA->AsmString;
|
|
||||||
unsigned Indent = 8;
|
|
||||||
unsigned LastOpNo = CGA->ResultInstOperandIndex.size();
|
|
||||||
|
|
||||||
std::string Cond;
|
|
||||||
raw_string_ostream CondO(Cond);
|
|
||||||
|
|
||||||
CondO << "if (MI->getNumOperands() == " << LastOpNo;
|
|
||||||
|
|
||||||
std::map<StringRef, unsigned> OpMap;
|
|
||||||
bool CantHandle = false;
|
|
||||||
|
|
||||||
for (unsigned i = 0, e = LastOpNo; i != e; ++i) {
|
|
||||||
const CodeGenInstAlias::ResultOperand &RO = CGA->ResultOperands[i];
|
|
||||||
|
|
||||||
switch (RO.Kind) {
|
|
||||||
default: assert(0 && "unexpected InstAlias operand kind");
|
|
||||||
case CodeGenInstAlias::ResultOperand::K_Record: {
|
|
||||||
const Record *Rec = RO.getRecord();
|
|
||||||
StringRef ROName = RO.getName();
|
|
||||||
|
|
||||||
if (Rec->isSubClassOf("RegisterClass")) {
|
|
||||||
CondO << " &&\n";
|
|
||||||
CondO.indent(Indent) << "MI->getOperand(" << i << ").isReg() &&\n";
|
|
||||||
if (OpMap.find(ROName) == OpMap.end()) {
|
|
||||||
OpMap[ROName] = i;
|
|
||||||
CondO.indent(Indent)
|
|
||||||
<< "regIsInRegisterClass(RC_"
|
|
||||||
<< CGA->ResultOperands[i].getRecord()->getName()
|
|
||||||
<< ", MI->getOperand(" << i << ").getReg())";
|
|
||||||
} else {
|
|
||||||
CondO.indent(Indent)
|
|
||||||
<< "MI->getOperand(" << i
|
|
||||||
<< ").getReg() == MI->getOperand("
|
|
||||||
<< OpMap[ROName] << ").getReg()";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
assert(Rec->isSubClassOf("Operand") && "Unexpected operand!");
|
|
||||||
// FIXME: We need to handle these situations.
|
|
||||||
CantHandle = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CodeGenInstAlias::ResultOperand::K_Imm:
|
|
||||||
CondO << " &&\n";
|
|
||||||
CondO.indent(Indent) << "MI->getOperand(" << i << ").getImm() == ";
|
|
||||||
CondO << CGA->ResultOperands[i].getImm();
|
|
||||||
break;
|
|
||||||
case CodeGenInstAlias::ResultOperand::K_Reg:
|
|
||||||
CondO << " &&\n";
|
|
||||||
CondO.indent(Indent) << "MI->getOperand(" << i << ").getReg() == ";
|
|
||||||
CondO << Target.getName() << "::"
|
|
||||||
<< CGA->ResultOperands[i].getRegister()->getName();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CantHandle) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CantHandle) continue;
|
|
||||||
|
|
||||||
CondO << ")";
|
|
||||||
|
|
||||||
std::string Body;
|
|
||||||
raw_string_ostream BodyO(Body);
|
|
||||||
|
|
||||||
BodyO << " // " << CGA->Result->getAsString() << "\n";
|
|
||||||
BodyO << " AsmString = \"" << AsmString << "\";\n";
|
|
||||||
|
|
||||||
for (std::map<StringRef, unsigned>::iterator
|
|
||||||
III = OpMap.begin(), IIE = OpMap.end(); III != IIE; ++III)
|
|
||||||
BodyO << " OpMap[\"" << III->first << "\"] = "
|
|
||||||
<< III->second << ";\n";
|
|
||||||
|
|
||||||
++CondCount[CondO.str()];
|
|
||||||
BodyMap[CondO.str()] = BodyO.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Code;
|
|
||||||
raw_string_ostream CodeO(Code);
|
|
||||||
|
|
||||||
bool EmitElse = false;
|
|
||||||
for (std::map<std::string, unsigned>::iterator
|
|
||||||
II = CondCount.begin(), IE = CondCount.end(); II != IE; ++II) {
|
|
||||||
if (II->second != 1) continue;
|
|
||||||
CodeO << " ";
|
|
||||||
if (EmitElse) CodeO << "} else ";
|
|
||||||
CodeO << II->first << " {\n";
|
|
||||||
CodeO << BodyMap[II->first];
|
|
||||||
EmitElse = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CodeO.str().empty()) continue;
|
|
||||||
|
|
||||||
O << " case " << I->first << ":\n";
|
|
||||||
O << CodeO.str();
|
|
||||||
O << " }\n";
|
|
||||||
O << " break;\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
O << " }\n\n";
|
|
||||||
|
|
||||||
// Code that prints the alias, replacing the operands with the ones from the
|
// Code that prints the alias, replacing the operands with the ones from the
|
||||||
// MCInst.
|
// MCInst.
|
||||||
O << " if (AsmString.empty()) return true;\n";
|
|
||||||
O << " std::pair<StringRef, StringRef> ASM = AsmString.split(' ');\n";
|
O << " std::pair<StringRef, StringRef> ASM = AsmString.split(' ');\n";
|
||||||
O << " OS << '\\t' << ASM.first;\n";
|
O << " OS << '\\t' << ASM.first;\n";
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user