mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01: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:
parent
3e609e8430
commit
51cfbc91d9
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 -
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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)
|
||||
|
@ -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)
|
Loading…
Reference in New Issue
Block a user