R600InstrInfo.cpp revision 4fb224e3bd7655e25bc1f43d05a0922098aae4e0
1f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===-- R600InstrInfo.cpp - R600 Instruction Information ------------------===// 2f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 3f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// The LLVM Compiler Infrastructure 4f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 5f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// This file is distributed under the University of Illinois Open Source 6f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// License. See LICENSE.TXT for details. 7f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 8f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 9f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 10f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// \file 11f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// \brief R600 Implementation of TargetInstrInfo. 12f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 13f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 14f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 15f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600InstrInfo.h" 164fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune#include "AMDGPU.h" 17f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDGPUSubtarget.h" 1858a2cbef4aac9ee7d530dfb690c78d6fc11a2371Chandler Carruth#include "AMDGPUTargetMachine.h" 19f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600Defines.h" 20c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard#include "R600MachineFunctionInfo.h" 21f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600RegisterInfo.h" 22f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/MachineInstrBuilder.h" 23c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard#include "llvm/CodeGen/MachineFrameInfo.h" 24c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard#include "llvm/CodeGen/MachineRegisterInfo.h" 25f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 26f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#define GET_INSTRINFO_CTOR 27f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDGPUGenDFAPacketizer.inc" 28f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 29f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm; 30f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 31f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::R600InstrInfo(AMDGPUTargetMachine &tm) 32f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard : AMDGPUInstrInfo(tm), 33631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune RI(tm, *this), 34631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune ST(tm.getSubtarget<AMDGPUSubtarget>()) 35f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard { } 36f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 37f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardconst R600RegisterInfo &R600InstrInfo::getRegisterInfo() const { 38f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return RI; 39f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 40f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 41f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isTrig(const MachineInstr &MI) const { 42f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return get(MI.getOpcode()).TSFlags & R600_InstFlag::TRIG; 43f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 44f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 45f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isVector(const MachineInstr &MI) const { 46f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return get(MI.getOpcode()).TSFlags & R600_InstFlag::VECTOR; 47f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 48f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 49f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid 50f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 51f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator MI, DebugLoc DL, 52f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned DestReg, unsigned SrcReg, 53f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool KillSrc) const { 54f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (AMDGPU::R600_Reg128RegClass.contains(DestReg) 55f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard && AMDGPU::R600_Reg128RegClass.contains(SrcReg)) { 56f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (unsigned I = 0; I < 4; I++) { 57f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned SubRegIndex = RI.getSubRegFromChannel(I); 58f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard buildDefaultInstruction(MBB, MI, AMDGPU::MOV, 59f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard RI.getSubReg(DestReg, SubRegIndex), 60f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard RI.getSubReg(SrcReg, SubRegIndex)) 61f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(DestReg, 62f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard RegState::Define | RegState::Implicit); 63f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 64f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 65f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 66f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // We can't copy vec4 registers 67f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!AMDGPU::R600_Reg128RegClass.contains(DestReg) 68f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard && !AMDGPU::R600_Reg128RegClass.contains(SrcReg)); 69f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 70f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *NewMI = buildDefaultInstruction(MBB, MI, AMDGPU::MOV, 71f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DestReg, SrcReg); 72f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard NewMI->getOperand(getOperandIdx(*NewMI, R600Operands::SRC0)) 73f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .setIsKill(KillSrc); 74f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 75f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 76f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 77f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineInstr * R600InstrInfo::getMovImmInstr(MachineFunction *MF, 78f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned DstReg, int64_t Imm) const { 79f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr * MI = MF->CreateMachineInstr(get(AMDGPU::MOV), DebugLoc()); 806b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MachineInstrBuilder MIB(*MF, MI); 816b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MIB.addReg(DstReg, RegState::Define); 826b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MIB.addReg(AMDGPU::ALU_LITERAL_X); 836b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MIB.addImm(Imm); 846b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MIB.addReg(0); // PREDICATE_BIT 85f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 86f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MI; 87f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 88f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 89f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned R600InstrInfo::getIEQOpcode() const { 90f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return AMDGPU::SETE_INT; 91f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 92f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 93f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isMov(unsigned Opcode) const { 94f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 95f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 96f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch(Opcode) { 97f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 98f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MOV: 99f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MOV_IMM_F32: 100f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MOV_IMM_I32: 101f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 102f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 103f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 104f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 105f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Some instructions act as place holders to emulate operations that the GPU 106f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// hardware does automatically. This function can be used to check if 107f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// an opcode falls into this category. 108f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isPlaceHolderOpcode(unsigned Opcode) const { 109f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Opcode) { 110f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 111f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::RETURN: 112f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 113f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 114f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 115f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 116f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isReductionOp(unsigned Opcode) const { 117f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch(Opcode) { 118f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 119f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::DOT4_r600_pseudo: 120f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::DOT4_eg_pseudo: 121f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 122f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 123f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 124f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 125f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isCubeOp(unsigned Opcode) const { 126f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch(Opcode) { 127f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 128f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_r600_pseudo: 129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_r600_real: 130f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_eg_pseudo: 131f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_eg_real: 132f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 133f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 134f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 135f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 136f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isALUInstr(unsigned Opcode) const { 137f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(Opcode).TSFlags; 138f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 139f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return ((TargetFlags & R600_InstFlag::OP1) | 140f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard (TargetFlags & R600_InstFlag::OP2) | 141f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard (TargetFlags & R600_InstFlag::OP3)); 142f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 143f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 144abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeunebool R600InstrInfo::isTransOnly(unsigned Opcode) const { 145abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune return (get(Opcode).TSFlags & R600_InstFlag::TRANS_ONLY); 146abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune} 147abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune 148abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeunebool R600InstrInfo::isTransOnly(const MachineInstr *MI) const { 149abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune return isTransOnly(MI->getOpcode()); 150abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune} 151abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune 152631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesVertexCache(unsigned Opcode) const { 153631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune return ST.hasVertexCache() && get(Opcode).TSFlags & R600_InstFlag::VTX_INST; 154631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 155631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 156631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesVertexCache(const MachineInstr *MI) const { 1574fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune const R600MachineFunctionInfo *MFI = MI->getParent()->getParent()->getInfo<R600MachineFunctionInfo>(); 1584fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune return MFI->ShaderType != ShaderType::COMPUTE && usesVertexCache(MI->getOpcode()); 159631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 160631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 161631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesTextureCache(unsigned Opcode) const { 162631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune return (!ST.hasVertexCache() && get(Opcode).TSFlags & R600_InstFlag::VTX_INST) || 163631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune (get(Opcode).TSFlags & R600_InstFlag::TEX_INST); 164631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 165631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 166631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesTextureCache(const MachineInstr *MI) const { 1674fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune const R600MachineFunctionInfo *MFI = MI->getParent()->getParent()->getInfo<R600MachineFunctionInfo>(); 1684fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune return (MFI->ShaderType == ShaderType::COMPUTE && usesVertexCache(MI->getOpcode())) || 1694fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune usesTextureCache(MI->getOpcode()); 170631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 171631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 1723ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeunebool 1733ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent LejeuneR600InstrInfo::fitsConstReadLimitations(const std::vector<unsigned> &Consts) 1743ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune const { 1753ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune assert (Consts.size() <= 12 && "Too many operands in instructions group"); 1763ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned Pair1 = 0, Pair2 = 0; 1773ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune for (unsigned i = 0, n = Consts.size(); i < n; ++i) { 1783ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned ReadConstHalf = Consts[i] & 2; 1793ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned ReadConstIndex = Consts[i] & (~3); 1803ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned ReadHalfConst = ReadConstIndex | ReadConstHalf; 1813ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (!Pair1) { 1823ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune Pair1 = ReadHalfConst; 1833ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 1843ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 1853ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (Pair1 == ReadHalfConst) 1863ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 1873ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (!Pair2) { 1883ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune Pair2 = ReadHalfConst; 1893ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 1903ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 1913ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (Pair2 != ReadHalfConst) 1923ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune return false; 1933ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 1943ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune return true; 1953ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune} 1963ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 1973ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeunebool 1983ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent LejeuneR600InstrInfo::canBundle(const std::vector<MachineInstr *> &MIs) const { 1993ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune std::vector<unsigned> Consts; 2003ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune for (unsigned i = 0, n = MIs.size(); i < n; i++) { 2013ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune const MachineInstr *MI = MIs[i]; 2023ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 2033ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune const R600Operands::Ops OpTable[3][2] = { 2043ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune {R600Operands::SRC0, R600Operands::SRC0_SEL}, 2053ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune {R600Operands::SRC1, R600Operands::SRC1_SEL}, 2063ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune {R600Operands::SRC2, R600Operands::SRC2_SEL}, 2073ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune }; 2083ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 2093ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (!isALUInstr(MI->getOpcode())) 2103ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 2113ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 2123ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune for (unsigned j = 0; j < 3; j++) { 2133ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune int SrcIdx = getOperandIdx(MI->getOpcode(), OpTable[j][0]); 2143ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (SrcIdx < 0) 2153ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune break; 21625f259cde28860ea76c2f5628010968945a28edbVincent Lejeune unsigned Reg = MI->getOperand(SrcIdx).getReg(); 21725f259cde28860ea76c2f5628010968945a28edbVincent Lejeune if (Reg == AMDGPU::ALU_CONST) { 2183ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned Const = MI->getOperand( 2193ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune getOperandIdx(MI->getOpcode(), OpTable[j][1])).getImm(); 2203ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune Consts.push_back(Const); 22125f259cde28860ea76c2f5628010968945a28edbVincent Lejeune continue; 22225f259cde28860ea76c2f5628010968945a28edbVincent Lejeune } 22325f259cde28860ea76c2f5628010968945a28edbVincent Lejeune if (AMDGPU::R600_KC0RegClass.contains(Reg) || 22425f259cde28860ea76c2f5628010968945a28edbVincent Lejeune AMDGPU::R600_KC1RegClass.contains(Reg)) { 22525f259cde28860ea76c2f5628010968945a28edbVincent Lejeune unsigned Index = RI.getEncodingValue(Reg) & 0xff; 22625f259cde28860ea76c2f5628010968945a28edbVincent Lejeune unsigned Chan = RI.getHWRegChan(Reg); 22725f259cde28860ea76c2f5628010968945a28edbVincent Lejeune Consts.push_back((Index << 2) | Chan); 22825f259cde28860ea76c2f5628010968945a28edbVincent Lejeune continue; 2293ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 2303ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 2313ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 2323ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune return fitsConstReadLimitations(Consts); 2333ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune} 2343ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 235f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardDFAPacketizer *R600InstrInfo::CreateTargetScheduleState(const TargetMachine *TM, 236f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const ScheduleDAG *DAG) const { 237f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const InstrItineraryData *II = TM->getInstrItineraryData(); 238f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return TM->getSubtarget<AMDGPUSubtarget>().createDFAPacketizer(II); 239f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 240f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 241f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic bool 242f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardisPredicateSetter(unsigned Opcode) { 243f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Opcode) { 244f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_X: 245f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 246f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 247f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 248f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 249f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 250f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 251f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic MachineInstr * 252f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardfindFirstPredicateSetterFrom(MachineBasicBlock &MBB, 253f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I) { 254f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard while (I != MBB.begin()) { 255f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 256f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *MI = I; 257f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isPredicateSetter(MI->getOpcode())) 258f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MI; 259f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 260f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 261f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return NULL; 262f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 263f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 264fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeunestatic 265fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeunebool isJump(unsigned Opcode) { 266fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune return Opcode == AMDGPU::JUMP || Opcode == AMDGPU::JUMP_COND; 267fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune} 268fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune 269f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 270f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 271f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *&TBB, 272f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *&FBB, 273f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<MachineOperand> &Cond, 274f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool AllowModify) const { 275f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Most of the following comes from the ARM implementation of AnalyzeBranch 276f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 277f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If the block has no terminators, it just falls into the block after it. 278f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I = MBB.end(); 279f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) 280f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 281f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 282f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard while (I->isDebugValue()) { 283f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) 284f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 285f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 286f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 287fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune if (!isJump(static_cast<MachineInstr *>(I)->getOpcode())) { 288f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 289f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 290f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 291f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Get the last instruction in the block. 292f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *LastInst = I; 293f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 294f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If there is only one terminator instruction, process it. 295f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned LastOpc = LastInst->getOpcode(); 296f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin() || 297fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune !isJump(static_cast<MachineInstr *>(--I)->getOpcode())) { 298f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (LastOpc == AMDGPU::JUMP) { 299fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune TBB = LastInst->getOperand(0).getMBB(); 300fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune return false; 301fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune } else if (LastOpc == AMDGPU::JUMP_COND) { 302fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune MachineInstr *predSet = I; 303fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune while (!isPredicateSetter(predSet->getOpcode())) { 304fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune predSet = --I; 305f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 306fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune TBB = LastInst->getOperand(0).getMBB(); 307fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune Cond.push_back(predSet->getOperand(1)); 308fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune Cond.push_back(predSet->getOperand(2)); 309fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune Cond.push_back(MachineOperand::CreateReg(AMDGPU::PRED_SEL_ONE, false)); 310fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune return false; 311f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 312f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; // Can't handle indirect branch. 313f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 314f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 315f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Get the instruction before it if it is a terminator. 316f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *SecondLastInst = I; 317f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned SecondLastOpc = SecondLastInst->getOpcode(); 318f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 319f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If the block ends with a B and a Bcc, handle it. 320fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune if (SecondLastOpc == AMDGPU::JUMP_COND && LastOpc == AMDGPU::JUMP) { 321f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *predSet = --I; 322f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard while (!isPredicateSetter(predSet->getOpcode())) { 323f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard predSet = --I; 324f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 325f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TBB = SecondLastInst->getOperand(0).getMBB(); 326f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FBB = LastInst->getOperand(0).getMBB(); 327f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond.push_back(predSet->getOperand(1)); 328f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond.push_back(predSet->getOperand(2)); 329f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond.push_back(MachineOperand::CreateReg(AMDGPU::PRED_SEL_ONE, false)); 330f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 331f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 332f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 333f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Otherwise, can't handle this. 334f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 335f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 336f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 337f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardint R600InstrInfo::getBranchInstr(const MachineOperand &op) const { 338f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MachineInstr *MI = op.getParent(); 339f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 340f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (MI->getDesc().OpInfo->RegClass) { 341f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: // FIXME: fallthrough?? 342f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::GPRI32RegClassID: return AMDGPU::BRANCH_COND_i32; 343f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::GPRF32RegClassID: return AMDGPU::BRANCH_COND_f32; 344f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard }; 345f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 346f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 347f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned 348f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::InsertBranch(MachineBasicBlock &MBB, 349f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *TBB, 350f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *FBB, 351f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SmallVectorImpl<MachineOperand> &Cond, 352f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL) const { 353f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 354f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 355f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (FBB == 0) { 356f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Cond.empty()) { 357fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP)).addMBB(TBB); 358f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 359f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 360f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end()); 361f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(PredSet && "No previous predicate !"); 362f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addFlag(PredSet, 0, MO_FLAG_PUSH); 363f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PredSet->getOperand(2).setImm(Cond[1].getImm()); 364f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 365fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP_COND)) 366f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addMBB(TBB) 367f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); 368f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 369f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 370f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 371f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end()); 372f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(PredSet && "No previous predicate !"); 373f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addFlag(PredSet, 0, MO_FLAG_PUSH); 374f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PredSet->getOperand(2).setImm(Cond[1].getImm()); 375fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP_COND)) 376f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addMBB(TBB) 377f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); 378fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP)).addMBB(FBB); 379f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 2; 380f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 381f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 382f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 383f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned 384f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 385f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 386f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Note : we leave PRED* instructions there. 387f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // They may be needed when predicating instructions. 388f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 389f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I = MBB.end(); 390f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 391f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) { 392f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 0; 393f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 394f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 395f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (I->getOpcode()) { 396f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 397f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 0; 398fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune case AMDGPU::JUMP_COND: { 399fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I); 400fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune clearFlag(predSet, 0, MO_FLAG_PUSH); 401fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune I->eraseFromParent(); 402fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune break; 403fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune } 404f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::JUMP: 405f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard I->eraseFromParent(); 406f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 407f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 408f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard I = MBB.end(); 409f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 410f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) { 411f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 412f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 413f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 414f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (I->getOpcode()) { 415f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // FIXME: only one case?? 416f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 417f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 418fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune case AMDGPU::JUMP_COND: { 419fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I); 420fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune clearFlag(predSet, 0, MO_FLAG_PUSH); 421fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune I->eraseFromParent(); 422fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune break; 423fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune } 424f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::JUMP: 425f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard I->eraseFromParent(); 426f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 427f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 428f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 2; 429f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 430f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 431f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 432f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isPredicated(const MachineInstr *MI) const { 433f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int idx = MI->findFirstPredOperandIdx(); 434f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (idx < 0) 435f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 436f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 437f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Reg = MI->getOperand(idx).getReg(); 438f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Reg) { 439f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 440f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ONE: 441f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ZERO: 442f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PREDICATE_BIT: 443f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 444f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 445f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 446f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 447f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 448f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isPredicable(MachineInstr *MI) const { 449f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // XXX: KILL* instructions can be predicated, but they must be the last 450f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // instruction in a clause, so this means any instructions after them cannot 451f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // be predicated. Until we have proper support for instruction clauses in the 452f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // backend, we will mark KILL* instructions as unpredicable. 453f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 454f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (MI->getOpcode() == AMDGPU::KILLGT) { 455f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 45662b0a9b1e6189947b7e46df1b64968e66476c912Vincent Lejeune } else if (isVector(*MI)) { 45762b0a9b1e6189947b7e46df1b64968e66476c912Vincent Lejeune return false; 458f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 459f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return AMDGPUInstrInfo::isPredicable(MI); 460f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 461f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 462f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 463f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 464f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 465f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB, 466f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumCyles, 467f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ExtraPredCycles, 468f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const BranchProbability &Probability) const{ 469f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 470f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 471f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 472f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 473f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB, 474f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumTCycles, 475f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ExtraTCycles, 476f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock &FMBB, 477f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumFCycles, 478f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ExtraFCycles, 479f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const BranchProbability &Probability) const { 480f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 481f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 482f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 483f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 484f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB, 485f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumCyles, 486f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const BranchProbability &Probability) 487f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const { 488f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 489f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 490f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 491f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 492f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToUnpredicate(MachineBasicBlock &TMBB, 493f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock &FMBB) const { 494f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 495f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 496f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 497f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 498f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 499f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 500f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &MO = Cond[1]; 501f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (MO.getImm()) { 502f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_ZERO_INT: 503f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_NOT_ZERO_INT); 504f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 505f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_NOT_ZERO_INT: 506f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_ZERO_INT); 507f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 508f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_ZERO: 509f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_NOT_ZERO); 510f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 511f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_NOT_ZERO: 512f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_ZERO); 513f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 514f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 515f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 516f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 517f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 518f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &MO2 = Cond[2]; 519f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (MO2.getReg()) { 520f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ZERO: 521f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO2.setReg(AMDGPU::PRED_SEL_ONE); 522f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 523f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ONE: 524f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO2.setReg(AMDGPU::PRED_SEL_ZERO); 525f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 526f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 527f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 528f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 529f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 530f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 531f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 532f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 533f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::DefinesPredicate(MachineInstr *MI, 534f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard std::vector<MachineOperand> &Pred) const { 535f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return isPredicateSetter(MI->getOpcode()); 536f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 537f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 538f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 539f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 540f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 541f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SmallVectorImpl<MachineOperand> &Pred2) const { 542f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 543f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 544f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 545f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 546f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 547f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::PredicateInstruction(MachineInstr *MI, 548f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SmallVectorImpl<MachineOperand> &Pred) const { 549f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int PIdx = MI->findFirstPredOperandIdx(); 550f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 551f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (PIdx != -1) { 552f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &PMO = MI->getOperand(PIdx); 553f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PMO.setReg(Pred[2].getReg()); 5546b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MachineInstrBuilder MIB(*MI->getParent()->getParent(), MI); 5556b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MIB.addReg(AMDGPU::PREDICATE_BIT, RegState::Implicit); 556f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 557f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 558f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 559f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 560f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 561f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 562f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned int R600InstrInfo::getInstrLatency(const InstrItineraryData *ItinData, 563f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MachineInstr *MI, 564f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned *PredCost) const { 565f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (PredCost) 566f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard *PredCost = 2; 567f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 2; 568f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 569f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 570c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardint R600InstrInfo::getIndirectIndexBegin(const MachineFunction &MF) const { 571c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineRegisterInfo &MRI = MF.getRegInfo(); 572c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineFrameInfo *MFI = MF.getFrameInfo(); 573c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard int Offset = 0; 574c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 575c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (MFI->getNumObjects() == 0) { 576c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return -1; 577c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 578c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 579c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (MRI.livein_empty()) { 580c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return 0; 581c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 582c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 583c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (MachineRegisterInfo::livein_iterator LI = MRI.livein_begin(), 584c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard LE = MRI.livein_end(); 585c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard LI != LE; ++LI) { 586c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Offset = std::max(Offset, 587c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard GET_REG_INDEX(RI.getEncodingValue(LI->first))); 588c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 589c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 590c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Offset + 1; 591c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 592c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 593c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardint R600InstrInfo::getIndirectIndexEnd(const MachineFunction &MF) const { 594c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard int Offset = 0; 595c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineFrameInfo *MFI = MF.getFrameInfo(); 596c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 597c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // Variable sized objects are not supported 598c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard assert(!MFI->hasVarSizedObjects()); 599c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 600c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (MFI->getNumObjects() == 0) { 601c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return -1; 602c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 603c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 604c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Offset = TM.getFrameLowering()->getFrameIndexOffset(MF, -1); 605c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 606c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return getIndirectIndexBegin(MF) + Offset; 607c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 608c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 609c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardstd::vector<unsigned> R600InstrInfo::getIndirectReservedRegs( 610c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineFunction &MF) const { 611c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const AMDGPUFrameLowering *TFL = 612c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard static_cast<const AMDGPUFrameLowering*>(TM.getFrameLowering()); 613c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard std::vector<unsigned> Regs; 614c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 615c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned StackWidth = TFL->getStackWidth(MF); 616c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard int End = getIndirectIndexEnd(MF); 617c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 618c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (End == -1) { 619c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Regs; 620c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 621c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 622c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (int Index = getIndirectIndexBegin(MF); Index <= End; ++Index) { 623c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned SuperReg = AMDGPU::R600_Reg128RegClass.getRegister(Index); 624c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Regs.push_back(SuperReg); 625c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (unsigned Chan = 0; Chan < StackWidth; ++Chan) { 626c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister((4 * Index) + Chan); 627c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Regs.push_back(Reg); 628c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 629c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 630c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Regs; 631c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 632c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 633c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardunsigned R600InstrInfo::calculateIndirectAddress(unsigned RegIndex, 634c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned Channel) const { 635c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // XXX: Remove when we support a stack width > 2 636c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard assert(Channel == 0); 637c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return RegIndex; 638c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 639c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 640c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardconst TargetRegisterClass * R600InstrInfo::getIndirectAddrStoreRegClass( 641c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned SourceReg) const { 642c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return &AMDGPU::R600_TReg32RegClass; 643c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 644c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 645c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardconst TargetRegisterClass *R600InstrInfo::getIndirectAddrLoadRegClass() const { 646c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return &AMDGPU::TRegMemRegClass; 647c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 648c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 649c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardMachineInstrBuilder R600InstrInfo::buildIndirectWrite(MachineBasicBlock *MBB, 650c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineBasicBlock::iterator I, 651c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned ValueReg, unsigned Address, 652c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned OffsetReg) const { 653c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address); 654c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, AMDGPU::MOVA_INT_eg, 655c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AMDGPU::AR_X, OffsetReg); 656c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard setImmOperand(MOVA, R600Operands::WRITE, 0); 657c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 658c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, AMDGPU::MOV, 659c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AddrReg, ValueReg) 660c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard .addReg(AMDGPU::AR_X, RegState::Implicit); 661c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard setImmOperand(Mov, R600Operands::DST_REL, 1); 662c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Mov; 663c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 664c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 665c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardMachineInstrBuilder R600InstrInfo::buildIndirectRead(MachineBasicBlock *MBB, 666c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineBasicBlock::iterator I, 667c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned ValueReg, unsigned Address, 668c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned OffsetReg) const { 669c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address); 670c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, AMDGPU::MOVA_INT_eg, 671c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AMDGPU::AR_X, 672c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard OffsetReg); 673c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard setImmOperand(MOVA, R600Operands::WRITE, 0); 674c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, AMDGPU::MOV, 675c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard ValueReg, 676c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AddrReg) 677c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard .addReg(AMDGPU::AR_X, RegState::Implicit); 678c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard setImmOperand(Mov, R600Operands::SRC0_REL, 1); 679c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 680c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Mov; 681c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 682c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 683c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardconst TargetRegisterClass *R600InstrInfo::getSuperIndirectRegClass() const { 684c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return &AMDGPU::IndirectRegRegClass; 685c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 686c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 687dae2a20a56b28b4685249982a80a0043b7673e09Vincent Lejeuneunsigned R600InstrInfo::getMaxAlusPerClause() const { 688dae2a20a56b28b4685249982a80a0043b7673e09Vincent Lejeune return 115; 689dae2a20a56b28b4685249982a80a0043b7673e09Vincent Lejeune} 690c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 691f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineInstrBuilder R600InstrInfo::buildDefaultInstruction(MachineBasicBlock &MBB, 692f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I, 693f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Opcode, 694f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned DstReg, 695f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Src0Reg, 696f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Src1Reg) const { 697f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstrBuilder MIB = BuildMI(MBB, I, MBB.findDebugLoc(I), get(Opcode), 698f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DstReg); // $dst 699f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 700f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Src1Reg) { 701f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addImm(0) // $update_exec_mask 702f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0); // $update_predicate 703f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 704f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addImm(1) // $write 705f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $omod 706f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $dst_rel 707f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $dst_clamp 708f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(Src0Reg) // $src0 709f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src0_neg 710f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src0_rel 7119f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(0) // $src0_abs 7129f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(-1); // $src0_sel 713f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 714f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Src1Reg) { 715f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addReg(Src1Reg) // $src1 716f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src1_neg 717f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src1_rel 7189f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(0) // $src1_abs 7199f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(-1); // $src1_sel 720f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 721f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 722f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard //XXX: The r600g finalizer expects this to be 1, once we've moved the 723f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard //scheduling to the backend, we can change the default to 0. 724f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addImm(1) // $last 725f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PRED_SEL_OFF) // $pred_sel 726e332e3559b5c09040de1528920006756e0962d6aVincent Lejeune .addImm(0) // $literal 727e332e3559b5c09040de1528920006756e0962d6aVincent Lejeune .addImm(0); // $bank_swizzle 728f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 729f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MIB; 730f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 731f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 732f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineInstr *R600InstrInfo::buildMovImm(MachineBasicBlock &BB, 733f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I, 734f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned DstReg, 735f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard uint64_t Imm) const { 736f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *MovImm = buildDefaultInstruction(BB, I, AMDGPU::MOV, DstReg, 737f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::ALU_LITERAL_X); 738f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard setImmOperand(MovImm, R600Operands::IMM, Imm); 739f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MovImm; 740f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 741f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 742f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardint R600InstrInfo::getOperandIdx(const MachineInstr &MI, 743f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R600Operands::Ops Op) const { 744f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return getOperandIdx(MI.getOpcode(), Op); 745f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 746f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 747f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardint R600InstrInfo::getOperandIdx(unsigned Opcode, 748f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard R600Operands::Ops Op) const { 749f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(Opcode).TSFlags; 750f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned OpTableIdx; 751f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 752f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (!HAS_NATIVE_OPERANDS(TargetFlags)) { 753f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Op) { 754f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case R600Operands::DST: return 0; 755f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case R600Operands::SRC0: return 1; 756f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case R600Operands::SRC1: return 2; 757f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case R600Operands::SRC2: return 3; 758f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 759f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!"Unknown operand type for instruction"); 760f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return -1; 761f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 762f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 763f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 764f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (TargetFlags & R600_InstFlag::OP1) { 765f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard OpTableIdx = 0; 766f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (TargetFlags & R600_InstFlag::OP2) { 767f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard OpTableIdx = 1; 768f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 769f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert((TargetFlags & R600_InstFlag::OP3) && "OP1, OP2, or OP3 not defined " 770f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard "for this instruction"); 771f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard OpTableIdx = 2; 772f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 773f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 7749f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard return R600Operands::ALUOpTable[OpTableIdx][Op]; 775f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 776f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 777f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid R600InstrInfo::setImmOperand(MachineInstr *MI, R600Operands::Ops Op, 778f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int64_t Imm) const { 779f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int Idx = getOperandIdx(*MI, Op); 780f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(Idx != -1 && "Operand not supported for this instruction."); 781f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(MI->getOperand(Idx).isImm()); 782f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(Idx).setImm(Imm); 783f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 784f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 785f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 786f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Instruction flag getters/setters 787f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 788f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 789f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::hasFlagOperand(const MachineInstr &MI) const { 790f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return GET_FLAG_OPERAND_IDX(get(MI.getOpcode()).TSFlags) != 0; 791f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 792f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 793f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineOperand &R600InstrInfo::getFlagOp(MachineInstr *MI, unsigned SrcIdx, 794f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Flag) const { 795f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(MI->getOpcode()).TSFlags; 796f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int FlagIndex = 0; 797f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Flag != 0) { 798f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If we pass something other than the default value of Flag to this 799f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // function, it means we are want to set a flag on an instruction 800f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // that uses native encoding. 801f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(HAS_NATIVE_OPERANDS(TargetFlags)); 802f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool IsOP3 = (TargetFlags & R600_InstFlag::OP3) == R600_InstFlag::OP3; 803f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Flag) { 804f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_CLAMP: 805f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagIndex = getOperandIdx(*MI, R600Operands::CLAMP); 806f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 807f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_MASK: 808f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagIndex = getOperandIdx(*MI, R600Operands::WRITE); 809f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 810f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_NOT_LAST: 811f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_LAST: 812f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagIndex = getOperandIdx(*MI, R600Operands::LAST); 813f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 814f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_NEG: 815f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (SrcIdx) { 816f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case 0: FlagIndex = getOperandIdx(*MI, R600Operands::SRC0_NEG); break; 817f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case 1: FlagIndex = getOperandIdx(*MI, R600Operands::SRC1_NEG); break; 818f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case 2: FlagIndex = getOperandIdx(*MI, R600Operands::SRC2_NEG); break; 819f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 820f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 821f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 822f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_ABS: 823f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!IsOP3 && "Cannot set absolute value modifier for OP3 " 824f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard "instructions."); 82508f2d9379c486a0e4b950e476913ee97b38ec333Tom Stellard (void)IsOP3; 826f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (SrcIdx) { 827f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case 0: FlagIndex = getOperandIdx(*MI, R600Operands::SRC0_ABS); break; 828f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case 1: FlagIndex = getOperandIdx(*MI, R600Operands::SRC1_ABS); break; 829f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 830f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 831f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 832f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 833f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagIndex = -1; 834f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 835f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 836f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(FlagIndex != -1 && "Flag not supported for this instruction"); 837f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 838f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagIndex = GET_FLAG_OPERAND_IDX(TargetFlags); 839f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(FlagIndex != 0 && 840f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard "Instruction flags not supported for this instruction"); 841f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 842f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 843f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = MI->getOperand(FlagIndex); 844f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(FlagOp.isImm()); 845f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return FlagOp; 846f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 847f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 848f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid R600InstrInfo::addFlag(MachineInstr *MI, unsigned Operand, 849f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Flag) const { 850f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(MI->getOpcode()).TSFlags; 851f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Flag == 0) { 852f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return; 853f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 854f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (HAS_NATIVE_OPERANDS(TargetFlags)) { 855f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag); 856f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Flag == MO_FLAG_NOT_LAST) { 857f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard clearFlag(MI, Operand, MO_FLAG_LAST); 858f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (Flag == MO_FLAG_MASK) { 859f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard clearFlag(MI, Operand, Flag); 860f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 861f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(1); 862f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 863f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 864f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI, Operand); 865f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(FlagOp.getImm() | (Flag << (NUM_MO_FLAGS * Operand))); 866f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 867f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 868f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 869f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid R600InstrInfo::clearFlag(MachineInstr *MI, unsigned Operand, 870f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Flag) const { 871f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(MI->getOpcode()).TSFlags; 872f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (HAS_NATIVE_OPERANDS(TargetFlags)) { 873f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag); 874f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(0); 875f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 876f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI); 877f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned InstFlags = FlagOp.getImm(); 878f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard InstFlags &= ~(Flag << (NUM_MO_FLAGS * Operand)); 879f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(InstFlags); 880f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 881f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 882