mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
[Hexagon] Adding loop0/1 sp0/1/2loop0 instructions.
llvm-svn: 224556
This commit is contained in:
parent
23258069b7
commit
ab28d2b2e6
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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<string mnemonic, Operand brOp, bit mustExtend = 0>
|
||||
: 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<string mnemonic, Operand brOp, bit mustExtend = 0>
|
||||
: 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<string mnemonic> {
|
||||
def i : LOOP_iBase<mnemonic, brtarget>;
|
||||
def r : LOOP_rBase<mnemonic, brtarget>;
|
||||
}
|
||||
|
||||
|
||||
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<string SP, bits<2> 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<string SP, bits<2> 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<string mnemonic, bits<2> op> {
|
||||
def i : SPLOOP_iBase<mnemonic, op>;
|
||||
def r : SPLOOP_rBase<mnemonic, op>;
|
||||
}
|
||||
|
||||
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, [
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user