void SIRegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, int64_t Offset) const { MachineBasicBlock *MBB = MI.getParent(); MachineFunction *MF = MBB->getParent(); const SISubtarget &Subtarget = MF->getSubtarget<SISubtarget>(); const SIInstrInfo *TII = Subtarget.getInstrInfo(); #ifndef NDEBUG // FIXME: Is it possible to be storing a frame index to itself? bool SeenFI = false; for (const MachineOperand &MO: MI.operands()) { if (MO.isFI()) { if (SeenFI) llvm_unreachable("should not see multiple frame indices"); SeenFI = true; } } #endif MachineOperand *FIOp = TII->getNamedOperand(MI, AMDGPU::OpName::vaddr); assert(FIOp && FIOp->isFI() && "frame index must be address operand"); assert(TII->isMUBUF(MI)); MachineOperand *OffsetOp = TII->getNamedOperand(MI, AMDGPU::OpName::offset); int64_t NewOffset = OffsetOp->getImm() + Offset; if (isUInt<12>(NewOffset)) { // If we have a legal offset, fold it directly into the instruction. FIOp->ChangeToRegister(BaseReg, false); OffsetOp->setImm(NewOffset); return; } // The offset is not legal, so we must insert an add of the offset. MachineRegisterInfo &MRI = MF->getRegInfo(); unsigned NewReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); DebugLoc DL = MI.getDebugLoc(); assert(Offset != 0 && "Non-zero offset expected"); unsigned UnusedCarry = MRI.createVirtualRegister(&AMDGPU::SReg_64RegClass); unsigned OffsetReg = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); // In the case the instruction already had an immediate offset, here only // the requested new offset is added because we are leaving the original // immediate in place. BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_MOV_B32), OffsetReg) .addImm(Offset); BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_ADD_I32_e64), NewReg) .addReg(UnusedCarry, RegState::Define | RegState::Dead) .addReg(OffsetReg, RegState::Kill) .addReg(BaseReg); FIOp->ChangeToRegister(NewReg, false); }
void HexagonPeephole::ChangeOpInto(MachineOperand &Dst, MachineOperand &Src) { assert (&Dst != &Src && "Cannot duplicate into itself"); switch (Dst.getType()) { case MachineOperand::MO_Register: if (Src.isReg()) { Dst.setReg(Src.getReg()); } else if (Src.isImm()) { Dst.ChangeToImmediate(Src.getImm()); } else { llvm_unreachable("Unexpected src operand type"); } break; case MachineOperand::MO_Immediate: if (Src.isImm()) { Dst.setImm(Src.getImm()); } else if (Src.isReg()) { Dst.ChangeToRegister(Src.getReg(), Src.isDef(), Src.isImplicit(), Src.isKill(), Src.isDead(), Src.isUndef(), Src.isDebug()); } else { llvm_unreachable("Unexpected src operand type"); } break; default: llvm_unreachable("Unexpected dst operand type"); break; } }
void SIRegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, int64_t Offset) const { MachineBasicBlock *MBB = MI.getParent(); MachineFunction *MF = MBB->getParent(); const SISubtarget &Subtarget = MF->getSubtarget<SISubtarget>(); const SIInstrInfo *TII = Subtarget.getInstrInfo(); #ifndef NDEBUG // FIXME: Is it possible to be storing a frame index to itself? bool SeenFI = false; for (const MachineOperand &MO: MI.operands()) { if (MO.isFI()) { if (SeenFI) llvm_unreachable("should not see multiple frame indices"); SeenFI = true; } } #endif MachineOperand *FIOp = TII->getNamedOperand(MI, AMDGPU::OpName::vaddr); assert(FIOp && FIOp->isFI() && "frame index must be address operand"); assert(TII->isMUBUF(MI)); MachineOperand *OffsetOp = TII->getNamedOperand(MI, AMDGPU::OpName::offset); int64_t NewOffset = OffsetOp->getImm() + Offset; assert(isUInt<12>(NewOffset) && "offset should be legal"); FIOp->ChangeToRegister(BaseReg, false); OffsetOp->setImm(NewOffset); }