From 5ccbb1298b9c5ef2e474d7b3883c75e72710bd1b Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Fri, 19 Dec 2014 00:06:53 +0000 Subject: [PATCH] [Hexagon] Adding loop0/1 sp0/1/2loop0 instructions. llvm-svn: 224556 --- llvm/lib/Target/Hexagon/HexagonFixupHwLoops.cpp | 4 +- llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp | 12 +- llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp | 2 +- llvm/lib/Target/Hexagon/HexagonInstrInfo.td | 140 ++++++++++++++++++---- llvm/lib/Target/Hexagon/HexagonRegisterInfo.td | 13 +- llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp | 4 +- llvm/test/MC/Disassembler/Hexagon/cr.txt | 20 ++++ 7 files changed, 158 insertions(+), 37 deletions(-) diff --git a/llvm/lib/Target/Hexagon/HexagonFixupHwLoops.cpp b/llvm/lib/Target/Hexagon/HexagonFixupHwLoops.cpp index 209b83f..a91c2e1 100644 --- a/llvm/lib/Target/Hexagon/HexagonFixupHwLoops.cpp +++ b/llvm/lib/Target/Hexagon/HexagonFixupHwLoops.cpp @@ -81,8 +81,8 @@ FunctionPass *llvm::createHexagonFixupHwLoops() { /// \brief Returns true if the instruction is a hardware loop instruction. static bool isHardwareLoop(const MachineInstr *MI) { - return MI->getOpcode() == Hexagon::LOOP0_r || - MI->getOpcode() == Hexagon::LOOP0_i; + return MI->getOpcode() == Hexagon::J2_loop0r || + MI->getOpcode() == Hexagon::J2_loop0i; } diff --git a/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp b/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp index 39ed1ab..cbb80f3 100644 --- a/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp +++ b/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp @@ -285,8 +285,8 @@ INITIALIZE_PASS_END(HexagonHardwareLoops, "hwloops", /// \brief Returns true if the instruction is a hardware loop instruction. static bool isHardwareLoop(const MachineInstr *MI) { - return MI->getOpcode() == Hexagon::LOOP0_r || - MI->getOpcode() == Hexagon::LOOP0_i; + return MI->getOpcode() == Hexagon::J2_loop0r || + MI->getOpcode() == Hexagon::J2_loop0i; } FunctionPass *llvm::createHexagonHardwareLoops() { @@ -1086,7 +1086,7 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) { BuildMI(*Preheader, InsertPos, DL, TII->get(TargetOpcode::COPY), CountReg) .addReg(TripCount->getReg(), 0, TripCount->getSubReg()); // Add the Loop instruction to the beginning of the loop. - BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::LOOP0_r)) + BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::J2_loop0r)) .addMBB(LoopStart) .addReg(CountReg); } else { @@ -1095,14 +1095,14 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) { // if the immediate fits in the instructions. Otherwise, we need to // create a new virtual register. int64_t CountImm = TripCount->getImm(); - if (!TII->isValidOffset(Hexagon::LOOP0_i, CountImm)) { + if (!TII->isValidOffset(Hexagon::J2_loop0i, CountImm)) { unsigned CountReg = MRI->createVirtualRegister(&Hexagon::IntRegsRegClass); BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::A2_tfrsi), CountReg) .addImm(CountImm); - BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::LOOP0_r)) + BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::J2_loop0r)) .addMBB(LoopStart).addReg(CountReg); } else - BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::LOOP0_i)) + BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::J2_loop0i)) .addMBB(LoopStart).addImm(CountImm); } diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp index 997a526..5eb922a 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -1172,7 +1172,7 @@ isValidOffset(const int Opcode, const int Offset) const { case Hexagon::LDriw_pred: return true; - case Hexagon::LOOP0_i: + case Hexagon::J2_loop0i: return isUInt<10>(Offset); // INLINEASM is very special. diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td index 3ac379d..b12fff0 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td @@ -3249,6 +3249,124 @@ def BARRIER : SYSInst<(outs), (ins), //===----------------------------------------------------------------------===// // SYSTEM/SUPER - //===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// +// CRUSER - Type. +//===----------------------------------------------------------------------===// +// HW loop +let isExtendable = 1, isExtentSigned = 1, opExtentBits = 9, opExtentAlign = 2, + opExtendable = 0, hasSideEffects = 0 in +class LOOP_iBase + : CRInst<(outs), (ins brOp:$offset, u10Imm:$src2), + #mnemonic#"($offset, #$src2)", + [], "" , CR_tc_3x_SLOT3> { + bits<9> offset; + bits<10> src2; + + let IClass = 0b0110; + + let Inst{27-22} = 0b100100; + let Inst{21} = !if (!eq(mnemonic, "loop0"), 0b0, 0b1); + let Inst{20-16} = src2{9-5}; + let Inst{12-8} = offset{8-4}; + let Inst{7-5} = src2{4-2}; + let Inst{4-3} = offset{3-2}; + let Inst{1-0} = src2{1-0}; +} + +let isExtendable = 1, isExtentSigned = 1, opExtentBits = 9, opExtentAlign = 2, + opExtendable = 0, hasSideEffects = 0 in +class LOOP_rBase + : CRInst<(outs), (ins brOp:$offset, IntRegs:$src2), + #mnemonic#"($offset, $src2)", + [], "" ,CR_tc_3x_SLOT3> { + bits<9> offset; + bits<5> src2; + + let IClass = 0b0110; + + let Inst{27-22} = 0b000000; + let Inst{21} = !if (!eq(mnemonic, "loop0"), 0b0, 0b1); + let Inst{20-16} = src2; + let Inst{12-8} = offset{8-4}; + let Inst{4-3} = offset{3-2}; + } + +multiclass LOOP_ri { + def i : LOOP_iBase; + def r : LOOP_rBase; +} + + +let Defs = [SA0, LC0, USR], isCodeGenOnly = 0 in +defm J2_loop0 : LOOP_ri<"loop0">; + +// Interestingly only loop0's appear to set usr.lpcfg +let Defs = [SA1, LC1], isCodeGenOnly = 0 in +defm J2_loop1 : LOOP_ri<"loop1">; + +let isBranch = 1, isTerminator = 1, hasSideEffects = 0, + Defs = [PC, LC0], Uses = [SA0, LC0] in { +def ENDLOOP0 : Endloop<(outs), (ins brtarget:$offset), + ":endloop0", + []>; +} + +let isBranch = 1, isTerminator = 1, hasSideEffects = 0, + Defs = [PC, LC1], Uses = [SA1, LC1] in { +def ENDLOOP1 : Endloop<(outs), (ins brtarget:$offset), + ":endloop1", + []>; +} + +// Pipelined loop instructions, sp[123]loop0 +let Defs = [LC0, SA0, P3, USR], hasSideEffects = 0, + isExtentSigned = 1, isExtendable = 1, opExtentBits = 9, opExtentAlign = 2, + opExtendable = 0, isPredicateLate = 1 in +class SPLOOP_iBase op> + : CRInst <(outs), (ins brtarget:$r7_2, u10Imm:$U10), + "p3 = sp"#SP#"loop0($r7_2, #$U10)" > { + bits<9> r7_2; + bits<10> U10; + + let IClass = 0b0110; + + let Inst{22-21} = op; + let Inst{27-23} = 0b10011; + let Inst{20-16} = U10{9-5}; + let Inst{12-8} = r7_2{8-4}; + let Inst{7-5} = U10{4-2}; + let Inst{4-3} = r7_2{3-2}; + let Inst{1-0} = U10{1-0}; + } + +let Defs = [LC0, SA0, P3, USR], hasSideEffects = 0, + isExtentSigned = 1, isExtendable = 1, opExtentBits = 9, opExtentAlign = 2, + opExtendable = 0, isPredicateLate = 1 in +class SPLOOP_rBase op> + : CRInst <(outs), (ins brtarget:$r7_2, IntRegs:$Rs), + "p3 = sp"#SP#"loop0($r7_2, $Rs)" > { + bits<9> r7_2; + bits<5> Rs; + + let IClass = 0b0110; + + let Inst{22-21} = op; + let Inst{27-23} = 0b00001; + let Inst{20-16} = Rs; + let Inst{12-8} = r7_2{8-4}; + let Inst{4-3} = r7_2{3-2}; + } + +multiclass SPLOOP_ri op> { + def i : SPLOOP_iBase; + def r : SPLOOP_rBase; +} + +let isCodeGenOnly = 0 in { +defm J2_ploop1s : SPLOOP_ri<"1", 0b01>; +defm J2_ploop2s : SPLOOP_ri<"2", 0b10>; +defm J2_ploop3s : SPLOOP_ri<"3", 0b11>; +} // TFRI64 - assembly mapped. let isReMaterializable = 1 in @@ -3286,28 +3404,6 @@ def TFR_FI : ALU32_ri<(outs IntRegs:$dst), (ins FrameIndex:$src1), "$dst = add($src1)", [(set (i32 IntRegs:$dst), ADDRri:$src1)]>; -// -// CR - Type. -// -let hasSideEffects = 0, Defs = [SA0, LC0] in { -def LOOP0_i : CRInst<(outs), (ins brtarget:$offset, u10Imm:$src2), - "loop0($offset, #$src2)", - []>; -} - -let hasSideEffects = 0, Defs = [SA0, LC0] in { -def LOOP0_r : CRInst<(outs), (ins brtarget:$offset, IntRegs:$src2), - "loop0($offset, $src2)", - []>; -} - -let isBranch = 1, isTerminator = 1, hasSideEffects = 0, - Defs = [PC, LC0], Uses = [SA0, LC0] in { -def ENDLOOP0 : Endloop<(outs), (ins brtarget:$offset), - ":endloop0", - []>; -} - // Support for generating global address. // Taken from X86InstrInfo.td. def SDTHexagonCONST32 : SDTypeProfile<1, 1, [ diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td index 98b6200..930a148 100644 --- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td +++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td @@ -57,6 +57,7 @@ let Namespace = "Hexagon" in { def subreg_loreg : SubRegIndex<32>; def subreg_hireg : SubRegIndex<32, 32>; + def subreg_overflow : SubRegIndex<1, 0>; // Integer registers. foreach i = 0-28 in { @@ -109,6 +110,10 @@ let Namespace = "Hexagon" in { def M0 : Rc<6, "m0">, DwarfRegNum<[71]>; def M1 : Rc<7, "m1">, DwarfRegNum<[72]>; + def USR : Rc<8, "usr">, DwarfRegNum<[74]> { + let SubRegIndices = [subreg_overflow]; + let SubRegs = [USR_OVF]; + } def PC : Rc<9, "pc">, DwarfRegNum<[32]>; // is the Dwarf number correct? def GP : Rc<11, "gp">, DwarfRegNum<[33]>; // is the Dwarf number correct? } @@ -135,9 +140,9 @@ def PredRegs : RegisterClass<"Hexagon", [i1], 32, (add (sequence "P%u", 0, 3))> } def CRRegs : RegisterClass<"Hexagon", [i32], 32, - (add (sequence "LC%u", 0, 1), - (sequence "SA%u", 0, 1), - (sequence "M%u", 0, 1), PC, GP)> { + (add LC0, SA0, LC1, SA1, + M0, M1, + USR, USR_OVF, PC, GP)> { let Size = 32; } @@ -146,7 +151,7 @@ def VolatileV3 { R28, R31, P0, P1, P2, P3, M0, M1, - LC0, LC1, SA0, SA1, USR_OVF]; + LC0, LC1, SA0, SA1, USR, USR_OVF]; } def PositiveHalfWord : PatLeaf<(i32 IntRegs:$a), diff --git a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp index 9eb3bb6..179e496 100644 --- a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp +++ b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp @@ -382,8 +382,8 @@ static bool IsControlFlow(MachineInstr* MI) { } static bool IsLoopN(MachineInstr *MI) { - return (MI->getOpcode() == Hexagon::LOOP0_i || - MI->getOpcode() == Hexagon::LOOP0_r); + return (MI->getOpcode() == Hexagon::J2_loop0i || + MI->getOpcode() == Hexagon::J2_loop0r); } /// DoesModifyCalleeSavedReg - Returns true if the instruction modifies a diff --git a/llvm/test/MC/Disassembler/Hexagon/cr.txt b/llvm/test/MC/Disassembler/Hexagon/cr.txt index 9957e6f..b16a7e0 100644 --- a/llvm/test/MC/Disassembler/Hexagon/cr.txt +++ b/llvm/test/MC/Disassembler/Hexagon/cr.txt @@ -4,6 +4,26 @@ # CHECK: p1 = any8(p2) 0x01 0xc0 0xa2 0x6b # CHECK: p1 = all8(p2) +0x08 0xc4 0x15 0x60 +# CHECK: loop0 +0x08 0xc4 0x35 0x60 +# CHECK: loop1 +0x68 0xc4 0x00 0x69 +# CHECK: loop0 +0x68 0xc4 0x20 0x69 +# CHECK: loop1 +0x08 0xc4 0xb5 0x60 +# CHECK: p3 = sp1loop0 +0x08 0xc4 0xd5 0x60 +# CHECK: p3 = sp2loop0 +0x08 0xc4 0xf5 0x60 +# CHECK: p3 = sp3loop0 +0xa9 0xc4 0xa0 0x69 +# CHECK: p3 = sp1loop0 +0xa9 0xc4 0xc0 0x69 +# CHECK: p3 = sp2loop0 +0xa9 0xc4 0xe0 0x69 +# CHECK: p3 = sp3loop0 0x01 0xc3 0x02 0x6b # CHECK: p1 = and(p3, p2) 0x01 0xc3 0x62 0x6b -- 2.7.4