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 { 54692ee102ebef535d311c35d53457028083e5c5beTom Stellard unsigned VectorComponents = 0; 55692ee102ebef535d311c35d53457028083e5c5beTom Stellard if (AMDGPU::R600_Reg128RegClass.contains(DestReg) && 56692ee102ebef535d311c35d53457028083e5c5beTom Stellard AMDGPU::R600_Reg128RegClass.contains(SrcReg)) { 57692ee102ebef535d311c35d53457028083e5c5beTom Stellard VectorComponents = 4; 58692ee102ebef535d311c35d53457028083e5c5beTom Stellard } else if(AMDGPU::R600_Reg64RegClass.contains(DestReg) && 59692ee102ebef535d311c35d53457028083e5c5beTom Stellard AMDGPU::R600_Reg64RegClass.contains(SrcReg)) { 60692ee102ebef535d311c35d53457028083e5c5beTom Stellard VectorComponents = 2; 61692ee102ebef535d311c35d53457028083e5c5beTom Stellard } 62692ee102ebef535d311c35d53457028083e5c5beTom Stellard 63692ee102ebef535d311c35d53457028083e5c5beTom Stellard if (VectorComponents > 0) { 64692ee102ebef535d311c35d53457028083e5c5beTom Stellard for (unsigned I = 0; I < VectorComponents; I++) { 65f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned SubRegIndex = RI.getSubRegFromChannel(I); 66f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard buildDefaultInstruction(MBB, MI, AMDGPU::MOV, 67f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard RI.getSubReg(DestReg, SubRegIndex), 68f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard RI.getSubReg(SrcReg, SubRegIndex)) 69f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(DestReg, 70f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard RegState::Define | RegState::Implicit); 71f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 72f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 73f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *NewMI = buildDefaultInstruction(MBB, MI, AMDGPU::MOV, 74f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DestReg, SrcReg); 755e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard NewMI->getOperand(getOperandIdx(*NewMI, AMDGPU::OpName::src0)) 76f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .setIsKill(KillSrc); 77f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 78f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 79f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 80f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineInstr * R600InstrInfo::getMovImmInstr(MachineFunction *MF, 81f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned DstReg, int64_t Imm) const { 82f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr * MI = MF->CreateMachineInstr(get(AMDGPU::MOV), DebugLoc()); 836b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MachineInstrBuilder MIB(*MF, MI); 846b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MIB.addReg(DstReg, RegState::Define); 856b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MIB.addReg(AMDGPU::ALU_LITERAL_X); 866b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MIB.addImm(Imm); 876b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MIB.addReg(0); // PREDICATE_BIT 88f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 89f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MI; 90f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 91f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 92f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned R600InstrInfo::getIEQOpcode() const { 93f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return AMDGPU::SETE_INT; 94f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 95f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 96f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isMov(unsigned Opcode) const { 97f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 98f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 99f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch(Opcode) { 100f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 101f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MOV: 102f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MOV_IMM_F32: 103f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MOV_IMM_I32: 104f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 105f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 106f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 107f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 108f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Some instructions act as place holders to emulate operations that the GPU 109f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// hardware does automatically. This function can be used to check if 110f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// an opcode falls into this category. 111f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isPlaceHolderOpcode(unsigned Opcode) const { 112f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Opcode) { 113f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 114f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::RETURN: 115f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 116f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 117f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 118f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 119f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isReductionOp(unsigned Opcode) const { 12080095e5f8e433b7a68fbad4ff460503fd06f84efAaron Ballman return false; 121f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 122f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 123f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isCubeOp(unsigned Opcode) const { 124f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch(Opcode) { 125f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 126f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_r600_pseudo: 127f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_r600_real: 128f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_eg_pseudo: 129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_eg_real: 130f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 131f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 132f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 133f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 134f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isALUInstr(unsigned Opcode) const { 135f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(Opcode).TSFlags; 136f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1377e9381951eb4dadf9c59257786416ac51a6a6c09Tom Stellard return (TargetFlags & R600_InstFlag::ALU_INST); 138f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 139f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 140e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellardbool R600InstrInfo::hasInstrModifiers(unsigned Opcode) const { 141e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard unsigned TargetFlags = get(Opcode).TSFlags; 142e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard 143e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard return ((TargetFlags & R600_InstFlag::OP1) | 144e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard (TargetFlags & R600_InstFlag::OP2) | 145e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard (TargetFlags & R600_InstFlag::OP3)); 146e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard} 147e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard 148e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellardbool R600InstrInfo::isLDSInstr(unsigned Opcode) const { 149e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard unsigned TargetFlags = get(Opcode).TSFlags; 150e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard 151e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard return ((TargetFlags & R600_InstFlag::LDS_1A) | 152e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard (TargetFlags & R600_InstFlag::LDS_1A1D)); 153e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard} 154e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard 155abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeunebool R600InstrInfo::isTransOnly(unsigned Opcode) const { 156af2ea2a4fb785652ec79dbe179c499823ea45f63Tom Stellard return (get(Opcode).TSFlags & R600_InstFlag::TRANS_ONLY); 157abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune} 158abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune 159abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeunebool R600InstrInfo::isTransOnly(const MachineInstr *MI) const { 160abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune return isTransOnly(MI->getOpcode()); 161abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune} 162abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune 163631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesVertexCache(unsigned Opcode) const { 16432c76107d029c1cad5935d08cdcde6139cf874bbTom Stellard return ST.hasVertexCache() && IS_VTX(get(Opcode)); 165631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 166631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 167631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesVertexCache(const MachineInstr *MI) const { 1684fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune const R600MachineFunctionInfo *MFI = MI->getParent()->getParent()->getInfo<R600MachineFunctionInfo>(); 1694fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune return MFI->ShaderType != ShaderType::COMPUTE && usesVertexCache(MI->getOpcode()); 170631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 171631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 172631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesTextureCache(unsigned Opcode) const { 17332c76107d029c1cad5935d08cdcde6139cf874bbTom Stellard return (!ST.hasVertexCache() && IS_VTX(get(Opcode))) || IS_TEX(get(Opcode)); 174631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 175631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 176631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesTextureCache(const MachineInstr *MI) const { 1774fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune const R600MachineFunctionInfo *MFI = MI->getParent()->getParent()->getInfo<R600MachineFunctionInfo>(); 1784fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune return (MFI->ShaderType == ShaderType::COMPUTE && usesVertexCache(MI->getOpcode())) || 1794fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune usesTextureCache(MI->getOpcode()); 180631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 181631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 182cedcfee405a22b245e869abe8609f094df34085aTom Stellardbool R600InstrInfo::mustBeLastInClause(unsigned Opcode) const { 183cedcfee405a22b245e869abe8609f094df34085aTom Stellard switch (Opcode) { 184cedcfee405a22b245e869abe8609f094df34085aTom Stellard case AMDGPU::KILLGT: 185cedcfee405a22b245e869abe8609f094df34085aTom Stellard case AMDGPU::GROUP_BARRIER: 186cedcfee405a22b245e869abe8609f094df34085aTom Stellard return true; 187cedcfee405a22b245e869abe8609f094df34085aTom Stellard default: 188cedcfee405a22b245e869abe8609f094df34085aTom Stellard return false; 189cedcfee405a22b245e869abe8609f094df34085aTom Stellard } 190cedcfee405a22b245e869abe8609f094df34085aTom Stellard} 191cedcfee405a22b245e869abe8609f094df34085aTom Stellard 19258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellardint R600InstrInfo::getSrcIdx(unsigned Opcode, unsigned SrcNum) const { 19358d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard static const unsigned OpTable[] = { 19458d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard AMDGPU::OpName::src0, 19558d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard AMDGPU::OpName::src1, 19658d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard AMDGPU::OpName::src2 19758d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard }; 19858d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard 19958d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard assert (SrcNum < 3); 20058d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard return getOperandIdx(Opcode, OpTable[SrcNum]); 20158d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard} 20258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard 20358d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard#define SRC_SEL_ROWS 11 20458d3335cb9d2a40bd15c29a12ba045163295190eTom Stellardint R600InstrInfo::getSelIdx(unsigned Opcode, unsigned SrcIdx) const { 20558d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard static const unsigned SrcSelTable[SRC_SEL_ROWS][2] = { 20658d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src0, AMDGPU::OpName::src0_sel}, 20758d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src1, AMDGPU::OpName::src1_sel}, 20858d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src2, AMDGPU::OpName::src2_sel}, 20958d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src0_X, AMDGPU::OpName::src0_sel_X}, 21058d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src0_Y, AMDGPU::OpName::src0_sel_Y}, 21158d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src0_Z, AMDGPU::OpName::src0_sel_Z}, 21258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src0_W, AMDGPU::OpName::src0_sel_W}, 21358d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src1_X, AMDGPU::OpName::src1_sel_X}, 21458d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src1_Y, AMDGPU::OpName::src1_sel_Y}, 21558d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src1_Z, AMDGPU::OpName::src1_sel_Z}, 21658d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src1_W, AMDGPU::OpName::src1_sel_W} 21758d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard }; 21858d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard 21958d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard for (unsigned i = 0; i < SRC_SEL_ROWS; ++i) { 22058d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard if (getOperandIdx(Opcode, SrcSelTable[i][0]) == (int)SrcIdx) { 22158d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard return getOperandIdx(Opcode, SrcSelTable[i][1]); 22258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard } 22358d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard } 22458d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard return -1; 22558d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard} 22658d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard#undef SRC_SEL_ROWS 22758d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard 22825c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneSmallVector<std::pair<MachineOperand *, int64_t>, 3> 22925c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneR600InstrInfo::getSrcs(MachineInstr *MI) const { 23025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune SmallVector<std::pair<MachineOperand *, int64_t>, 3> Result; 23125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 232e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune if (MI->getOpcode() == AMDGPU::DOT_4) { 2335e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard static const unsigned OpTable[8][2] = { 2345e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0_X, AMDGPU::OpName::src0_sel_X}, 2355e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0_Y, AMDGPU::OpName::src0_sel_Y}, 2365e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0_Z, AMDGPU::OpName::src0_sel_Z}, 2375e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0_W, AMDGPU::OpName::src0_sel_W}, 2385e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1_X, AMDGPU::OpName::src1_sel_X}, 2395e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1_Y, AMDGPU::OpName::src1_sel_Y}, 2405e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1_Z, AMDGPU::OpName::src1_sel_Z}, 2415e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1_W, AMDGPU::OpName::src1_sel_W}, 242e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune }; 243e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 244e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune for (unsigned j = 0; j < 8; j++) { 2455e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard MachineOperand &MO = MI->getOperand(getOperandIdx(MI->getOpcode(), 2465e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OpTable[j][0])); 247e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune unsigned Reg = MO.getReg(); 248e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune if (Reg == AMDGPU::ALU_CONST) { 2495e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard unsigned Sel = MI->getOperand(getOperandIdx(MI->getOpcode(), 2505e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OpTable[j][1])).getImm(); 251e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, Sel)); 252e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune continue; 253e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune } 254e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 255e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune } 256e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune return Result; 257e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune } 258e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 2595e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard static const unsigned OpTable[3][2] = { 2605e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0, AMDGPU::OpName::src0_sel}, 2615e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1, AMDGPU::OpName::src1_sel}, 2625e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src2, AMDGPU::OpName::src2_sel}, 26325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune }; 26425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 26525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned j = 0; j < 3; j++) { 26625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune int SrcIdx = getOperandIdx(MI->getOpcode(), OpTable[j][0]); 26725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (SrcIdx < 0) 26825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 26925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune MachineOperand &MO = MI->getOperand(SrcIdx); 27025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Reg = MI->getOperand(SrcIdx).getReg(); 27125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Reg == AMDGPU::ALU_CONST) { 27225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Sel = MI->getOperand( 27325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune getOperandIdx(MI->getOpcode(), OpTable[j][1])).getImm(); 27425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, Sel)); 27525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 27625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 27725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Reg == AMDGPU::ALU_LITERAL_X) { 27825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Imm = MI->getOperand( 2795e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard getOperandIdx(MI->getOpcode(), AMDGPU::OpName::literal)).getImm(); 28025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, Imm)); 28125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 28225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 28325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, 0)); 28425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 28525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return Result; 28625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 28725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 28825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunestd::vector<std::pair<int, unsigned> > 28925c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneR600InstrInfo::ExtractSrcs(MachineInstr *MI, 2908f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const DenseMap<unsigned, unsigned> &PV, 2918f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned &ConstCount) const { 2928f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ConstCount = 0; 29325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const SmallVector<std::pair<MachineOperand *, int64_t>, 3> Srcs = getSrcs(MI); 29425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const std::pair<int, unsigned> DummyPair(-1, 0); 29525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::vector<std::pair<int, unsigned> > Result; 29625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned i = 0; 29725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned n = Srcs.size(); i < n; ++i) { 29825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Reg = Srcs[i].first->getReg(); 29925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Index = RI.getEncodingValue(Reg) & 0xff; 300e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard if (Reg == AMDGPU::OQAP) { 301e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard Result.push_back(std::pair<int, unsigned>(Index, 0)); 302e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard } 3038f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (PV.find(Reg) != PV.end()) { 3048f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune // 255 is used to tells its a PS/PV reg 3058f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune Result.push_back(std::pair<int, unsigned>(255, 0)); 30625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 30725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 3088f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Index > 127) { 3098f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ConstCount++; 31025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(DummyPair); 31125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 31225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 3138f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Chan = RI.getHWRegChan(Reg); 31425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(std::pair<int, unsigned>(Index, Chan)); 31525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 31625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (; i < 3; ++i) 31725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(DummyPair); 31825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return Result; 31925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 32025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 32125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunestatic std::vector<std::pair<int, unsigned> > 32225c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneSwizzle(std::vector<std::pair<int, unsigned> > Src, 32325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune R600InstrInfo::BankSwizzle Swz) { 32425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune switch (Swz) { 3257d1a0d4e3ebf058a8b1d0dea9b6119444ed041c8Vincent Lejeune case R600InstrInfo::ALU_VEC_012_SCL_210: 32625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 3277d1a0d4e3ebf058a8b1d0dea9b6119444ed041c8Vincent Lejeune case R600InstrInfo::ALU_VEC_021_SCL_122: 32825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[1], Src[2]); 32925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 3307d1a0d4e3ebf058a8b1d0dea9b6119444ed041c8Vincent Lejeune case R600InstrInfo::ALU_VEC_102_SCL_221: 33125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[1]); 33225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 3337d1a0d4e3ebf058a8b1d0dea9b6119444ed041c8Vincent Lejeune case R600InstrInfo::ALU_VEC_120_SCL_212: 33425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[1]); 33525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[2]); 33625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 33725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune case R600InstrInfo::ALU_VEC_201: 33825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[2]); 33925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[1]); 34025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 34125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune case R600InstrInfo::ALU_VEC_210: 34225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[2]); 34325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 34425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 34525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return Src; 34625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 34725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 3488f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunestatic unsigned 3498f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent LejeunegetTransSwizzle(R600InstrInfo::BankSwizzle Swz, unsigned Op) { 3508f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune switch (Swz) { 3518f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune case R600InstrInfo::ALU_VEC_012_SCL_210: { 3528f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Cycles[3] = { 2, 1, 0}; 3538f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return Cycles[Op]; 3548f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 3558f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune case R600InstrInfo::ALU_VEC_021_SCL_122: { 3568f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Cycles[3] = { 1, 2, 2}; 3578f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return Cycles[Op]; 3588f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 3598f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune case R600InstrInfo::ALU_VEC_120_SCL_212: { 3608f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Cycles[3] = { 2, 1, 2}; 3618f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return Cycles[Op]; 3628f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 3638f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune case R600InstrInfo::ALU_VEC_102_SCL_221: { 3648f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Cycles[3] = { 2, 2, 1}; 3658f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return Cycles[Op]; 3668f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 3678f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune default: 3688f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune llvm_unreachable("Wrong Swizzle for Trans Slot"); 3698f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return 0; 3708f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 3718f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune} 3728f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune 3738f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// returns how many MIs (whose inputs are represented by IGSrcs) can be packed 3748f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// in the same Instruction Group while meeting read port limitations given a 3758f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// Swz swizzle sequence. 3768f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeuneunsigned R600InstrInfo::isLegalUpTo( 3778f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs, 3788f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::vector<R600InstrInfo::BankSwizzle> &Swz, 3798f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::vector<std::pair<int, unsigned> > &TransSrcs, 3808f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune R600InstrInfo::BankSwizzle TransSwz) const { 38125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune int Vector[4][3]; 38225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune memset(Vector, -1, sizeof(Vector)); 3838f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune for (unsigned i = 0, e = IGSrcs.size(); i < e; i++) { 38425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const std::vector<std::pair<int, unsigned> > &Srcs = 38525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Swizzle(IGSrcs[i], Swz[i]); 38625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned j = 0; j < 3; j++) { 38725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const std::pair<int, unsigned> &Src = Srcs[j]; 3888f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Src.first < 0 || Src.first == 255) 38925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 390e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard if (Src.first == GET_REG_INDEX(RI.getEncodingValue(AMDGPU::OQAP))) { 3918f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Swz[i] != R600InstrInfo::ALU_VEC_012_SCL_210 && 3928f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune Swz[i] != R600InstrInfo::ALU_VEC_021_SCL_122) { 393e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard // The value from output queue A (denoted by register OQAP) can 394e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard // only be fetched during the first cycle. 395e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard return false; 396e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard } 397e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard // OQAP does not count towards the normal read port restrictions 398e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard continue; 399e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard } 40025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Vector[Src.second][j] < 0) 40125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Vector[Src.second][j] = Src.first; 40225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Vector[Src.second][j] != Src.first) 4038f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return i; 40425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 40525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 4068f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune // Now check Trans Alu 4078f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune for (unsigned i = 0, e = TransSrcs.size(); i < e; ++i) { 4088f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::pair<int, unsigned> &Src = TransSrcs[i]; 4098f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Cycle = getTransSwizzle(TransSwz, i); 4108f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Src.first < 0) 4118f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune continue; 4128f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Src.first == 255) 4138f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune continue; 4148f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Vector[Src.second][Cycle] < 0) 4158f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune Vector[Src.second][Cycle] = Src.first; 4168f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Vector[Src.second][Cycle] != Src.first) 4178f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return IGSrcs.size() - 1; 4188f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 4198f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return IGSrcs.size(); 42025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 42125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 4228f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// Given a swizzle sequence SwzCandidate and an index Idx, returns the next 4238f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// (in lexicographic term) swizzle sequence assuming that all swizzles after 4248f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// Idx can be skipped 4258f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunestatic bool 4268f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent LejeuneNextPossibleSolution( 4278f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate, 4288f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Idx) { 4298f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune assert(Idx < SwzCandidate.size()); 4308f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune int ResetIdx = Idx; 4318f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune while (ResetIdx > -1 && SwzCandidate[ResetIdx] == R600InstrInfo::ALU_VEC_210) 4328f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ResetIdx --; 4338f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune for (unsigned i = ResetIdx + 1, e = SwzCandidate.size(); i < e; i++) { 4348f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune SwzCandidate[i] = R600InstrInfo::ALU_VEC_012_SCL_210; 4358f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 4368f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (ResetIdx == -1) 43725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return false; 43897daabf318ff4751aca49bc1c334d2553b125671Benjamin Kramer int NextSwizzle = SwzCandidate[ResetIdx] + 1; 43997daabf318ff4751aca49bc1c334d2553b125671Benjamin Kramer SwzCandidate[ResetIdx] = (R600InstrInfo::BankSwizzle)NextSwizzle; 4408f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return true; 4418f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune} 4428f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune 4438f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// Enumerate all possible Swizzle sequence to find one that can meet all 4448f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// read port requirements. 4458f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunebool R600InstrInfo::FindSwizzleForVectorSlot( 4468f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs, 4478f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate, 4488f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::vector<std::pair<int, unsigned> > &TransSrcs, 4498f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune R600InstrInfo::BankSwizzle TransSwz) const { 4508f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned ValidUpTo = 0; 4518f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune do { 4528f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ValidUpTo = isLegalUpTo(IGSrcs, SwzCandidate, TransSrcs, TransSwz); 4538f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (ValidUpTo == IGSrcs.size()) 45425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return true; 4558f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } while (NextPossibleSolution(SwzCandidate, ValidUpTo)); 45625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return false; 45725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 45825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 4598f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// Instructions in Trans slot can't read gpr at cycle 0 if they also read 4608f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// a const, and can't read a gpr at cycle 1 if they read 2 const. 4618f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunestatic bool 4628f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent LejeuneisConstCompatible(R600InstrInfo::BankSwizzle TransSwz, 4638f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::vector<std::pair<int, unsigned> > &TransOps, 4648f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned ConstCount) { 4658f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune for (unsigned i = 0, e = TransOps.size(); i < e; ++i) { 4668f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::pair<int, unsigned> &Src = TransOps[i]; 4678f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Cycle = getTransSwizzle(TransSwz, i); 4688f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Src.first < 0) 4698f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune continue; 4708f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (ConstCount > 0 && Cycle == 0) 4718f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return false; 4728f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (ConstCount > 1 && Cycle == 1) 4738f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return false; 4748f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 4758f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return true; 4768f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune} 4778f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune 47825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunebool 47925c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneR600InstrInfo::fitsReadPortLimitations(const std::vector<MachineInstr *> &IG, 4808f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const DenseMap<unsigned, unsigned> &PV, 4818f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune std::vector<BankSwizzle> &ValidSwizzle, 4828f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune bool isLastAluTrans) 48325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const { 48425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune //Todo : support shared src0 - src1 operand 48525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 48625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::vector<std::vector<std::pair<int, unsigned> > > IGSrcs; 48725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune ValidSwizzle.clear(); 4888f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned ConstCount; 489c36a8d2b3d6e543de8d9f210ecd39a9a0641d826Vincent Lejeune BankSwizzle TransBS = ALU_VEC_012_SCL_210; 49025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned i = 0, e = IG.size(); i < e; ++i) { 4918f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune IGSrcs.push_back(ExtractSrcs(IG[i], PV, ConstCount)); 49225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Op = getOperandIdx(IG[i]->getOpcode(), 4935e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::bank_swizzle); 49425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune ValidSwizzle.push_back( (R600InstrInfo::BankSwizzle) 49525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune IG[i]->getOperand(Op).getImm()); 49625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 4978f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune std::vector<std::pair<int, unsigned> > TransOps; 4988f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (!isLastAluTrans) 4998f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return FindSwizzleForVectorSlot(IGSrcs, ValidSwizzle, TransOps, TransBS); 5008f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune 5018f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune TransOps = IGSrcs.back(); 5028f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune IGSrcs.pop_back(); 5038f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ValidSwizzle.pop_back(); 5048f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune 5058f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune static const R600InstrInfo::BankSwizzle TransSwz[] = { 5068f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ALU_VEC_012_SCL_210, 5078f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ALU_VEC_021_SCL_122, 5088f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ALU_VEC_120_SCL_212, 5098f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ALU_VEC_102_SCL_221 5108f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune }; 5118f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune for (unsigned i = 0; i < 4; i++) { 5128f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune TransBS = TransSwz[i]; 5138f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (!isConstCompatible(TransBS, TransOps, ConstCount)) 5148f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune continue; 5158f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune bool Result = FindSwizzleForVectorSlot(IGSrcs, ValidSwizzle, TransOps, 5168f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune TransBS); 5178f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Result) { 5188f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ValidSwizzle.push_back(TransBS); 5198f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return true; 5208f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 5218f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 5228f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune 5238f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return false; 52425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 52525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 52625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 5273ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeunebool 5283ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent LejeuneR600InstrInfo::fitsConstReadLimitations(const std::vector<unsigned> &Consts) 5293ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune const { 5303ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune assert (Consts.size() <= 12 && "Too many operands in instructions group"); 5313ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned Pair1 = 0, Pair2 = 0; 5323ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune for (unsigned i = 0, n = Consts.size(); i < n; ++i) { 5333ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned ReadConstHalf = Consts[i] & 2; 5343ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned ReadConstIndex = Consts[i] & (~3); 5353ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned ReadHalfConst = ReadConstIndex | ReadConstHalf; 5363ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (!Pair1) { 5373ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune Pair1 = ReadHalfConst; 5383ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 5393ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 5403ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (Pair1 == ReadHalfConst) 5413ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 5423ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (!Pair2) { 5433ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune Pair2 = ReadHalfConst; 5443ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 5453ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 5463ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (Pair2 != ReadHalfConst) 5473ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune return false; 5483ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 5493ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune return true; 5503ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune} 5513ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 5523ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeunebool 5538f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent LejeuneR600InstrInfo::fitsConstReadLimitations(const std::vector<MachineInstr *> &MIs) 5548f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const { 5553ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune std::vector<unsigned> Consts; 5568e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune SmallSet<int64_t, 4> Literals; 5573ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune for (unsigned i = 0, n = MIs.size(); i < n; i++) { 55825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune MachineInstr *MI = MIs[i]; 5593ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (!isALUInstr(MI->getOpcode())) 5603ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 5613ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 562a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper const SmallVectorImpl<std::pair<MachineOperand *, int64_t> > &Srcs = 56325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune getSrcs(MI); 56425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 56525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned j = 0, e = Srcs.size(); j < e; j++) { 56625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::pair<MachineOperand *, unsigned> Src = Srcs[j]; 5678e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune if (Src.first->getReg() == AMDGPU::ALU_LITERAL_X) 5688e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune Literals.insert(Src.second); 5698e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune if (Literals.size() > 4) 5708e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune return false; 57125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Src.first->getReg() == AMDGPU::ALU_CONST) 57225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Consts.push_back(Src.second); 57325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (AMDGPU::R600_KC0RegClass.contains(Src.first->getReg()) || 57425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune AMDGPU::R600_KC1RegClass.contains(Src.first->getReg())) { 57525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Index = RI.getEncodingValue(Src.first->getReg()) & 0xff; 57625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Chan = RI.getHWRegChan(Src.first->getReg()); 57725f259cde28860ea76c2f5628010968945a28edbVincent Lejeune Consts.push_back((Index << 2) | Chan); 5783ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 5793ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 5803ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 5813ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune return fitsConstReadLimitations(Consts); 5823ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune} 5833ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 584f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardDFAPacketizer *R600InstrInfo::CreateTargetScheduleState(const TargetMachine *TM, 585f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const ScheduleDAG *DAG) const { 586f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const InstrItineraryData *II = TM->getInstrItineraryData(); 587f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return TM->getSubtarget<AMDGPUSubtarget>().createDFAPacketizer(II); 588f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 589f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 590f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic bool 591f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardisPredicateSetter(unsigned Opcode) { 592f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Opcode) { 593f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_X: 594f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 595f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 596f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 597f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 598f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 599f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 600f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic MachineInstr * 601f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardfindFirstPredicateSetterFrom(MachineBasicBlock &MBB, 602f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I) { 603f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard while (I != MBB.begin()) { 604f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 605f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *MI = I; 606f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isPredicateSetter(MI->getOpcode())) 607f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MI; 608f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 609f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 610f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return NULL; 611f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 612f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 613fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeunestatic 614fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeunebool isJump(unsigned Opcode) { 615fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune return Opcode == AMDGPU::JUMP || Opcode == AMDGPU::JUMP_COND; 616fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune} 617fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune 618f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 619f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 620f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *&TBB, 621f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *&FBB, 622f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<MachineOperand> &Cond, 623f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool AllowModify) const { 624f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Most of the following comes from the ARM implementation of AnalyzeBranch 625f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 626f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If the block has no terminators, it just falls into the block after it. 627f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I = MBB.end(); 628f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) 629f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 630f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 631f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard while (I->isDebugValue()) { 632f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) 633f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 634f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 635f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 636fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune if (!isJump(static_cast<MachineInstr *>(I)->getOpcode())) { 637f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 638f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 639f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 640f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Get the last instruction in the block. 641f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *LastInst = I; 642f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 643f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If there is only one terminator instruction, process it. 644f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned LastOpc = LastInst->getOpcode(); 645f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin() || 646fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune !isJump(static_cast<MachineInstr *>(--I)->getOpcode())) { 647f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (LastOpc == AMDGPU::JUMP) { 648fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune TBB = LastInst->getOperand(0).getMBB(); 649fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune return false; 650fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune } else if (LastOpc == AMDGPU::JUMP_COND) { 651fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune MachineInstr *predSet = I; 652fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune while (!isPredicateSetter(predSet->getOpcode())) { 653fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune predSet = --I; 654f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 655fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune TBB = LastInst->getOperand(0).getMBB(); 656fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune Cond.push_back(predSet->getOperand(1)); 657fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune Cond.push_back(predSet->getOperand(2)); 658fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune Cond.push_back(MachineOperand::CreateReg(AMDGPU::PRED_SEL_ONE, false)); 659fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune return false; 660f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 661f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; // Can't handle indirect branch. 662f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 663f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 664f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Get the instruction before it if it is a terminator. 665f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *SecondLastInst = I; 666f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned SecondLastOpc = SecondLastInst->getOpcode(); 667f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 668f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If the block ends with a B and a Bcc, handle it. 669fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune if (SecondLastOpc == AMDGPU::JUMP_COND && LastOpc == AMDGPU::JUMP) { 670f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *predSet = --I; 671f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard while (!isPredicateSetter(predSet->getOpcode())) { 672f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard predSet = --I; 673f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 674f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TBB = SecondLastInst->getOperand(0).getMBB(); 675f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FBB = LastInst->getOperand(0).getMBB(); 676f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond.push_back(predSet->getOperand(1)); 677f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond.push_back(predSet->getOperand(2)); 678f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond.push_back(MachineOperand::CreateReg(AMDGPU::PRED_SEL_ONE, false)); 679f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 680f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 681f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 682f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Otherwise, can't handle this. 683f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 684f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 685f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 686f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardint R600InstrInfo::getBranchInstr(const MachineOperand &op) const { 687f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MachineInstr *MI = op.getParent(); 688f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 689f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (MI->getDesc().OpInfo->RegClass) { 690f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: // FIXME: fallthrough?? 691f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::GPRI32RegClassID: return AMDGPU::BRANCH_COND_i32; 692f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::GPRF32RegClassID: return AMDGPU::BRANCH_COND_f32; 693f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard }; 694f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 695f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 696f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeunestatic 697f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent LejeuneMachineBasicBlock::iterator FindLastAluClause(MachineBasicBlock &MBB) { 698f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune for (MachineBasicBlock::reverse_iterator It = MBB.rbegin(), E = MBB.rend(); 699f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune It != E; ++It) { 700f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (It->getOpcode() == AMDGPU::CF_ALU || 701f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune It->getOpcode() == AMDGPU::CF_ALU_PUSH_BEFORE) 702f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return llvm::prior(It.base()); 703f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune } 704f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return MBB.end(); 705f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune} 706f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune 707f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned 708f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::InsertBranch(MachineBasicBlock &MBB, 709f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *TBB, 710f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *FBB, 711f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SmallVectorImpl<MachineOperand> &Cond, 712f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL) const { 713f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 714f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 715f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (FBB == 0) { 716f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Cond.empty()) { 717fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP)).addMBB(TBB); 718f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 719f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 720f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end()); 721f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(PredSet && "No previous predicate !"); 722f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addFlag(PredSet, 0, MO_FLAG_PUSH); 723f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PredSet->getOperand(2).setImm(Cond[1].getImm()); 724f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 725fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP_COND)) 726f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addMBB(TBB) 727f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); 728f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB); 729f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (CfAlu == MBB.end()) 730f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return 1; 731f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune assert (CfAlu->getOpcode() == AMDGPU::CF_ALU); 732f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune CfAlu->setDesc(get(AMDGPU::CF_ALU_PUSH_BEFORE)); 733f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 734f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 735f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 736f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end()); 737f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(PredSet && "No previous predicate !"); 738f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addFlag(PredSet, 0, MO_FLAG_PUSH); 739f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PredSet->getOperand(2).setImm(Cond[1].getImm()); 740fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP_COND)) 741f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addMBB(TBB) 742f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); 743fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP)).addMBB(FBB); 744f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB); 745f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (CfAlu == MBB.end()) 746f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return 2; 747f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune assert (CfAlu->getOpcode() == AMDGPU::CF_ALU); 748f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune CfAlu->setDesc(get(AMDGPU::CF_ALU_PUSH_BEFORE)); 749f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 2; 750f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 751f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 752f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 753f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned 754f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 755f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 756f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Note : we leave PRED* instructions there. 757f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // They may be needed when predicating instructions. 758f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 759f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I = MBB.end(); 760f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 761f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) { 762f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 0; 763f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 764f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 765f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (I->getOpcode()) { 766f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 767f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 0; 768fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune case AMDGPU::JUMP_COND: { 769fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I); 770fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune clearFlag(predSet, 0, MO_FLAG_PUSH); 771fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune I->eraseFromParent(); 772f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB); 773f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (CfAlu == MBB.end()) 774f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune break; 775f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune assert (CfAlu->getOpcode() == AMDGPU::CF_ALU_PUSH_BEFORE); 776f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune CfAlu->setDesc(get(AMDGPU::CF_ALU)); 777fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune break; 778fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune } 779f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::JUMP: 780f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard I->eraseFromParent(); 781f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 782f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 783f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard I = MBB.end(); 784f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 785f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) { 786f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 787f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 788f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 789f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (I->getOpcode()) { 790f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // FIXME: only one case?? 791f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 792f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 793fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune case AMDGPU::JUMP_COND: { 794fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I); 795fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune clearFlag(predSet, 0, MO_FLAG_PUSH); 796fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune I->eraseFromParent(); 797f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB); 798f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (CfAlu == MBB.end()) 799f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune break; 800f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune assert (CfAlu->getOpcode() == AMDGPU::CF_ALU_PUSH_BEFORE); 801f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune CfAlu->setDesc(get(AMDGPU::CF_ALU)); 802fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune break; 803fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune } 804f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::JUMP: 805f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard I->eraseFromParent(); 806f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 807f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 808f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 2; 809f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 810f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 811f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 812f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isPredicated(const MachineInstr *MI) const { 813f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int idx = MI->findFirstPredOperandIdx(); 814f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (idx < 0) 815f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 816f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 817f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Reg = MI->getOperand(idx).getReg(); 818f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Reg) { 819f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 820f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ONE: 821f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ZERO: 822f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PREDICATE_BIT: 823f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 824f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 825f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 826f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 827f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 828f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isPredicable(MachineInstr *MI) const { 829f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // XXX: KILL* instructions can be predicated, but they must be the last 830f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // instruction in a clause, so this means any instructions after them cannot 831f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // be predicated. Until we have proper support for instruction clauses in the 832f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // backend, we will mark KILL* instructions as unpredicable. 833f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 834f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (MI->getOpcode() == AMDGPU::KILLGT) { 835f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 836f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune } else if (MI->getOpcode() == AMDGPU::CF_ALU) { 837f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune // If the clause start in the middle of MBB then the MBB has more 838f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune // than a single clause, unable to predicate several clauses. 839f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (MI->getParent()->begin() != MachineBasicBlock::iterator(MI)) 840f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return false; 841f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune // TODO: We don't support KC merging atm 842f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (MI->getOperand(3).getImm() != 0 || MI->getOperand(4).getImm() != 0) 843f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return false; 844f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return true; 84562b0a9b1e6189947b7e46df1b64968e66476c912Vincent Lejeune } else if (isVector(*MI)) { 84662b0a9b1e6189947b7e46df1b64968e66476c912Vincent Lejeune return false; 847f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 848f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return AMDGPUInstrInfo::isPredicable(MI); 849f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 850f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 851f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 852f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 853f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 854f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB, 855f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumCyles, 856f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ExtraPredCycles, 857f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const BranchProbability &Probability) const{ 858f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 859f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 860f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 861f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 862f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB, 863f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumTCycles, 864f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ExtraTCycles, 865f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock &FMBB, 866f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumFCycles, 867f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ExtraFCycles, 868f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const BranchProbability &Probability) const { 869f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 870f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 871f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 872f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 873f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB, 874f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumCyles, 875f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const BranchProbability &Probability) 876f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const { 877f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 878f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 879f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 880f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 881f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToUnpredicate(MachineBasicBlock &TMBB, 882f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock &FMBB) const { 883f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 884f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 885f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 886f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 887f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 888f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 889f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &MO = Cond[1]; 890f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (MO.getImm()) { 891f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_ZERO_INT: 892f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_NOT_ZERO_INT); 893f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 894f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_NOT_ZERO_INT: 895f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_ZERO_INT); 896f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 897f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_ZERO: 898f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_NOT_ZERO); 899f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 900f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_NOT_ZERO: 901f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_ZERO); 902f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 903f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 904f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 905f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 906f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 907f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &MO2 = Cond[2]; 908f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (MO2.getReg()) { 909f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ZERO: 910f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO2.setReg(AMDGPU::PRED_SEL_ONE); 911f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 912f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ONE: 913f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO2.setReg(AMDGPU::PRED_SEL_ZERO); 914f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 915f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 916f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 917f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 918f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 919f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 920f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 921f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 922f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::DefinesPredicate(MachineInstr *MI, 923f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard std::vector<MachineOperand> &Pred) const { 924f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return isPredicateSetter(MI->getOpcode()); 925f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 926f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 927f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 928f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 929f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 930f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SmallVectorImpl<MachineOperand> &Pred2) const { 931f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 932f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 933f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 934f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 935f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 936f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::PredicateInstruction(MachineInstr *MI, 937f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SmallVectorImpl<MachineOperand> &Pred) const { 938f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int PIdx = MI->findFirstPredOperandIdx(); 939f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 940f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (MI->getOpcode() == AMDGPU::CF_ALU) { 941f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune MI->getOperand(8).setImm(0); 942f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return true; 943f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune } 944f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune 945f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (PIdx != -1) { 946f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &PMO = MI->getOperand(PIdx); 947f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PMO.setReg(Pred[2].getReg()); 9486b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MachineInstrBuilder MIB(*MI->getParent()->getParent(), MI); 9496b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MIB.addReg(AMDGPU::PREDICATE_BIT, RegState::Implicit); 950f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 951f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 952f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 953f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 954f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 955f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 956f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned int R600InstrInfo::getInstrLatency(const InstrItineraryData *ItinData, 957f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MachineInstr *MI, 958f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned *PredCost) const { 959f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (PredCost) 960f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard *PredCost = 2; 961f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 2; 962f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 963f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 964c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardint R600InstrInfo::getIndirectIndexBegin(const MachineFunction &MF) const { 965c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineRegisterInfo &MRI = MF.getRegInfo(); 966c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineFrameInfo *MFI = MF.getFrameInfo(); 967c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard int Offset = 0; 968c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 969c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (MFI->getNumObjects() == 0) { 970c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return -1; 971c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 972c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 973c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (MRI.livein_empty()) { 974c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return 0; 975c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 976c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 977c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (MachineRegisterInfo::livein_iterator LI = MRI.livein_begin(), 978c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard LE = MRI.livein_end(); 979c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard LI != LE; ++LI) { 980c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Offset = std::max(Offset, 981c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard GET_REG_INDEX(RI.getEncodingValue(LI->first))); 982c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 983c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 984c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Offset + 1; 985c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 986c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 987c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardint R600InstrInfo::getIndirectIndexEnd(const MachineFunction &MF) const { 988c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard int Offset = 0; 989c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineFrameInfo *MFI = MF.getFrameInfo(); 990c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 991c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // Variable sized objects are not supported 992c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard assert(!MFI->hasVarSizedObjects()); 993c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 994c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (MFI->getNumObjects() == 0) { 995c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return -1; 996c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 997c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 998c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Offset = TM.getFrameLowering()->getFrameIndexOffset(MF, -1); 999c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1000c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return getIndirectIndexBegin(MF) + Offset; 1001c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 1002c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1003c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardstd::vector<unsigned> R600InstrInfo::getIndirectReservedRegs( 1004c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineFunction &MF) const { 1005c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const AMDGPUFrameLowering *TFL = 1006c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard static_cast<const AMDGPUFrameLowering*>(TM.getFrameLowering()); 1007c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard std::vector<unsigned> Regs; 1008c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1009c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned StackWidth = TFL->getStackWidth(MF); 1010c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard int End = getIndirectIndexEnd(MF); 1011c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1012c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (End == -1) { 1013c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Regs; 1014c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 1015c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1016c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (int Index = getIndirectIndexBegin(MF); Index <= End; ++Index) { 1017c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned SuperReg = AMDGPU::R600_Reg128RegClass.getRegister(Index); 1018c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Regs.push_back(SuperReg); 1019c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (unsigned Chan = 0; Chan < StackWidth; ++Chan) { 1020c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister((4 * Index) + Chan); 1021c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Regs.push_back(Reg); 1022c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 1023c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 1024c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Regs; 1025c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 1026c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1027c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardunsigned R600InstrInfo::calculateIndirectAddress(unsigned RegIndex, 1028c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned Channel) const { 1029c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // XXX: Remove when we support a stack width > 2 1030c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard assert(Channel == 0); 1031c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return RegIndex; 1032c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 1033c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1034c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardconst TargetRegisterClass * R600InstrInfo::getIndirectAddrStoreRegClass( 1035c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned SourceReg) const { 1036c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return &AMDGPU::R600_TReg32RegClass; 1037c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 1038c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1039c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardconst TargetRegisterClass *R600InstrInfo::getIndirectAddrLoadRegClass() const { 1040c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return &AMDGPU::TRegMemRegClass; 1041c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 1042c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1043c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardMachineInstrBuilder R600InstrInfo::buildIndirectWrite(MachineBasicBlock *MBB, 1044c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineBasicBlock::iterator I, 1045c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned ValueReg, unsigned Address, 1046c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned OffsetReg) const { 1047c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address); 1048c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, AMDGPU::MOVA_INT_eg, 1049c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AMDGPU::AR_X, OffsetReg); 10505e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(MOVA, AMDGPU::OpName::write, 0); 1051c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1052c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, AMDGPU::MOV, 1053c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AddrReg, ValueReg) 1054ad7ecc65b1b1d6466ff035168c86f208a91aa1b4Tom Stellard .addReg(AMDGPU::AR_X, 1055ad7ecc65b1b1d6466ff035168c86f208a91aa1b4Tom Stellard RegState::Implicit | RegState::Kill); 10565e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(Mov, AMDGPU::OpName::dst_rel, 1); 1057c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Mov; 1058c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 1059c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1060c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardMachineInstrBuilder R600InstrInfo::buildIndirectRead(MachineBasicBlock *MBB, 1061c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineBasicBlock::iterator I, 1062c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned ValueReg, unsigned Address, 1063c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned OffsetReg) const { 1064c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address); 1065c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, AMDGPU::MOVA_INT_eg, 1066c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AMDGPU::AR_X, 1067c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard OffsetReg); 10685e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(MOVA, AMDGPU::OpName::write, 0); 1069c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, AMDGPU::MOV, 1070c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard ValueReg, 1071c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AddrReg) 1072ad7ecc65b1b1d6466ff035168c86f208a91aa1b4Tom Stellard .addReg(AMDGPU::AR_X, 1073ad7ecc65b1b1d6466ff035168c86f208a91aa1b4Tom Stellard RegState::Implicit | RegState::Kill); 10745e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(Mov, AMDGPU::OpName::src0_rel, 1); 1075c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1076c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Mov; 1077c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 1078c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1079c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardconst TargetRegisterClass *R600InstrInfo::getSuperIndirectRegClass() const { 1080c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return &AMDGPU::IndirectRegRegClass; 1081c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 1082c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1083dae2a20a56b28b4685249982a80a0043b7673e09Vincent Lejeuneunsigned R600InstrInfo::getMaxAlusPerClause() const { 1084dae2a20a56b28b4685249982a80a0043b7673e09Vincent Lejeune return 115; 1085dae2a20a56b28b4685249982a80a0043b7673e09Vincent Lejeune} 1086c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1087f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineInstrBuilder R600InstrInfo::buildDefaultInstruction(MachineBasicBlock &MBB, 1088f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I, 1089f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Opcode, 1090f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned DstReg, 1091f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Src0Reg, 1092f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Src1Reg) const { 1093f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstrBuilder MIB = BuildMI(MBB, I, MBB.findDebugLoc(I), get(Opcode), 1094f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DstReg); // $dst 1095f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1096f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Src1Reg) { 1097f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addImm(0) // $update_exec_mask 1098f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0); // $update_predicate 1099f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1100f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addImm(1) // $write 1101f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $omod 1102f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $dst_rel 1103f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $dst_clamp 1104f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(Src0Reg) // $src0 1105f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src0_neg 1106f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src0_rel 11079f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(0) // $src0_abs 11089f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(-1); // $src0_sel 1109f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1110f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Src1Reg) { 1111f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addReg(Src1Reg) // $src1 1112f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src1_neg 1113f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src1_rel 11149f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(0) // $src1_abs 11159f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(-1); // $src1_sel 1116f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1117f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1118f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard //XXX: The r600g finalizer expects this to be 1, once we've moved the 1119f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard //scheduling to the backend, we can change the default to 0. 1120f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addImm(1) // $last 1121f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PRED_SEL_OFF) // $pred_sel 1122e332e3559b5c09040de1528920006756e0962d6aVincent Lejeune .addImm(0) // $literal 1123e332e3559b5c09040de1528920006756e0962d6aVincent Lejeune .addImm(0); // $bank_swizzle 1124f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1125f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MIB; 1126f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1127f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 11284ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune#define OPERAND_CASE(Label) \ 11294ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune case Label: { \ 11305e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard static const unsigned Ops[] = \ 11314ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune { \ 11324ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Label##_X, \ 11334ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Label##_Y, \ 11344ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Label##_Z, \ 11354ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Label##_W \ 11364ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune }; \ 11374ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune return Ops[Slot]; \ 11384ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune } 11394ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 11405e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellardstatic unsigned getSlotedOps(unsigned Op, unsigned Slot) { 11414ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune switch (Op) { 11425e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::update_exec_mask) 11435e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::update_pred) 11445e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::write) 11455e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::omod) 11465e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::dst_rel) 11475e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::clamp) 11485e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0) 11495e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0_neg) 11505e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0_rel) 11515e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0_abs) 11525e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0_sel) 11535e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1) 11545e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1_neg) 11555e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1_rel) 11565e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1_abs) 11575e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1_sel) 11585e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::pred_sel) 11594ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune default: 11604ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune llvm_unreachable("Wrong Operand"); 11614ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune } 11624ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune} 11634ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 11644ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune#undef OPERAND_CASE 11654ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 11664ed9917147b1d1f2616f7c941bbe6999b979f510Vincent LejeuneMachineInstr *R600InstrInfo::buildSlotOfVectorInstruction( 11674ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineBasicBlock &MBB, MachineInstr *MI, unsigned Slot, unsigned DstReg) 11684ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune const { 11694ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune assert (MI->getOpcode() == AMDGPU::DOT_4 && "Not Implemented"); 11704ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune unsigned Opcode; 11714ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); 11723ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard if (ST.getGeneration() <= AMDGPUSubtarget::R700) 11734ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Opcode = AMDGPU::DOT4_r600; 11744ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune else 11754ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Opcode = AMDGPU::DOT4_eg; 11764ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineBasicBlock::iterator I = MI; 11774ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineOperand &Src0 = MI->getOperand( 11785e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard getOperandIdx(MI->getOpcode(), getSlotedOps(AMDGPU::OpName::src0, Slot))); 11794ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineOperand &Src1 = MI->getOperand( 11805e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard getOperandIdx(MI->getOpcode(), getSlotedOps(AMDGPU::OpName::src1, Slot))); 11814ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineInstr *MIB = buildDefaultInstruction( 11824ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MBB, I, Opcode, DstReg, Src0.getReg(), Src1.getReg()); 11835e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard static const unsigned Operands[14] = { 11845e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::update_exec_mask, 11855e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::update_pred, 11865e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::write, 11875e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::omod, 11885e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::dst_rel, 11895e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::clamp, 11905e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src0_neg, 11915e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src0_rel, 11925e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src0_abs, 11935e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src0_sel, 11945e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src1_neg, 11955e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src1_rel, 11965e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src1_abs, 11975e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src1_sel, 11984ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune }; 11994ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 12004ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune for (unsigned i = 0; i < 14; i++) { 12014ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineOperand &MO = MI->getOperand( 12025e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard getOperandIdx(MI->getOpcode(), getSlotedOps(Operands[i], Slot))); 12034ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune assert (MO.isImm()); 12044ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune setImmOperand(MIB, Operands[i], MO.getImm()); 12054ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune } 12064ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MIB->getOperand(20).setImm(0); 12074ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune return MIB; 12084ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune} 12094ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 1210f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineInstr *R600InstrInfo::buildMovImm(MachineBasicBlock &BB, 1211f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I, 1212f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned DstReg, 1213f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard uint64_t Imm) const { 1214f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *MovImm = buildDefaultInstruction(BB, I, AMDGPU::MOV, DstReg, 1215f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::ALU_LITERAL_X); 12165e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(MovImm, AMDGPU::OpName::literal, Imm); 1217f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MovImm; 1218f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1219f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 12205e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellardint R600InstrInfo::getOperandIdx(const MachineInstr &MI, unsigned Op) const { 1221e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune return getOperandIdx(MI.getOpcode(), Op); 1222e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune} 1223e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 12245e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellardint R600InstrInfo::getOperandIdx(unsigned Opcode, unsigned Op) const { 12255e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard return AMDGPU::getNamedOperandIdx(Opcode, Op); 1226e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune} 1227e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 12285e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellardvoid R600InstrInfo::setImmOperand(MachineInstr *MI, unsigned Op, 1229f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int64_t Imm) const { 1230f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int Idx = getOperandIdx(*MI, Op); 1231f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(Idx != -1 && "Operand not supported for this instruction."); 1232f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(MI->getOperand(Idx).isImm()); 1233f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(Idx).setImm(Imm); 1234f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1235f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1236f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 1237f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Instruction flag getters/setters 1238f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 1239f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1240f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::hasFlagOperand(const MachineInstr &MI) const { 1241f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return GET_FLAG_OPERAND_IDX(get(MI.getOpcode()).TSFlags) != 0; 1242f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1243f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1244f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineOperand &R600InstrInfo::getFlagOp(MachineInstr *MI, unsigned SrcIdx, 1245f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Flag) const { 1246f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(MI->getOpcode()).TSFlags; 1247f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int FlagIndex = 0; 1248f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Flag != 0) { 1249f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If we pass something other than the default value of Flag to this 1250f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // function, it means we are want to set a flag on an instruction 1251f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // that uses native encoding. 1252f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(HAS_NATIVE_OPERANDS(TargetFlags)); 1253f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool IsOP3 = (TargetFlags & R600_InstFlag::OP3) == R600_InstFlag::OP3; 1254f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Flag) { 1255f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_CLAMP: 12565e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::clamp); 1257f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1258f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_MASK: 12595e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::write); 1260f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1261f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_NOT_LAST: 1262f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_LAST: 12635e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::last); 1264f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1265f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_NEG: 1266f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (SrcIdx) { 12675e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 0: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src0_neg); break; 12685e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 1: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src1_neg); break; 12695e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 2: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src2_neg); break; 1270f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1271f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1272f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1273f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_ABS: 1274f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!IsOP3 && "Cannot set absolute value modifier for OP3 " 1275f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard "instructions."); 127608f2d9379c486a0e4b950e476913ee97b38ec333Tom Stellard (void)IsOP3; 1277f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (SrcIdx) { 12785e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 0: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src0_abs); break; 12795e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 1: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src1_abs); break; 1280f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1281f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1282f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1283f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 1284f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagIndex = -1; 1285f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1286f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1287f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(FlagIndex != -1 && "Flag not supported for this instruction"); 1288f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 1289f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagIndex = GET_FLAG_OPERAND_IDX(TargetFlags); 1290f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(FlagIndex != 0 && 1291f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard "Instruction flags not supported for this instruction"); 1292f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1293f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1294f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = MI->getOperand(FlagIndex); 1295f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(FlagOp.isImm()); 1296f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return FlagOp; 1297f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1298f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1299f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid R600InstrInfo::addFlag(MachineInstr *MI, unsigned Operand, 1300f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Flag) const { 1301f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(MI->getOpcode()).TSFlags; 1302f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Flag == 0) { 1303f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return; 1304f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1305f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (HAS_NATIVE_OPERANDS(TargetFlags)) { 1306f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag); 1307f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Flag == MO_FLAG_NOT_LAST) { 1308f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard clearFlag(MI, Operand, MO_FLAG_LAST); 1309f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (Flag == MO_FLAG_MASK) { 1310f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard clearFlag(MI, Operand, Flag); 1311f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 1312f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(1); 1313f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1314f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 1315f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI, Operand); 1316f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(FlagOp.getImm() | (Flag << (NUM_MO_FLAGS * Operand))); 1317f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1318f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1319f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1320f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid R600InstrInfo::clearFlag(MachineInstr *MI, unsigned Operand, 1321f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Flag) const { 1322f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(MI->getOpcode()).TSFlags; 1323f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (HAS_NATIVE_OPERANDS(TargetFlags)) { 1324f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag); 1325f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(0); 1326f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 1327f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI); 1328f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned InstFlags = FlagOp.getImm(); 1329f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard InstFlags &= ~(Flag << (NUM_MO_FLAGS * Operand)); 1330f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(InstFlags); 1331f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1332f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1333