diff options
author | tstellar <tstellar@91177308-0d34-0410-b5e6-96231b3b80d8> | 2012-10-19 21:10:11 +0000 |
---|---|---|
committer | tstellar <tstellar@91177308-0d34-0410-b5e6-96231b3b80d8> | 2012-10-19 21:10:11 +0000 |
commit | 7ccfc25abbbbaa4082b06f8cf9b3899ffd4153ac (patch) | |
tree | 69c8f368874dc32a1cff37eff884da5c194c4e3c | |
parent | 55e7bfae98de01d2b518849cfdcd8f8c7b2c3063 (diff) |
R600: Lower PRED_X to a native instruction prior to codegen
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/R600/@166331 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/AMDGPU/AMDGPUInstrInfo.h | 8 | ||||
-rw-r--r-- | lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp | 10 | ||||
-rw-r--r-- | lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h | 2 | ||||
-rw-r--r-- | lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp | 2 | ||||
-rw-r--r-- | lib/Target/AMDGPU/R600Defines.h | 2 | ||||
-rw-r--r-- | lib/Target/AMDGPU/R600ExpandSpecialInstrs.cpp | 34 | ||||
-rw-r--r-- | lib/Target/AMDGPU/R600ISelLowering.cpp | 4 | ||||
-rw-r--r-- | lib/Target/AMDGPU/R600InstrInfo.cpp | 47 | ||||
-rw-r--r-- | lib/Target/AMDGPU/R600Instructions.td | 52 |
9 files changed, 111 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 3fe16a713c3..b3cee401764 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 b14db823597..b05089c3c2c 100644 --- a/lib/Target/AMDGPU/R600ISelLowering.cpp +++ b/lib/Target/AMDGPU/R600ISelLowering.cpp @@ -230,7 +230,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); @@ -244,7 +244,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 6b90bfad4e7..d1649345cea 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 4e0440982f4..573dcabeeb0 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,11 @@ def : Pat < (MOV_IMM_F32 fpimm:$val) >; +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", []>; + def KILLGT : InstR600 <0x2D, (outs R600_Reg32:$dst), (ins R600_Reg32:$src0, R600_Reg32:$src1, i32imm:$flags, R600_Pred:$p, @@ -632,6 +628,11 @@ def SETGE_UINT : R600_2OP < (selectcc (i32 R600_Reg32:$src0), R600_Reg32:$src1, -1, 0, SETUGE))] >; +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", []>; + def CNDE_INT : R600_3OP < 0x1C, "CNDE_INT", [(set (i32 R600_Reg32:$dst), @@ -1351,6 +1352,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 < |