summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2007-05-01 05:57:02 +0000
committerNate Begeman <natebegeman@mac.com>2007-05-01 05:57:02 +0000
commit7bf1c272ab27297a7bbab329de3f17ddb26e02a3 (patch)
tree6fc181f3207ebd7bc26e82219f7f61d2d56f77ac
parent980e5aad4cfaa32e13b297f4201eb1088ca96cc4 (diff)
downloadllvm-7bf1c272ab27297a7bbab329de3f17ddb26e02a3.tar.gz
llvm-7bf1c272ab27297a7bbab329de3f17ddb26e02a3.tar.bz2
llvm-7bf1c272ab27297a7bbab329de3f17ddb26e02a3.tar.xz
llvm bug #1350, parts 1, 2, and 3.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36618 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/MachineInstr.h47
-rw-r--r--include/llvm/Target/MRegisterInfo.h6
-rw-r--r--lib/CodeGen/MachineInstr.cpp4
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.td51
-rw-r--r--lib/Target/Target.td16
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp36
6 files changed, 133 insertions, 27 deletions
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index a81c70e371..a6e14e21fd 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -71,10 +71,17 @@ private:
// immediately after the write. i.e. A register
// that is defined but never used.
- /// offset - Offset to address of global or external, only valid for
- /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
- int offset;
-
+ /// auxInfo - auxiliary information used by the MachineOperand
+ union {
+ /// offset - Offset to address of global or external, only valid for
+ /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
+ int offset;
+
+ /// subReg - SubRegister number, only valid for MO_Register. A value of 0
+ /// indicates the MO_Register has no subReg.
+ unsigned subReg;
+ } auxInfo;
+
MachineOperand() {}
void print(std::ostream &os) const;
@@ -95,7 +102,7 @@ public:
Op.IsImp = false;
Op.IsKill = false;
Op.IsDead = false;
- Op.offset = 0;
+ Op.auxInfo.offset = 0;
return Op;
}
@@ -106,7 +113,7 @@ public:
IsKill = MO.IsKill;
IsDead = MO.IsDead;
opType = MO.opType;
- offset = MO.offset;
+ auxInfo = MO.auxInfo;
return *this;
}
@@ -169,7 +176,11 @@ public:
int getOffset() const {
assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
"Wrong MachineOperand accessor");
- return offset;
+ return auxInfo.offset;
+ }
+ unsigned getSubReg() const {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ return auxInfo.subReg;
}
const char *getSymbolName() const {
assert(isExternalSymbol() && "Wrong MachineOperand accessor");
@@ -254,7 +265,11 @@ public:
assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() ||
isJumpTableIndex()) &&
"Wrong MachineOperand accessor");
- offset = Offset;
+ auxInfo.offset = Offset;
+ }
+ void setSubReg(unsigned subReg) {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ auxInfo.subReg = subReg;
}
void setConstantPoolIndex(unsigned Idx) {
assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
@@ -433,7 +448,7 @@ public:
Op.IsKill = IsKill;
Op.IsDead = IsDead;
Op.contents.RegNo = Reg;
- Op.offset = 0;
+ Op.auxInfo.subReg = 0;
}
/// addImmOperand - Add a zero extended constant argument to the
@@ -443,14 +458,14 @@ public:
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_Immediate;
Op.contents.immedVal = Val;
- Op.offset = 0;
+ Op.auxInfo.offset = 0;
}
void addMachineBasicBlockOperand(MachineBasicBlock *MBB) {
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_MachineBasicBlock;
Op.contents.MBB = MBB;
- Op.offset = 0;
+ Op.auxInfo.offset = 0;
}
/// addFrameIndexOperand - Add an abstract frame index to the instruction
@@ -459,7 +474,7 @@ public:
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_FrameIndex;
Op.contents.immedVal = Idx;
- Op.offset = 0;
+ Op.auxInfo.offset = 0;
}
/// addConstantPoolndexOperand - Add a constant pool object index to the
@@ -469,7 +484,7 @@ public:
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_ConstantPoolIndex;
Op.contents.immedVal = Idx;
- Op.offset = Offset;
+ Op.auxInfo.offset = Offset;
}
/// addJumpTableIndexOperand - Add a jump table object index to the
@@ -479,14 +494,14 @@ public:
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_JumpTableIndex;
Op.contents.immedVal = Idx;
- Op.offset = 0;
+ Op.auxInfo.offset = 0;
}
void addGlobalAddressOperand(GlobalValue *GV, int Offset) {
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_GlobalAddress;
Op.contents.GV = GV;
- Op.offset = Offset;
+ Op.auxInfo.offset = Offset;
}
/// addExternalSymbolOperand - Add an external symbol operand to this instr
@@ -495,7 +510,7 @@ public:
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_ExternalSymbol;
Op.contents.SymbolName = SymName;
- Op.offset = 0;
+ Op.auxInfo.offset = 0;
}
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/Target/MRegisterInfo.h b/include/llvm/Target/MRegisterInfo.h
index 4b9389accb..da4b750fe1 100644
--- a/include/llvm/Target/MRegisterInfo.h
+++ b/include/llvm/Target/MRegisterInfo.h
@@ -41,7 +41,7 @@ class Type;
/// The SubRegs field is a zero terminated array of registers that are
/// sub-registers of the specific register, e.g. AL, AH are sub-registers of AX.
/// The SuperRegs field is a zero terminated array of registers that are
-/// super-registers of the specific register, e.g. RAX, EAX, are sub-registers
+/// super-registers of the specific register, e.g. RAX, EAX, are super-registers
/// of AX.
///
struct TargetRegisterDesc {
@@ -354,6 +354,10 @@ public:
/// register scavenger to determine what registers are free.
virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;
+ /// getSubReg - Returns the physical register number of sub-register "Index"
+ /// for physical register RegNo.
+ virtual unsigned getSubReg(unsigned RegNo, unsigned Index) const = 0;
+
//===--------------------------------------------------------------------===//
// Register Class Information
//
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index 1c0d9cc4eb..9d09a9f95e 100644
--- a/lib/CodeGen/MachineInstr.cpp
+++ b/lib/CodeGen/MachineInstr.cpp
@@ -39,7 +39,7 @@ void MachineInstr::addImplicitDefUseOperands() {
Op.IsKill = false;
Op.IsDead = false;
Op.contents.RegNo = *ImpDefs;
- Op.offset = 0;
+ Op.auxInfo.subReg = 0;
Operands.push_back(Op);
}
if (TID->ImplicitUses)
@@ -51,7 +51,7 @@ void MachineInstr::addImplicitDefUseOperands() {
Op.IsKill = false;
Op.IsDead = false;
Op.contents.RegNo = *ImpUses;
- Op.offset = 0;
+ Op.auxInfo.subReg = 0;
Operands.push_back(Op);
}
}
diff --git a/lib/Target/PowerPC/PPCRegisterInfo.td b/lib/Target/PowerPC/PPCRegisterInfo.td
index b1040e9204..3891755247 100644
--- a/lib/Target/PowerPC/PPCRegisterInfo.td
+++ b/lib/Target/PowerPC/PPCRegisterInfo.td
@@ -43,10 +43,16 @@ class VR<bits<5> num, string n> : PPCReg<n> {
}
// CR - One of the 8 4-bit condition registers
-class CR<bits<5> num, string n> : PPCReg<n> {
+class CR<bits<3> num, string n> : PPCReg<n> {
+ field bits<3> Num = num;
+}
+
+// CRBIT - One of the 32 1-bit condition register fields
+class CRBIT<bits<5> num, string n> : PPCReg<n> {
field bits<5> Num = num;
}
+
// General-purpose registers
def R0 : GPR< 0, "r0">, DwarfRegNum<0>;
def R1 : GPR< 1, "r1">, DwarfRegNum<1>;
@@ -193,6 +199,49 @@ def CR5 : CR<5, "cr5">, DwarfRegNum<73>;
def CR6 : CR<6, "cr6">, DwarfRegNum<74>;
def CR7 : CR<7, "cr7">, DwarfRegNum<75>;
+// Condition register bits
+def CR0LT : CRBIT< 0, "0">, DwarfRegNum<0>;
+def CR0GT : CRBIT< 1, "1">, DwarfRegNum<0>;
+def CR0EQ : CRBIT< 2, "2">, DwarfRegNum<0>;
+def CR0UN : CRBIT< 3, "3">, DwarfRegNum<0>;
+def CR1LT : CRBIT< 4, "4">, DwarfRegNum<0>;
+def CR1GT : CRBIT< 5, "5">, DwarfRegNum<0>;
+def CR1EQ : CRBIT< 6, "6">, DwarfRegNum<0>;
+def CR1UN : CRBIT< 7, "7">, DwarfRegNum<0>;
+def CR2LT : CRBIT< 8, "8">, DwarfRegNum<0>;
+def CR2GT : CRBIT< 9, "9">, DwarfRegNum<0>;
+def CR2EQ : CRBIT<10, "10">, DwarfRegNum<0>;
+def CR2UN : CRBIT<11, "11">, DwarfRegNum<0>;
+def CR3LT : CRBIT<12, "12">, DwarfRegNum<0>;
+def CR3GT : CRBIT<13, "13">, DwarfRegNum<0>;
+def CR3EQ : CRBIT<14, "14">, DwarfRegNum<0>;
+def CR3UN : CRBIT<15, "15">, DwarfRegNum<0>;
+def CR4LT : CRBIT<16, "16">, DwarfRegNum<0>;
+def CR4GT : CRBIT<17, "17">, DwarfRegNum<0>;
+def CR4EQ : CRBIT<18, "18">, DwarfRegNum<0>;
+def CR4UN : CRBIT<19, "19">, DwarfRegNum<0>;
+def CR5LT : CRBIT<20, "20">, DwarfRegNum<0>;
+def CR5GT : CRBIT<21, "21">, DwarfRegNum<0>;
+def CR5EQ : CRBIT<22, "22">, DwarfRegNum<0>;
+def CR5UN : CRBIT<23, "23">, DwarfRegNum<0>;
+def CR6LT : CRBIT<24, "24">, DwarfRegNum<0>;
+def CR6GT : CRBIT<25, "25">, DwarfRegNum<0>;
+def CR6EQ : CRBIT<26, "26">, DwarfRegNum<0>;
+def CR6UN : CRBIT<27, "27">, DwarfRegNum<0>;
+def CR7LT : CRBIT<28, "28">, DwarfRegNum<0>;
+def CR7GT : CRBIT<29, "29">, DwarfRegNum<0>;
+def CR7EQ : CRBIT<30, "30">, DwarfRegNum<0>;
+def CR7UN : CRBIT<31, "31">, DwarfRegNum<0>;
+
+def : SubRegSet<1, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7],
+ [CR0LT, CR1LT, CR2LT, CR3LT, CR4LT, CR5LT, CR6LT, CR7LT]>;
+def : SubRegSet<2, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7],
+ [CR0GT, CR1GT, CR2GT, CR3GT, CR4GT, CR5GT, CR6GT, CR7GT]>;
+def : SubRegSet<3, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7],
+ [CR0EQ, CR1EQ, CR2EQ, CR3EQ, CR4EQ, CR5EQ, CR6EQ, CR7EQ]>;
+def : SubRegSet<4, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7],
+ [CR0UN, CR1UN, CR2UN, CR3UN, CR4UN, CR5UN, CR6UN, CR7UN]>;
+
// Link register
def LR : SPR<8, "lr">, DwarfRegNum<65>;
//let Aliases = [LR] in
diff --git a/lib/Target/Target.td b/lib/Target/Target.td
index 094a4adf3b..fce45a5c2d 100644
--- a/lib/Target/Target.td
+++ b/lib/Target/Target.td
@@ -67,13 +67,15 @@ class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
let SubRegs = subregs;
}
-// RegisterGroup - This can be used to define instances of Register which
-// need to specify aliases.
-// List "aliases" specifies which registers are aliased to this one. This
-// allows the code generator to be careful not to put two values with
-// overlapping live ranges into registers which alias.
-class RegisterGroup<string n, list<Register> aliases> : Register<n> {
- let Aliases = aliases;
+// SubRegSet - This can be used to define a specific mapping of registers to
+// indices, for use as named subregs of a particular physical register. Each
+// register in 'subregs' becomes an addressable subregister at index 'n' of the
+// corresponding register in 'regs'.
+class SubRegSet<int n, list<Register> regs, list<Register> subregs> {
+ int index = n;
+
+ list<Register> From = regs;
+ list<Register> To = subregs;
}
// RegisterClass - Now that all of the registers are defined, and aliases
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index d4671a5fbb..61d731ad73 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -61,6 +61,7 @@ void RegisterInfoEmitter::runHeader(std::ostream &OS) {
<< " " << ClassName
<< "(int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);\n"
<< " int getDwarfRegNum(unsigned RegNum) const;\n"
+ << " unsigned getSubReg(unsigned RegNo, unsigned Index) const;\n"
<< "};\n\n";
const std::vector<CodeGenRegisterClass> &RegisterClasses =
@@ -322,6 +323,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
std::map<Record*, std::set<Record*> > RegisterSubRegs;
std::map<Record*, std::set<Record*> > RegisterSuperRegs;
std::map<Record*, std::set<Record*> > RegisterAliases;
+ std::map<Record*, std::vector<std::pair<int, Record*> > > SubRegVectors;
const std::vector<CodeGenRegister> &Regs = Target.getRegisters();
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
@@ -441,6 +443,40 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
std::string ClassName = Target.getName() + "GenRegisterInfo";
+ // Calculate the mapping of subregister+index pairs to physical registers.
+ std::vector<Record*> SubRegs = Records.getAllDerivedDefinitions("SubRegSet");
+ for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) {
+ int subRegIndex = SubRegs[i]->getValueAsInt("index");
+ std::vector<Record*> From = SubRegs[i]->getValueAsListOfDefs("From");
+ std::vector<Record*> To = SubRegs[i]->getValueAsListOfDefs("To");
+
+ assert((From.size() == To.size()) &&
+ "SubRegSet has mismatched from/to size");
+
+ // For each entry in from/to vectors, insert the to register at index
+ for (unsigned ii = 0, ee = From.size(); ii != ee; ++ii)
+ SubRegVectors[From[ii]].push_back(std::make_pair(subRegIndex, To[ii]));
+ }
+
+ // Emit the subregister + index mapping function based on the information
+ // calculated above.
+ OS << "unsigned " << ClassName
+ << "::getSubReg(unsigned RegNo, unsigned Index) const {\n"
+ << " switch (RegNo) {\n"
+ << " default: abort(); break;\n";
+ for (std::map<Record*, std::vector<std::pair<int, Record*> > >::iterator
+ I = SubRegVectors.begin(), E = SubRegVectors.end(); I != E; ++I) {
+ OS << " case " << getQualifiedName(I->first) << ":\n";
+ OS << " switch (Index) {\n";
+ OS << " default: abort(); break;\n";
+ for (unsigned i = 0, e = I->second.size(); i != e; ++i)
+ OS << " case " << (I->second)[i].first << ": return "
+ << getQualifiedName((I->second)[i].second) << ";\n";
+ OS << " }; break;\n";
+ }
+ OS << " };\n";
+ OS << "}\n\n";
+
// Emit the constructor of the class...
OS << ClassName << "::" << ClassName
<< "(int CallFrameSetupOpcode, int CallFrameDestroyOpcode)\n"