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