aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2012-08-17 14:35:45 -0700
committerDerek Schuff <dschuff@chromium.org>2012-08-17 14:35:45 -0700
commitb62e9abf7dd9e39c95327914ce9dfe216386824a (patch)
treec683f0bcbef19f622727251165eaf89a4f806c62 /utils
parent66f65db9406ca9e59d4bfed89436f668d6a84374 (diff)
parentc723eb1aef817d47feec620933ee1ec6005cdd14 (diff)
Merge commit 'c723eb1aef817d47feec620933ee1ec6005cdd14'
This merges r159618 from upstream into master. It goes with clang rev af50aab0c317462129d73ae8000c6394c718598d Conflicts: include/llvm/CodeGen/LexicalScopes.h include/llvm/Target/TargetOptions.h lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/Target/ARM/ARMBaseInstrInfo.cpp lib/Target/ARM/ARMTargetMachine.cpp lib/Target/ARM/ARMTargetObjectFile.cpp lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp lib/Target/Mips/MipsISelDAGToDAG.cpp lib/Target/Mips/MipsInstrFPU.td lib/Target/Mips/MipsMCInstLower.cpp lib/Target/Mips/MipsTargetMachine.cpp lib/Target/TargetMachine.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86RegisterInfo.cpp lib/Target/X86/X86TargetObjectFile.cpp lib/Target/X86/X86TargetObjectFile.h tools/llc/llc.cpp (tools/llc/llc.cpp is from a merged version of r160532 because it was a bit hairy and I didn't want to redo it.)
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp99
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp7
-rw-r--r--utils/TableGen/DFAPacketizerEmitter.cpp70
-rw-r--r--utils/TableGen/EDEmitter.cpp2
-rw-r--r--utils/TableGen/SubtargetEmitter.cpp80
-rw-r--r--utils/TableGen/X86RecognizableInstr.cpp4
-rw-r--r--utils/obj2yaml/CMakeLists.txt7
-rw-r--r--utils/obj2yaml/Makefile20
-rw-r--r--utils/obj2yaml/coff2yaml.cpp361
-rw-r--r--utils/obj2yaml/obj2yaml.cpp89
-rw-r--r--utils/obj2yaml/obj2yaml.h35
-rwxr-xr-xutils/test_debuginfo.pl2
12 files changed, 697 insertions, 79 deletions
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index e980b1a7d9..f5e094e486 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -186,6 +186,8 @@ struct ClassInfo {
/// For register classes, the records for all the registers in this class.
std::set<Record*> Registers;
+ /// For custom match classes, he diagnostic kind for when the predicate fails.
+ std::string DiagnosticType;
public:
/// isRegisterClass() - Check if this is a register class.
bool isRegisterClass() const {
@@ -593,6 +595,9 @@ public:
/// Map of Predicate records to their subtarget information.
std::map<Record*, SubtargetFeatureInfo*> SubtargetFeatures;
+ /// Map of AsmOperandClass records to their class information.
+ std::map<Record*, ClassInfo*> AsmOperandClasses;
+
private:
/// Map of token to class information which has already been constructed.
std::map<std::string, ClassInfo*> TokenClasses;
@@ -600,9 +605,6 @@ private:
/// Map of RegisterClass records to their class information.
std::map<Record*, ClassInfo*> RegisterClassClasses;
- /// Map of AsmOperandClass records to their class information.
- std::map<Record*, ClassInfo*> AsmOperandClasses;
-
private:
/// getTokenClass - Lookup or create the class for the given token.
ClassInfo *getTokenClass(StringRef Token);
@@ -960,6 +962,7 @@ ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
Entry->PredicateMethod = "<invalid>";
Entry->RenderMethod = "<invalid>";
Entry->ParserMethod = "";
+ Entry->DiagnosticType = "";
Classes.push_back(Entry);
}
@@ -1085,6 +1088,8 @@ buildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters) {
CI->PredicateMethod = ""; // unused
CI->RenderMethod = "addRegOperands";
CI->Registers = *it;
+ // FIXME: diagnostic type.
+ CI->DiagnosticType = "";
Classes.push_back(CI);
RegisterSetClasses.insert(std::make_pair(*it, CI));
}
@@ -1200,6 +1205,12 @@ void AsmMatcherInfo::buildOperandClasses() {
if (StringInit *SI = dynamic_cast<StringInit*>(PRMName))
CI->ParserMethod = SI->getValue();
+ // Get the diagnostic type or leave it as empty.
+ // Get the parse method name or leave it as empty.
+ Init *DiagnosticType = (*it)->getValueInit("DiagnosticType");
+ if (StringInit *SI = dynamic_cast<StringInit*>(DiagnosticType))
+ CI->DiagnosticType = SI->getValue();
+
AsmOperandClasses[*it] = CI;
Classes.push_back(CI);
}
@@ -1802,19 +1813,21 @@ static void emitMatchClassEnumeration(CodeGenTarget &Target,
/// emitValidateOperandClass - Emit the function to validate an operand class.
static void emitValidateOperandClass(AsmMatcherInfo &Info,
raw_ostream &OS) {
- OS << "static bool validateOperandClass(MCParsedAsmOperand *GOp, "
+ OS << "static unsigned validateOperandClass(MCParsedAsmOperand *GOp, "
<< "MatchClassKind Kind) {\n";
OS << " " << Info.Target.getName() << "Operand &Operand = *("
<< Info.Target.getName() << "Operand*)GOp;\n";
// The InvalidMatchClass is not to match any operand.
OS << " if (Kind == InvalidMatchClass)\n";
- OS << " return false;\n\n";
+ OS << " return MCTargetAsmParser::Match_InvalidOperand;\n\n";
// Check for Token operands first.
+ // FIXME: Use a more specific diagnostic type.
OS << " if (Operand.isToken())\n";
- OS << " return isSubclass(matchTokenString(Operand.getToken()), Kind);"
- << "\n\n";
+ OS << " return isSubclass(matchTokenString(Operand.getToken()), Kind) ?\n"
+ << " MCTargetAsmParser::Match_Success :\n"
+ << " MCTargetAsmParser::Match_InvalidOperand;\n\n";
// Check for register operands, including sub-classes.
OS << " if (Operand.isReg()) {\n";
@@ -1828,8 +1841,9 @@ static void emitValidateOperandClass(AsmMatcherInfo &Info,
<< it->first->getName() << ": OpKind = " << it->second->Name
<< "; break;\n";
OS << " }\n";
- OS << " return isSubclass(OpKind, Kind);\n";
- OS << " }\n\n";
+ OS << " return isSubclass(OpKind, Kind) ? "
+ << "MCTargetAsmParser::Match_Success :\n "
+ << " MCTargetAsmParser::Match_InvalidOperand;\n }\n\n";
// Check the user classes. We don't care what order since we're only
// actually matching against one of them.
@@ -1841,13 +1855,18 @@ static void emitValidateOperandClass(AsmMatcherInfo &Info,
continue;
OS << " // '" << CI.ClassName << "' class\n";
- OS << " if (Kind == " << CI.Name
- << " && Operand." << CI.PredicateMethod << "()) {\n";
- OS << " return true;\n";
+ OS << " if (Kind == " << CI.Name << ") {\n";
+ OS << " if (Operand." << CI.PredicateMethod << "())\n";
+ OS << " return MCTargetAsmParser::Match_Success;\n";
+ if (!CI.DiagnosticType.empty())
+ OS << " return " << Info.Target.getName() << "AsmParser::Match_"
+ << CI.DiagnosticType << ";\n";
OS << " }\n\n";
}
- OS << " return false;\n";
+ // Generic fallthrough match failure case for operands that don't have
+ // specialized diagnostic types.
+ OS << " return MCTargetAsmParser::Match_InvalidOperand;\n";
OS << "}\n\n";
}
@@ -1963,6 +1982,26 @@ static void emitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info,
OS << "};\n\n";
}
+/// emitOperandDiagnosticTypes - Emit the operand matching diagnostic types.
+static void emitOperandDiagnosticTypes(AsmMatcherInfo &Info, raw_ostream &OS) {
+ // Get the set of diagnostic types from all of the operand classes.
+ std::set<StringRef> Types;
+ for (std::map<Record*, ClassInfo*>::const_iterator
+ I = Info.AsmOperandClasses.begin(),
+ E = Info.AsmOperandClasses.end(); I != E; ++I) {
+ if (!I->second->DiagnosticType.empty())
+ Types.insert(I->second->DiagnosticType);
+ }
+
+ if (Types.empty()) return;
+
+ // Now emit the enum entries.
+ for (std::set<StringRef>::const_iterator I = Types.begin(), E = Types.end();
+ I != E; ++I)
+ OS << " Match_" << *I << ",\n";
+ OS << " END_OPERAND_DIAGNOSTIC_TYPES\n";
+}
+
/// emitGetSubtargetFeatureName - Emit the helper function to get the
/// user-level name for a subtarget feature.
static void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) {
@@ -2394,6 +2433,13 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << "#endif // GET_ASSEMBLER_HEADER_INFO\n\n";
+ // Emit the operand match diagnostic enum names.
+ OS << "\n#ifdef GET_OPERAND_DIAGNOSTIC_TYPES\n";
+ OS << "#undef GET_OPERAND_DIAGNOSTIC_TYPES\n\n";
+ emitOperandDiagnosticTypes(Info, OS);
+ OS << "#endif // GET_OPERAND_DIAGNOSTIC_TYPES\n\n";
+
+
OS << "\n#ifdef GET_REGISTER_MATCHER\n";
OS << "#undef GET_REGISTER_MATCHER\n\n";
@@ -2575,6 +2621,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " bool HadMatchOtherThanFeatures = false;\n";
OS << " bool HadMatchOtherThanPredicate = false;\n";
OS << " unsigned RetCode = Match_InvalidOperand;\n";
+ OS << " unsigned MissingFeatures = ~0U;\n";
OS << " // Set ErrorInfo to the operand that mismatches if it is\n";
OS << " // wrong for all instances of the instruction.\n";
OS << " ErrorInfo = ~0U;\n";
@@ -2604,13 +2651,22 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " OperandsValid = (it->Classes[i] == " <<"InvalidMatchClass);\n";
OS << " break;\n";
OS << " }\n";
- OS << " if (validateOperandClass(Operands[i+1], "
- "(MatchClassKind)it->Classes[i]))\n";
+ OS << " unsigned Diag = validateOperandClass(Operands[i+1],\n";
+ OS.indent(43);
+ OS << "(MatchClassKind)it->Classes[i]);\n";
+ OS << " if (Diag == Match_Success)\n";
OS << " continue;\n";
OS << " // If this operand is broken for all of the instances of this\n";
OS << " // mnemonic, keep track of it so we can report loc info.\n";
- OS << " if (it == MnemonicRange.first || ErrorInfo <= i+1)\n";
+ OS << " // If we already had a match that only failed due to a\n";
+ OS << " // target predicate, that diagnostic is preferred.\n";
+ OS << " if (!HadMatchOtherThanPredicate &&\n";
+ OS << " (it == MnemonicRange.first || ErrorInfo <= i+1)) {\n";
OS << " ErrorInfo = i+1;\n";
+ OS << " // InvalidOperand is the default. Prefer specificity.\n";
+ OS << " if (Diag != Match_InvalidOperand)\n";
+ OS << " RetCode = Diag;\n";
+ OS << " }\n";
OS << " // Otherwise, just reject this instance of the mnemonic.\n";
OS << " OperandsValid = false;\n";
OS << " break;\n";
@@ -2622,7 +2678,11 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " if ((AvailableFeatures & it->RequiredFeatures) "
<< "!= it->RequiredFeatures) {\n";
OS << " HadMatchOtherThanFeatures = true;\n";
- OS << " ErrorInfo = it->RequiredFeatures & ~AvailableFeatures;\n";
+ OS << " unsigned NewMissingFeatures = it->RequiredFeatures & "
+ "~AvailableFeatures;\n";
+ OS << " if (CountPopulation_32(NewMissingFeatures) <= "
+ "CountPopulation_32(MissingFeatures))\n";
+ OS << " MissingFeatures = NewMissingFeatures;\n";
OS << " continue;\n";
OS << " }\n";
OS << "\n";
@@ -2656,8 +2716,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " // Okay, we had no match. Try to return a useful error code.\n";
OS << " if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)";
- OS << " return RetCode;\n";
- OS << " assert(ErrorInfo && \"missing feature(s) but what?!\");";
+ OS << " return RetCode;\n";
+ OS << " // Missing feature matches return which features were missing\n";
+ OS << " ErrorInfo = MissingFeatures;\n";
OS << " return Match_MissingFeature;\n";
OS << "}\n\n";
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index 2ac7b87e70..aed222c094 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -690,6 +690,13 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
bool NodeHasChain = InstPatNode &&
InstPatNode->TreeHasProperty(SDNPHasChain, CGP);
+ // Instructions which load and store from memory should have a chain,
+ // regardless of whether they happen to have an internal pattern saying so.
+ if (Pattern.getSrcPattern()->TreeHasProperty(SDNPHasChain, CGP)
+ && (II.hasCtrlDep || II.mayLoad || II.mayStore || II.canFoldAsLoad ||
+ II.hasSideEffects))
+ NodeHasChain = true;
+
bool isRoot = N == Pattern.getDstPattern();
// TreeHasOutGlue - True if this tree has glue.
diff --git a/utils/TableGen/DFAPacketizerEmitter.cpp b/utils/TableGen/DFAPacketizerEmitter.cpp
index 26ab76390e..8bfecead6d 100644
--- a/utils/TableGen/DFAPacketizerEmitter.cpp
+++ b/utils/TableGen/DFAPacketizerEmitter.cpp
@@ -94,7 +94,12 @@ class State {
// PossibleStates is the set of valid resource states that ensue from valid
// transitions.
//
- bool canAddInsnClass(unsigned InsnClass, std::set<unsigned> &PossibleStates);
+ bool canAddInsnClass(unsigned InsnClass) const;
+ //
+ // AddInsnClass - Return all combinations of resource reservation
+ // which are possible from this state (PossibleStates).
+ //
+ void AddInsnClass(unsigned InsnClass, std::set<unsigned> &PossibleStates);
};
} // End anonymous namespace.
@@ -120,6 +125,10 @@ namespace {
struct ltState {
bool operator()(const State *s1, const State *s2) const;
};
+
+struct ltTransition {
+ bool operator()(const Transition *s1, const Transition *s2) const;
+};
} // End anonymous namespace.
@@ -135,7 +144,8 @@ public:
std::set<State*, ltState> states;
// Map from a state to the list of transitions with that state as source.
- std::map<State*, SmallVector<Transition*, 16>, ltState> stateTransitions;
+ std::map<State*, std::set<Transition*, ltTransition>, ltState>
+ stateTransitions;
State *currentState;
// Highest valued Input seen.
@@ -193,21 +203,19 @@ bool ltState::operator()(const State *s1, const State *s2) const {
return (s1->stateNum < s2->stateNum);
}
+bool ltTransition::operator()(const Transition *s1, const Transition *s2) const {
+ return (s1->input < s2->input);
+}
//
-// canAddInsnClass - Returns true if an instruction of type InsnClass is a
-// valid transition from this state i.e., can an instruction of type InsnClass
-// be added to the packet represented by this state.
+// AddInsnClass - Return all combinations of resource reservation
+// which are possible from this state (PossibleStates).
//
-// PossibleStates is the set of valid resource states that ensue from valid
-// transitions.
-//
-bool State::canAddInsnClass(unsigned InsnClass,
+void State::AddInsnClass(unsigned InsnClass,
std::set<unsigned> &PossibleStates) {
//
// Iterate over all resource states in currentState.
//
- bool AddedState = false;
for (std::set<unsigned>::iterator SI = stateInfo.begin();
SI != stateInfo.end(); ++SI) {
@@ -240,13 +248,26 @@ bool State::canAddInsnClass(unsigned InsnClass,
(VisitedResourceStates.count(ResultingResourceState) == 0)) {
VisitedResourceStates.insert(ResultingResourceState);
PossibleStates.insert(ResultingResourceState);
- AddedState = true;
}
}
}
}
- return AddedState;
+}
+
+
+//
+// canAddInsnClass - Quickly verifies if an instruction of type InsnClass is a
+// valid transition from this state i.e., can an instruction of type InsnClass
+// be added to the packet represented by this state.
+//
+bool State::canAddInsnClass(unsigned InsnClass) const {
+ for (std::set<unsigned>::const_iterator SI = stateInfo.begin();
+ SI != stateInfo.end(); ++SI) {
+ if (~*SI & InsnClass)
+ return true;
+ }
+ return false;
}
@@ -267,7 +288,9 @@ void DFA::addTransition(Transition *T) {
LargestInput = T->input;
// Add the new transition.
- stateTransitions[T->from].push_back(T);
+ bool Added = stateTransitions[T->from].insert(T).second;
+ assert(Added && "Cannot have multiple states for the same input");
+ (void)Added;
}
@@ -281,11 +304,13 @@ State *DFA::getTransition(State *From, unsigned I) {
return NULL;
// Do we have a transition from state From with Input I?
- for (SmallVector<Transition*, 16>::iterator VI =
- stateTransitions[From].begin();
- VI != stateTransitions[From].end(); ++VI)
- if ((*VI)->input == I)
- return (*VI)->to;
+ Transition TVal(NULL, I, NULL);
+ // Do not count this temporal instance
+ Transition::currentTransitionNum--;
+ std::set<Transition*, ltTransition>::iterator T =
+ stateTransitions[From].find(&TVal);
+ if (T != stateTransitions[From].end())
+ return (*T)->to;
return NULL;
}
@@ -331,11 +356,12 @@ void DFA::writeTableAndAPI(raw_ostream &OS, const std::string &TargetName) {
StateEntry[i] = ValidTransitions;
for (unsigned j = 0; j <= LargestInput; ++j) {
assert (((*SI)->stateNum == (int) i) && "Mismatch in state numbers");
- if (!isValidTransition(*SI, j))
+ State *To = getTransition(*SI, j);
+ if (To == NULL)
continue;
OS << "{" << j << ", "
- << getTransition(*SI, j)->stateNum
+ << To->stateNum
<< "}, ";
++ValidTransitions;
}
@@ -514,8 +540,10 @@ void DFAPacketizerEmitter::run(raw_ostream &OS) {
// and the state can accommodate this InsnClass, create a transition.
//
if (!D.getTransition(current, InsnClass) &&
- current->canAddInsnClass(InsnClass, NewStateResources)) {
+ current->canAddInsnClass(InsnClass)) {
State *NewState = NULL;
+ current->AddInsnClass(InsnClass, NewStateResources);
+ assert(NewStateResources.size() && "New states must be generated");
//
// If we have seen this state before, then do not create a new state.
diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp
index 6fb2feecbc..7b9354c169 100644
--- a/utils/TableGen/EDEmitter.cpp
+++ b/utils/TableGen/EDEmitter.cpp
@@ -317,6 +317,8 @@ static int X86TypeFromOpName(LiteralConstantEmitter *type,
MEM("i256mem");
MEM("f128mem");
MEM("f256mem");
+ MEM("v128mem");
+ MEM("v256mem");
MEM("opaque512mem");
// all R, I, R, I
diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp
index 1b871a8b66..8089908c1f 100644
--- a/utils/TableGen/SubtargetEmitter.cpp
+++ b/utils/TableGen/SubtargetEmitter.cpp
@@ -422,15 +422,18 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
// Get processor itinerary name
const std::string &Name = Proc->getName();
- // Skip default
- if (Name == "NoItineraries") continue;
-
- // Create and expand processor itinerary to cover all itinerary classes
- std::vector<InstrItinerary> ItinList;
- ItinList.resize(NItinClasses);
-
// Get itinerary data list
std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID");
+ std::vector<InstrItinerary> ItinList;
+
+ // Add an empty itinerary.
+ if (ItinDataList.empty()) {
+ ProcList.push_back(ItinList);
+ continue;
+ }
+
+ // Expand processor itinerary to cover all itinerary classes
+ ItinList.resize(NItinClasses);
// For each itinerary data
for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) {
@@ -495,7 +498,7 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
unsigned Find = ItinClassesMap[Name];
// Set up itinerary as location and location + stage count
- unsigned NumUOps = ItinClassList[Find]->getValueAsInt("NumMicroOps");
+ int NumUOps = ItinData->getValueAsInt("NumMicroOps");
InstrItinerary Intinerary = { NumUOps, FindStage, FindStage + NStages,
FindOperandCycle,
FindOperandCycle + NOperandCycles};
@@ -559,8 +562,6 @@ EmitProcessorData(raw_ostream &OS,
const std::string &Name = Itin->getName();
// Skip default
- if (Name == "NoItineraries") continue;
-
// Begin processor itinerary properties
OS << "\n";
OS << "static const llvm::InstrItineraryProps " << Name << "Props(\n";
@@ -570,42 +571,45 @@ EmitProcessorData(raw_ostream &OS,
EmitItineraryProp(OS, Itin, "HighLatency", ' ');
OS << ");\n";
- // Begin processor itinerary table
- OS << "\n";
- OS << "static const llvm::InstrItinerary " << Name << "Entries"
- << "[] = {\n";
-
// For each itinerary class
std::vector<InstrItinerary> &ItinList = *ProcListIter++;
- assert(ItinList.size() == ItinClassList.size() && "bad itinerary");
- for (unsigned j = 0, M = ItinList.size(); j < M; ++j) {
- InstrItinerary &Intinerary = ItinList[j];
-
- // Emit in the form of
- // { firstStage, lastStage, firstCycle, lastCycle } // index
- if (Intinerary.FirstStage == 0) {
- OS << " { 1, 0, 0, 0, 0 }";
- } else {
- OS << " { " <<
- Intinerary.NumMicroOps << ", " <<
- Intinerary.FirstStage << ", " <<
- Intinerary.LastStage << ", " <<
- Intinerary.FirstOperandCycle << ", " <<
- Intinerary.LastOperandCycle << " }";
- }
+ if (!ItinList.empty()) {
+ assert(ItinList.size() == ItinClassList.size() && "bad itinerary");
- OS << ", // " << j << " " << ItinClassList[j]->getName() << "\n";
+ // Begin processor itinerary table
+ OS << "\n";
+ OS << "static const llvm::InstrItinerary " << Name << "Entries"
+ << "[] = {\n";
+
+ for (unsigned j = 0, M = ItinList.size(); j < M; ++j) {
+ InstrItinerary &Intinerary = ItinList[j];
+
+ // Emit in the form of
+ // { firstStage, lastStage, firstCycle, lastCycle } // index
+ if (Intinerary.FirstStage == 0) {
+ OS << " { 1, 0, 0, 0, 0 }";
+ } else {
+ OS << " { " <<
+ Intinerary.NumMicroOps << ", " <<
+ Intinerary.FirstStage << ", " <<
+ Intinerary.LastStage << ", " <<
+ Intinerary.FirstOperandCycle << ", " <<
+ Intinerary.LastOperandCycle << " }";
+ }
+ OS << ", // " << j << " " << ItinClassList[j]->getName() << "\n";
+ }
+ // End processor itinerary table
+ OS << " { 1, ~0U, ~0U, ~0U, ~0U } // end marker\n";
+ OS << "};\n";
}
-
- // End processor itinerary table
- OS << " { 1, ~0U, ~0U, ~0U, ~0U } // end marker\n";
- OS << "};\n";
-
OS << '\n';
OS << "static const llvm::InstrItinerarySubtargetValue "
<< Name << " = {\n";
OS << " &" << Name << "Props,\n";
- OS << " " << Name << "Entries\n";
+ if (ItinList.empty())
+ OS << " 0\n";
+ else
+ OS << " " << Name << "Entries\n";
OS << "};\n";
}
}
diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp
index afb25be7ff..0ab21c8a54 100644
--- a/utils/TableGen/X86RecognizableInstr.cpp
+++ b/utils/TableGen/X86RecognizableInstr.cpp
@@ -1106,6 +1106,8 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
TYPE("VR128", TYPE_XMM128)
TYPE("f128mem", TYPE_M128)
TYPE("f256mem", TYPE_M256)
+ TYPE("v128mem", TYPE_M128)
+ TYPE("v256mem", TYPE_M256)
TYPE("FR64", TYPE_XMM64)
TYPE("f64mem", TYPE_M64FP)
TYPE("sdmem", TYPE_M64FP)
@@ -1235,6 +1237,8 @@ OperandEncoding RecognizableInstr::memoryEncodingFromString
ENCODING("sdmem", ENCODING_RM)
ENCODING("f128mem", ENCODING_RM)
ENCODING("f256mem", ENCODING_RM)
+ ENCODING("v128mem", ENCODING_RM)
+ ENCODING("v256mem", ENCODING_RM)
ENCODING("f64mem", ENCODING_RM)
ENCODING("f32mem", ENCODING_RM)
ENCODING("i128mem", ENCODING_RM)
diff --git a/utils/obj2yaml/CMakeLists.txt b/utils/obj2yaml/CMakeLists.txt
new file mode 100644
index 0000000000..d64bf1bad8
--- /dev/null
+++ b/utils/obj2yaml/CMakeLists.txt
@@ -0,0 +1,7 @@
+set(LLVM_LINK_COMPONENTS archive object)
+
+add_llvm_utility(obj2yaml
+ obj2yaml.cpp coff2yaml.cpp
+ )
+
+target_link_libraries(obj2yaml LLVMSupport)
diff --git a/utils/obj2yaml/Makefile b/utils/obj2yaml/Makefile
new file mode 100644
index 0000000000..5b96bdd5b9
--- /dev/null
+++ b/utils/obj2yaml/Makefile
@@ -0,0 +1,20 @@
+##===- utils/obj2yaml/Makefile ----------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TOOLNAME = obj2yaml
+USEDLIBS = LLVMObject.a LLVMSupport.a
+
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+# Don't install this utility
+NO_INSTALL = 1
+
+include $(LEVEL)/Makefile.common
diff --git a/utils/obj2yaml/coff2yaml.cpp b/utils/obj2yaml/coff2yaml.cpp
new file mode 100644
index 0000000000..2dbd53117a
--- /dev/null
+++ b/utils/obj2yaml/coff2yaml.cpp
@@ -0,0 +1,361 @@
+//===------ utils/obj2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "obj2yaml.h"
+
+#include "llvm/Object/COFF.h"
+
+
+template <typename One, typename Two>
+struct pod_pair { // I'd much rather use std::pair, but it's not a POD
+ One first;
+ Two second;
+};
+
+#define STRING_PAIR(x) {llvm::COFF::x, #x}
+static const pod_pair<llvm::COFF::MachineTypes, const char *>
+MachineTypePairs [] = {
+ STRING_PAIR(IMAGE_FILE_MACHINE_UNKNOWN),
+ STRING_PAIR(IMAGE_FILE_MACHINE_AM33),
+ STRING_PAIR(IMAGE_FILE_MACHINE_AMD64),
+ STRING_PAIR(IMAGE_FILE_MACHINE_ARM),
+ STRING_PAIR(IMAGE_FILE_MACHINE_ARMV7),
+ STRING_PAIR(IMAGE_FILE_MACHINE_EBC),
+ STRING_PAIR(IMAGE_FILE_MACHINE_I386),
+ STRING_PAIR(IMAGE_FILE_MACHINE_IA64),
+ STRING_PAIR(IMAGE_FILE_MACHINE_M32R),
+ STRING_PAIR(IMAGE_FILE_MACHINE_MIPS16),
+ STRING_PAIR(IMAGE_FILE_MACHINE_MIPSFPU),
+ STRING_PAIR(IMAGE_FILE_MACHINE_MIPSFPU16),
+ STRING_PAIR(IMAGE_FILE_MACHINE_POWERPC),
+ STRING_PAIR(IMAGE_FILE_MACHINE_POWERPCFP),
+ STRING_PAIR(IMAGE_FILE_MACHINE_R4000),
+ STRING_PAIR(IMAGE_FILE_MACHINE_SH3),
+ STRING_PAIR(IMAGE_FILE_MACHINE_SH3DSP),
+ STRING_PAIR(IMAGE_FILE_MACHINE_SH4),
+ STRING_PAIR(IMAGE_FILE_MACHINE_SH5),
+ STRING_PAIR(IMAGE_FILE_MACHINE_THUMB),
+ STRING_PAIR(IMAGE_FILE_MACHINE_WCEMIPSV2)
+};
+
+static const pod_pair<llvm::COFF::SectionCharacteristics, const char *>
+SectionCharacteristicsPairs1 [] = {
+ STRING_PAIR(IMAGE_SCN_TYPE_NO_PAD),
+ STRING_PAIR(IMAGE_SCN_CNT_CODE),
+ STRING_PAIR(IMAGE_SCN_CNT_INITIALIZED_DATA),
+ STRING_PAIR(IMAGE_SCN_CNT_UNINITIALIZED_DATA),
+ STRING_PAIR(IMAGE_SCN_LNK_OTHER),
+ STRING_PAIR(IMAGE_SCN_LNK_INFO),
+ STRING_PAIR(IMAGE_SCN_LNK_REMOVE),
+ STRING_PAIR(IMAGE_SCN_LNK_COMDAT),
+ STRING_PAIR(IMAGE_SCN_GPREL),
+ STRING_PAIR(IMAGE_SCN_MEM_PURGEABLE),
+ STRING_PAIR(IMAGE_SCN_MEM_16BIT),
+ STRING_PAIR(IMAGE_SCN_MEM_LOCKED),
+ STRING_PAIR(IMAGE_SCN_MEM_PRELOAD)
+};
+
+static const pod_pair<llvm::COFF::SectionCharacteristics, const char *>
+SectionCharacteristicsPairsAlignment [] = {
+ STRING_PAIR(IMAGE_SCN_ALIGN_1BYTES),
+ STRING_PAIR(IMAGE_SCN_ALIGN_2BYTES),
+ STRING_PAIR(IMAGE_SCN_ALIGN_4BYTES),
+ STRING_PAIR(IMAGE_SCN_ALIGN_8BYTES),
+ STRING_PAIR(IMAGE_SCN_ALIGN_16BYTES),
+ STRING_PAIR(IMAGE_SCN_ALIGN_32BYTES),
+ STRING_PAIR(IMAGE_SCN_ALIGN_64BYTES),
+ STRING_PAIR(IMAGE_SCN_ALIGN_128BYTES),
+ STRING_PAIR(IMAGE_SCN_ALIGN_256BYTES),
+ STRING_PAIR(IMAGE_SCN_ALIGN_512BYTES),
+ STRING_PAIR(IMAGE_SCN_ALIGN_1024BYTES),
+ STRING_PAIR(IMAGE_SCN_ALIGN_2048BYTES),
+ STRING_PAIR(IMAGE_SCN_ALIGN_4096BYTES),
+ STRING_PAIR(IMAGE_SCN_ALIGN_8192BYTES)
+};
+
+static const pod_pair<llvm::COFF::SectionCharacteristics, const char *>
+SectionCharacteristicsPairs2 [] = {
+ STRING_PAIR(IMAGE_SCN_LNK_NRELOC_OVFL),
+ STRING_PAIR(IMAGE_SCN_MEM_DISCARDABLE),
+ STRING_PAIR(IMAGE_SCN_MEM_NOT_CACHED),
+ STRING_PAIR(IMAGE_SCN_MEM_NOT_PAGED),
+ STRING_PAIR(IMAGE_SCN_MEM_SHARED),
+ STRING_PAIR(IMAGE_SCN_MEM_EXECUTE),
+ STRING_PAIR(IMAGE_SCN_MEM_READ),
+ STRING_PAIR(IMAGE_SCN_MEM_WRITE)
+};
+
+static const pod_pair<llvm::COFF::SymbolBaseType, const char *>
+SymbolBaseTypePairs [] = {
+ STRING_PAIR(IMAGE_SYM_TYPE_NULL),
+ STRING_PAIR(IMAGE_SYM_TYPE_VOID),
+ STRING_PAIR(IMAGE_SYM_TYPE_CHAR),
+ STRING_PAIR(IMAGE_SYM_TYPE_SHORT),
+ STRING_PAIR(IMAGE_SYM_TYPE_INT),
+ STRING_PAIR(IMAGE_SYM_TYPE_LONG),
+ STRING_PAIR(IMAGE_SYM_TYPE_FLOAT),
+ STRING_PAIR(IMAGE_SYM_TYPE_DOUBLE),
+ STRING_PAIR(IMAGE_SYM_TYPE_STRUCT),
+ STRING_PAIR(IMAGE_SYM_TYPE_UNION),
+ STRING_PAIR(IMAGE_SYM_TYPE_ENUM),
+ STRING_PAIR(IMAGE_SYM_TYPE_MOE),
+ STRING_PAIR(IMAGE_SYM_TYPE_BYTE),
+ STRING_PAIR(IMAGE_SYM_TYPE_WORD),
+ STRING_PAIR(IMAGE_SYM_TYPE_UINT),
+ STRING_PAIR(IMAGE_SYM_TYPE_DWORD)
+};
+
+static const pod_pair<llvm::COFF::SymbolComplexType, const char *>
+SymbolComplexTypePairs [] = {
+ STRING_PAIR(IMAGE_SYM_DTYPE_NULL),
+ STRING_PAIR(IMAGE_SYM_DTYPE_POINTER),
+ STRING_PAIR(IMAGE_SYM_DTYPE_FUNCTION),
+ STRING_PAIR(IMAGE_SYM_DTYPE_ARRAY),
+};
+
+static const pod_pair<llvm::COFF::SymbolStorageClass, const char *>
+SymbolStorageClassPairs [] = {
+ STRING_PAIR(IMAGE_SYM_CLASS_END_OF_FUNCTION),
+ STRING_PAIR(IMAGE_SYM_CLASS_NULL),
+ STRING_PAIR(IMAGE_SYM_CLASS_AUTOMATIC),
+ STRING_PAIR(IMAGE_SYM_CLASS_EXTERNAL),
+ STRING_PAIR(IMAGE_SYM_CLASS_STATIC),
+ STRING_PAIR(IMAGE_SYM_CLASS_REGISTER),
+ STRING_PAIR(IMAGE_SYM_CLASS_EXTERNAL_DEF),
+ STRING_PAIR(IMAGE_SYM_CLASS_LABEL),
+ STRING_PAIR(IMAGE_SYM_CLASS_UNDEFINED_LABEL),
+ STRING_PAIR(IMAGE_SYM_CLASS_MEMBER_OF_STRUCT),
+ STRING_PAIR(IMAGE_SYM_CLASS_ARGUMENT),
+ STRING_PAIR(IMAGE_SYM_CLASS_STRUCT_TAG),
+ STRING_PAIR(IMAGE_SYM_CLASS_MEMBER_OF_UNION),
+ STRING_PAIR(IMAGE_SYM_CLASS_UNION_TAG),
+ STRING_PAIR(IMAGE_SYM_CLASS_TYPE_DEFINITION),
+ STRING_PAIR(IMAGE_SYM_CLASS_UNDEFINED_STATIC),
+ STRING_PAIR(IMAGE_SYM_CLASS_ENUM_TAG),
+ STRING_PAIR(IMAGE_SYM_CLASS_MEMBER_OF_ENUM),
+ STRING_PAIR(IMAGE_SYM_CLASS_REGISTER_PARAM),
+ STRING_PAIR(IMAGE_SYM_CLASS_BIT_FIELD),
+ STRING_PAIR(IMAGE_SYM_CLASS_BLOCK),
+ STRING_PAIR(IMAGE_SYM_CLASS_FUNCTION),
+ STRING_PAIR(IMAGE_SYM_CLASS_END_OF_STRUCT),
+ STRING_PAIR(IMAGE_SYM_CLASS_FILE),
+ STRING_PAIR(IMAGE_SYM_CLASS_SECTION),
+ STRING_PAIR(IMAGE_SYM_CLASS_WEAK_EXTERNAL),
+ STRING_PAIR(IMAGE_SYM_CLASS_CLR_TOKEN),
+};
+
+static const pod_pair<llvm::COFF::RelocationTypeX86, const char *>
+RelocationTypeX86Pairs [] = {
+ STRING_PAIR(IMAGE_REL_I386_ABSOLUTE),
+ STRING_PAIR(IMAGE_REL_I386_DIR16),
+ STRING_PAIR(IMAGE_REL_I386_REL16),
+ STRING_PAIR(IMAGE_REL_I386_DIR32),
+ STRING_PAIR(IMAGE_REL_I386_DIR32NB),
+ STRING_PAIR(IMAGE_REL_I386_SEG12),
+ STRING_PAIR(IMAGE_REL_I386_SECTION),
+ STRING_PAIR(IMAGE_REL_I386_SECREL),
+ STRING_PAIR(IMAGE_REL_I386_TOKEN),
+ STRING_PAIR(IMAGE_REL_I386_SECREL7),
+ STRING_PAIR(IMAGE_REL_I386_REL32),
+ STRING_PAIR(IMAGE_REL_AMD64_ABSOLUTE),
+ STRING_PAIR(IMAGE_REL_AMD64_ADDR64),
+ STRING_PAIR(IMAGE_REL_AMD64_ADDR32),
+ STRING_PAIR(IMAGE_REL_AMD64_ADDR32NB),
+ STRING_PAIR(IMAGE_REL_AMD64_REL32),
+ STRING_PAIR(IMAGE_REL_AMD64_REL32_1),
+ STRING_PAIR(IMAGE_REL_AMD64_REL32_2),
+ STRING_PAIR(IMAGE_REL_AMD64_REL32_3),
+ STRING_PAIR(IMAGE_REL_AMD64_REL32_4),
+ STRING_PAIR(IMAGE_REL_AMD64_REL32_5),
+ STRING_PAIR(IMAGE_REL_AMD64_SECTION),
+ STRING_PAIR(IMAGE_REL_AMD64_SECREL),
+ STRING_PAIR(IMAGE_REL_AMD64_SECREL7),
+ STRING_PAIR(IMAGE_REL_AMD64_TOKEN),
+ STRING_PAIR(IMAGE_REL_AMD64_SREL32),
+ STRING_PAIR(IMAGE_REL_AMD64_PAIR),
+ STRING_PAIR(IMAGE_REL_AMD64_SSPAN32)
+};
+
+static const pod_pair<llvm::COFF::RelocationTypesARM, const char *>
+RelocationTypesARMPairs [] = {
+ STRING_PAIR(IMAGE_REL_ARM_ABSOLUTE),
+ STRING_PAIR(IMAGE_REL_ARM_ADDR32),
+ STRING_PAIR(IMAGE_REL_ARM_ADDR32NB),
+ STRING_PAIR(IMAGE_REL_ARM_BRANCH24),
+ STRING_PAIR(IMAGE_REL_ARM_BRANCH11),
+ STRING_PAIR(IMAGE_REL_ARM_TOKEN),
+ STRING_PAIR(IMAGE_REL_ARM_BLX24),
+ STRING_PAIR(IMAGE_REL_ARM_BLX11),
+ STRING_PAIR(IMAGE_REL_ARM_SECTION),
+ STRING_PAIR(IMAGE_REL_ARM_SECREL),
+ STRING_PAIR(IMAGE_REL_ARM_MOV32A),
+ STRING_PAIR(IMAGE_REL_ARM_MOV32T),
+ STRING_PAIR(IMAGE_REL_ARM_BRANCH20T),
+ STRING_PAIR(IMAGE_REL_ARM_BRANCH24T),
+ STRING_PAIR(IMAGE_REL_ARM_BLX23T)
+};
+#undef STRING_PAIR
+
+
+static const char endl = '\n';
+
+namespace yaml { // COFF-specific yaml-writing specific routines
+
+static llvm::raw_ostream &writeName(llvm::raw_ostream &Out,
+ const char *Name, std::size_t NameSize) {
+ for (std::size_t i = 0; i < NameSize; ++i) {
+ if (!Name[i]) break;
+ Out << Name[i];
+ }
+ return Out;
+}
+
+// Given an array of pod_pair<enum, const char *>, write all enums that match
+template <typename T, std::size_t N>
+static llvm::raw_ostream &writeBitMask(llvm::raw_ostream &Out,
+ const pod_pair<T, const char *> (&