summaryrefslogtreecommitdiff
path: root/lib/Target/R600/SIInstrInfo.cpp
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2014-03-21 15:51:54 +0000
committerTom Stellard <thomas.stellard@amd.com>2014-03-21 15:51:54 +0000
commit1f1c0495d05fae15e71f62ac380e873460770d82 (patch)
tree48e0a5704ef8af0622f847641a87e92360b929ee /lib/Target/R600/SIInstrInfo.cpp
parentaf4c7da3064af741c27d528ba36a9cdbebd4a58a (diff)
downloadllvm-1f1c0495d05fae15e71f62ac380e873460770d82.tar.gz
llvm-1f1c0495d05fae15e71f62ac380e873460770d82.tar.bz2
llvm-1f1c0495d05fae15e71f62ac380e873460770d82.tar.xz
R600/SI: Handle S_MOV_B64 in SIInstrInfo::moveToVALU()
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204475 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/R600/SIInstrInfo.cpp')
-rw-r--r--lib/Target/R600/SIInstrInfo.cpp52
1 files changed, 50 insertions, 2 deletions
diff --git a/lib/Target/R600/SIInstrInfo.cpp b/lib/Target/R600/SIInstrInfo.cpp
index 3ed8dfa325..c8a52971ef 100644
--- a/lib/Target/R600/SIInstrInfo.cpp
+++ b/lib/Target/R600/SIInstrInfo.cpp
@@ -496,6 +496,9 @@ unsigned SIInstrInfo::getVALUOp(const MachineInstr &MI) {
case AMDGPU::REG_SEQUENCE: return AMDGPU::REG_SEQUENCE;
case AMDGPU::COPY: return AMDGPU::COPY;
case AMDGPU::PHI: return AMDGPU::PHI;
+ case AMDGPU::S_MOV_B32:
+ return MI.getOperand(1).isReg() ?
+ TargetOpcode::COPY : AMDGPU::V_MOV_B32_e32;
case AMDGPU::S_ADD_I32: return AMDGPU::V_ADD_I32_e32;
case AMDGPU::S_ADDC_U32: return AMDGPU::V_ADDC_U32_e32;
case AMDGPU::S_SUB_I32: return AMDGPU::V_SUB_I32_e32;
@@ -680,12 +683,57 @@ void SIInstrInfo::moveToVALU(MachineInstr &TopInst) const {
while (!Worklist.empty()) {
MachineInstr *Inst = Worklist.pop_back_val();
+ MachineBasicBlock *MBB = Inst->getParent();
+ MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
+
+ // Handle some special cases
+ switch(Inst->getOpcode()) {
+ case AMDGPU::S_MOV_B64: {
+ DebugLoc DL = Inst->getDebugLoc();
+
+ // If the source operand is a register we can replace this with a
+ // copy
+ if (Inst->getOperand(1).isReg()) {
+ MachineInstr *Copy = BuildMI(*MBB, Inst, DL,
+ get(TargetOpcode::COPY))
+ .addOperand(Inst->getOperand(0))
+ .addOperand(Inst->getOperand(1));
+ Worklist.push_back(Copy);
+ } else {
+ // Otherwise, we need to split this into two movs, because there is
+ // no 64-bit VALU move instruction.
+ unsigned LoDst, HiDst, Dst;
+ LoDst = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass);
+ HiDst = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass);
+ Dst = MRI.createVirtualRegister(
+ MRI.getRegClass(Inst->getOperand(0).getReg()));
+
+ MachineInstr *Lo = BuildMI(*MBB, Inst, DL, get(AMDGPU::S_MOV_B32),
+ LoDst)
+ .addImm(Inst->getOperand(1).getImm() & 0xFFFFFFFF);
+ MachineInstr *Hi = BuildMI(*MBB, Inst, DL, get(AMDGPU::S_MOV_B32),
+ HiDst)
+ .addImm(Inst->getOperand(1).getImm() >> 32);
+
+ BuildMI(*MBB, Inst, DL, get(TargetOpcode::REG_SEQUENCE), Dst)
+ .addReg(LoDst)
+ .addImm(AMDGPU::sub0)
+ .addReg(HiDst)
+ .addImm(AMDGPU::sub1);
+
+ MRI.replaceRegWith(Inst->getOperand(0).getReg(), Dst);
+ Worklist.push_back(Lo);
+ Worklist.push_back(Hi);
+ }
+ Inst->eraseFromParent();
+ continue;
+ }
+ }
+
unsigned NewOpcode = getVALUOp(*Inst);
if (NewOpcode == AMDGPU::INSTRUCTION_LIST_END)
continue;
- MachineRegisterInfo &MRI = Inst->getParent()->getParent()->getRegInfo();
-
// Use the new VALU Opcode.
const MCInstrDesc &NewDesc = get(NewOpcode);
Inst->setDesc(NewDesc);