diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td index 0a7f54937705..5612f97acf41 100644 --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -224,10 +224,13 @@ class Instruction { InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling. string Constraints = ""; // OperandConstraint, e.g. $src = $dst. - + /// DisableEncoding - List of operand names (e.g. "$op1,$op2") that should not /// be encoded into the output machineinstr. string DisableEncoding = ""; + + /// Target-specific flags. This becomes the TSFlags field in TargetInstrDesc. + bits<32> TSFlags = 0; } /// Predicates - These are extra conditionals which are turned into instruction @@ -372,13 +375,6 @@ class OptionalDefOperand // which are global to the target machine. // class InstrInfo { - // If the target wants to associate some target-specific information with each - // instruction, it should provide these two lists to indicate how to assemble - // the target specific information into the 32 bits available. - // - list TSFlagsFields = []; - list TSFlagsShifts = []; - // Target can specify its instructions in either big or little-endian formats. // For instance, while both Sparc and PowerPC are big-endian platforms, the // Sparc manual specifies its instructions in the format [31..0] (big), while diff --git a/llvm/lib/Target/ARM/ARM.td b/llvm/lib/Target/ARM/ARM.td index 6486a608e46d..8d9c62253cdd 100644 --- a/llvm/lib/Target/ARM/ARM.td +++ b/llvm/lib/Target/ARM/ARM.td @@ -140,23 +140,7 @@ include "ARMCallingConv.td" include "ARMInstrInfo.td" -def ARMInstrInfo : InstrInfo { - // Define how we want to layout our target-specific information field. - let TSFlagsFields = ["AddrModeBits", - "SizeFlag", - "IndexModeBits", - "Form", - "isUnaryDataProc", - "canXformTo16Bit", - "Dom"]; - let TSFlagsShifts = [0, - 4, - 7, - 9, - 15, - 16, - 17]; -} +def ARMInstrInfo : InstrInfo; //===----------------------------------------------------------------------===// // Declare the target which we are implementing diff --git a/llvm/lib/Target/ARM/ARMInstrFormats.td b/llvm/lib/Target/ARM/ARMInstrFormats.td index 4427e50bbdb1..b466d0dd994e 100644 --- a/llvm/lib/Target/ARM/ARMInstrFormats.td +++ b/llvm/lib/Target/ARM/ARMInstrFormats.td @@ -185,28 +185,25 @@ class InstTemplate AddrModeBits = AM.Value; - SizeFlagVal SZ = sz; - bits<3> SizeFlag = SZ.Value; - IndexMode IM = im; bits<2> IndexModeBits = IM.Value; - Format F = f; bits<6> Form = F.Value; - Domain D = d; - bits<2> Dom = D.Value; - - // - // Attributes specific to ARM instructions... - // bit isUnaryDataProc = 0; bit canXformTo16Bit = 0; + // The layout of TSFlags should be kept in sync with ARMBaseInstrInfo.h. + let TSFlags{3-0} = AM.Value; + let TSFlags{6-4} = SZ.Value; + let TSFlags{8-7} = IndexModeBits; + let TSFlags{14-9} = Form; + let TSFlags{15} = isUnaryDataProc; + let TSFlags{16} = canXformTo16Bit; + let TSFlags{18-17} = D.Value; + let Constraints = cstr; let Itinerary = itin; } @@ -1317,7 +1314,7 @@ class ADI5 opcod1, bits<2> opcod2, dag oops, dag iops, let Inst{11-8} = 0b1011; // 64-bit loads & stores operate on both NEON and VFP pipelines. - let Dom = VFPNeonDomain.Value; + let D = VFPNeonDomain; } class ASI5 opcod1, bits<2> opcod2, dag oops, dag iops, @@ -1341,7 +1338,7 @@ class AXDI5 FormBits = Form.Value; - SizeVal Sz = sz; - bits<3> Size = Sz.Value; + + // Define how we want to layout our TargetSpecific information field... This + // should be kept up-to-date with the fields in the MSP430InstrInfo.h file. + let TSFlags{1-0} = Form.Value; + let TSFlags{4-2} = Sz.Value; let AsmString = asmstr; } diff --git a/llvm/lib/Target/Mips/Mips.td b/llvm/lib/Target/Mips/Mips.td index 79a78d86aef7..aa036aef83d0 100644 --- a/llvm/lib/Target/Mips/Mips.td +++ b/llvm/lib/Target/Mips/Mips.td @@ -24,10 +24,7 @@ include "MipsSchedule.td" include "MipsInstrInfo.td" include "MipsCallingConv.td" -def MipsInstrInfo : InstrInfo { - let TSFlagsFields = []; - let TSFlagsShifts = []; -} +def MipsInstrInfo : InstrInfo; //===----------------------------------------------------------------------===// // Mips Subtarget features // diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td index 08f5bb43087f..27644b2daca8 100644 --- a/llvm/lib/Target/PowerPC/PPC.td +++ b/llvm/lib/Target/PowerPC/PPC.td @@ -96,14 +96,6 @@ def : Processor<"ppc64", G5Itineraries, include "PPCCallingConv.td" def PPCInstrInfo : InstrInfo { - // Define how we want to layout our TargetSpecific information field... This - // should be kept up-to-date with the fields in the PPCInstrInfo.h file. - let TSFlagsFields = ["PPC970_First", - "PPC970_Single", - "PPC970_Cracked", - "PPC970_Unit"]; - let TSFlagsShifts = [0, 1, 2, 3]; - let isLittleEndianEncoding = 1; } diff --git a/llvm/lib/Target/PowerPC/PPCInstrFormats.td b/llvm/lib/Target/PowerPC/PPCInstrFormats.td index 54cebcdecd61..4357bdccec7b 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrFormats.td +++ b/llvm/lib/Target/PowerPC/PPCInstrFormats.td @@ -23,13 +23,18 @@ class I opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin> let InOperandList = IOL; let AsmString = asmstr; let Itinerary = itin; - - /// These fields correspond to the fields in PPCInstrInfo.h. Any changes to - /// these must be reflected there! See comments there for what these are. + bits<1> PPC970_First = 0; bits<1> PPC970_Single = 0; bits<1> PPC970_Cracked = 0; bits<3> PPC970_Unit = 0; + + /// These fields correspond to the fields in PPCInstrInfo.h. Any changes to + /// these must be reflected there! See comments there for what these are. + let TSFlags{0} = PPC970_First; + let TSFlags{1} = PPC970_Single; + let TSFlags{2} = PPC970_Cracked; + let TSFlags{5-3} = PPC970_Unit; } class PPC970_DGroup_First { bits<1> PPC970_First = 1; } diff --git a/llvm/lib/Target/Sparc/Sparc.td b/llvm/lib/Target/Sparc/Sparc.td index 53ea8f4a35f0..925d782d988b 100644 --- a/llvm/lib/Target/Sparc/Sparc.td +++ b/llvm/lib/Target/Sparc/Sparc.td @@ -38,11 +38,7 @@ include "SparcRegisterInfo.td" include "SparcCallingConv.td" include "SparcInstrInfo.td" -def SparcInstrInfo : InstrInfo { - // Define how we want to layout our target-specific information field. - let TSFlagsFields = []; - let TSFlagsShifts = []; -} +def SparcInstrInfo : InstrInfo; //===----------------------------------------------------------------------===// // SPARC processors supported. diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index 89cc84ffb3c6..ec86fc248e3d 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -164,33 +164,7 @@ include "X86RegisterInfo.td" include "X86InstrInfo.td" -def X86InstrInfo : InstrInfo { - - // Define how we want to layout our TargetSpecific information field... This - // should be kept up-to-date with the fields in the X86InstrInfo.h file. - let TSFlagsFields = ["FormBits", - "hasOpSizePrefix", - "hasAdSizePrefix", - "Prefix", - "hasREX_WPrefix", - "ImmT.Value", - "FPForm.Value", - "hasLockPrefix", - "SegOvrBits", - "ExeDomain.Value", - "Opcode"]; - let TSFlagsShifts = [0, - 6, - 7, - 8, - 12, - 13, - 16, - 19, - 20, - 22, - 24]; -} +def X86InstrInfo : InstrInfo; //===----------------------------------------------------------------------===// // Calling Conventions diff --git a/llvm/lib/Target/X86/X86InstrFormats.td b/llvm/lib/Target/X86/X86InstrFormats.td index cbe4c8256299..424143379346 100644 --- a/llvm/lib/Target/X86/X86InstrFormats.td +++ b/llvm/lib/Target/X86/X86InstrFormats.td @@ -128,6 +128,19 @@ class X86Inst opcod, Format f, ImmType i, dag outs, dag ins, bit hasLockPrefix = 0; // Does this inst have a 0xF0 prefix? bits<2> SegOvrBits = 0; // Segment override prefix. Domain ExeDomain = d; + + // TSFlags layout should be kept in sync with X86InstrInfo.h. + let TSFlags{5-0} = FormBits; + let TSFlags{6} = hasOpSizePrefix; + let TSFlags{7} = hasAdSizePrefix; + let TSFlags{11-8} = Prefix; + let TSFlags{12} = hasREX_WPrefix; + let TSFlags{15-13} = ImmT.Value; + let TSFlags{18-16} = FPForm.Value; + let TSFlags{19} = hasLockPrefix; + let TSFlags{21-20} = SegOvrBits; + let TSFlags{23-22} = ExeDomain.Value; + let TSFlags{31-24} = Opcode; } class I o, Format f, dag outs, dag ins, string asm, diff --git a/llvm/lib/Target/XCore/XCore.td b/llvm/lib/Target/XCore/XCore.td index b07445dd386f..38401895e634 100644 --- a/llvm/lib/Target/XCore/XCore.td +++ b/llvm/lib/Target/XCore/XCore.td @@ -24,10 +24,7 @@ include "XCoreRegisterInfo.td" include "XCoreInstrInfo.td" include "XCoreCallingConv.td" -def XCoreInstrInfo : InstrInfo { - let TSFlagsFields = []; - let TSFlagsShifts = []; -} +def XCoreInstrInfo : InstrInfo; //===----------------------------------------------------------------------===// // XCore processors supported. diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp index 9bc545928d9b..006a2a1b0933 100644 --- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -288,19 +288,19 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, if (Inst.isAsCheapAsAMove) OS << "|(1<getValueAsListInit("TSFlagsFields"); - ListInit *Shift = InstrInfo->getValueAsListInit("TSFlagsShifts"); - if (LI->getSize() != Shift->getSize()) - throw "Lengths of " + InstrInfo->getName() + - ":(TargetInfoFields, TargetInfoPositions) must be equal!"; - - for (unsigned i = 0, e = LI->getSize(); i != e; ++i) - emitShiftedValue(Inst.TheDef, dynamic_cast(LI->getElement(i)), - dynamic_cast(Shift->getElement(i)), OS); - + BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); + if (!TSF) throw "no TSFlags?"; + uint64_t Value = 0; + for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) { + if (BitInit *Bit = dynamic_cast(TSF->getBit(i))) + Value |= uint64_t(Bit->getValue()) << i; + else + throw "Invalid TSFlags bit in " + Inst.TheDef->getName(); + } + OS << ", 0x"; + OS.write_hex(Value); OS << ", "; // Emit the implicit uses and defs lists... @@ -328,66 +328,6 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, OS << "0"; else OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; - + OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; } - - -void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val, - IntInit *ShiftInt, raw_ostream &OS) { - if (Val == 0 || ShiftInt == 0) - throw std::string("Illegal value or shift amount in TargetInfo*!"); - RecordVal *RV = R->getDottedValue(Val->getValue()); - int Shift = ShiftInt->getValue(); - - if (RV == 0 || RV->getValue() == 0) { - // This isn't an error if this is a builtin instruction. - if (R->getName() != "PHI" && - R->getName() != "INLINEASM" && - R->getName() != "DBG_LABEL" && - R->getName() != "EH_LABEL" && - R->getName() != "GC_LABEL" && - R->getName() != "KILL" && - R->getName() != "EXTRACT_SUBREG" && - R->getName() != "INSERT_SUBREG" && - R->getName() != "IMPLICIT_DEF" && - R->getName() != "SUBREG_TO_REG" && - R->getName() != "COPY_TO_REGCLASS" && - R->getName() != "DBG_VALUE") - throw R->getName() + " doesn't have a field named '" + - Val->getValue() + "'!"; - return; - } - - Init *Value = RV->getValue(); - if (BitInit *BI = dynamic_cast(Value)) { - if (BI->getValue()) OS << "|(1<<" << Shift << ")"; - return; - } else if (BitsInit *BI = dynamic_cast(Value)) { - // Convert the Bits to an integer to print... - Init *I = BI->convertInitializerTo(new IntRecTy()); - if (I) - if (IntInit *II = dynamic_cast(I)) { - if (II->getValue()) { - if (Shift) - OS << "|(" << II->getValue() << "<<" << Shift << ")"; - else - OS << "|" << II->getValue(); - } - return; - } - - } else if (IntInit *II = dynamic_cast(Value)) { - if (II->getValue()) { - if (Shift) - OS << "|(" << II->getValue() << "<<" << Shift << ")"; - else - OS << II->getValue(); - } - return; - } - - errs() << "Unhandled initializer: " << *Val << "\n"; - throw "In record '" + R->getName() + "' for TSFlag emission."; -} - diff --git a/llvm/utils/TableGen/InstrInfoEmitter.h b/llvm/utils/TableGen/InstrInfoEmitter.h index 657939e46388..abb1c6bc188c 100644 --- a/llvm/utils/TableGen/InstrInfoEmitter.h +++ b/llvm/utils/TableGen/InstrInfoEmitter.h @@ -47,8 +47,6 @@ private: std::map &BM, const OperandInfoMapTy &OpInfo, raw_ostream &OS); - void emitShiftedValue(Record *R, StringInit *Val, IntInit *Shift, - raw_ostream &OS); // Itinerary information. void GatherItinClasses(); diff --git a/llvm/utils/TableGen/Record.cpp b/llvm/utils/TableGen/Record.cpp index 55c998926c0a..4f9f6045c14c 100644 --- a/llvm/utils/TableGen/Record.cpp +++ b/llvm/utils/TableGen/Record.cpp @@ -1307,17 +1307,6 @@ void Record::resolveReferencesTo(const RecordVal *RV) { } } -RecordVal *Record::getDottedValue(StringRef Name) { - size_t pos = Name.find('.'); - if (pos == StringRef::npos) - return getValue(Name); - RecordVal *RV = getValue(Name.substr(0, pos)); - if (!RV) return 0; - DefInit *DI = dynamic_cast(RV->getValue()); - if (!DI) return 0; - return DI->getDef()->getDottedValue(Name.substr(pos+1)); -} - void Record::dump() const { errs() << *this; } raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) { diff --git a/llvm/utils/TableGen/Record.h b/llvm/utils/TableGen/Record.h index 41373c799a0d..55c1a80f9b6a 100644 --- a/llvm/utils/TableGen/Record.h +++ b/llvm/utils/TableGen/Record.h @@ -1262,9 +1262,6 @@ public: return 0; } - // Like getValue, but allow dotting into members: X.Y - RecordVal *getDottedValue(StringRef Name); - void addTemplateArg(StringRef Name) { assert(!isTemplateArg(Name) && "Template arg already defined!"); TemplateArgs.push_back(Name);