diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2010-04-05 03:10:20 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2010-04-05 03:10:20 +0000 |
commit | fddb7667ca4d8fe83f96b388295849281ddaa5b4 (patch) | |
tree | fdfe17e6a728d6560f0217760d6e3dd80ca924ed | |
parent | ba79d72eab446e64d360e8263d77732b5e13d556 (diff) | |
download | external_llvm-fddb7667ca4d8fe83f96b388295849281ddaa5b4.zip external_llvm-fddb7667ca4d8fe83f96b388295849281ddaa5b4.tar.gz external_llvm-fddb7667ca4d8fe83f96b388295849281ddaa5b4.tar.bz2 |
Replace TSFlagsFields and TSFlagsShifts with a simpler TSFlags field.
When a target instruction wants to set target-specific flags, it should simply
set bits in the TSFlags bit vector defined in the Instruction TableGen class.
This works well because TableGen resolves member references late:
class I : Instruction {
AddrMode AM = AddrModeNone;
let TSFlags{3-0} = AM.Value;
}
let AM = AddrMode4 in
def ADD : I;
TSFlags gets the expected bits from AddrMode4 in this example.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100384 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Target/Target.td | 12 | ||||
-rw-r--r-- | lib/Target/ARM/ARM.td | 18 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrFormats.td | 25 | ||||
-rw-r--r-- | lib/Target/Alpha/Alpha.td | 6 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlaze.td | 6 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430.td | 9 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430InstrFormats.td | 8 | ||||
-rw-r--r-- | lib/Target/Mips/Mips.td | 5 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPC.td | 8 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstrFormats.td | 11 | ||||
-rw-r--r-- | lib/Target/Sparc/Sparc.td | 6 | ||||
-rw-r--r-- | lib/Target/X86/X86.td | 28 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrFormats.td | 13 | ||||
-rw-r--r-- | lib/Target/XCore/XCore.td | 5 | ||||
-rw-r--r-- | utils/TableGen/InstrInfoEmitter.cpp | 84 | ||||
-rw-r--r-- | utils/TableGen/InstrInfoEmitter.h | 2 | ||||
-rw-r--r-- | utils/TableGen/Record.cpp | 11 | ||||
-rw-r--r-- | utils/TableGen/Record.h | 3 |
18 files changed, 61 insertions, 199 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 0a7f549..5612f97 100644 --- a/include/llvm/Target/Target.td +++ b/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<ValueType ty, dag OpTypes, dag defaultops> // 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<string> TSFlagsFields = []; - list<int> 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/lib/Target/ARM/ARM.td b/lib/Target/ARM/ARM.td index 6486a60..8d9c622 100644 --- a/lib/Target/ARM/ARM.td +++ b/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/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index 4427e50..b466d0d 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -185,28 +185,25 @@ class InstTemplate<AddrMode am, SizeFlagVal sz, IndexMode im, : Instruction { let Namespace = "ARM"; - // TSFlagsFields AddrMode AM = am; - bits<4> 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<bits<4> 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<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, @@ -1341,7 +1338,7 @@ class AXDI5<dag oops, dag iops, IndexMode im, InstrItinClass itin, let Inst{11-8} = 0b1011; // 64-bit loads & stores operate on both NEON and VFP pipelines. - let Dom = VFPNeonDomain.Value; + let D = VFPNeonDomain; } class AXSI5<dag oops, dag iops, IndexMode im, InstrItinClass itin, diff --git a/lib/Target/Alpha/Alpha.td b/lib/Target/Alpha/Alpha.td index 6efdf55..4508eda 100644 --- a/lib/Target/Alpha/Alpha.td +++ b/lib/Target/Alpha/Alpha.td @@ -47,11 +47,7 @@ include "AlphaSchedule.td" include "AlphaInstrInfo.td" -def AlphaInstrInfo : InstrInfo { - // Define how we want to layout our target-specific information field. - // let TSFlagsFields = []; - // let TSFlagsShifts = []; -} +def AlphaInstrInfo : InstrInfo; //===----------------------------------------------------------------------===// // Alpha Processor Definitions diff --git a/lib/Target/MBlaze/MBlaze.td b/lib/Target/MBlaze/MBlaze.td index 1679752..482ddd3 100644 --- a/lib/Target/MBlaze/MBlaze.td +++ b/lib/Target/MBlaze/MBlaze.td @@ -25,11 +25,7 @@ include "MBlazeIntrinsics.td" include "MBlazeInstrInfo.td" include "MBlazeCallingConv.td" -def MBlazeInstrInfo : InstrInfo { - let TSFlagsFields = []; - let TSFlagsShifts = []; -} - +def MBlazeInstrInfo : InstrInfo; //===----------------------------------------------------------------------===// // Microblaze Subtarget features // diff --git a/lib/Target/MSP430/MSP430.td b/lib/Target/MSP430/MSP430.td index fe533d3..0f08e3d 100644 --- a/lib/Target/MSP430/MSP430.td +++ b/lib/Target/MSP430/MSP430.td @@ -48,14 +48,7 @@ include "MSP430CallingConv.td" include "MSP430InstrInfo.td" -def MSP430InstrInfo : InstrInfo { - // 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 TSFlagsFields = ["FormBits", - "Size"]; - let TSFlagsShifts = [0, - 2]; -} +def MSP430InstrInfo : InstrInfo; def MSP430InstPrinter : AsmWriter { string AsmWriterClassName = "InstPrinter"; diff --git a/lib/Target/MSP430/MSP430InstrFormats.td b/lib/Target/MSP430/MSP430InstrFormats.td index 4ccc7df..73aef1f 100644 --- a/lib/Target/MSP430/MSP430InstrFormats.td +++ b/lib/Target/MSP430/MSP430InstrFormats.td @@ -61,10 +61,12 @@ class MSP430Inst<dag outs, dag ins, SizeVal sz, Format f, dag InOperandList = ins; Format Form = f; - bits<2> 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/lib/Target/Mips/Mips.td b/lib/Target/Mips/Mips.td index 79a78d8..aa036ae 100644 --- a/lib/Target/Mips/Mips.td +++ b/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/lib/Target/PowerPC/PPC.td b/lib/Target/PowerPC/PPC.td index 08f5bb4..27644b2 100644 --- a/lib/Target/PowerPC/PPC.td +++ b/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/lib/Target/PowerPC/PPCInstrFormats.td b/lib/Target/PowerPC/PPCInstrFormats.td index 54cebcd..4357bdc 100644 --- a/lib/Target/PowerPC/PPCInstrFormats.td +++ b/lib/Target/PowerPC/PPCInstrFormats.td @@ -23,13 +23,18 @@ class I<bits<6> 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/lib/Target/Sparc/Sparc.td b/lib/Target/Sparc/Sparc.td index 53ea8f4..925d782 100644 --- a/lib/Target/Sparc/Sparc.td +++ b/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/lib/Target/X86/X86.td b/lib/Target/X86/X86.td index 89cc84f..ec86fc2 100644 --- a/lib/Target/X86/X86.td +++ b/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/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td index cbe4c82..4241433 100644 --- a/lib/Target/X86/X86InstrFormats.td +++ b/lib/Target/X86/X86InstrFormats.td @@ -128,6 +128,19 @@ class X86Inst<bits<8> 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<bits<8> o, Format f, dag outs, dag ins, string asm, diff --git a/lib/Target/XCore/XCore.td b/lib/Target/XCore/XCore.td index b07445d..3840189 100644 --- a/lib/Target/XCore/XCore.td +++ b/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/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 9bc5459..006a2a1 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -288,19 +288,19 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, if (Inst.isAsCheapAsAMove) OS << "|(1<<TID::CheapAsAMove)"; if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<TID::ExtraSrcRegAllocReq)"; if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<TID::ExtraDefRegAllocReq)"; - OS << ", 0"; // Emit all of the target-specific flags... - ListInit *LI = InstrInfo->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<StringInit*>(LI->getElement(i)), - dynamic_cast<IntInit*>(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<BitInit*>(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<BitInit*>(Value)) { - if (BI->getValue()) OS << "|(1<<" << Shift << ")"; - return; - } else if (BitsInit *BI = dynamic_cast<BitsInit*>(Value)) { - // Convert the Bits to an integer to print... - Init *I = BI->convertInitializerTo(new IntRecTy()); - if (I) - if (IntInit *II = dynamic_cast<IntInit*>(I)) { - if (II->getValue()) { - if (Shift) - OS << "|(" << II->getValue() << "<<" << Shift << ")"; - else - OS << "|" << II->getValue(); - } - return; - } - - } else if (IntInit *II = dynamic_cast<IntInit*>(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."; + OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; } - diff --git a/utils/TableGen/InstrInfoEmitter.h b/utils/TableGen/InstrInfoEmitter.h index 657939e..abb1c6b 100644 --- a/utils/TableGen/InstrInfoEmitter.h +++ b/utils/TableGen/InstrInfoEmitter.h @@ -47,8 +47,6 @@ private: std::map<Record*, unsigned> &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/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp index 55c9989..4f9f604 100644 --- a/utils/TableGen/Record.cpp +++ b/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<DefInit*>(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/utils/TableGen/Record.h b/utils/TableGen/Record.h index 41373c7..55c1a80 100644 --- a/utils/TableGen/Record.h +++ b/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); |