From 73ea7bf4509663267317ec3911aac00ca35a2f2c Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Mon, 24 May 2010 14:48:12 +0000 Subject: [PATCH] Add the SubRegIndex TableGen class. This is the beginning of purely symbolic subregister indices, but we need a bit of jiggling before the explicit numeric indices can be completely removed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104492 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/Target.td | 8 ++++++ lib/Target/Blackfin/BlackfinInstrInfo.td | 30 ++++++++++---------- lib/Target/Blackfin/BlackfinRegisterInfo.cpp | 4 +-- lib/Target/Blackfin/BlackfinRegisterInfo.h | 7 ----- lib/Target/Blackfin/BlackfinRegisterInfo.td | 20 ++++++------- lib/Target/X86/X86InstrInfo.cpp | 4 +-- lib/Target/X86/X86RegisterInfo.td | 20 +++++++------ utils/TableGen/CodeGenDAGPatterns.cpp | 5 ++++ utils/TableGen/DAGISelMatcherGen.cpp | 9 ++++++ utils/TableGen/FastISelEmitter.cpp | 19 +++++++------ utils/TableGen/RegisterInfoEmitter.cpp | 25 +++++++++++++--- 11 files changed, 94 insertions(+), 57 deletions(-) diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 607dac7bd42..94430bc6cc0 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -21,6 +21,14 @@ include "llvm/Intrinsics.td" class RegisterClass; // Forward def +class SubRegIndex { + string Namespace = ""; + + // This explicit numbering is going away after RegisterClass::SubRegClassList + // is replaced. + int NumberHack; +} + // Register - You should define one instance of this class for each register // in the target machine. String n will become the "name" of the register. class Register { diff --git a/lib/Target/Blackfin/BlackfinInstrInfo.td b/lib/Target/Blackfin/BlackfinInstrInfo.td index 2471688b905..5cf350a0cb4 100644 --- a/lib/Target/Blackfin/BlackfinInstrInfo.td +++ b/lib/Target/Blackfin/BlackfinInstrInfo.td @@ -301,9 +301,9 @@ def LOAD32p_8z: F1<(outs D:$dst), (ins P:$ptr), def : Pat<(i32 (extloadi8 P:$ptr)), (LOAD32p_8z P:$ptr)>; def : Pat<(i16 (extloadi8 P:$ptr)), - (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), bfin_subreg_lo16)>; + (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), lo16)>; def : Pat<(i16 (zextloadi8 P:$ptr)), - (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), bfin_subreg_lo16)>; + (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), lo16)>; def LOAD32p_imm16_8z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off), "$dst = b[$ptr + $off] (z);", @@ -313,17 +313,17 @@ def : Pat<(i32 (extloadi8 (add P:$ptr, imm16:$off))), (LOAD32p_imm16_8z P:$ptr, imm:$off)>; def : Pat<(i16 (extloadi8 (add P:$ptr, imm16:$off))), (EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off), - bfin_subreg_lo16)>; + lo16)>; def : Pat<(i16 (zextloadi8 (add P:$ptr, imm16:$off))), (EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off), - bfin_subreg_lo16)>; + lo16)>; def LOAD32p_8s: F1<(outs D:$dst), (ins P:$ptr), "$dst = b[$ptr] (x);", [(set D:$dst, (sextloadi8 P:$ptr))]>; def : Pat<(i16 (sextloadi8 P:$ptr)), - (EXTRACT_SUBREG (LOAD32p_8s P:$ptr), bfin_subreg_lo16)>; + (EXTRACT_SUBREG (LOAD32p_8s P:$ptr), lo16)>; def LOAD32p_imm16_8s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off), "$dst = b[$ptr + $off] (x);", @@ -331,7 +331,7 @@ def LOAD32p_imm16_8s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off), def : Pat<(i16 (sextloadi8 (add P:$ptr, imm16:$off))), (EXTRACT_SUBREG (LOAD32p_imm16_8s P:$ptr, imm:$off), - bfin_subreg_lo16)>; + lo16)>; // Memory loads without patterns let mayLoad = 1 in { @@ -468,16 +468,16 @@ def STORE32i_post: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr, M:$off), def : Pat<(truncstorei16 D:$val, PI:$ptr), (STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)), - bfin_subreg_lo16), PI:$ptr)>; + lo16), PI:$ptr)>; def : Pat<(truncstorei16 (srl D:$val, (i16 16)), PI:$ptr), (STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)), - bfin_subreg_hi16), PI:$ptr)>; + hi16), PI:$ptr)>; def : Pat<(truncstorei8 D16L:$val, P:$ptr), (STORE8p (INSERT_SUBREG (i32 (IMPLICIT_DEF)), (i16 (COPY_TO_REGCLASS D16L:$val, D16L)), - bfin_subreg_lo16), + lo16), P:$ptr)>; //===----------------------------------------------------------------------===// @@ -516,19 +516,19 @@ def : Pat<(sext_inreg D16L:$src, i8), (EXTRACT_SUBREG (MOVEsext8 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), D16L:$src, - bfin_subreg_lo16)), - bfin_subreg_lo16)>; + lo16)), + lo16)>; def : Pat<(sext_inreg D:$src, i16), - (MOVEsext (EXTRACT_SUBREG D:$src, bfin_subreg_lo16))>; + (MOVEsext (EXTRACT_SUBREG D:$src, lo16))>; def : Pat<(and D:$src, 0xffff), - (MOVEzext (EXTRACT_SUBREG D:$src, bfin_subreg_lo16))>; + (MOVEzext (EXTRACT_SUBREG D:$src, lo16))>; def : Pat<(i32 (anyext D16L:$src)), (INSERT_SUBREG (i32 (IMPLICIT_DEF)), (i16 (COPY_TO_REGCLASS D16L:$src, D16L)), - bfin_subreg_lo16)>; + lo16)>; // TODO Dreg = Dreg_byte (X/Z) @@ -859,4 +859,4 @@ def : Pat<(BfinCall (i32 tglobaladdr:$dst)), def : Pat<(BfinCall (i32 texternalsym:$dst)), (CALLa texternalsym:$dst)>; def : Pat<(i16 (trunc D:$src)), - (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$src, D)), bfin_subreg_lo16)>; + (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$src, D)), lo16)>; diff --git a/lib/Target/Blackfin/BlackfinRegisterInfo.cpp b/lib/Target/Blackfin/BlackfinRegisterInfo.cpp index 0571eb30052..5153aceb8f7 100644 --- a/lib/Target/Blackfin/BlackfinRegisterInfo.cpp +++ b/lib/Target/Blackfin/BlackfinRegisterInfo.cpp @@ -177,11 +177,11 @@ void BlackfinRegisterInfo::loadConstant(MachineBasicBlock &MBB, // We must split into halves BuildMI(MBB, I, DL, - TII.get(BF::LOAD16i), getSubReg(Reg, bfin_subreg_hi16)) + TII.get(BF::LOAD16i), getSubReg(Reg, BF::hi16)) .addImm((value >> 16) & 0xffff) .addReg(Reg, RegState::ImplicitDefine); BuildMI(MBB, I, DL, - TII.get(BF::LOAD16i), getSubReg(Reg, bfin_subreg_lo16)) + TII.get(BF::LOAD16i), getSubReg(Reg, BF::lo16)) .addImm(value & 0xffff) .addReg(Reg, RegState::ImplicitKill) .addReg(Reg, RegState::ImplicitDefine); diff --git a/lib/Target/Blackfin/BlackfinRegisterInfo.h b/lib/Target/Blackfin/BlackfinRegisterInfo.h index 7cfb120bac5..03c54507ff6 100644 --- a/lib/Target/Blackfin/BlackfinRegisterInfo.h +++ b/lib/Target/Blackfin/BlackfinRegisterInfo.h @@ -24,13 +24,6 @@ namespace llvm { class TargetInstrInfo; class Type; - // Subregister indices, keep in sync with BlackfinRegisterInfo.td - enum BfinSubregIdx { - bfin_subreg_lo16 = 1, - bfin_subreg_hi16 = 2, - bfin_subreg_lo32 = 3 - }; - struct BlackfinRegisterInfo : public BlackfinGenRegisterInfo { BlackfinSubtarget &Subtarget; const TargetInstrInfo &TII; diff --git a/lib/Target/Blackfin/BlackfinRegisterInfo.td b/lib/Target/Blackfin/BlackfinRegisterInfo.td index d396cc807e8..2a7336c5b91 100644 --- a/lib/Target/Blackfin/BlackfinRegisterInfo.td +++ b/lib/Target/Blackfin/BlackfinRegisterInfo.td @@ -11,8 +11,17 @@ // Declarations that describe the Blackfin register file //===----------------------------------------------------------------------===// -// Registers are identified with 3-bit group and 3-bit ID numbers. +// Subregs are: +// 1: .L +// 2: .H +// 3: .W (32 low bits of 40-bit accu) +let Namespace = "BF" in { +def lo16 : SubRegIndex { let NumberHack = 1; } +def hi16 : SubRegIndex { let NumberHack = 2; } +def lo32 : SubRegIndex { let NumberHack = 3; } +} +// Registers are identified with 3-bit group and 3-bit ID numbers. class BlackfinReg : Register { field bits<3> Group; field bits<3> Num; @@ -182,15 +191,6 @@ def LC1 : Ri<6, 3, "lc1">, DwarfRegNum<[47]>; def LB0 : Ri<6, 2, "lb0">, DwarfRegNum<[48]>; def LB1 : Ri<6, 5, "lb1">, DwarfRegNum<[49]>; -// Subregs are: -// 1: .L -// 2: .H -// 3: .W (32 low bits of 40-bit accu) -// Keep in sync with enum in BlackfinRegisterInfo.h -def bfin_subreg_lo16 : PatLeaf<(i32 1)>; -def bfin_subreg_hi16 : PatLeaf<(i32 2)>; -def bfin_subreg_32bit : PatLeaf<(i32 3)>; - def : SubRegSet<1, [R0, R1, R2, R3, R4, R5, R6, R7, P0, P1, P2, P3, P4, P5, SP, FP, diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index d4f412258f1..77756a3885c 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -2483,9 +2483,9 @@ X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, unsigned DstReg = NewMI->getOperand(0).getReg(); if (TargetRegisterInfo::isPhysicalRegister(DstReg)) NewMI->getOperand(0).setReg(RI.getSubReg(DstReg, - 4/*x86_subreg_32bit*/)); + X86::x86_subreg_32bit)); else - NewMI->getOperand(0).setSubReg(4/*x86_subreg_32bit*/); + NewMI->getOperand(0).setSubReg(X86::x86_subreg_32bit); } return NewMI; } diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td index 3291c0c30b9..a07f3ef2e97 100644 --- a/lib/Target/X86/X86RegisterInfo.td +++ b/lib/Target/X86/X86RegisterInfo.td @@ -18,6 +18,17 @@ // let Namespace = "X86" in { + // Subregister indices. + def x86_subreg_8bit : SubRegIndex { let NumberHack = 1; } + def x86_subreg_8bit_hi : SubRegIndex { let NumberHack = 2; } + def x86_subreg_16bit : SubRegIndex { let NumberHack = 3; } + def x86_subreg_32bit : SubRegIndex { let NumberHack = 4; } + + def x86_subreg_ss : SubRegIndex { let NumberHack = 1; } + def x86_subreg_sd : SubRegIndex { let NumberHack = 2; } + def x86_subreg_xmm : SubRegIndex { let NumberHack = 3; } + + // In the register alias definitions below, we define which registers alias // which others. We only specify which registers the small registers alias, // because the register file generator is smart enough to figure out that @@ -224,15 +235,6 @@ let Namespace = "X86" in { // sub registers for each register. // -def x86_subreg_8bit : PatLeaf<(i32 1)>; -def x86_subreg_8bit_hi : PatLeaf<(i32 2)>; -def x86_subreg_16bit : PatLeaf<(i32 3)>; -def x86_subreg_32bit : PatLeaf<(i32 4)>; - -def x86_subreg_ss : PatLeaf<(i32 1)>; -def x86_subreg_sd : PatLeaf<(i32 2)>; -def x86_subreg_xmm : PatLeaf<(i32 3)>; - def : SubRegSet<1, [AX, CX, DX, BX, SP, BP, SI, DI, R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W], [AL, CL, DL, BL, SPL, BPL, SIL, DIL, diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index a0bccfc5e57..878ed09550a 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -1057,6 +1057,11 @@ static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo, const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo(); return EEVT::TypeSet(T.getRegisterVTs(R)); } + + if (R->isSubClassOf("SubRegIndex")) { + assert(ResNo == 0 && "SubRegisterIndices only produce one result!"); + return EEVT::TypeSet(); + } if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) { assert(ResNo == 0 && "This node only has one result!"); diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp index 9d469a9acbe..eb528eb02be 100644 --- a/utils/TableGen/DAGISelMatcherGen.cpp +++ b/utils/TableGen/DAGISelMatcherGen.cpp @@ -224,6 +224,7 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) { if (// Handle register references. Nothing to do here, they always match. LeafRec->isSubClassOf("RegisterClass") || LeafRec->isSubClassOf("PointerLikeRegClass") || + LeafRec->isSubClassOf("SubRegIndex") || // Place holder for SRCVALUE nodes. Nothing to do here. LeafRec->getName() == "srcvalue") return; @@ -597,6 +598,14 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N, ResultOps.push_back(NextRecordedOperandNo++); return; } + + // Handle a subregister index. This is used for INSERT_SUBREG etc. + if (DI->getDef()->isSubClassOf("SubRegIndex")) { + std::string Value = getQualifiedName(DI->getDef()); + AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32)); + ResultOps.push_back(NextRecordedOperandNo++); + return; + } } errs() << "unhandled leaf node: \n"; diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp index ce9d97b8ad3..9ec9e088424 100644 --- a/utils/TableGen/FastISelEmitter.cpp +++ b/utils/TableGen/FastISelEmitter.cpp @@ -31,7 +31,7 @@ namespace { struct InstructionMemo { std::string Name; const CodeGenRegisterClass *RC; - unsigned char SubRegNo; + std::string SubRegNo; std::vector* PhysRegs; }; @@ -278,7 +278,7 @@ void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) { // For now, ignore instructions where the first operand is not an // output register. const CodeGenRegisterClass *DstRC = 0; - unsigned SubRegNo = ~0; + std::string SubRegNo; if (Op->getName() != "EXTRACT_SUBREG") { Record *Op0Rec = II.OperandList[0].Rec; if (!Op0Rec->isSubClassOf("RegisterClass")) @@ -287,8 +287,11 @@ void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) { if (!DstRC) continue; } else { - SubRegNo = static_cast( - Dst->getChild(1)->getLeafValue())->getValue(); + DefInit *SR = dynamic_cast(Dst->getChild(1)->getLeafValue()); + if (SR) + SubRegNo = getQualifiedName(SR->getDef()); + else + SubRegNo = Dst->getChild(1)->getLeafValue()->getAsString(); } // Inspect the pattern. @@ -437,7 +440,7 @@ void FastISelMap::PrintFunctionDefinitions(raw_ostream &OS) { } OS << " return FastEmitInst_"; - if (Memo.SubRegNo == (unsigned char)~0) { + if (Memo.SubRegNo.empty()) { Operands.PrintManglingSuffix(OS, *Memo.PhysRegs); OS << "(" << InstNS << Memo.Name << ", "; OS << InstNS << Memo.RC->getName() << "RegisterClass"; @@ -448,7 +451,7 @@ void FastISelMap::PrintFunctionDefinitions(raw_ostream &OS) { } else { OS << "extractsubreg(" << getName(RetVT); OS << ", Op0, Op0IsKill, "; - OS << (unsigned)Memo.SubRegNo; + OS << Memo.SubRegNo; OS << ");\n"; } @@ -532,7 +535,7 @@ void FastISelMap::PrintFunctionDefinitions(raw_ostream &OS) { OS << " return FastEmitInst_"; - if (Memo.SubRegNo == (unsigned char)~0) { + if (Memo.SubRegNo.empty()) { Operands.PrintManglingSuffix(OS, *Memo.PhysRegs); OS << "(" << InstNS << Memo.Name << ", "; OS << InstNS << Memo.RC->getName() << "RegisterClass"; @@ -542,7 +545,7 @@ void FastISelMap::PrintFunctionDefinitions(raw_ostream &OS) { OS << ");\n"; } else { OS << "extractsubreg(RetVT, Op0, Op0IsKill, "; - OS << (unsigned)Memo.SubRegNo; + OS << Memo.SubRegNo; OS << ");\n"; } diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index fcf4123cefb..a5fabeab5a0 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -35,14 +35,31 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS) { if (!Namespace.empty()) OS << "namespace " << Namespace << " {\n"; - OS << " enum {\n NoRegister,\n"; + OS << "enum {\n NoRegister,\n"; for (unsigned i = 0, e = Registers.size(); i != e; ++i) - OS << " " << Registers[i].getName() << ", \t// " << i+1 << "\n"; - OS << " NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n"; - OS << " };\n"; + OS << " " << Registers[i].getName() << ", \t// " << i+1 << "\n"; + OS << " NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n"; + OS << "};\n"; if (!Namespace.empty()) OS << "}\n"; + + const std::vector SubRegIndices = + Records.getAllDerivedDefinitions("SubRegIndex"); + if (!SubRegIndices.empty()) { + OS << "\n// Subregister indices\n"; + Namespace = SubRegIndices[0]->getValueAsString("Namespace"); + if (!Namespace.empty()) + OS << "namespace " << Namespace << " {\n"; + OS << "enum {\n NoSubRegister,\n"; + for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) + OS << " " << SubRegIndices[i]->getName() << " = " + << SubRegIndices[i]->getValueAsInt("NumberHack") << ",\n"; + OS << " NUM_TARGET_SUBREGS = " << SubRegIndices.size()+1 << "\n"; + OS << "};\n"; + if (!Namespace.empty()) + OS << "}\n"; + } OS << "} // End llvm namespace \n"; }