diff options
author | Derek Schuff <dschuff@chromium.org> | 2012-08-17 14:35:45 -0700 |
---|---|---|
committer | Derek Schuff <dschuff@chromium.org> | 2012-08-17 14:35:45 -0700 |
commit | b62e9abf7dd9e39c95327914ce9dfe216386824a (patch) | |
tree | c683f0bcbef19f622727251165eaf89a4f806c62 /utils | |
parent | 66f65db9406ca9e59d4bfed89436f668d6a84374 (diff) | |
parent | c723eb1aef817d47feec620933ee1ec6005cdd14 (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.cpp | 99 | ||||
-rw-r--r-- | utils/TableGen/DAGISelMatcherGen.cpp | 7 | ||||
-rw-r--r-- | utils/TableGen/DFAPacketizerEmitter.cpp | 70 | ||||
-rw-r--r-- | utils/TableGen/EDEmitter.cpp | 2 | ||||
-rw-r--r-- | utils/TableGen/SubtargetEmitter.cpp | 80 | ||||
-rw-r--r-- | utils/TableGen/X86RecognizableInstr.cpp | 4 | ||||
-rw-r--r-- | utils/obj2yaml/CMakeLists.txt | 7 | ||||
-rw-r--r-- | utils/obj2yaml/Makefile | 20 | ||||
-rw-r--r-- | utils/obj2yaml/coff2yaml.cpp | 361 | ||||
-rw-r--r-- | utils/obj2yaml/obj2yaml.cpp | 89 | ||||
-rw-r--r-- | utils/obj2yaml/obj2yaml.h | 35 | ||||
-rwxr-xr-x | utils/test_debuginfo.pl | 2 |
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 *> (& |