1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 19:42:54 +02:00

[Hexagon] Adding allocframe, post-increment circular immediate stores, post-increment circular register stores, and bit reversed post-increment stores.

llvm-svn: 224957
This commit is contained in:
Colin LeMahieu 2014-12-29 21:33:45 +00:00
parent 3e609e8430
commit 51cfbc91d9
4 changed files with 183 additions and 18 deletions

View File

@ -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);
}
}
}

View File

@ -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\"", []>;
// Allocate stack frame.
let Defs = [R29, R30], Uses = [R31, R30], hasSideEffects = 0 in {
def ALLOCFRAME : STInst2<(outs),
(ins i32imm:$amt),
"allocframe(#$amt)",
[]>;
// 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;
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 -
//===----------------------------------------------------------------------===//

View File

@ -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)

View File

@ -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
# CHECK-NEXT: if (p3.new) memw(r17++#20) = r21
0x1f 0xc0 0x9d 0xa0
# CHECK: allocframe(#248)