summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2012-12-14 22:29:13 +0000
committerTom Stellard <thomas.stellard@amd.com>2012-12-14 22:29:13 +0000
commitc43ee57419aace5cc4ecb190ea24909b0ac200d5 (patch)
tree317b35e8a23c0839b3551b1cae81bf41cc317a85
parentfb4fda114cc15509697682697354871c710cf4e2 (diff)
XXX: Moved most of code into its own path using Christian's REG_SEQUENCEindirect-wip-4
idea
-rw-r--r--lib/Target/AMDGPU/AMDGPU.h2
-rw-r--r--lib/Target/AMDGPU/AMDGPUTargetMachine.cpp1
-rw-r--r--lib/Target/AMDGPU/R600AllocateMemoryRegs.cpp146
-rw-r--r--lib/Target/AMDGPU/R600ISelLowering.cpp12
-rw-r--r--lib/Target/AMDGPU/R600IndirectAddressing.cpp363
-rw-r--r--lib/Target/AMDGPU/R600Instructions.td4
6 files changed, 377 insertions, 151 deletions
diff --git a/lib/Target/AMDGPU/AMDGPU.h b/lib/Target/AMDGPU/AMDGPU.h
index fff8acd0cd8..70da83df281 100644
--- a/lib/Target/AMDGPU/AMDGPU.h
+++ b/lib/Target/AMDGPU/AMDGPU.h
@@ -21,7 +21,7 @@ class FunctionPass;
class AMDGPUTargetMachine;
// R600 Passes
-FunctionPass* createR600AllocateMemoryRegsPass(TargetMachine &tm);
+FunctionPass* createR600IndirectAddressingPass(TargetMachine &tm);
FunctionPass* createR600KernelParametersPass(const DataLayout *TD);
FunctionPass *createR600ExpandSpecialInstrsPass(TargetMachine &tm);
diff --git a/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index a851105a9a9..76a378b4009 100644
--- a/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -97,6 +97,7 @@ AMDGPUPassConfig::addPreISel() {
bool AMDGPUPassConfig::addInstSelector() {
addPass(createAMDGPUPeepholeOpt(*TM));
addPass(createAMDGPUISelDag(getAMDGPUTargetMachine()));
+ addPass(createR600IndirectAddressingPass(*TM));
return false;
}
diff --git a/lib/Target/AMDGPU/R600AllocateMemoryRegs.cpp b/lib/Target/AMDGPU/R600AllocateMemoryRegs.cpp
deleted file mode 100644
index a5b3c688e9a..00000000000
--- a/lib/Target/AMDGPU/R600AllocateMemoryRegs.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-//===-- R600AllocateMemoryRegs.cpp - Indirect Adressing Support -----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Instruction can use indirect addressing to index the register file as if it
-// were memory. In order to make this work correctly we need add all registers
-// that might be used for indirect addressing to the LiveIn lists of basic
-// blocks and also add them as implicit uses for instructions that do
-// indirect reads.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AMDGPU.h"
-#include "R600InstrInfo.h"
-#include "R600MachineFunctionInfo.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-
-using namespace llvm;
-
-namespace {
-
-class R600AllocateMemoryRegsPass : public MachineFunctionPass {
-
-private:
- static char ID;
- const R600InstrInfo *TII;
-
-public:
- R600AllocateMemoryRegsPass(TargetMachine &tm) :
- MachineFunctionPass(ID),
- TII(static_cast<const R600InstrInfo*>(tm.getInstrInfo()))
- { }
-
- virtual bool runOnMachineFunction(MachineFunction &MF);
-
- const char *getPassName() const { return "R600 Handle indirect addressing"; }
-
-};
-
-} // End anonymous namespace
-
-char R600AllocateMemoryRegsPass::ID = 0;
-
-FunctionPass *llvm::createR600AllocateMemoryRegsPass(TargetMachine &tm) {
- return new R600AllocateMemoryRegsPass(tm);
-}
-
-bool R600AllocateMemoryRegsPass::runOnMachineFunction(MachineFunction &MF) {
-
- std::vector<unsigned> IndirectRegs = TII->getIndirectReservedRegs(MF);
- MachineRegisterInfo &MRI = MF.getRegInfo();
- unsigned IndirectRegOffset = TII->getIndirectIndexBegin(MF);
-
- for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
- BB != BB_E; ++BB) {
- MachineBasicBlock &MBB = *BB;
- for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
- I != MBB.end(); I = Next) {
- Next = llvm::next(I);
- MachineInstr &MI = *I;
- switch (MI.getOpcode()) {
- default: continue;
- case AMDGPU::RegisterStore_i32:
- case AMDGPU::RegisterStore_f32:
- {
- int64_t Offset = (MI.getOperand(2).getImm() * 4) +
- MI.getOperand(3).getImm() +
- (IndirectRegOffset * 4);
- unsigned DstReg = AMDGPU::R600_TReg32RegClass.getRegister(Offset);
- R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
-
- MFI->IndirectChannels.set(MI.getOperand(3).getImm());
-
- if (MI.getOperand(1).getReg() == AMDGPU::ZERO) {
- MFI->ReservedRegs.push_back(DstReg);
- TII->buildDefaultInstruction(*BB, I, AMDGPU::MOV, DstReg,
- MI.getOperand(0).getReg());
- } else {
- MachineInstr *MOVA = TII->buildDefaultInstruction(*BB, I,
- AMDGPU::MOVA_INT_eg,
- AMDGPU::AR_X,
- MI.getOperand(1).getReg());
- TII->setImmOperand(MOVA, R600Operands::WRITE, 0);
- unsigned OffsetReg = AMDGPU::R600_AddrRegClass.getRegister(Offset);
- MachineInstrBuilder MIBuilder = TII->buildDefaultInstruction(*BB, I,
- AMDGPU::StackMOV, OffsetReg,
- MI.getOperand(0).getReg());
- MachineInstr *NewMI = MIBuilder.addReg(AMDGPU::AR_X, RegState::Implicit);
- TII->setImmOperand(NewMI, R600Operands::DST_REL, 1);
- }
- break;
- }
-
- case AMDGPU::RegisterLoad_i32:
- case AMDGPU::RegisterLoad_f32:
- {
- unsigned Channel = MI.getOperand(3).getImm();
- unsigned Offset = (MI.getOperand(2).getImm() * 4) + Channel +
- (IndirectRegOffset * 4);
- unsigned OffsetReg;
-
- if (MI.getOperand(1).getReg() == AMDGPU::ZERO) {
- OffsetReg = AMDGPU::R600_TReg32RegClass.getRegister(Offset);
- TII->buildDefaultInstruction(MBB, I, AMDGPU::MOV,
- MI.getOperand(0).getReg(),
- OffsetReg);
- } else {
- R600MachineFunctionInfo * MFI = MF.getInfo<R600MachineFunctionInfo>();
- MachineInstr *MOVA = TII->buildDefaultInstruction(*BB, I,
- AMDGPU::MOVA_INT_eg,
- AMDGPU::AR_X,
- MI.getOperand(1).getReg());
- TII->setImmOperand(MOVA, R600Operands::WRITE, 0);
- OffsetReg = AMDGPU::R600_AddrRegClass.getRegister(Offset);
- MachineInstrBuilder MIBuilder = TII->buildDefaultInstruction(*BB, I,
- AMDGPU::MOV, MI.getOperand(0).getReg(),
- OffsetReg);
- for (std::vector<unsigned>::iterator RRI = MFI->ReservedRegs.begin(),
- RRE = MFI->ReservedRegs.end();
- RRE != RRI; ++RRI) {
- unsigned Reg = *RRI;
- if (GET_REG_CHAN(Reg) == Channel) {
- MIBuilder.addReg(Reg, RegState::Implicit);
- }
- }
- MachineInstr *NewMI = MIBuilder.addReg(AMDGPU::AR_X, RegState::Implicit);
- TII->setImmOperand(NewMI, R600Operands::SRC0_REL, 1);
- }
- break;
- }
- }
- MI.eraseFromParent();
- }
- }
-
- return false;
-}
-
diff --git a/lib/Target/AMDGPU/R600ISelLowering.cpp b/lib/Target/AMDGPU/R600ISelLowering.cpp
index 2e8760443da..9428890e277 100644
--- a/lib/Target/AMDGPU/R600ISelLowering.cpp
+++ b/lib/Target/AMDGPU/R600ISelLowering.cpp
@@ -167,10 +167,10 @@ MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
unsigned IndirectRegOffset = TII->getIndirectIndexBegin(*MF);
unsigned Offset = (MI->getOperand(2).getImm() * 4) + Channel +
(IndirectRegOffset * 4);
+ R600MachineFunctionInfo *MFI = MF->getInfo<R600MachineFunctionInfo>();
+ unsigned IndirectReg = MRI.createVirtualRegister(&AMDGPU::IndirectRegRegClass);
if (MI->getOperand(1).getReg() != AMDGPU::ZERO) {
- R600MachineFunctionInfo *MFI = MF->getInfo<R600MachineFunctionInfo>();
- unsigned IndirectReg = MRI.createVirtualRegister(&AMDGPU::IndirectRegRegClass);
MachineInstrBuilder Sequence = BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::REG_SEQUENCE), IndirectReg);
MachineInstr *MOVA = TII->buildDefaultInstruction(*BB, I,
@@ -191,6 +191,14 @@ MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
MIBuilder.addReg(IndirectReg, RegState::Implicit | RegState::Kill);
MachineInstr *NewMI = MIBuilder.addReg(AMDGPU::AR_X, RegState::Implicit);
TII->setImmOperand(NewMI, R600Operands::SRC0_REL, 1);
+ } else {
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDGPU::REG_SEQUENCE),
+ IndirectReg)
+ .addReg(MFI->IndirectRegs[Channel + (MI->getOperand(2).getImm() * 4)])
+ .addImm(TII->getRegisterInfo().getIndirectSubReg(Offset));
+ TII->buildDefaultInstruction(*BB, I, AMDGPU::MOV,
+ MI->getOperand(0).getReg(),
+ IndirectReg);
}
break;
diff --git a/lib/Target/AMDGPU/R600IndirectAddressing.cpp b/lib/Target/AMDGPU/R600IndirectAddressing.cpp
new file mode 100644
index 00000000000..cc832c12212
--- /dev/null
+++ b/lib/Target/AMDGPU/R600IndirectAddressing.cpp
@@ -0,0 +1,363 @@
+//===-- R600IndirectAddressing.cpp - Indirect Adressing Support -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Instruction can use indirect addressing to index the register file as if it
+// were memory. In order to make this work correctly we need add all registers
+// that might be used for indirect addressing to the LiveIn lists of basic
+// blocks and also add them as implicit uses for instructions that do
+// indirect reads.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "r600-indirect"
+
+#include "AMDGPU.h"
+#include "R600InstrInfo.h"
+#include "R600MachineFunctionInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+
+namespace {
+
+class R600IndirectAddressingPass : public MachineFunctionPass {
+
+private:
+ static char ID;
+ const R600InstrInfo *TII;
+
+public:
+ R600IndirectAddressingPass(TargetMachine &tm) :
+ MachineFunctionPass(ID),
+ TII(static_cast<const R600InstrInfo*>(tm.getInstrInfo()))
+ { }
+
+ virtual bool runOnMachineFunction(MachineFunction &MF);
+
+ const char *getPassName() const { return "R600 Handle indirect addressing"; }
+
+};
+
+} // End anonymous namespace
+
+char R600IndirectAddressingPass::ID = 0;
+
+FunctionPass *llvm::createR600IndirectAddressingPass(TargetMachine &tm) {
+ return new R600IndirectAddressingPass(tm);
+}
+
+bool R600IndirectAddressingPass::runOnMachineFunction(MachineFunction &MF) {
+
+ MF.dump();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
+
+ // Key is the register and the value is the indirect address it uses.
+ std::map<unsigned, unsigned> RegisterAddressMap;
+
+ // First pass - Lower all of the RegisterStore instructions and track which
+ // registers are live.
+ for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
+ BB != BB_E; ++BB) {
+ // Key is the address and the value is the register
+ std::map<unsigned, unsigned> LiveAddressRegisterMap;
+ MachineBasicBlock &MBB = *BB;
+
+ for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
+ I != MBB.end(); I = Next) {
+ Next = llvm::next(I);
+ MachineInstr &MI = *I;
+
+ if (MI.getOpcode() != AMDGPU::RegisterStore_i32) {
+ continue;
+ }
+
+ unsigned RegIndex = MI.getOperand(2).getImm();
+ unsigned Channel = MI.getOperand(3).getImm();
+ unsigned Address = RegIndex + Channel;
+
+ if (MI.getOperand(1).getReg() == AMDGPU::ZERO) {
+ // We know what register this value will be written to.
+ unsigned DstReg = MRI.createVirtualRegister(
+ &AMDGPU::R600_TReg32RegClass);
+
+ BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY), DstReg)
+ .addOperand(MI.getOperand(0));
+
+ RegisterAddressMap[DstReg] = Address;
+ LiveAddressRegisterMap[Address] = DstReg;
+ } else {
+ // We don't know what register this value will be written to.
+ unsigned AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address);
+
+ MachineInstr *MOVA = TII->buildDefaultInstruction(*BB, I,
+ AMDGPU::MOVA_INT_eg,
+ AMDGPU::AR_X,
+ MI.getOperand(1).getReg());
+ TII->setImmOperand(MOVA, R600Operands::WRITE, 0);
+ MachineInstrBuilder MIBuilder = TII->buildDefaultInstruction(*BB, I,
+ AMDGPU::MOV,
+ AddrReg,
+ MI.getOperand(0).getReg())
+ .addReg(AMDGPU::AR_X, RegState::Implicit);
+ for (unsigned i = Channel; i < MFI->IndirectRegs.size(); i += 4) {
+ unsigned DstReg = MRI.createVirtualRegister(
+ &AMDGPU::R600_TReg32RegClass);
+ MIBuilder.addReg(DstReg, RegState::Define | RegState::Implicit);
+ RegisterAddressMap[DstReg] = i;
+ LiveAddressRegisterMap[Address] = i;
+ }
+ TII->setImmOperand(MIBuilder, R600Operands::DST_REL, 1);
+ }
+ MI.eraseFromParent();
+ }
+
+ // Update the live-ins of the succesor blocks
+ for (MachineBasicBlock::succ_iterator Succ = MBB.succ_begin(),
+ SuccEnd = MBB.succ_end();
+ SuccEnd != Succ; ++Succ) {
+ std::map<unsigned, unsigned>::const_iterator Key, KeyEnd;
+ for (Key = LiveAddressRegisterMap.begin(),
+ KeyEnd = LiveAddressRegisterMap.end(); KeyEnd != Key; ++Key) {
+ (*Succ)->addLiveIn(Key->second);
+ }
+ }
+ }
+
+ // Second pass - Lower the RegisterLoad instructions
+ for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
+ BB != BB_E; ++BB) {
+ // Key is the address and the value is the register
+ std::map<unsigned, unsigned> LiveAddressRegisterMap;
+ MachineBasicBlock &MBB = *BB;
+
+ dbgs() << "Entering " << MBB.getFullName() << "\n";
+
+ for (MachineBasicBlock::livein_iterator LI = MBB.livein_begin();
+ LI != MBB.livein_end(); ++LI) {
+ std::vector<unsigned> PhiRegisters;
+
+ // Make sure this live in is used for indirect addressing
+ if (RegisterAddressMap.find(*LI) == RegisterAddressMap.end()) {
+ continue;
+ }
+
+ unsigned Address = RegisterAddressMap[*LI];
+ PhiRegisters.push_back(LiveAddressRegisterMap[Address]);
+
+ // Check if there are other live in register which map to the same
+ // indirect address.
+ for (MachineBasicBlock::livein_iterator LJ = llvm::next(LI),
+ LE = MBB.livein_end();
+ LJ != LE; ++LJ) {
+ unsigned Reg = *LJ;
+ if (RegisterAddressMap.find(Reg) == RegisterAddressMap.end()) {
+ continue;
+ }
+
+ if (RegisterAddressMap[Reg] == Address) {
+ PhiRegisters.push_back(Reg);
+ }
+ }
+
+ if (PhiRegisters.size() == 1) {
+ // We don't need to insert a Phi instruction, so we can just add the
+ // registers to the live list for the block.
+ LiveAddressRegisterMap[Address] = *LI;
+ } else {
+ // We need to insert a PHI, because we have the same address being
+ // written in multiplie predecessor blocks.
+ unsigned PhiDstReg = MRI.createVirtualRegister(
+ &AMDGPU::R600_TReg32RegClass);
+ MachineInstrBuilder Phi = BuildMI(MBB, MBB.begin(),
+ MBB.findDebugLoc(MBB.begin()),
+ TII->get(AMDGPU::PHI), PhiDstReg);
+
+ for (std::vector<unsigned>::const_iterator RI = PhiRegisters.begin(),
+ RE = PhiRegisters.end();
+ RI != RE; ++RI) {
+ unsigned Reg = *RI;
+ MachineBasicBlock *RegBlock = MRI.getVRegDef(Reg)->getParent();
+ Phi.addReg(Reg);
+ Phi.addMBB(RegBlock);
+ MBB.removeLiveIn(Reg);
+ }
+ RegisterAddressMap[PhiDstReg] = Address;
+ LiveAddressRegisterMap[Address] = PhiDstReg;
+ }
+ // XXX !!! XXX !!!
+ LI = MBB.livein_begin();
+ }
+
+ for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
+ I != MBB.end(); I = Next) {
+ Next = llvm::next(I);
+ MachineInstr &MI = *I;
+
+ if (MI.getOpcode() != AMDGPU::RegisterLoad_i32) {
+ // Check for indirect register defs
+ for (unsigned OpIdx = 0, NumOperands = MI.getNumOperands();
+ OpIdx < NumOperands; ++OpIdx) {
+ MachineOperand &MO = MI.getOperand(OpIdx);
+ if (MO.isReg() && MO.isDef() &&
+ RegisterAddressMap.find(MO.getReg()) != RegisterAddressMap.end()) {
+ LiveAddressRegisterMap[RegisterAddressMap[MO.getReg()]] = MO.getReg();
+ dbgs() << "Adding " << MO.getReg() << "@" <<
+ RegisterAddressMap[MO.getReg()] << " to live registers.\n";
+ }
+ }
+ continue;
+ }
+
+ unsigned IndirectReg = MRI.createVirtualRegister(
+ &AMDGPU::IndirectRegRegClass);
+
+ unsigned RegIndex = MI.getOperand(2).getImm();
+ unsigned Channel = MI.getOperand(3).getImm();
+ unsigned Address = RegIndex + Channel;
+
+ if (MI.getOperand(1).getReg() == AMDGPU::ZERO) {
+ // We know which register this instruction will read.
+ BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::REG_SEQUENCE),
+ IndirectReg)
+ .addReg(LiveAddressRegisterMap[Address])
+ .addImm(TII->getRegisterInfo().getIndirectSubReg(Address));
+ TII->buildDefaultInstruction(*BB, I, AMDGPU::MOV,
+ MI.getOperand(0).getReg(),
+ IndirectReg);
+ } else {
+ // We don't know which register this instruction will read.
+ MachineInstrBuilder Sequence = BuildMI(MBB, I, MBB.findDebugLoc(I),
+ TII->get(AMDGPU::REG_SEQUENCE),
+ IndirectReg);
+ for (unsigned i = Channel; i < MFI->IndirectRegs.size(); i += 4) {
+ dbgs() << "Adding address " << i << "\n";
+ if (LiveAddressRegisterMap.find(i) == LiveAddressRegisterMap.end()) {
+ continue;
+ }
+ Sequence.addReg(LiveAddressRegisterMap[i]);
+ Sequence.addImm(TII->getRegisterInfo().getIndirectSubReg(i));
+ }
+
+ MachineInstr *MOVA = TII->buildDefaultInstruction(*BB, I,
+ AMDGPU::MOVA_INT_eg,
+ AMDGPU::AR_X,
+ MI.getOperand(1).getReg());
+ TII->setImmOperand(MOVA, R600Operands::WRITE, 0);
+ unsigned AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address);
+ MachineInstrBuilder MIBuilder = TII->buildDefaultInstruction(MBB, I,
+ AMDGPU::MOV, MI.getOperand(0).getReg(),
+ AddrReg);
+ MIBuilder.addReg(IndirectReg, RegState::Implicit | RegState::Kill);
+ MachineInstr *NewMI = MIBuilder.addReg(AMDGPU::AR_X, RegState::Implicit);
+ TII->setImmOperand(NewMI, R600Operands::SRC0_REL, 1);
+
+ }
+ MI.eraseFromParent();
+ }
+ }
+ MF.dump();
+ return false;
+}
+
+
+#if 0
+ std::vector<unsigned> IndirectRegs = TII->getIndirectReservedRegs(MF);
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ unsigned IndirectRegOffset = TII->getIndirectIndexBegin(MF);
+
+ for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
+ BB != BB_E; ++BB) {
+ MachineBasicBlock &MBB = *BB;
+ for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
+ I != MBB.end(); I = Next) {
+ Next = llvm::next(I);
+ MachineInstr &MI = *I;
+ switch (MI.getOpcode()) {
+ default: continue;
+ case AMDGPU::RegisterStore_i32:
+ case AMDGPU::RegisterStore_f32:
+ {
+ int64_t Offset = (MI.getOperand(2).getImm() * 4) +
+ MI.getOperand(3).getImm() +
+ (IndirectRegOffset * 4);
+ unsigned DstReg = AMDGPU::R600_TReg32RegClass.getRegister(Offset);
+ R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
+
+ MFI->IndirectChannels.set(MI.getOperand(3).getImm());
+
+ if (MI.getOperand(1).getReg() == AMDGPU::ZERO) {
+ MFI->ReservedRegs.push_back(DstReg);
+ TII->buildDefaultInstruction(*BB, I, AMDGPU::MOV, DstReg,
+ MI.getOperand(0).getReg());
+ } else {
+ MachineInstr *MOVA = TII->buildDefaultInstruction(*BB, I,
+ AMDGPU::MOVA_INT_eg,
+ AMDGPU::AR_X,
+ MI.getOperand(1).getReg());
+ TII->setImmOperand(MOVA, R600Operands::WRITE, 0);
+ unsigned OffsetReg = AMDGPU::R600_AddrRegClass.getRegister(Offset);
+ MachineInstrBuilder MIBuilder = TII->buildDefaultInstruction(*BB, I,
+ AMDGPU::StackMOV, OffsetReg,
+ MI.getOperand(0).getReg());
+ MachineInstr *NewMI = MIBuilder.addReg(AMDGPU::AR_X, RegState::Implicit);
+ TII->setImmOperand(NewMI, R600Operands::DST_REL, 1);
+ }
+ break;
+ }
+
+ case AMDGPU::RegisterLoad_i32:
+ case AMDGPU::RegisterLoad_f32:
+ {
+ unsigned Channel = MI.getOperand(3).getImm();
+ unsigned Offset = (MI.getOperand(2).getImm() * 4) + Channel +
+ (IndirectRegOffset * 4);
+ unsigned OffsetReg;
+
+ if (MI.getOperand(1).getReg() == AMDGPU::ZERO) {
+ OffsetReg = AMDGPU::R600_TReg32RegClass.getRegister(Offset);
+ TII->buildDefaultInstruction(MBB, I, AMDGPU::MOV,
+ MI.getOperand(0).getReg(),
+ OffsetReg);
+ } else {
+ R600MachineFunctionInfo * MFI = MF.getInfo<R600MachineFunctionInfo>();
+ MachineInstr *MOVA = TII->buildDefaultInstruction(*BB, I,
+ AMDGPU::MOVA_INT_eg,
+ AMDGPU::AR_X,
+ MI.getOperand(1).getReg());
+ TII->setImmOperand(MOVA, R600Operands::WRITE, 0);
+ OffsetReg = AMDGPU::R600_AddrRegClass.getRegister(Offset);
+ MachineInstrBuilder MIBuilder = TII->buildDefaultInstruction(*BB, I,
+ AMDGPU::MOV, MI.getOperand(0).getReg(),
+ OffsetReg);
+ for (std::vector<unsigned>::iterator RRI = MFI->ReservedRegs.begin(),
+ RRE = MFI->ReservedRegs.end();
+ RRE != RRI; ++RRI) {
+ unsigned Reg = *RRI;
+ if (GET_REG_CHAN(Reg) == Channel) {
+ MIBuilder.addReg(Reg, RegState::Implicit);
+ }
+ }
+ MachineInstr *NewMI = MIBuilder.addReg(AMDGPU::AR_X, RegState::Implicit);
+ TII->setImmOperand(NewMI, R600Operands::SRC0_REL, 1);
+ }
+ break;
+ }
+ }
+ MI.eraseFromParent();
+ }
+ }
+
+ return false;
+}
+#endif
diff --git a/lib/Target/AMDGPU/R600Instructions.td b/lib/Target/AMDGPU/R600Instructions.td
index 3affa96149f..3a1529fd162 100644
--- a/lib/Target/AMDGPU/R600Instructions.td
+++ b/lib/Target/AMDGPU/R600Instructions.td
@@ -1442,7 +1442,7 @@ def CONSTANT_LOAD_eg : VTX_READ_32_eg <1,
// Regist loads and stores - for indirect addressing
//===----------------------------------------------------------------------===//
-let usesCustomInserter = 1, isPseudo = 1, isCodeGenOnly = 1 in {
+let isPseudo = 1, isCodeGenOnly = 1 in {
class RegisterLoad <ValueType vt> : InstR600 <0x0,
(outs R600_Reg32:$dst), (ins FRAMEri:$addr, i32imm:$chan),
@@ -1460,7 +1460,7 @@ class RegisterStore <ValueType vt> : InstR600 <0x0,
>;
-} // End usesCustomInserter = 1, isPseudo = 1, isCodeGenOnly = 1
+} // isPseudo = 1, isCodeGenOnly = 1
def RegisterLoad_i32 : RegisterLoad<i32>;
def RegisterLoad_f32 : RegisterLoad<f32>;