aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2010-04-05 03:10:20 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2010-04-05 03:10:20 +0000
commitfddb7667ca4d8fe83f96b388295849281ddaa5b4 (patch)
treefdfe17e6a728d6560f0217760d6e3dd80ca924ed
parentba79d72eab446e64d360e8263d77732b5e13d556 (diff)
downloadexternal_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.td12
-rw-r--r--lib/Target/ARM/ARM.td18
-rw-r--r--lib/Target/ARM/ARMInstrFormats.td25
-rw-r--r--lib/Target/Alpha/Alpha.td6
-rw-r--r--lib/Target/MBlaze/MBlaze.td6
-rw-r--r--lib/Target/MSP430/MSP430.td9
-rw-r--r--lib/Target/MSP430/MSP430InstrFormats.td8
-rw-r--r--lib/Target/Mips/Mips.td5
-rw-r--r--lib/Target/PowerPC/PPC.td8
-rw-r--r--lib/Target/PowerPC/PPCInstrFormats.td11
-rw-r--r--lib/Target/Sparc/Sparc.td6
-rw-r--r--lib/Target/X86/X86.td28
-rw-r--r--lib/Target/X86/X86InstrFormats.td13
-rw-r--r--lib/Target/XCore/XCore.td5
-rw-r--r--utils/TableGen/InstrInfoEmitter.cpp84
-rw-r--r--utils/TableGen/InstrInfoEmitter.h2
-rw-r--r--utils/TableGen/Record.cpp11
-rw-r--r--utils/TableGen/Record.h3
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);