1
0
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:
Colin LeMahieu 2014-12-19 00:06:53 +00:00
parent 23258069b7
commit ab28d2b2e6
7 changed files with 158 additions and 37 deletions

View File

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

View File

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

View File

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

View File

@ -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, [

View File

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

View File

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

View File

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