diff options
author | Tom Stellard <thomas.stellard@amd.com> | 2012-12-14 22:29:13 +0000 |
---|---|---|
committer | Tom Stellard <thomas.stellard@amd.com> | 2012-12-14 22:29:13 +0000 |
commit | c43ee57419aace5cc4ecb190ea24909b0ac200d5 (patch) | |
tree | 317b35e8a23c0839b3551b1cae81bf41cc317a85 | |
parent | fb4fda114cc15509697682697354871c710cf4e2 (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.h | 2 | ||||
-rw-r--r-- | lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 1 | ||||
-rw-r--r-- | lib/Target/AMDGPU/R600AllocateMemoryRegs.cpp | 146 | ||||
-rw-r--r-- | lib/Target/AMDGPU/R600ISelLowering.cpp | 12 | ||||
-rw-r--r-- | lib/Target/AMDGPU/R600IndirectAddressing.cpp | 363 | ||||
-rw-r--r-- | lib/Target/AMDGPU/R600Instructions.td | 4 |
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>; |