summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2012-10-17 18:26:53 +0000
committerTom Stellard <thomas.stellard@amd.com>2012-10-17 21:18:28 +0000
commitdcf09c7661b85c69f1f95080c72fdb2e3028d476 (patch)
tree1e722db6cbb6cdb745143c6e72fec30b3d0fe4aa
parent9ff0eeb0791b6edf763e9a7b31c3d423ec90cc8d (diff)
R600: Lower PRED_X to a native instruction prior to codegen
-rw-r--r--lib/Target/AMDGPU/AMDGPUInstrInfo.h8
-rw-r--r--lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp10
-rw-r--r--lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h2
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp2
-rw-r--r--lib/Target/AMDGPU/R600Defines.h2
-rw-r--r--lib/Target/AMDGPU/R600ExpandSpecialInstrs.cpp34
-rw-r--r--lib/Target/AMDGPU/R600ISelLowering.cpp4
-rw-r--r--lib/Target/AMDGPU/R600InstrInfo.cpp47
-rw-r--r--lib/Target/AMDGPU/R600Instructions.td60
9 files changed, 119 insertions, 50 deletions
diff --git a/lib/Target/AMDGPU/AMDGPUInstrInfo.h b/lib/Target/AMDGPU/AMDGPUInstrInfo.h
index a3080767883..e81f73d8f58 100644
--- a/lib/Target/AMDGPU/AMDGPUInstrInfo.h
+++ b/lib/Target/AMDGPU/AMDGPUInstrInfo.h
@@ -25,10 +25,10 @@
#define GET_INSTRINFO_ENUM
#include "AMDGPUGenInstrInfo.inc"
-#define OPCODE_IS_ZERO_INT 0x00000042
-#define OPCODE_IS_NOT_ZERO_INT 0x00000045
-#define OPCODE_IS_ZERO 0x00000020
-#define OPCODE_IS_NOT_ZERO 0x00000023
+#define OPCODE_IS_ZERO_INT AMDGPU::PRED_SETE_INT
+#define OPCODE_IS_NOT_ZERO_INT AMDGPU::PRED_SETNE_INT
+#define OPCODE_IS_ZERO AMDGPU::PRED_SETE
+#define OPCODE_IS_NOT_ZERO AMDGPU::PRED_SETNE
namespace llvm {
diff --git a/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp b/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp
index 7e761d52408..fe2032ea0ef 100644
--- a/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp
+++ b/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp
@@ -97,6 +97,16 @@ void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo,
}
}
+void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ printIfSet(MI, OpNo, O, "ExecMask,");
+}
+
+void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ printIfSet(MI, OpNo, O, "Pred,");
+}
+
void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
diff --git a/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h b/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h
index b4feb6fb3f9..de94eda7dd9 100644
--- a/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h
+++ b/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h
@@ -40,6 +40,8 @@ private:
void printNeg(const MCInst *MI, unsigned OpNo, raw_ostream &O);
void printOMOD(const MCInst *MI, unsigned OpNo, raw_ostream &O);
void printRel(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printUpdateExecMask(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printUpdatePred(const MCInst *MI, unsigned OpNo, raw_ostream &O);
void printWrite(const MCInst *MI, unsigned OpNo, raw_ostream &O);
};
diff --git a/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp b/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp
index a9d04408542..35d76fed0bf 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp
+++ b/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp
@@ -280,7 +280,7 @@ void R600MCCodeEmitter::EmitALUInstr(const MCInst &MI,
}
// XXX: Emit push modifier
- if(isFlagSet(MI, 1, MO_FLAG_PUSH)) {
+ if(isFlagSet(MI, 0, MO_FLAG_PUSH)) {
InstWord01 |= 1ULL << 34;
}
diff --git a/lib/Target/AMDGPU/R600Defines.h b/lib/Target/AMDGPU/R600Defines.h
index a17d1341304..4a0e238b849 100644
--- a/lib/Target/AMDGPU/R600Defines.h
+++ b/lib/Target/AMDGPU/R600Defines.h
@@ -51,6 +51,8 @@ namespace R600_InstFlag {
namespace R600Operands {
enum Ops {
DST,
+ UPDATE_EXEC_MASK,
+ UPDATE_PREDICATE,
WRITE,
OMOD,
DST_REL,
diff --git a/lib/Target/AMDGPU/R600ExpandSpecialInstrs.cpp b/lib/Target/AMDGPU/R600ExpandSpecialInstrs.cpp
index d5ae33d4168..e1f08f4b489 100644
--- a/lib/Target/AMDGPU/R600ExpandSpecialInstrs.cpp
+++ b/lib/Target/AMDGPU/R600ExpandSpecialInstrs.cpp
@@ -184,10 +184,36 @@ bool R600ExpandSpecialInstrsPass::runOnMachineFunction(MachineFunction &MF) {
MachineInstr &MI = *I;
I = llvm::next(I);
- if (ExpandInputPerspective(MI))
- continue;
- if (ExpandInputConstant(MI))
- continue;
+ switch (MI.getOpcode()) {
+ default: break;
+ // Expand PRED_X to one of the PRED_SET instructions.
+ case AMDGPU::PRED_X: {
+ uint64_t Flags = MI.getOperand(3).getImm();
+ // The native opcode used by PRED_X is stored as an immediate in the
+ // third operand.
+ MachineInstr *PredSet = TII->buildDefaultInstruction(MBB, I,
+ MI.getOperand(2).getImm(), // opcode
+ MI.getOperand(0).getReg(), // dst
+ MI.getOperand(1).getReg(), // src0
+ AMDGPU::ZERO); // src1
+ TII->addFlag(PredSet, 0, MO_FLAG_MASK);
+ if (Flags & MO_FLAG_PUSH) {
+ PredSet->getOperand(TII->getOperandIdx(
+ *PredSet, R600Operands::UPDATE_EXEC_MASK)).setImm(1);
+ } else {
+ PredSet->getOperand(
+ TII->getOperandIdx(
+ *PredSet, R600Operands::UPDATE_PREDICATE)).setImm(1);
+ }
+ MI.eraseFromParent();
+ continue;
+ }
+ }
+
+ if (ExpandInputPerspective(MI))
+ continue;
+ if (ExpandInputConstant(MI))
+ continue;
bool IsReduction = TII->isReductionOp(MI.getOpcode());
bool IsVector = TII->isVector(MI);
diff --git a/lib/Target/AMDGPU/R600ISelLowering.cpp b/lib/Target/AMDGPU/R600ISelLowering.cpp
index 4467c6cdbc0..cf77aecc329 100644
--- a/lib/Target/AMDGPU/R600ISelLowering.cpp
+++ b/lib/Target/AMDGPU/R600ISelLowering.cpp
@@ -229,7 +229,7 @@ MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
.addOperand(MI->getOperand(1))
.addImm(OPCODE_IS_NOT_ZERO)
.addImm(0); // Flags
- TII->addFlag(NewMI, 1, MO_FLAG_PUSH);
+ TII->addFlag(NewMI, 0, MO_FLAG_PUSH);
BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP))
.addOperand(MI->getOperand(0))
.addReg(AMDGPU::PREDICATE_BIT, RegState::Kill);
@@ -243,7 +243,7 @@ MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
.addOperand(MI->getOperand(1))
.addImm(OPCODE_IS_NOT_ZERO_INT)
.addImm(0); // Flags
- TII->addFlag(NewMI, 1, MO_FLAG_PUSH);
+ TII->addFlag(NewMI, 0, MO_FLAG_PUSH);
BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::JUMP))
.addOperand(MI->getOperand(0))
.addReg(AMDGPU::PREDICATE_BIT, RegState::Kill);
diff --git a/lib/Target/AMDGPU/R600InstrInfo.cpp b/lib/Target/AMDGPU/R600InstrInfo.cpp
index 716c6f0c4b1..db8b1dab0a0 100644
--- a/lib/Target/AMDGPU/R600InstrInfo.cpp
+++ b/lib/Target/AMDGPU/R600InstrInfo.cpp
@@ -271,7 +271,7 @@ R600InstrInfo::InsertBranch(MachineBasicBlock &MBB,
} else {
MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end());
assert(PredSet && "No previous predicate !");
- addFlag(PredSet, 1, MO_FLAG_PUSH);
+ addFlag(PredSet, 0, MO_FLAG_PUSH);
PredSet->getOperand(2).setImm(Cond[1].getImm());
BuildMI(&MBB, DL, get(AMDGPU::JUMP))
@@ -282,7 +282,7 @@ R600InstrInfo::InsertBranch(MachineBasicBlock &MBB,
} else {
MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end());
assert(PredSet && "No previous predicate !");
- addFlag(PredSet, 1, MO_FLAG_PUSH);
+ addFlag(PredSet, 0, MO_FLAG_PUSH);
PredSet->getOperand(2).setImm(Cond[1].getImm());
BuildMI(&MBB, DL, get(AMDGPU::JUMP))
.addMBB(TBB)
@@ -311,7 +311,7 @@ R600InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const
case AMDGPU::JUMP:
if (isPredicated(I)) {
MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I);
- clearFlag(predSet, 1, MO_FLAG_PUSH);
+ clearFlag(predSet, 0, MO_FLAG_PUSH);
}
I->eraseFromParent();
break;
@@ -329,7 +329,7 @@ R600InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const
case AMDGPU::JUMP:
if (isPredicated(I)) {
MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I);
- clearFlag(predSet, 1, MO_FLAG_PUSH);
+ clearFlag(predSet, 0, MO_FLAG_PUSH);
}
I->eraseFromParent();
break;
@@ -482,15 +482,20 @@ MachineInstrBuilder R600InstrInfo::buildDefaultInstruction(MachineBasicBlock &MB
unsigned Src1Reg) const
{
MachineInstrBuilder MIB = BuildMI(MBB, I, MBB.findDebugLoc(I), get(Opcode),
- DstReg) // $dst
- .addImm(1) // $write
- .addImm(0) // $omod
- .addImm(0) // $dst_rel
- .addImm(0) // $dst_clamp
- .addReg(Src0Reg) // $src0
- .addImm(0) // $src0_neg
- .addImm(0) // $src0_rel
- .addImm(0); // $src0_abs
+ DstReg); // $dst
+
+ if (Src1Reg) {
+ MIB.addImm(0) // $update_exec_mask
+ .addImm(0); // $update_predicate
+ }
+ MIB.addImm(1) // $write
+ .addImm(0) // $omod
+ .addImm(0) // $dst_rel
+ .addImm(0) // $dst_clamp
+ .addReg(Src0Reg) // $src0
+ .addImm(0) // $src0_neg
+ .addImm(0) // $src0_rel
+ .addImm(0); // $src0_abs
if (Src1Reg) {
MIB.addReg(Src1Reg) // $src1
@@ -523,14 +528,14 @@ int R600InstrInfo::getOperandIdx(const MachineInstr &MI,
R600Operands::Ops Op) const
{
const static int OpTable[3][R600Operands::COUNT] = {
-// W C S S S S S S S S
-// R O D L S R R R S R R R S R R L P
-// D I M R A R C C C C C C C R C C A R I
-// S T O E M C 0 0 0 C 1 1 1 C 2 2 S E M
-// T E D L P 0 N R A 1 N R A 2 N R T D M
- {0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,-1, 9,10,11},
- {0, 1, 2, 3, 4 ,5 ,6 ,7, 8, 9,10,11,12,-1,-1,-1,13,14,15},
- {0, 1, 2, 3, 4, 5, 6, 7,-1, 8, 9,10,-1,11,12,13,14,15,16}
+// W C S S S S S S S S
+// R O D L S R R R S R R R S R R L P
+// D U I M R A R C C C C C C C R C C A R I
+// S E U T O E M C 0 0 0 C 1 1 1 C 2 2 S E M
+// T M P E D L P 0 N R A 1 N R A 2 N R T D M
+ {0,-1,-1, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,-1, 9,10,11},
+ {0, 1, 2, 3, 4 ,5 ,6 ,7, 8, 9,10,11,12,-1,-1,-1,13,14,15,16,17},
+ {0,-1,-1, 1, 2, 3, 4, 5, 6, 7,-1, 8, 9,10,-1,11,12,13,14,15,16}
};
unsigned TargetFlags = get(MI.getOpcode()).TSFlags;
unsigned OpTableIdx;
diff --git a/lib/Target/AMDGPU/R600Instructions.td b/lib/Target/AMDGPU/R600Instructions.td
index 29ed4bbb56e..2a468abdb75 100644
--- a/lib/Target/AMDGPU/R600Instructions.td
+++ b/lib/Target/AMDGPU/R600Instructions.td
@@ -78,6 +78,8 @@ def REL : InstFlag <"printRel">;
def CLAMP : InstFlag <"printClamp">;
def NEG : InstFlag <"printNeg">;
def ABS : InstFlag <"printAbs">;
+def UEM : InstFlag <"printUpdateExecMask">;
+def UP : InstFlag <"printUpdatePred">;
// XXX: The r600g finalizer in Mesa expects last to be one in most cases.
// Once we start using the packetizer in this backend we should have this
@@ -141,8 +143,8 @@ class R600ALU_Word1_OP2 <bits<11> alu_inst> : R600ALU_Word1{
bits<1> src0_abs;
bits<1> src1_abs;
- bits<1> update_exec_mask = 0;
- bits<1> update_pred = 0;
+ bits<1> update_exec_mask;
+ bits<1> update_pred;
bits<1> write;
bits<2> omod;
@@ -227,6 +229,8 @@ class R600_1OP <bits<11> inst, string opName, list<dag> pattern,
let src1_rel = 0;
let src1_neg = 0;
let src1_abs = 0;
+ let update_exec_mask = 0;
+ let update_pred = 0;
let HasNativeOperands = 1;
let Op1 = 1;
let DisableEncoding = "$literal";
@@ -248,12 +252,13 @@ class R600_2OP <bits<11> inst, string opName, list<dag> pattern,
InstrItinClass itin = AnyALU> :
InstR600 <inst,
(outs R600_Reg32:$dst),
- (ins WRITE:$write, OMOD:$omod, REL:$dst_rel, CLAMP:$clamp,
+ (ins UEM:$update_exec_mask, UP:$update_pred, WRITE:$write,
+ OMOD:$omod, REL:$dst_rel, CLAMP:$clamp,
R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, ABS:$src0_abs,
R600_Reg32:$src1, NEG:$src1_neg, REL:$src1_rel, ABS:$src1_abs,
LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal),
!strconcat(opName,
- "$clamp $dst$write$dst_rel$omod, "
+ "$clamp $update_exec_mask$update_pred$dst$write$dst_rel$omod, "
"$src0_neg$src0_abs$src0$src0_abs$src0_rel, "
"$src1_neg$src1_abs$src1$src1_abs$src1_rel, "
"$literal $pred_sel$last"),
@@ -308,20 +313,6 @@ class R600_3OP <bits<5> inst, string opName, list<dag> pattern,
let Inst{63-32} = Word1;
}
-def PRED_X : InstR600 <0, (outs R600_Predicate_Bit:$dst),
- (ins R600_Reg32:$src0, i32imm:$src1, i32imm:$flags),
- "PRED $dst, $src0, $src1",
- [], NullALU>
-{
- bits<7> dst;
- bits<9> src0;
- bits<11> src1;
- let Inst{8-0} = src0;
- let Inst{49-39} = src1;
- let Inst{59-53} = dst;
- let FlagOperandIdx = 3;
-}
-
let isTerminator = 1, isBranch = 1, isPseudo = 1 in {
def JUMP : InstR600 <0x10,
(outs),
@@ -568,6 +559,15 @@ def : Pat <
(MOV_IMM_F32 fpimm:$val)
>;
+let update_pred = 1 in {
+
+def PRED_SETE : R600_2OP <0x20, "PRED_SETE", []>;
+def PRED_SETGT : R600_2OP <0x21, "PRED_SETGT", []>;
+def PRED_SETGE : R600_2OP <0x22, "PRED_SETGE", []>;
+def PRED_SETNE : R600_2OP <0x23, "PRED_SETNE", []>;
+
+} // end update_pred = 1
+
def KILLGT : InstR600 <0x2D,
(outs R600_Reg32:$dst),
(ins R600_Reg32:$src0, R600_Reg32:$src1, i32imm:$flags, R600_Pred:$p,
@@ -632,6 +632,15 @@ def SETGE_UINT : R600_2OP <
(selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETUGE))]
>;
+let update_pred = 1 in {
+
+def PRED_SETE_INT : R600_2OP <0x42, "PRED_SETE_INT", []>;
+def PRED_SETGT_INT : R600_2OP <0x43, "PRED_SETGE_INT", []>;
+def PRED_SETGE_INT : R600_2OP <0x44, "PRED_SETGE_INT", []>;
+def PRED_SETNE_INT : R600_2OP <0x45, "PRED_SETNE_INT", []>;
+
+} // end update_pred = 1
+
def CNDE_INT : R600_3OP <
0x1C, "CNDE_INT",
[(set (i32 R600_Reg32:$dst),
@@ -1349,6 +1358,21 @@ def : Pat <
} // End isCayman
+//===----------------------------------------------------------------------===//
+// Pseudo instructions
+//===----------------------------------------------------------------------===//
+
+let isPseudo = 1 in {
+
+def PRED_X : InstR600 <
+ 0, (outs R600_Predicate_Bit:$dst),
+ (ins R600_Reg32:$src0, i32imm:$src1, i32imm:$flags),
+ "", [], NullALU> {
+ let FlagOperandIdx = 3;
+}
+
+} // End isPseudo = 1
+
let isCodeGenOnly = 1 in {
def MULLIT : AMDGPUShaderInst <