From 7c58cad0ca671117bf65cc2f9377f0b79a5d45ed Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Mon, 29 Dec 2014 21:33:45 +0000 Subject: [PATCH] [Hexagon] Adding allocframe, post-increment circular immediate stores, post-increment circular register stores, and bit reversed post-increment stores. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224957 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Hexagon/HexagonFrameLowering.cpp | 4 +- lib/Target/Hexagon/HexagonInstrInfo.td | 156 +++++++++++++++++-- lib/Target/Hexagon/HexagonVLIWPacketizer.cpp | 6 +- test/MC/Disassembler/Hexagon/st.txt | 35 ++++- 4 files changed, 183 insertions(+), 18 deletions(-) diff --git a/lib/Target/Hexagon/HexagonFrameLowering.cpp b/lib/Target/Hexagon/HexagonFrameLowering.cpp index cccdd4e195b..f57171cdb39 100644 --- a/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -122,7 +122,7 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const { if (NumBytes >= ALLOCFRAME_MAX) { // Emit allocframe(#0). - BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(0); + BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::S2_allocframe)).addImm(0); // Subtract offset from frame pointer. BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real), @@ -132,7 +132,7 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const { addReg(QRI->getStackRegister()). addReg(HEXAGON_RESERVED_REG_1); } else { - BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(NumBytes); + BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::S2_allocframe)).addImm(NumBytes); } } } diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index 565aed7062a..d73adc66b5c 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -2962,21 +2962,153 @@ def : Pat<(store (i64 DoubleRegs:$src1), (add IntRegs:$src2, // memh(Rx++#s4:1)=Rt.H -// Store word. // Store predicate. -let Defs = [R10,R11,D5], hasSideEffects = 0 in -def STriw_pred : STInst2<(outs), - (ins MEMri:$addr, PredRegs:$src1), - "Error; should not emit", - []>; +let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13, + isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in +def STriw_pred : STInst<(outs), + (ins IntRegs:$addr, s11_2Ext:$off, PredRegs:$src1), + ".error \"should not emit\"", []>; + +// S2_allocframe: Allocate stack frame. +let Defs = [R29, R30], Uses = [R29, R31, R30], + hasSideEffects = 0, accessSize = DoubleWordAccess, isCodeGenOnly = 0 in +def S2_allocframe: ST0Inst < + (outs), (ins u11_3Imm:$u11_3), + "allocframe(#$u11_3)" > { + bits<14> u11_3; -// Allocate stack frame. -let Defs = [R29, R30], Uses = [R31, R30], hasSideEffects = 0 in { - def ALLOCFRAME : STInst2<(outs), - (ins i32imm:$amt), - "allocframe(#$amt)", - []>; + let IClass = 0b1010; + let Inst{27-16} = 0b000010011101; + let Inst{13-11} = 0b000; + let Inst{10-0} = u11_3{13-3}; + } + +// S2_storer[bhwdf]_pci: Store byte/half/word/double. +// S2_storer[bhwdf]_pci -> S2_storerbnew_pci +let Uses = [CS], isNVStorable = 1 in +class T_store_pci MajOp, + MemAccessSize AlignSize, string RegSrc = "Rt"> + : STInst <(outs IntRegs:$_dst_), + (ins IntRegs:$Rz, Imm:$offset, ModRegs:$Mu, RC:$Rt), + #mnemonic#"($Rz ++ #$offset:circ($Mu)) = $"#RegSrc#"", + [] , + "$Rz = $_dst_" > { + bits<5> Rz; + bits<7> offset; + bits<1> Mu; + bits<5> Rt; + let accessSize = AlignSize; + + let IClass = 0b1010; + let Inst{27-25} = 0b100; + let Inst{24-21} = MajOp; + let Inst{20-16} = Rz; + let Inst{13} = Mu; + let Inst{12-8} = Rt; + let Inst{7} = 0b0; + let Inst{6-3} = + !if (!eq(!cast(AlignSize), "DoubleWordAccess"), offset{6-3}, + !if (!eq(!cast(AlignSize), "WordAccess"), offset{5-2}, + !if (!eq(!cast(AlignSize), "HalfWordAccess"), offset{4-1}, + /* ByteAccess */ offset{3-0}))); + let Inst{1} = 0b0; + } + +let isCodeGenOnly = 0 in { +def S2_storerb_pci : T_store_pci<"memb", IntRegs, s4_0Imm, 0b1000, + ByteAccess>; +def S2_storerh_pci : T_store_pci<"memh", IntRegs, s4_1Imm, 0b1010, + HalfWordAccess>; +def S2_storerf_pci : T_store_pci<"memh", IntRegs, s4_1Imm, 0b1011, + HalfWordAccess, "Rt.h">; +def S2_storeri_pci : T_store_pci<"memw", IntRegs, s4_2Imm, 0b1100, + WordAccess>; +def S2_storerd_pci : T_store_pci<"memd", DoubleRegs, s4_3Imm, 0b1110, + DoubleWordAccess>; +} + +//===----------------------------------------------------------------------===// +// Circular stores with auto-increment register +//===----------------------------------------------------------------------===// +let Uses = [CS], isNVStorable = 1, isCodeGenOnly = 0 in +class T_store_pcr MajOp, + MemAccessSize AlignSize, string RegSrc = "Rt"> + : STInst <(outs IntRegs:$_dst_), + (ins IntRegs:$Rz, ModRegs:$Mu, RC:$Rt), + #mnemonic#"($Rz ++ I:circ($Mu)) = $"#RegSrc#"", + [], + "$Rz = $_dst_" > { + bits<5> Rz; + bits<1> Mu; + bits<5> Rt; + + let accessSize = AlignSize; + + let IClass = 0b1010; + let Inst{27-25} = 0b100; + let Inst{24-21} = MajOp; + let Inst{20-16} = Rz; + let Inst{13} = Mu; + let Inst{12-8} = Rt; + let Inst{7} = 0b0; + let Inst{1} = 0b1; + } + +let isCodeGenOnly = 0 in { +def S2_storerb_pcr : T_store_pcr<"memb", IntRegs, 0b1000, ByteAccess>; +def S2_storerh_pcr : T_store_pcr<"memh", IntRegs, 0b1010, HalfWordAccess>; +def S2_storeri_pcr : T_store_pcr<"memw", IntRegs, 0b1100, WordAccess>; +def S2_storerd_pcr : T_store_pcr<"memd", DoubleRegs, 0b1110, DoubleWordAccess>; +def S2_storerf_pcr : T_store_pcr<"memh", IntRegs, 0b1011, + HalfWordAccess, "Rt.h">; } + +//===----------------------------------------------------------------------===// +// Bit-reversed stores with auto-increment register +//===----------------------------------------------------------------------===// +let hasSideEffects = 0 in +class T_store_pbr majOp, + bit isHalf = 0> + : STInst + <(outs IntRegs:$_dst_), + (ins IntRegs:$Rz, ModRegs:$Mu, RC:$src), + #mnemonic#"($Rz ++ $Mu:brev) = $src"#!if (!eq(isHalf, 1), ".h", ""), + [], "$Rz = $_dst_" > { + + let accessSize = addrSize; + + bits<5> Rz; + bits<1> Mu; + bits<5> src; + + let IClass = 0b1010; + + let Inst{27-24} = 0b1111; + let Inst{23-21} = majOp; + let Inst{7} = 0b0; + let Inst{20-16} = Rz; + let Inst{13} = Mu; + let Inst{12-8} = src; + } + +let isNVStorable = 1, isCodeGenOnly = 0 in { + let BaseOpcode = "S2_storerb_pbr" in + def S2_storerb_pbr : T_store_pbr<"memb", IntRegs, ByteAccess, + 0b000>, NewValueRel; + let BaseOpcode = "S2_storerh_pbr" in + def S2_storerh_pbr : T_store_pbr<"memh", IntRegs, HalfWordAccess, + 0b010>, NewValueRel; + let BaseOpcode = "S2_storeri_pbr" in + def S2_storeri_pbr : T_store_pbr<"memw", IntRegs, WordAccess, + 0b100>, NewValueRel; +} +let isCodeGenOnly = 0 in { +def S2_storerf_pbr : T_store_pbr<"memh", IntRegs, HalfWordAccess, 0b011, 1>; +def S2_storerd_pbr : T_store_pbr<"memd", DoubleRegs, DoubleWordAccess, 0b110>; +} + //===----------------------------------------------------------------------===// // ST - //===----------------------------------------------------------------------===// diff --git a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp index b1b36d4959e..7a4d2b06613 100644 --- a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp +++ b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp @@ -563,7 +563,7 @@ bool HexagonPacketizerList::CanPromoteToNewValueStore( if (PacketSU->getInstr()->getDesc().mayStore() || // if we have mayStore = 1 set on ALLOCFRAME and DEALLOCFRAME, // then we don't need this - PacketSU->getInstr()->getOpcode() == Hexagon::ALLOCFRAME || + PacketSU->getInstr()->getOpcode() == Hexagon::S2_allocframe || PacketSU->getInstr()->getOpcode() == Hexagon::L2_deallocframe) return false; } @@ -1115,7 +1115,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) { // first operand is also a reg), first reg is not defined in // the same packet. if (PacketSU->getInstr()->getDesc().mayStore() || - PacketSU->getInstr()->getOpcode() == Hexagon::ALLOCFRAME || + PacketSU->getInstr()->getOpcode() == Hexagon::S2_allocframe || // Check #2. (!secondRegMatch && NextMI->getOperand(1).isReg() && PacketSU->getInstr()->modifiesRegister( @@ -1279,7 +1279,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) { // caller's SP. Hence, offset needs to be updated accordingly. else if (DepType == SDep::Data && QRI->Subtarget.hasV4TOps() - && J->getOpcode() == Hexagon::ALLOCFRAME + && J->getOpcode() == Hexagon::S2_allocframe && (I->getOpcode() == Hexagon::S2_storerd_io || I->getOpcode() == Hexagon::S2_storeri_io || I->getOpcode() == Hexagon::S2_storerb_io) diff --git a/test/MC/Disassembler/Hexagon/st.txt b/test/MC/Disassembler/Hexagon/st.txt index 1abd95ad3fc..09a677ad88f 100644 --- a/test/MC/Disassembler/Hexagon/st.txt +++ b/test/MC/Disassembler/Hexagon/st.txt @@ -2,10 +2,16 @@ 0x15 0xd4 0xd1 0xa1 # CHECK: memd(r17+#168) = r21:20 +0x02 0xf4 0xd1 0xa9 +# CHECK: memd(r17 ++ I:circ(m1)) = r21:20 +0x28 0xf4 0xd1 0xa9 +# CHECK: memd(r17 ++ #40:circ(m1)) = r21:20 0x28 0xd4 0xd1 0xab # CHECK: memd(r17++#40) = r21:20 0x00 0xf4 0xd1 0xad # CHECK: memd(r17++m1) = r21:20 +0x00 0xf4 0xd1 0xaf +# CHECK: memd(r17 ++ m1:brev) = r21:20 0xab 0xde 0xd1 0x40 # CHECK: if (p3) memd(r17+#168) = r31:30 0xab 0xde 0xd1 0x44 @@ -29,10 +35,16 @@ 0x15 0xd5 0x11 0xa1 # CHECK: memb(r17+#21) = r21 +0x02 0xf5 0x11 0xa9 +# CHECK: memb(r17 ++ I:circ(m1)) = r21 +0x28 0xf5 0x11 0xa9 +# CHECK: memb(r17 ++ #5:circ(m1)) = r21 0x28 0xd5 0x11 0xab # CHECK: memb(r17++#5) = r21 0x00 0xf5 0x11 0xad # CHECK: memb(r17++m1) = r21 +0x00 0xf5 0x11 0xaf +# CHECK: memb(r17 ++ m1:brev) = r21 0xab 0xdf 0x11 0x40 # CHECK: if (p3) memb(r17+#21) = r31 0xab 0xdf 0x11 0x44 @@ -58,6 +70,14 @@ # CHECK: memh(r17+#42) = r31 0x15 0xdf 0x71 0xa1 # CHECK: memh(r17+#42) = r31.h +0x02 0xf5 0x51 0xa9 +# CHECK: memh(r17 ++ I:circ(m1)) = r21 +0x28 0xf5 0x51 0xa9 +# CHECK: memh(r17 ++ #10:circ(m1)) = r21 +0x02 0xf5 0x71 0xa9 +# CHECK: memh(r17 ++ I:circ(m1)) = r21.h +0x28 0xf5 0x71 0xa9 +# CHECK: memh(r17 ++ #10:circ(m1)) = r21.h 0x28 0xd5 0x51 0xab # CHECK: memh(r17++#10) = r21 0x28 0xd5 0x71 0xab @@ -66,6 +86,10 @@ # CHECK: memh(r17++m1) = r21 0x00 0xf5 0x71 0xad # CHECK: memh(r17++m1) = r21.h +0x00 0xf5 0x51 0xaf +# CHECK: memh(r17 ++ m1:brev) = r21 +0x00 0xf5 0x71 0xaf +# CHECK: memh(r17 ++ m1:brev) = r21.h 0xfb 0xd5 0x51 0x40 # CHECK: if (p3) memh(r17+#62) = r21 0xfb 0xd5 0x71 0x40 @@ -109,10 +133,16 @@ 0x15 0xdf 0x91 0xa1 # CHECK: memw(r17+#84) = r31 +0x02 0xf5 0x91 0xa9 +# CHECK: memw(r17 ++ I:circ(m1)) = r21 +0x28 0xf5 0x91 0xa9 +# CHECK: memw(r17 ++ #20:circ(m1)) = r21 0x28 0xd5 0x91 0xab # CHECK: memw(r17++#20) = r21 0x00 0xf5 0x91 0xad # CHECK: memw(r17++m1) = r21 +0x00 0xf5 0x91 0xaf +# CHECK: memw(r17 ++ m1:brev) = r21 0xab 0xdf 0x91 0x40 # CHECK: if (p3) memw(r17+#84) = r31 0xab 0xdf 0x91 0x44 @@ -132,4 +162,7 @@ # CHECK-NEXT: if (!p3.new) memw(r17++#20) = r21 0x03 0x40 0x45 0x85 0xab 0xf5 0x91 0xab # CHECK: p3 = r5 -# CHECK-NEXT: if (p3.new) memw(r17++#20) = r21 \ No newline at end of file +# CHECK-NEXT: if (p3.new) memw(r17++#20) = r21 + +0x1f 0xc0 0x9d 0xa0 +# CHECK: allocframe(#248) \ No newline at end of file -- 2.34.1