diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index a81c70e3711..a6e14e21fdf 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 4b9389accb7..da4b750fe1e 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 1c0d9cc4eb1..9d09a9f95e5 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 b1040e92045..3891755247e 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.td +++ b/lib/Target/PowerPC/PPCRegisterInfo.td @@ -43,10 +43,16 @@ class VR num, string n> : PPCReg { } // CR - One of the 8 4-bit condition registers -class CR num, string n> : PPCReg { +class CR num, string n> : PPCReg { + field bits<3> Num = num; +} + +// CRBIT - One of the 32 1-bit condition register fields +class CRBIT num, string n> : PPCReg { 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 094a4adf3ba..fce45a5c2d4 100644 --- a/lib/Target/Target.td +++ b/lib/Target/Target.td @@ -67,13 +67,15 @@ class RegisterWithSubRegs subregs> : Register { 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 aliases> : Register { - 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 regs, list subregs> { + int index = n; + + list From = regs; + list 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 d4671a5fbbb..61d731ad73f 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 &RegisterClasses = @@ -322,6 +323,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) { std::map > RegisterSubRegs; std::map > RegisterSuperRegs; std::map > RegisterAliases; + std::map > > SubRegVectors; const std::vector &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 SubRegs = Records.getAllDerivedDefinitions("SubRegSet"); + for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { + int subRegIndex = SubRegs[i]->getValueAsInt("index"); + std::vector From = SubRegs[i]->getValueAsListOfDefs("From"); + std::vector 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 > >::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"