R600InstrInfo.cpp revision 7e9381951eb4dadf9c59257786416ac51a6a6c09
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" 22c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard#include "llvm/CodeGen/MachineFrameInfo.h" 235c35290fa35ae234fed02496404cb0fc37e1c8a5Benjamin Kramer#include "llvm/CodeGen/MachineInstrBuilder.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), 33b5632b5b456db647b42239cbd4d8b58c82290c4eBill Wendling RI(tm), 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); 725e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard NewMI->getOperand(getOperandIdx(*NewMI, AMDGPU::OpName::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 } 120f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 121f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 122f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isCubeOp(unsigned Opcode) const { 123f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch(Opcode) { 124f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 125f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_r600_pseudo: 126f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_r600_real: 127f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_eg_pseudo: 128f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_eg_real: 129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 130f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 131f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 132f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 133f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isALUInstr(unsigned Opcode) const { 134f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(Opcode).TSFlags; 135f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1367e9381951eb4dadf9c59257786416ac51a6a6c09Tom Stellard return (TargetFlags & R600_InstFlag::ALU_INST); 137f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 138f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 139abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeunebool R600InstrInfo::isTransOnly(unsigned Opcode) const { 140abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune return (get(Opcode).TSFlags & R600_InstFlag::TRANS_ONLY); 141abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune} 142abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune 143abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeunebool R600InstrInfo::isTransOnly(const MachineInstr *MI) const { 144abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune return isTransOnly(MI->getOpcode()); 145abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune} 146abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune 147631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesVertexCache(unsigned Opcode) const { 14832c76107d029c1cad5935d08cdcde6139cf874bbTom Stellard return ST.hasVertexCache() && IS_VTX(get(Opcode)); 149631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 150631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 151631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesVertexCache(const MachineInstr *MI) const { 1524fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune const R600MachineFunctionInfo *MFI = MI->getParent()->getParent()->getInfo<R600MachineFunctionInfo>(); 1534fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune return MFI->ShaderType != ShaderType::COMPUTE && usesVertexCache(MI->getOpcode()); 154631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 155631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 156631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesTextureCache(unsigned Opcode) const { 15732c76107d029c1cad5935d08cdcde6139cf874bbTom Stellard return (!ST.hasVertexCache() && IS_VTX(get(Opcode))) || IS_TEX(get(Opcode)); 158631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 159631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 160631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesTextureCache(const MachineInstr *MI) const { 1614fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune const R600MachineFunctionInfo *MFI = MI->getParent()->getParent()->getInfo<R600MachineFunctionInfo>(); 1624fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune return (MFI->ShaderType == ShaderType::COMPUTE && usesVertexCache(MI->getOpcode())) || 1634fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune usesTextureCache(MI->getOpcode()); 164631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 165631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 16625c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneSmallVector<std::pair<MachineOperand *, int64_t>, 3> 16725c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneR600InstrInfo::getSrcs(MachineInstr *MI) const { 16825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune SmallVector<std::pair<MachineOperand *, int64_t>, 3> Result; 16925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 170e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune if (MI->getOpcode() == AMDGPU::DOT_4) { 1715e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard static const unsigned OpTable[8][2] = { 1725e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0_X, AMDGPU::OpName::src0_sel_X}, 1735e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0_Y, AMDGPU::OpName::src0_sel_Y}, 1745e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0_Z, AMDGPU::OpName::src0_sel_Z}, 1755e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0_W, AMDGPU::OpName::src0_sel_W}, 1765e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1_X, AMDGPU::OpName::src1_sel_X}, 1775e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1_Y, AMDGPU::OpName::src1_sel_Y}, 1785e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1_Z, AMDGPU::OpName::src1_sel_Z}, 1795e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1_W, AMDGPU::OpName::src1_sel_W}, 180e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune }; 181e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 182e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune for (unsigned j = 0; j < 8; j++) { 1835e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard MachineOperand &MO = MI->getOperand(getOperandIdx(MI->getOpcode(), 1845e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OpTable[j][0])); 185e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune unsigned Reg = MO.getReg(); 186e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune if (Reg == AMDGPU::ALU_CONST) { 1875e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard unsigned Sel = MI->getOperand(getOperandIdx(MI->getOpcode(), 1885e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OpTable[j][1])).getImm(); 189e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, Sel)); 190e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune continue; 191e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune } 192e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 193e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune } 194e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune return Result; 195e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune } 196e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 1975e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard static const unsigned OpTable[3][2] = { 1985e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0, AMDGPU::OpName::src0_sel}, 1995e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1, AMDGPU::OpName::src1_sel}, 2005e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src2, AMDGPU::OpName::src2_sel}, 20125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune }; 20225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 20325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned j = 0; j < 3; j++) { 20425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune int SrcIdx = getOperandIdx(MI->getOpcode(), OpTable[j][0]); 20525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (SrcIdx < 0) 20625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 20725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune MachineOperand &MO = MI->getOperand(SrcIdx); 20825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Reg = MI->getOperand(SrcIdx).getReg(); 20925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Reg == AMDGPU::ALU_CONST) { 21025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Sel = MI->getOperand( 21125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune getOperandIdx(MI->getOpcode(), OpTable[j][1])).getImm(); 21225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, Sel)); 21325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 21425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 21525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Reg == AMDGPU::ALU_LITERAL_X) { 21625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Imm = MI->getOperand( 2175e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard getOperandIdx(MI->getOpcode(), AMDGPU::OpName::literal)).getImm(); 21825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, Imm)); 21925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 22025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 22125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, 0)); 22225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 22325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return Result; 22425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 22525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 22625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunestd::vector<std::pair<int, unsigned> > 22725c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneR600InstrInfo::ExtractSrcs(MachineInstr *MI, 22825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const DenseMap<unsigned, unsigned> &PV) 22925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const { 23025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const SmallVector<std::pair<MachineOperand *, int64_t>, 3> Srcs = getSrcs(MI); 23125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const std::pair<int, unsigned> DummyPair(-1, 0); 23225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::vector<std::pair<int, unsigned> > Result; 23325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned i = 0; 23425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned n = Srcs.size(); i < n; ++i) { 23525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Reg = Srcs[i].first->getReg(); 23625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Index = RI.getEncodingValue(Reg) & 0xff; 23725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Chan = RI.getHWRegChan(Reg); 23825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Index > 127) { 23925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(DummyPair); 24025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 24125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 242f7c9b95f94b18d1c8ae15a59bf28c5c2cafa5ad8Vincent Lejeune if (PV.find(Reg) != PV.end()) { 24325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(DummyPair); 24425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 24525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 24625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(std::pair<int, unsigned>(Index, Chan)); 24725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 24825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (; i < 3; ++i) 24925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(DummyPair); 25025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return Result; 25125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 25225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 25325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunestatic std::vector<std::pair<int, unsigned> > 25425c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneSwizzle(std::vector<std::pair<int, unsigned> > Src, 25525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune R600InstrInfo::BankSwizzle Swz) { 25625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune switch (Swz) { 25725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune case R600InstrInfo::ALU_VEC_012: 25825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 25925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune case R600InstrInfo::ALU_VEC_021: 26025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[1], Src[2]); 26125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 26225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune case R600InstrInfo::ALU_VEC_102: 26325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[1]); 26425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 26525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune case R600InstrInfo::ALU_VEC_120: 26625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[1]); 26725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[2]); 26825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 26925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune case R600InstrInfo::ALU_VEC_201: 27025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[2]); 27125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[1]); 27225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 27325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune case R600InstrInfo::ALU_VEC_210: 27425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[2]); 27525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 27625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 27725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return Src; 27825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 27925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 28025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunestatic bool 28125c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneisLegal(const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs, 28225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const std::vector<R600InstrInfo::BankSwizzle> &Swz, 28325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned CheckedSize) { 28425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune int Vector[4][3]; 28525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune memset(Vector, -1, sizeof(Vector)); 28625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned i = 0; i < CheckedSize; i++) { 28725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const std::vector<std::pair<int, unsigned> > &Srcs = 28825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Swizzle(IGSrcs[i], Swz[i]); 28925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned j = 0; j < 3; j++) { 29025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const std::pair<int, unsigned> &Src = Srcs[j]; 29125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Src.first < 0) 29225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 29325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Vector[Src.second][j] < 0) 29425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Vector[Src.second][j] = Src.first; 29525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Vector[Src.second][j] != Src.first) 29625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return false; 29725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 29825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 29925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return true; 30025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 30125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 30225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunestatic bool recursiveFitsFPLimitation( 30325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeuneconst std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs, 30425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunestd::vector<R600InstrInfo::BankSwizzle> &SwzCandidate, 30525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeuneunsigned Depth = 0) { 30625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (!isLegal(IGSrcs, SwzCandidate, Depth)) 30725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return false; 30825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (IGSrcs.size() == Depth) 30925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return true; 31025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned i = SwzCandidate[Depth]; 31125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (; i < 6; i++) { 31225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune SwzCandidate[Depth] = (R600InstrInfo::BankSwizzle) i; 31325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (recursiveFitsFPLimitation(IGSrcs, SwzCandidate, Depth + 1)) 31425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return true; 31525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 31625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune SwzCandidate[Depth] = R600InstrInfo::ALU_VEC_012; 31725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return false; 31825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 31925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 32025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunebool 32125c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneR600InstrInfo::fitsReadPortLimitations(const std::vector<MachineInstr *> &IG, 32225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const DenseMap<unsigned, unsigned> &PV, 32325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::vector<BankSwizzle> &ValidSwizzle) 32425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const { 32525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune //Todo : support shared src0 - src1 operand 32625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 32725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::vector<std::vector<std::pair<int, unsigned> > > IGSrcs; 32825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune ValidSwizzle.clear(); 32925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned i = 0, e = IG.size(); i < e; ++i) { 33025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune IGSrcs.push_back(ExtractSrcs(IG[i], PV)); 33125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Op = getOperandIdx(IG[i]->getOpcode(), 3325e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::bank_swizzle); 33325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune ValidSwizzle.push_back( (R600InstrInfo::BankSwizzle) 33425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune IG[i]->getOperand(Op).getImm()); 33525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 33625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune bool Result = recursiveFitsFPLimitation(IGSrcs, ValidSwizzle); 33725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (!Result) 33825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return false; 33925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return true; 34025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 34125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 34225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 3433ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeunebool 3443ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent LejeuneR600InstrInfo::fitsConstReadLimitations(const std::vector<unsigned> &Consts) 3453ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune const { 3463ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune assert (Consts.size() <= 12 && "Too many operands in instructions group"); 3473ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned Pair1 = 0, Pair2 = 0; 3483ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune for (unsigned i = 0, n = Consts.size(); i < n; ++i) { 3493ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned ReadConstHalf = Consts[i] & 2; 3503ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned ReadConstIndex = Consts[i] & (~3); 3513ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned ReadHalfConst = ReadConstIndex | ReadConstHalf; 3523ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (!Pair1) { 3533ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune Pair1 = ReadHalfConst; 3543ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 3553ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 3563ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (Pair1 == ReadHalfConst) 3573ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 3583ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (!Pair2) { 3593ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune Pair2 = ReadHalfConst; 3603ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 3613ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 3623ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (Pair2 != ReadHalfConst) 3633ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune return false; 3643ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 3653ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune return true; 3663ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune} 3673ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 3683ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeunebool 3693ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent LejeuneR600InstrInfo::canBundle(const std::vector<MachineInstr *> &MIs) const { 3703ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune std::vector<unsigned> Consts; 3713ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune for (unsigned i = 0, n = MIs.size(); i < n; i++) { 37225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune MachineInstr *MI = MIs[i]; 3733ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (!isALUInstr(MI->getOpcode())) 3743ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 3753ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 37625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const SmallVector<std::pair<MachineOperand *, int64_t>, 3> &Srcs = 37725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune getSrcs(MI); 37825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 37925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned j = 0, e = Srcs.size(); j < e; j++) { 38025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::pair<MachineOperand *, unsigned> Src = Srcs[j]; 38125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Src.first->getReg() == AMDGPU::ALU_CONST) 38225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Consts.push_back(Src.second); 38325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (AMDGPU::R600_KC0RegClass.contains(Src.first->getReg()) || 38425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune AMDGPU::R600_KC1RegClass.contains(Src.first->getReg())) { 38525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Index = RI.getEncodingValue(Src.first->getReg()) & 0xff; 38625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Chan = RI.getHWRegChan(Src.first->getReg()); 38725f259cde28860ea76c2f5628010968945a28edbVincent Lejeune Consts.push_back((Index << 2) | Chan); 3883ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 3893ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 3903ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 3913ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune return fitsConstReadLimitations(Consts); 3923ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune} 3933ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 394f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardDFAPacketizer *R600InstrInfo::CreateTargetScheduleState(const TargetMachine *TM, 395f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const ScheduleDAG *DAG) const { 396f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const InstrItineraryData *II = TM->getInstrItineraryData(); 397f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return TM->getSubtarget<AMDGPUSubtarget>().createDFAPacketizer(II); 398f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 399f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 400f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic bool 401f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardisPredicateSetter(unsigned Opcode) { 402f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Opcode) { 403f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_X: 404f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 405f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 406f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 407f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 408f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 409f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 410f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic MachineInstr * 411f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardfindFirstPredicateSetterFrom(MachineBasicBlock &MBB, 412f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I) { 413f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard while (I != MBB.begin()) { 414f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 415f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *MI = I; 416f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isPredicateSetter(MI->getOpcode())) 417f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MI; 418f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 419f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 420f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return NULL; 421f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 422f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 423fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeunestatic 424fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeunebool isJump(unsigned Opcode) { 425fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune return Opcode == AMDGPU::JUMP || Opcode == AMDGPU::JUMP_COND; 426fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune} 427fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune 428f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 429f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 430f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *&TBB, 431f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *&FBB, 432f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<MachineOperand> &Cond, 433f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool AllowModify) const { 434f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Most of the following comes from the ARM implementation of AnalyzeBranch 435f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 436f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If the block has no terminators, it just falls into the block after it. 437f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I = MBB.end(); 438f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) 439f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 440f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 441f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard while (I->isDebugValue()) { 442f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) 443f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 444f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 445f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 446fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune if (!isJump(static_cast<MachineInstr *>(I)->getOpcode())) { 447f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 448f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 449f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 450f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Get the last instruction in the block. 451f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *LastInst = I; 452f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 453f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If there is only one terminator instruction, process it. 454f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned LastOpc = LastInst->getOpcode(); 455f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin() || 456fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune !isJump(static_cast<MachineInstr *>(--I)->getOpcode())) { 457f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (LastOpc == AMDGPU::JUMP) { 458fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune TBB = LastInst->getOperand(0).getMBB(); 459fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune return false; 460fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune } else if (LastOpc == AMDGPU::JUMP_COND) { 461fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune MachineInstr *predSet = I; 462fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune while (!isPredicateSetter(predSet->getOpcode())) { 463fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune predSet = --I; 464f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 465fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune TBB = LastInst->getOperand(0).getMBB(); 466fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune Cond.push_back(predSet->getOperand(1)); 467fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune Cond.push_back(predSet->getOperand(2)); 468fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune Cond.push_back(MachineOperand::CreateReg(AMDGPU::PRED_SEL_ONE, false)); 469fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune return false; 470f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 471f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; // Can't handle indirect branch. 472f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 473f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 474f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Get the instruction before it if it is a terminator. 475f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *SecondLastInst = I; 476f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned SecondLastOpc = SecondLastInst->getOpcode(); 477f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 478f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If the block ends with a B and a Bcc, handle it. 479fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune if (SecondLastOpc == AMDGPU::JUMP_COND && LastOpc == AMDGPU::JUMP) { 480f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *predSet = --I; 481f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard while (!isPredicateSetter(predSet->getOpcode())) { 482f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard predSet = --I; 483f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 484f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TBB = SecondLastInst->getOperand(0).getMBB(); 485f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FBB = LastInst->getOperand(0).getMBB(); 486f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond.push_back(predSet->getOperand(1)); 487f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond.push_back(predSet->getOperand(2)); 488f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond.push_back(MachineOperand::CreateReg(AMDGPU::PRED_SEL_ONE, false)); 489f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 490f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 491f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 492f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Otherwise, can't handle this. 493f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 494f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 495f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 496f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardint R600InstrInfo::getBranchInstr(const MachineOperand &op) const { 497f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MachineInstr *MI = op.getParent(); 498f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 499f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (MI->getDesc().OpInfo->RegClass) { 500f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: // FIXME: fallthrough?? 501f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::GPRI32RegClassID: return AMDGPU::BRANCH_COND_i32; 502f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::GPRF32RegClassID: return AMDGPU::BRANCH_COND_f32; 503f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard }; 504f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 505f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 506f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned 507f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::InsertBranch(MachineBasicBlock &MBB, 508f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *TBB, 509f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *FBB, 510f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SmallVectorImpl<MachineOperand> &Cond, 511f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL) const { 512f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 513f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 514f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (FBB == 0) { 515f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Cond.empty()) { 516fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP)).addMBB(TBB); 517f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 518f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 519f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end()); 520f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(PredSet && "No previous predicate !"); 521f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addFlag(PredSet, 0, MO_FLAG_PUSH); 522f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PredSet->getOperand(2).setImm(Cond[1].getImm()); 523f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 524fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP_COND)) 525f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addMBB(TBB) 526f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); 527f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 528f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 529f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 530f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end()); 531f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(PredSet && "No previous predicate !"); 532f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addFlag(PredSet, 0, MO_FLAG_PUSH); 533f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PredSet->getOperand(2).setImm(Cond[1].getImm()); 534fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP_COND)) 535f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addMBB(TBB) 536f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); 537fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP)).addMBB(FBB); 538f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 2; 539f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 540f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 541f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 542f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned 543f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 544f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 545f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Note : we leave PRED* instructions there. 546f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // They may be needed when predicating instructions. 547f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 548f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I = MBB.end(); 549f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 550f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) { 551f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 0; 552f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 553f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 554f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (I->getOpcode()) { 555f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 556f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 0; 557fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune case AMDGPU::JUMP_COND: { 558fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I); 559fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune clearFlag(predSet, 0, MO_FLAG_PUSH); 560fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune I->eraseFromParent(); 561fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune break; 562fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune } 563f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::JUMP: 564f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard I->eraseFromParent(); 565f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 566f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 567f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard I = MBB.end(); 568f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 569f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) { 570f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 571f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 572f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 573f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (I->getOpcode()) { 574f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // FIXME: only one case?? 575f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 576f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 577fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune case AMDGPU::JUMP_COND: { 578fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I); 579fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune clearFlag(predSet, 0, MO_FLAG_PUSH); 580fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune I->eraseFromParent(); 581fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune break; 582fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune } 583f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::JUMP: 584f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard I->eraseFromParent(); 585f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 586f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 587f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 2; 588f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 589f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 590f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 591f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isPredicated(const MachineInstr *MI) const { 592f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int idx = MI->findFirstPredOperandIdx(); 593f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (idx < 0) 594f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 595f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 596f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Reg = MI->getOperand(idx).getReg(); 597f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Reg) { 598f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 599f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ONE: 600f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ZERO: 601f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PREDICATE_BIT: 602f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 603f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 604f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 605f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 606f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 607f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isPredicable(MachineInstr *MI) const { 608f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // XXX: KILL* instructions can be predicated, but they must be the last 609f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // instruction in a clause, so this means any instructions after them cannot 610f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // be predicated. Until we have proper support for instruction clauses in the 611f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // backend, we will mark KILL* instructions as unpredicable. 612f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 613f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (MI->getOpcode() == AMDGPU::KILLGT) { 614f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 61562b0a9b1e6189947b7e46df1b64968e66476c912Vincent Lejeune } else if (isVector(*MI)) { 61662b0a9b1e6189947b7e46df1b64968e66476c912Vincent Lejeune return false; 617f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 618f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return AMDGPUInstrInfo::isPredicable(MI); 619f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 620f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 621f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 622f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 623f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 624f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB, 625f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumCyles, 626f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ExtraPredCycles, 627f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const BranchProbability &Probability) const{ 628f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 629f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 630f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 631f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 632f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB, 633f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumTCycles, 634f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ExtraTCycles, 635f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock &FMBB, 636f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumFCycles, 637f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ExtraFCycles, 638f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const BranchProbability &Probability) const { 639f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 640f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 641f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 642f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 643f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB, 644f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumCyles, 645f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const BranchProbability &Probability) 646f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const { 647f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 648f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 649f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 650f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 651f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToUnpredicate(MachineBasicBlock &TMBB, 652f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock &FMBB) const { 653f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 654f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 655f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 656f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 657f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 658f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 659f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &MO = Cond[1]; 660f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (MO.getImm()) { 661f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_ZERO_INT: 662f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_NOT_ZERO_INT); 663f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 664f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_NOT_ZERO_INT: 665f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_ZERO_INT); 666f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 667f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_ZERO: 668f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_NOT_ZERO); 669f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 670f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_NOT_ZERO: 671f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_ZERO); 672f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 673f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 674f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 675f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 676f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 677f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &MO2 = Cond[2]; 678f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (MO2.getReg()) { 679f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ZERO: 680f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO2.setReg(AMDGPU::PRED_SEL_ONE); 681f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 682f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ONE: 683f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO2.setReg(AMDGPU::PRED_SEL_ZERO); 684f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 685f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 686f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 687f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 688f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 689f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 690f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 691f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 692f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::DefinesPredicate(MachineInstr *MI, 693f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard std::vector<MachineOperand> &Pred) const { 694f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return isPredicateSetter(MI->getOpcode()); 695f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 696f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 697f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 698f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 699f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 700f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SmallVectorImpl<MachineOperand> &Pred2) const { 701f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 702f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 703f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 704f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 705f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 706f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::PredicateInstruction(MachineInstr *MI, 707f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SmallVectorImpl<MachineOperand> &Pred) const { 708f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int PIdx = MI->findFirstPredOperandIdx(); 709f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 710f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (PIdx != -1) { 711f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &PMO = MI->getOperand(PIdx); 712f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PMO.setReg(Pred[2].getReg()); 7136b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MachineInstrBuilder MIB(*MI->getParent()->getParent(), MI); 7146b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MIB.addReg(AMDGPU::PREDICATE_BIT, RegState::Implicit); 715f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 716f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 717f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 718f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 719f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 720f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 721f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned int R600InstrInfo::getInstrLatency(const InstrItineraryData *ItinData, 722f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MachineInstr *MI, 723f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned *PredCost) const { 724f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (PredCost) 725f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard *PredCost = 2; 726f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 2; 727f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 728f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 729c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardint R600InstrInfo::getIndirectIndexBegin(const MachineFunction &MF) const { 730c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineRegisterInfo &MRI = MF.getRegInfo(); 731c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineFrameInfo *MFI = MF.getFrameInfo(); 732c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard int Offset = 0; 733c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 734c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (MFI->getNumObjects() == 0) { 735c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return -1; 736c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 737c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 738c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (MRI.livein_empty()) { 739c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return 0; 740c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 741c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 742c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (MachineRegisterInfo::livein_iterator LI = MRI.livein_begin(), 743c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard LE = MRI.livein_end(); 744c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard LI != LE; ++LI) { 745c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Offset = std::max(Offset, 746c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard GET_REG_INDEX(RI.getEncodingValue(LI->first))); 747c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 748c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 749c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Offset + 1; 750c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 751c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 752c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardint R600InstrInfo::getIndirectIndexEnd(const MachineFunction &MF) const { 753c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard int Offset = 0; 754c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineFrameInfo *MFI = MF.getFrameInfo(); 755c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 756c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // Variable sized objects are not supported 757c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard assert(!MFI->hasVarSizedObjects()); 758c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 759c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (MFI->getNumObjects() == 0) { 760c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return -1; 761c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 762c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 763c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Offset = TM.getFrameLowering()->getFrameIndexOffset(MF, -1); 764c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 765c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return getIndirectIndexBegin(MF) + Offset; 766c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 767c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 768c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardstd::vector<unsigned> R600InstrInfo::getIndirectReservedRegs( 769c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineFunction &MF) const { 770c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const AMDGPUFrameLowering *TFL = 771c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard static_cast<const AMDGPUFrameLowering*>(TM.getFrameLowering()); 772c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard std::vector<unsigned> Regs; 773c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 774c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned StackWidth = TFL->getStackWidth(MF); 775c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard int End = getIndirectIndexEnd(MF); 776c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 777c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (End == -1) { 778c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Regs; 779c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 780c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 781c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (int Index = getIndirectIndexBegin(MF); Index <= End; ++Index) { 782c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned SuperReg = AMDGPU::R600_Reg128RegClass.getRegister(Index); 783c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Regs.push_back(SuperReg); 784c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (unsigned Chan = 0; Chan < StackWidth; ++Chan) { 785c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister((4 * Index) + Chan); 786c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Regs.push_back(Reg); 787c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 788c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 789c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Regs; 790c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 791c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 792c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardunsigned R600InstrInfo::calculateIndirectAddress(unsigned RegIndex, 793c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned Channel) const { 794c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // XXX: Remove when we support a stack width > 2 795c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard assert(Channel == 0); 796c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return RegIndex; 797c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 798c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 799c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardconst TargetRegisterClass * R600InstrInfo::getIndirectAddrStoreRegClass( 800c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned SourceReg) const { 801c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return &AMDGPU::R600_TReg32RegClass; 802c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 803c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 804c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardconst TargetRegisterClass *R600InstrInfo::getIndirectAddrLoadRegClass() const { 805c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return &AMDGPU::TRegMemRegClass; 806c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 807c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 808c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardMachineInstrBuilder R600InstrInfo::buildIndirectWrite(MachineBasicBlock *MBB, 809c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineBasicBlock::iterator I, 810c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned ValueReg, unsigned Address, 811c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned OffsetReg) const { 812c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address); 813c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, AMDGPU::MOVA_INT_eg, 814c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AMDGPU::AR_X, OffsetReg); 8155e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(MOVA, AMDGPU::OpName::write, 0); 816c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 817c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, AMDGPU::MOV, 818c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AddrReg, ValueReg) 819ad7ecc65b1b1d6466ff035168c86f208a91aa1b4Tom Stellard .addReg(AMDGPU::AR_X, 820ad7ecc65b1b1d6466ff035168c86f208a91aa1b4Tom Stellard RegState::Implicit | RegState::Kill); 8215e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(Mov, AMDGPU::OpName::dst_rel, 1); 822c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Mov; 823c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 824c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 825c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardMachineInstrBuilder R600InstrInfo::buildIndirectRead(MachineBasicBlock *MBB, 826c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineBasicBlock::iterator I, 827c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned ValueReg, unsigned Address, 828c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned OffsetReg) const { 829c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address); 830c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, AMDGPU::MOVA_INT_eg, 831c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AMDGPU::AR_X, 832c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard OffsetReg); 8335e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(MOVA, AMDGPU::OpName::write, 0); 834c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, AMDGPU::MOV, 835c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard ValueReg, 836c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AddrReg) 837ad7ecc65b1b1d6466ff035168c86f208a91aa1b4Tom Stellard .addReg(AMDGPU::AR_X, 838ad7ecc65b1b1d6466ff035168c86f208a91aa1b4Tom Stellard RegState::Implicit | RegState::Kill); 8395e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(Mov, AMDGPU::OpName::src0_rel, 1); 840c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 841c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Mov; 842c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 843c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 844c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardconst TargetRegisterClass *R600InstrInfo::getSuperIndirectRegClass() const { 845c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return &AMDGPU::IndirectRegRegClass; 846c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 847c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 848dae2a20a56b28b4685249982a80a0043b7673e09Vincent Lejeuneunsigned R600InstrInfo::getMaxAlusPerClause() const { 849dae2a20a56b28b4685249982a80a0043b7673e09Vincent Lejeune return 115; 850dae2a20a56b28b4685249982a80a0043b7673e09Vincent Lejeune} 851c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 852f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineInstrBuilder R600InstrInfo::buildDefaultInstruction(MachineBasicBlock &MBB, 853f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I, 854f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Opcode, 855f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned DstReg, 856f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Src0Reg, 857f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Src1Reg) const { 858f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstrBuilder MIB = BuildMI(MBB, I, MBB.findDebugLoc(I), get(Opcode), 859f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DstReg); // $dst 860f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 861f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Src1Reg) { 862f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addImm(0) // $update_exec_mask 863f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0); // $update_predicate 864f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 865f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addImm(1) // $write 866f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $omod 867f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $dst_rel 868f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $dst_clamp 869f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(Src0Reg) // $src0 870f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src0_neg 871f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src0_rel 8729f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(0) // $src0_abs 8739f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(-1); // $src0_sel 874f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 875f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Src1Reg) { 876f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addReg(Src1Reg) // $src1 877f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src1_neg 878f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src1_rel 8799f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(0) // $src1_abs 8809f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(-1); // $src1_sel 881f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 882f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 883f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard //XXX: The r600g finalizer expects this to be 1, once we've moved the 884f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard //scheduling to the backend, we can change the default to 0. 885f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addImm(1) // $last 886f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PRED_SEL_OFF) // $pred_sel 887e332e3559b5c09040de1528920006756e0962d6aVincent Lejeune .addImm(0) // $literal 888e332e3559b5c09040de1528920006756e0962d6aVincent Lejeune .addImm(0); // $bank_swizzle 889f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 890f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MIB; 891f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 892f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 8934ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune#define OPERAND_CASE(Label) \ 8944ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune case Label: { \ 8955e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard static const unsigned Ops[] = \ 8964ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune { \ 8974ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Label##_X, \ 8984ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Label##_Y, \ 8994ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Label##_Z, \ 9004ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Label##_W \ 9014ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune }; \ 9024ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune return Ops[Slot]; \ 9034ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune } 9044ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 9055e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellardstatic unsigned getSlotedOps(unsigned Op, unsigned Slot) { 9064ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune switch (Op) { 9075e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::update_exec_mask) 9085e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::update_pred) 9095e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::write) 9105e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::omod) 9115e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::dst_rel) 9125e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::clamp) 9135e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0) 9145e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0_neg) 9155e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0_rel) 9165e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0_abs) 9175e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0_sel) 9185e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1) 9195e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1_neg) 9205e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1_rel) 9215e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1_abs) 9225e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1_sel) 9235e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::pred_sel) 9244ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune default: 9254ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune llvm_unreachable("Wrong Operand"); 9264ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune } 9274ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune} 9284ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 9294ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune#undef OPERAND_CASE 9304ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 9314ed9917147b1d1f2616f7c941bbe6999b979f510Vincent LejeuneMachineInstr *R600InstrInfo::buildSlotOfVectorInstruction( 9324ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineBasicBlock &MBB, MachineInstr *MI, unsigned Slot, unsigned DstReg) 9334ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune const { 9344ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune assert (MI->getOpcode() == AMDGPU::DOT_4 && "Not Implemented"); 9354ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune unsigned Opcode; 9364ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); 9373ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard if (ST.getGeneration() <= AMDGPUSubtarget::R700) 9384ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Opcode = AMDGPU::DOT4_r600; 9394ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune else 9404ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Opcode = AMDGPU::DOT4_eg; 9414ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineBasicBlock::iterator I = MI; 9424ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineOperand &Src0 = MI->getOperand( 9435e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard getOperandIdx(MI->getOpcode(), getSlotedOps(AMDGPU::OpName::src0, Slot))); 9444ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineOperand &Src1 = MI->getOperand( 9455e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard getOperandIdx(MI->getOpcode(), getSlotedOps(AMDGPU::OpName::src1, Slot))); 9464ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineInstr *MIB = buildDefaultInstruction( 9474ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MBB, I, Opcode, DstReg, Src0.getReg(), Src1.getReg()); 9485e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard static const unsigned Operands[14] = { 9495e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::update_exec_mask, 9505e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::update_pred, 9515e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::write, 9525e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::omod, 9535e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::dst_rel, 9545e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::clamp, 9555e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src0_neg, 9565e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src0_rel, 9575e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src0_abs, 9585e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src0_sel, 9595e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src1_neg, 9605e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src1_rel, 9615e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src1_abs, 9625e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src1_sel, 9634ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune }; 9644ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 9654ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune for (unsigned i = 0; i < 14; i++) { 9664ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineOperand &MO = MI->getOperand( 9675e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard getOperandIdx(MI->getOpcode(), getSlotedOps(Operands[i], Slot))); 9684ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune assert (MO.isImm()); 9694ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune setImmOperand(MIB, Operands[i], MO.getImm()); 9704ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune } 9714ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MIB->getOperand(20).setImm(0); 9724ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune return MIB; 9734ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune} 9744ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 975f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineInstr *R600InstrInfo::buildMovImm(MachineBasicBlock &BB, 976f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I, 977f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned DstReg, 978f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard uint64_t Imm) const { 979f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *MovImm = buildDefaultInstruction(BB, I, AMDGPU::MOV, DstReg, 980f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::ALU_LITERAL_X); 9815e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(MovImm, AMDGPU::OpName::literal, Imm); 982f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MovImm; 983f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 984f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 9855e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellardint R600InstrInfo::getOperandIdx(const MachineInstr &MI, unsigned Op) const { 986e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune return getOperandIdx(MI.getOpcode(), Op); 987e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune} 988e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 9895e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellardint R600InstrInfo::getOperandIdx(unsigned Opcode, unsigned Op) const { 9905e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard return AMDGPU::getNamedOperandIdx(Opcode, Op); 991e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune} 992e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 9935e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellardvoid R600InstrInfo::setImmOperand(MachineInstr *MI, unsigned Op, 994f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int64_t Imm) const { 995f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int Idx = getOperandIdx(*MI, Op); 996f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(Idx != -1 && "Operand not supported for this instruction."); 997f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(MI->getOperand(Idx).isImm()); 998f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(Idx).setImm(Imm); 999f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1000f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1001f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 1002f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Instruction flag getters/setters 1003f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 1004f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1005f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::hasFlagOperand(const MachineInstr &MI) const { 1006f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return GET_FLAG_OPERAND_IDX(get(MI.getOpcode()).TSFlags) != 0; 1007f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1008f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1009f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineOperand &R600InstrInfo::getFlagOp(MachineInstr *MI, unsigned SrcIdx, 1010f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Flag) const { 1011f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(MI->getOpcode()).TSFlags; 1012f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int FlagIndex = 0; 1013f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Flag != 0) { 1014f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If we pass something other than the default value of Flag to this 1015f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // function, it means we are want to set a flag on an instruction 1016f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // that uses native encoding. 1017f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(HAS_NATIVE_OPERANDS(TargetFlags)); 1018f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool IsOP3 = (TargetFlags & R600_InstFlag::OP3) == R600_InstFlag::OP3; 1019f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Flag) { 1020f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_CLAMP: 10215e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::clamp); 1022f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1023f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_MASK: 10245e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::write); 1025f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1026f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_NOT_LAST: 1027f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_LAST: 10285e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::last); 1029f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1030f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_NEG: 1031f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (SrcIdx) { 10325e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 0: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src0_neg); break; 10335e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 1: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src1_neg); break; 10345e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 2: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src2_neg); break; 1035f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1036f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1037f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1038f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_ABS: 1039f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!IsOP3 && "Cannot set absolute value modifier for OP3 " 1040f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard "instructions."); 104108f2d9379c486a0e4b950e476913ee97b38ec333Tom Stellard (void)IsOP3; 1042f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (SrcIdx) { 10435e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 0: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src0_abs); break; 10445e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 1: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src1_abs); break; 1045f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1046f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1047f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1048f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 1049f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagIndex = -1; 1050f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1051f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1052f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(FlagIndex != -1 && "Flag not supported for this instruction"); 1053f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 1054f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagIndex = GET_FLAG_OPERAND_IDX(TargetFlags); 1055f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(FlagIndex != 0 && 1056f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard "Instruction flags not supported for this instruction"); 1057f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1058f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1059f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = MI->getOperand(FlagIndex); 1060f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(FlagOp.isImm()); 1061f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return FlagOp; 1062f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1063f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1064f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid R600InstrInfo::addFlag(MachineInstr *MI, unsigned Operand, 1065f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Flag) const { 1066f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(MI->getOpcode()).TSFlags; 1067f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Flag == 0) { 1068f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return; 1069f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1070f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (HAS_NATIVE_OPERANDS(TargetFlags)) { 1071f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag); 1072f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Flag == MO_FLAG_NOT_LAST) { 1073f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard clearFlag(MI, Operand, MO_FLAG_LAST); 1074f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (Flag == MO_FLAG_MASK) { 1075f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard clearFlag(MI, Operand, Flag); 1076f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 1077f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(1); 1078f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1079f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 1080f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI, Operand); 1081f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(FlagOp.getImm() | (Flag << (NUM_MO_FLAGS * Operand))); 1082f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1083f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1084f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1085f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid R600InstrInfo::clearFlag(MachineInstr *MI, unsigned Operand, 1086f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Flag) const { 1087f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(MI->getOpcode()).TSFlags; 1088f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (HAS_NATIVE_OPERANDS(TargetFlags)) { 1089f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag); 1090f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(0); 1091f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 1092f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI); 1093f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned InstFlags = FlagOp.getImm(); 1094f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard InstFlags &= ~(Flag << (NUM_MO_FLAGS * Operand)); 1095f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(InstFlags); 1096f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1097f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1098