diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonInstrInfo.td | 156 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp | 6 |
3 files changed, 149 insertions, 17 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp index cccdd4e195b..f57171cdb39 100644 --- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/llvm/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/llvm/lib/Target/Hexagon/HexagonInstrInfo.td b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td index 565aed7062a..d73adc66b5c 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/llvm/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 <string mnemonic, RegisterClass RC, + Operand Imm, bits<4>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<string>(AlignSize), "DoubleWordAccess"), offset{6-3}, + !if (!eq(!cast<string>(AlignSize), "WordAccess"), offset{5-2}, + !if (!eq(!cast<string>(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 <string mnemonic, RegisterClass RC, bits<4>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<string mnemonic, RegisterClass RC, + MemAccessSize addrSize, bits<3> 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/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp index b1b36d4959e..7a4d2b06613 100644 --- a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp +++ b/llvm/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) |