// Store Memory Operations
//===----------------------------------------------------------------------===//
defm GLOBALTRUNCSTORE : GTRUNCSTORE<"!global trunc store">;
- defm GLOBALSTORE : STORE<"!global store" , global_store>;
defm LOCALTRUNCSTORE : LTRUNCSTORE<"!local trunc store">;
defm LOCALSTORE : STORE<"!local store" , local_store>;
defm PRIVATETRUNCSTORE : PTRUNCSTORE<"!private trunc store">;
// Store Memory Operations
//===----------------------------------------------------------------------===//
defm GLOBALTRUNCSTORE64 : GTRUNCSTORE64<"!global trunc store">;
- defm GLOBALSTORE64 : STORE64<"!global store" , global_store>;
defm LOCALTRUNCSTORE64 : LTRUNCSTORE64<"!local trunc store">;
defm LOCALSTORE64 : STORE64<"!local store" , local_store>;
defm PRIVATETRUNCSTORE64 : PTRUNCSTORE64<"!private trunc store">;
return BB;
}
+ case AMDIL::RAT_WRITE_CACHELESS_eg:
+ {
+ // Convert to DWORD address
+ unsigned NewAddr = MRI.createVirtualRegister(
+ AMDIL::R600_TReg32_XRegisterClass);
+ unsigned ShiftValue = MRI.createVirtualRegister(
+ AMDIL::R600_TReg32RegisterClass);
+
+ // XXX In theory, we should be able to pass ShiftValue directly to
+ // the LSHR_eg instruction as an inline literal, but I tried doing it
+ // this way and it didn't produce the correct results.
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::MOV), ShiftValue)
+ .addReg(AMDIL::ALU_LITERAL_X)
+ .addImm(2);
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::LSHR_eg), NewAddr)
+ .addOperand(MI->getOperand(1))
+ .addReg(ShiftValue);
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(MI->getOpcode()))
+ .addOperand(MI->getOperand(0))
+ .addReg(NewAddr);
+ break;
+ }
+
case AMDIL::STORE_OUTPUT:
{
int64_t OutputIndex = MI->getOperand(1).getImm();
}
def ADDRParam : ComplexPattern<i32, 2, "SelectADDRParam", [], []>;
+def ADDRDWord : ComplexPattern<i32, 1, "SelectADDRDWord", [], []>;
class R600_ALU {
case ISD::SETLE: return true;}}}]
>;
-class EG_CF_RAT <bits <8> cf_inst, bits <6> rat_inst, dag outs, dag ins,
- string asm> :
- InstR600ISA <outs, ins, asm, []>
+class EG_CF_RAT <bits <8> cf_inst, bits <6> rat_inst, bits<4> rat_id, dag outs,
+ dag ins, string asm, list<dag> pattern> :
+ InstR600ISA <outs, ins, asm, pattern>
{
bits<7> RW_GPR;
bits<7> INDEX_GPR;
- bits<4> RAT_ID;
bits<2> RIM;
bits<2> TYPE;
bits<1> BARRIER;
/* CF_ALLOC_EXPORT_WORD0_RAT */
- let Inst{3-0} = RAT_ID;
+ let Inst{3-0} = rat_id;
let Inst{9-4} = rat_inst;
let Inst{10} = 0; /* Reserved */
let Inst{12-11} = RIM;
let Predicates = [isEG] in {
-def RAT_WRITE_CACHELESS_eg :
- EG_CF_RAT <0x57, 0x2, (outs), (ins R600_TReg32_X:$rw_gpr,
- R600_TReg32_X:$index_gpr, i32imm:$rat_id), "">
+let usesCustomInserter = 1 in {
+
+def RAT_WRITE_CACHELESS_eg : EG_CF_RAT <0x57, 0x2, 0, (outs),
+ (ins R600_TReg32_X:$rw_gpr, R600_TReg32_X:$index_gpr),
+ "RAT_WRITE_CACHELESS_eg $rw_gpr, $index_gpr",
+ [(global_store (i32 R600_TReg32_X:$rw_gpr), R600_TReg32_X:$index_gpr)]>
{
let RIM = 0;
/* XXX: Have a separate instruction for non-indexed writes. */
let BARRIER = 1;
}
+} // End usesCustomInserter = 1
+
class VTX_READ_eg <int buffer_id, list<dag> pattern> : InstR600ISA <
(outs R600_TReg32_X:$dst),
(ins MEMxi:$ptr),
void lowerFLT(MachineInstr &MI);
- void calcAddress(const MachineOperand &ptrOp,
- const MachineOperand &indexOp,
- unsigned indexReg,
- MachineBasicBlock &MBB,
- MachineBasicBlock::iterator I) const;
-
public:
R600LowerInstructionsPass(TargetMachine &tm) :
MachineFunctionPass(ID), TM(tm),
}
*/ /* XXX: This is an optimization */
- case AMDIL::GLOBALSTORE_i32:
- case AMDIL::GLOBALSTORE_f32:
- {
- MachineOperand &ptrOperand = MI.getOperand(1);
- MachineOperand &indexOperand = MI.getOperand(2);
- unsigned rwReg =
- MRI->createVirtualRegister(&AMDIL::R600_TReg32_XRegClass);
- unsigned byteIndexReg =
- MRI->createVirtualRegister(&AMDIL::R600_TReg32RegClass);
- unsigned shiftReg =
- MRI->createVirtualRegister(&AMDIL::R600_TReg32RegClass);
- unsigned indexReg =
- MRI->createVirtualRegister(&AMDIL::R600_TReg32_XRegClass);
-
- /* Move the store value to the correct register class */
- BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDIL::COPY), rwReg)
- .addOperand(MI.getOperand(0));
-
- /* Calculate the address in the RAT */
- calcAddress(ptrOperand, indexOperand, byteIndexReg, MBB, I);
-
-
- BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDIL::MOV), shiftReg)
- .addReg(AMDIL::ALU_LITERAL_X)
- .addImm(2);
-
- /* XXX: Check GPU family */
- BuildMI(MBB, I, MBB.findDebugLoc(I),
- TII->get(AMDIL::LSHR_eg), indexReg)
- .addReg(byteIndexReg)
- .addReg(shiftReg);
-
- /* XXX: Check GPU Family */
- BuildMI(MBB, I, MBB.findDebugLoc(I),
- TII->get(AMDIL::RAT_WRITE_CACHELESS_eg))
- .addReg(rwReg)
- .addReg(indexReg)
- .addImm(0);
- break;
- }
-
case AMDIL::ILT:
BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDIL::SETGT_INT))
.addOperand(MI.getOperand(0))
}
return false;
}
-
-void R600LowerInstructionsPass::calcAddress(const MachineOperand &ptrOp,
- const MachineOperand &indexOp,
- unsigned indexReg,
- MachineBasicBlock &MBB,
- MachineBasicBlock::iterator I) const
-{
- /* Optimize the case where the indexOperand is 0 */
- if (indexOp.isImm() && indexOp.getImm() == 0) {
- assert(ptrOp.isReg());
- BuildMI(MBB, I, MBB.findDebugLoc(I),
- TII->get(AMDIL::COPY), indexReg)
- .addOperand(ptrOp);
- } else {
- BuildMI(MBB, I, MBB.findDebugLoc(I),
- TII->get(AMDIL::ADD_INT), indexReg)
- .addOperand(indexOp)
- .addOperand(ptrOp);
- }
-}