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 26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesusing namespace llvm; 27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 28354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka#define GET_INSTRINFO_CTOR_DTOR 29f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDGPUGenDFAPacketizer.inc" 30f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 31cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesR600InstrInfo::R600InstrInfo(const AMDGPUSubtarget &st) 32cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : AMDGPUInstrInfo(st), 33cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RI(st) 34f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard { } 35f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 36f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardconst R600RegisterInfo &R600InstrInfo::getRegisterInfo() const { 37f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return RI; 38f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 39f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 40f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isTrig(const MachineInstr &MI) const { 41f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return get(MI.getOpcode()).TSFlags & R600_InstFlag::TRIG; 42f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 43f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 44f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isVector(const MachineInstr &MI) const { 45f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return get(MI.getOpcode()).TSFlags & R600_InstFlag::VECTOR; 46f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 47f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 48f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid 49f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 50f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator MI, DebugLoc DL, 51f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned DestReg, unsigned SrcReg, 52f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool KillSrc) const { 53692ee102ebef535d311c35d53457028083e5c5beTom Stellard unsigned VectorComponents = 0; 54cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if ((AMDGPU::R600_Reg128RegClass.contains(DestReg) || 55cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AMDGPU::R600_Reg128VerticalRegClass.contains(DestReg)) && 56cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines (AMDGPU::R600_Reg128RegClass.contains(SrcReg) || 57cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AMDGPU::R600_Reg128VerticalRegClass.contains(SrcReg))) { 58692ee102ebef535d311c35d53457028083e5c5beTom Stellard VectorComponents = 4; 59cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if((AMDGPU::R600_Reg64RegClass.contains(DestReg) || 60cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AMDGPU::R600_Reg64VerticalRegClass.contains(DestReg)) && 61cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines (AMDGPU::R600_Reg64RegClass.contains(SrcReg) || 62cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AMDGPU::R600_Reg64VerticalRegClass.contains(SrcReg))) { 63692ee102ebef535d311c35d53457028083e5c5beTom Stellard VectorComponents = 2; 64692ee102ebef535d311c35d53457028083e5c5beTom Stellard } 65692ee102ebef535d311c35d53457028083e5c5beTom Stellard 66692ee102ebef535d311c35d53457028083e5c5beTom Stellard if (VectorComponents > 0) { 67692ee102ebef535d311c35d53457028083e5c5beTom Stellard for (unsigned I = 0; I < VectorComponents; I++) { 68f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned SubRegIndex = RI.getSubRegFromChannel(I); 69f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard buildDefaultInstruction(MBB, MI, AMDGPU::MOV, 70f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard RI.getSubReg(DestReg, SubRegIndex), 71f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard RI.getSubReg(SrcReg, SubRegIndex)) 72f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(DestReg, 73f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard RegState::Define | RegState::Implicit); 74f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 75f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 76f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *NewMI = buildDefaultInstruction(MBB, MI, AMDGPU::MOV, 77f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DestReg, SrcReg); 785e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard NewMI->getOperand(getOperandIdx(*NewMI, AMDGPU::OpName::src0)) 79f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .setIsKill(KillSrc); 80f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 81f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 82f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 839e78ba4ddcf80e2e292220b4a07a9baba21cfa15Bill Wendling/// \returns true if \p MBBI can be moved into a new basic. 849e78ba4ddcf80e2e292220b4a07a9baba21cfa15Bill Wendlingbool R600InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock &MBB, 859e78ba4ddcf80e2e292220b4a07a9baba21cfa15Bill Wendling MachineBasicBlock::iterator MBBI) const { 869e78ba4ddcf80e2e292220b4a07a9baba21cfa15Bill Wendling for (MachineInstr::const_mop_iterator I = MBBI->operands_begin(), 879e78ba4ddcf80e2e292220b4a07a9baba21cfa15Bill Wendling E = MBBI->operands_end(); I != E; ++I) { 889e78ba4ddcf80e2e292220b4a07a9baba21cfa15Bill Wendling if (I->isReg() && !TargetRegisterInfo::isVirtualRegister(I->getReg()) && 899e78ba4ddcf80e2e292220b4a07a9baba21cfa15Bill Wendling I->isUse() && RI.isPhysRegLiveAcrossClauses(I->getReg())) 909e78ba4ddcf80e2e292220b4a07a9baba21cfa15Bill Wendling return false; 919e78ba4ddcf80e2e292220b4a07a9baba21cfa15Bill Wendling } 929e78ba4ddcf80e2e292220b4a07a9baba21cfa15Bill Wendling return true; 939e78ba4ddcf80e2e292220b4a07a9baba21cfa15Bill Wendling} 949e78ba4ddcf80e2e292220b4a07a9baba21cfa15Bill Wendling 95f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned R600InstrInfo::getIEQOpcode() const { 96f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return AMDGPU::SETE_INT; 97f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 98f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 99f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isMov(unsigned Opcode) const { 100f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 101f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 102f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch(Opcode) { 103f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 104f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MOV: 105f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MOV_IMM_F32: 106f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::MOV_IMM_I32: 107f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 108f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 109f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 110f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 111f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Some instructions act as place holders to emulate operations that the GPU 112f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// hardware does automatically. This function can be used to check if 113f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// an opcode falls into this category. 114f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isPlaceHolderOpcode(unsigned Opcode) const { 115f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Opcode) { 116f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 117f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::RETURN: 118f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 119f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 120f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 121f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 122f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isReductionOp(unsigned Opcode) const { 12380095e5f8e433b7a68fbad4ff460503fd06f84efAaron Ballman return false; 124f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 125f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 126f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isCubeOp(unsigned Opcode) const { 127f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch(Opcode) { 128f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_r600_pseudo: 130f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_r600_real: 131f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_eg_pseudo: 132f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::CUBE_eg_real: 133f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 134f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 135f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 136f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 137f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::isALUInstr(unsigned Opcode) const { 138f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(Opcode).TSFlags; 139f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1407e9381951eb4dadf9c59257786416ac51a6a6c09Tom Stellard return (TargetFlags & R600_InstFlag::ALU_INST); 141f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 142f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 143e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellardbool R600InstrInfo::hasInstrModifiers(unsigned Opcode) const { 144e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard unsigned TargetFlags = get(Opcode).TSFlags; 145e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard 146e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard return ((TargetFlags & R600_InstFlag::OP1) | 147e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard (TargetFlags & R600_InstFlag::OP2) | 148e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard (TargetFlags & R600_InstFlag::OP3)); 149e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard} 150e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard 151e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellardbool R600InstrInfo::isLDSInstr(unsigned Opcode) const { 152e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard unsigned TargetFlags = get(Opcode).TSFlags; 153e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard 154e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard return ((TargetFlags & R600_InstFlag::LDS_1A) | 1558e78012457682d335ee97cf2859dfe03b7e2ae93Tom Stellard (TargetFlags & R600_InstFlag::LDS_1A1D) | 1568e78012457682d335ee97cf2859dfe03b7e2ae93Tom Stellard (TargetFlags & R600_InstFlag::LDS_1A2D)); 157e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard} 158e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard 15919a99df130f5747da950faf4ca5170d71f05594cTom Stellardbool R600InstrInfo::isLDSNoRetInstr(unsigned Opcode) const { 16019a99df130f5747da950faf4ca5170d71f05594cTom Stellard return isLDSInstr(Opcode) && getOperandIdx(Opcode, AMDGPU::OpName::dst) == -1; 16119a99df130f5747da950faf4ca5170d71f05594cTom Stellard} 16219a99df130f5747da950faf4ca5170d71f05594cTom Stellard 16319a99df130f5747da950faf4ca5170d71f05594cTom Stellardbool R600InstrInfo::isLDSRetInstr(unsigned Opcode) const { 16419a99df130f5747da950faf4ca5170d71f05594cTom Stellard return isLDSInstr(Opcode) && getOperandIdx(Opcode, AMDGPU::OpName::dst) != -1; 16519a99df130f5747da950faf4ca5170d71f05594cTom Stellard} 16619a99df130f5747da950faf4ca5170d71f05594cTom Stellard 167dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeunebool R600InstrInfo::canBeConsideredALU(const MachineInstr *MI) const { 168dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune if (isALUInstr(MI->getOpcode())) 169dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune return true; 170dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune if (isVector(*MI) || isCubeOp(MI->getOpcode())) 171dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune return true; 172dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune switch (MI->getOpcode()) { 173dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune case AMDGPU::PRED_X: 174dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune case AMDGPU::INTERP_PAIR_XY: 175dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune case AMDGPU::INTERP_PAIR_ZW: 176dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune case AMDGPU::INTERP_VEC_LOAD: 177dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune case AMDGPU::COPY: 178dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune case AMDGPU::DOT_4: 179dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune return true; 180dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune default: 181dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune return false; 182dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune } 183dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune} 184dfef7cbfc6a96d129b99750f554c7dbc000d3228Vincent Lejeune 185abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeunebool R600InstrInfo::isTransOnly(unsigned Opcode) const { 186b3df27d4402d8c8fc81d5acec812035360806cdcVincent Lejeune if (ST.hasCaymanISA()) 187b3df27d4402d8c8fc81d5acec812035360806cdcVincent Lejeune return false; 188b3df27d4402d8c8fc81d5acec812035360806cdcVincent Lejeune return (get(Opcode).getSchedClass() == AMDGPU::Sched::TransALU); 189abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune} 190abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune 191abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeunebool R600InstrInfo::isTransOnly(const MachineInstr *MI) const { 192abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune return isTransOnly(MI->getOpcode()); 193abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune} 194abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune 195b3df27d4402d8c8fc81d5acec812035360806cdcVincent Lejeunebool R600InstrInfo::isVectorOnly(unsigned Opcode) const { 196b3df27d4402d8c8fc81d5acec812035360806cdcVincent Lejeune return (get(Opcode).getSchedClass() == AMDGPU::Sched::VecALU); 197b3df27d4402d8c8fc81d5acec812035360806cdcVincent Lejeune} 198b3df27d4402d8c8fc81d5acec812035360806cdcVincent Lejeune 199b3df27d4402d8c8fc81d5acec812035360806cdcVincent Lejeunebool R600InstrInfo::isVectorOnly(const MachineInstr *MI) const { 200b3df27d4402d8c8fc81d5acec812035360806cdcVincent Lejeune return isVectorOnly(MI->getOpcode()); 201b3df27d4402d8c8fc81d5acec812035360806cdcVincent Lejeune} 202b3df27d4402d8c8fc81d5acec812035360806cdcVincent Lejeune 203e7ac2ed1c268891a856ab38db1e34372a79da86aTom Stellardbool R600InstrInfo::isExport(unsigned Opcode) const { 204e7ac2ed1c268891a856ab38db1e34372a79da86aTom Stellard return (get(Opcode).TSFlags & R600_InstFlag::IS_EXPORT); 205e7ac2ed1c268891a856ab38db1e34372a79da86aTom Stellard} 206e7ac2ed1c268891a856ab38db1e34372a79da86aTom Stellard 207631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesVertexCache(unsigned Opcode) const { 20832c76107d029c1cad5935d08cdcde6139cf874bbTom Stellard return ST.hasVertexCache() && IS_VTX(get(Opcode)); 209631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 210631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 211631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesVertexCache(const MachineInstr *MI) const { 2124fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune const R600MachineFunctionInfo *MFI = MI->getParent()->getParent()->getInfo<R600MachineFunctionInfo>(); 2134fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune return MFI->ShaderType != ShaderType::COMPUTE && usesVertexCache(MI->getOpcode()); 214631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 215631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 216631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesTextureCache(unsigned Opcode) const { 21732c76107d029c1cad5935d08cdcde6139cf874bbTom Stellard return (!ST.hasVertexCache() && IS_VTX(get(Opcode))) || IS_TEX(get(Opcode)); 218631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 219631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 220631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunebool R600InstrInfo::usesTextureCache(const MachineInstr *MI) const { 2214fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune const R600MachineFunctionInfo *MFI = MI->getParent()->getParent()->getInfo<R600MachineFunctionInfo>(); 2224fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune return (MFI->ShaderType == ShaderType::COMPUTE && usesVertexCache(MI->getOpcode())) || 2234fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune usesTextureCache(MI->getOpcode()); 224631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune} 225631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune 226cedcfee405a22b245e869abe8609f094df34085aTom Stellardbool R600InstrInfo::mustBeLastInClause(unsigned Opcode) const { 227cedcfee405a22b245e869abe8609f094df34085aTom Stellard switch (Opcode) { 228cedcfee405a22b245e869abe8609f094df34085aTom Stellard case AMDGPU::KILLGT: 229cedcfee405a22b245e869abe8609f094df34085aTom Stellard case AMDGPU::GROUP_BARRIER: 230cedcfee405a22b245e869abe8609f094df34085aTom Stellard return true; 231cedcfee405a22b245e869abe8609f094df34085aTom Stellard default: 232cedcfee405a22b245e869abe8609f094df34085aTom Stellard return false; 233cedcfee405a22b245e869abe8609f094df34085aTom Stellard } 234cedcfee405a22b245e869abe8609f094df34085aTom Stellard} 235cedcfee405a22b245e869abe8609f094df34085aTom Stellard 23604c559569f87d755c3f2828a765f5eb7308e6753Tom Stellardbool R600InstrInfo::usesAddressRegister(MachineInstr *MI) const { 23704c559569f87d755c3f2828a765f5eb7308e6753Tom Stellard return MI->findRegisterUseOperandIdx(AMDGPU::AR_X) != -1; 23804c559569f87d755c3f2828a765f5eb7308e6753Tom Stellard} 23904c559569f87d755c3f2828a765f5eb7308e6753Tom Stellard 24004c559569f87d755c3f2828a765f5eb7308e6753Tom Stellardbool R600InstrInfo::definesAddressRegister(MachineInstr *MI) const { 24104c559569f87d755c3f2828a765f5eb7308e6753Tom Stellard return MI->findRegisterDefOperandIdx(AMDGPU::AR_X) != -1; 24204c559569f87d755c3f2828a765f5eb7308e6753Tom Stellard} 24304c559569f87d755c3f2828a765f5eb7308e6753Tom Stellard 244ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellardbool R600InstrInfo::readsLDSSrcReg(const MachineInstr *MI) const { 245ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard if (!isALUInstr(MI->getOpcode())) { 246ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard return false; 247ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard } 248ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard for (MachineInstr::const_mop_iterator I = MI->operands_begin(), 249ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard E = MI->operands_end(); I != E; ++I) { 250ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard if (!I->isReg() || !I->isUse() || 251ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard TargetRegisterInfo::isVirtualRegister(I->getReg())) 252ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard continue; 253ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard 254ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard if (AMDGPU::R600_LDS_SRC_REGRegClass.contains(I->getReg())) 255ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard return true; 256ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard } 257ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard return false; 258ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard} 259ac779b8494ad3d2f2ea40cb566552c0fb1b17363Tom Stellard 26058d3335cb9d2a40bd15c29a12ba045163295190eTom Stellardint R600InstrInfo::getSrcIdx(unsigned Opcode, unsigned SrcNum) const { 26158d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard static const unsigned OpTable[] = { 26258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard AMDGPU::OpName::src0, 26358d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard AMDGPU::OpName::src1, 26458d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard AMDGPU::OpName::src2 26558d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard }; 26658d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard 26758d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard assert (SrcNum < 3); 26858d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard return getOperandIdx(Opcode, OpTable[SrcNum]); 26958d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard} 27058d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard 27158d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard#define SRC_SEL_ROWS 11 27258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellardint R600InstrInfo::getSelIdx(unsigned Opcode, unsigned SrcIdx) const { 27358d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard static const unsigned SrcSelTable[SRC_SEL_ROWS][2] = { 27458d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src0, AMDGPU::OpName::src0_sel}, 27558d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src1, AMDGPU::OpName::src1_sel}, 27658d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src2, AMDGPU::OpName::src2_sel}, 27758d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src0_X, AMDGPU::OpName::src0_sel_X}, 27858d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src0_Y, AMDGPU::OpName::src0_sel_Y}, 27958d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src0_Z, AMDGPU::OpName::src0_sel_Z}, 28058d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src0_W, AMDGPU::OpName::src0_sel_W}, 28158d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src1_X, AMDGPU::OpName::src1_sel_X}, 28258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src1_Y, AMDGPU::OpName::src1_sel_Y}, 28358d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src1_Z, AMDGPU::OpName::src1_sel_Z}, 28458d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard {AMDGPU::OpName::src1_W, AMDGPU::OpName::src1_sel_W} 28558d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard }; 28658d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard 28758d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard for (unsigned i = 0; i < SRC_SEL_ROWS; ++i) { 28858d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard if (getOperandIdx(Opcode, SrcSelTable[i][0]) == (int)SrcIdx) { 28958d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard return getOperandIdx(Opcode, SrcSelTable[i][1]); 29058d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard } 29158d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard } 29258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard return -1; 29358d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard} 29458d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard#undef SRC_SEL_ROWS 29558d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard 29625c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneSmallVector<std::pair<MachineOperand *, int64_t>, 3> 29725c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneR600InstrInfo::getSrcs(MachineInstr *MI) const { 29825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune SmallVector<std::pair<MachineOperand *, int64_t>, 3> Result; 29925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 300e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune if (MI->getOpcode() == AMDGPU::DOT_4) { 3015e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard static const unsigned OpTable[8][2] = { 3025e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0_X, AMDGPU::OpName::src0_sel_X}, 3035e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0_Y, AMDGPU::OpName::src0_sel_Y}, 3045e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0_Z, AMDGPU::OpName::src0_sel_Z}, 3055e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0_W, AMDGPU::OpName::src0_sel_W}, 3065e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1_X, AMDGPU::OpName::src1_sel_X}, 3075e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1_Y, AMDGPU::OpName::src1_sel_Y}, 3085e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1_Z, AMDGPU::OpName::src1_sel_Z}, 3095e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1_W, AMDGPU::OpName::src1_sel_W}, 310e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune }; 311e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 312e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune for (unsigned j = 0; j < 8; j++) { 3135e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard MachineOperand &MO = MI->getOperand(getOperandIdx(MI->getOpcode(), 3145e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OpTable[j][0])); 315e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune unsigned Reg = MO.getReg(); 316e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune if (Reg == AMDGPU::ALU_CONST) { 3175e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard unsigned Sel = MI->getOperand(getOperandIdx(MI->getOpcode(), 3185e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OpTable[j][1])).getImm(); 319e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, Sel)); 320e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune continue; 321e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune } 322e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 323e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune } 324e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune return Result; 325e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune } 326e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 3275e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard static const unsigned OpTable[3][2] = { 3285e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src0, AMDGPU::OpName::src0_sel}, 3295e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src1, AMDGPU::OpName::src1_sel}, 3305e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard {AMDGPU::OpName::src2, AMDGPU::OpName::src2_sel}, 33125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune }; 33225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 33325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned j = 0; j < 3; j++) { 33425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune int SrcIdx = getOperandIdx(MI->getOpcode(), OpTable[j][0]); 33525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (SrcIdx < 0) 33625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 33725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune MachineOperand &MO = MI->getOperand(SrcIdx); 33825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Reg = MI->getOperand(SrcIdx).getReg(); 33925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Reg == AMDGPU::ALU_CONST) { 34025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Sel = MI->getOperand( 34125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune getOperandIdx(MI->getOpcode(), OpTable[j][1])).getImm(); 34225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, Sel)); 34325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 34425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 34525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Reg == AMDGPU::ALU_LITERAL_X) { 34625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Imm = MI->getOperand( 3475e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard getOperandIdx(MI->getOpcode(), AMDGPU::OpName::literal)).getImm(); 34825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, Imm)); 34925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 35025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 35125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(std::pair<MachineOperand *, int64_t>(&MO, 0)); 35225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 35325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return Result; 35425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 35525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 35625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunestd::vector<std::pair<int, unsigned> > 35725c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneR600InstrInfo::ExtractSrcs(MachineInstr *MI, 3588f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const DenseMap<unsigned, unsigned> &PV, 3598f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned &ConstCount) const { 3608f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ConstCount = 0; 36125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const SmallVector<std::pair<MachineOperand *, int64_t>, 3> Srcs = getSrcs(MI); 36225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const std::pair<int, unsigned> DummyPair(-1, 0); 36325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::vector<std::pair<int, unsigned> > Result; 36425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned i = 0; 36525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned n = Srcs.size(); i < n; ++i) { 36625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Reg = Srcs[i].first->getReg(); 36725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Index = RI.getEncodingValue(Reg) & 0xff; 368e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard if (Reg == AMDGPU::OQAP) { 369e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard Result.push_back(std::pair<int, unsigned>(Index, 0)); 370e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard } 3718f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (PV.find(Reg) != PV.end()) { 3728f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune // 255 is used to tells its a PS/PV reg 3738f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune Result.push_back(std::pair<int, unsigned>(255, 0)); 37425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 37525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 3768f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Index > 127) { 3778f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ConstCount++; 37825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(DummyPair); 37925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 38025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 3818f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Chan = RI.getHWRegChan(Reg); 38225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(std::pair<int, unsigned>(Index, Chan)); 38325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 38425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (; i < 3; ++i) 38525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Result.push_back(DummyPair); 38625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return Result; 38725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 38825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 38925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunestatic std::vector<std::pair<int, unsigned> > 39025c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneSwizzle(std::vector<std::pair<int, unsigned> > Src, 39125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune R600InstrInfo::BankSwizzle Swz) { 392f94eea9e112a75d0d328f799dd889681094cee97Vincent Lejeune if (Src[0] == Src[1]) 393f94eea9e112a75d0d328f799dd889681094cee97Vincent Lejeune Src[1].first = -1; 39425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune switch (Swz) { 3957d1a0d4e3ebf058a8b1d0dea9b6119444ed041c8Vincent Lejeune case R600InstrInfo::ALU_VEC_012_SCL_210: 39625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 3977d1a0d4e3ebf058a8b1d0dea9b6119444ed041c8Vincent Lejeune case R600InstrInfo::ALU_VEC_021_SCL_122: 39825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[1], Src[2]); 39925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 4007d1a0d4e3ebf058a8b1d0dea9b6119444ed041c8Vincent Lejeune case R600InstrInfo::ALU_VEC_102_SCL_221: 40125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[1]); 40225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 4037d1a0d4e3ebf058a8b1d0dea9b6119444ed041c8Vincent Lejeune case R600InstrInfo::ALU_VEC_120_SCL_212: 40425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[1]); 40525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[2]); 40625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 40725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune case R600InstrInfo::ALU_VEC_201: 40825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[2]); 40925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[1]); 41025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 41125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune case R600InstrInfo::ALU_VEC_210: 41225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::swap(Src[0], Src[2]); 41325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune break; 41425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 41525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return Src; 41625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 41725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 4188f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunestatic unsigned 4198f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent LejeunegetTransSwizzle(R600InstrInfo::BankSwizzle Swz, unsigned Op) { 4208f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune switch (Swz) { 4218f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune case R600InstrInfo::ALU_VEC_012_SCL_210: { 4228f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Cycles[3] = { 2, 1, 0}; 4238f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return Cycles[Op]; 4248f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 4258f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune case R600InstrInfo::ALU_VEC_021_SCL_122: { 4268f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Cycles[3] = { 1, 2, 2}; 4278f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return Cycles[Op]; 4288f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 4298f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune case R600InstrInfo::ALU_VEC_120_SCL_212: { 4308f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Cycles[3] = { 2, 1, 2}; 4318f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return Cycles[Op]; 4328f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 4338f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune case R600InstrInfo::ALU_VEC_102_SCL_221: { 4348f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Cycles[3] = { 2, 2, 1}; 4358f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return Cycles[Op]; 4368f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 4378f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune default: 4388f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune llvm_unreachable("Wrong Swizzle for Trans Slot"); 4398f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return 0; 4408f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 4418f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune} 4428f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune 4438f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// returns how many MIs (whose inputs are represented by IGSrcs) can be packed 4448f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// in the same Instruction Group while meeting read port limitations given a 4458f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// Swz swizzle sequence. 4468f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeuneunsigned R600InstrInfo::isLegalUpTo( 4478f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs, 4488f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::vector<R600InstrInfo::BankSwizzle> &Swz, 4498f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::vector<std::pair<int, unsigned> > &TransSrcs, 4508f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune R600InstrInfo::BankSwizzle TransSwz) const { 45125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune int Vector[4][3]; 45225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune memset(Vector, -1, sizeof(Vector)); 4538f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune for (unsigned i = 0, e = IGSrcs.size(); i < e; i++) { 45425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const std::vector<std::pair<int, unsigned> > &Srcs = 45525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Swizzle(IGSrcs[i], Swz[i]); 45625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned j = 0; j < 3; j++) { 45725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const std::pair<int, unsigned> &Src = Srcs[j]; 4588f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Src.first < 0 || Src.first == 255) 45925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune continue; 460e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard if (Src.first == GET_REG_INDEX(RI.getEncodingValue(AMDGPU::OQAP))) { 4618f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Swz[i] != R600InstrInfo::ALU_VEC_012_SCL_210 && 4628f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune Swz[i] != R600InstrInfo::ALU_VEC_021_SCL_122) { 463e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard // The value from output queue A (denoted by register OQAP) can 464e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard // only be fetched during the first cycle. 465e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard return false; 466e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard } 467e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard // OQAP does not count towards the normal read port restrictions 468e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard continue; 469e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard } 47025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Vector[Src.second][j] < 0) 47125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Vector[Src.second][j] = Src.first; 47225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Vector[Src.second][j] != Src.first) 4738f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return i; 47425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 47525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 4768f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune // Now check Trans Alu 4778f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune for (unsigned i = 0, e = TransSrcs.size(); i < e; ++i) { 4788f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::pair<int, unsigned> &Src = TransSrcs[i]; 4798f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Cycle = getTransSwizzle(TransSwz, i); 4808f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Src.first < 0) 4818f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune continue; 4828f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Src.first == 255) 4838f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune continue; 4848f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Vector[Src.second][Cycle] < 0) 4858f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune Vector[Src.second][Cycle] = Src.first; 4868f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Vector[Src.second][Cycle] != Src.first) 4878f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return IGSrcs.size() - 1; 4888f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 4898f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return IGSrcs.size(); 49025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 49125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 4928f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// Given a swizzle sequence SwzCandidate and an index Idx, returns the next 4938f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// (in lexicographic term) swizzle sequence assuming that all swizzles after 4948f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// Idx can be skipped 4958f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunestatic bool 4968f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent LejeuneNextPossibleSolution( 4978f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate, 4988f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Idx) { 4998f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune assert(Idx < SwzCandidate.size()); 5008f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune int ResetIdx = Idx; 5018f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune while (ResetIdx > -1 && SwzCandidate[ResetIdx] == R600InstrInfo::ALU_VEC_210) 5028f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ResetIdx --; 5038f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune for (unsigned i = ResetIdx + 1, e = SwzCandidate.size(); i < e; i++) { 5048f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune SwzCandidate[i] = R600InstrInfo::ALU_VEC_012_SCL_210; 5058f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 5068f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (ResetIdx == -1) 50725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return false; 50897daabf318ff4751aca49bc1c334d2553b125671Benjamin Kramer int NextSwizzle = SwzCandidate[ResetIdx] + 1; 50997daabf318ff4751aca49bc1c334d2553b125671Benjamin Kramer SwzCandidate[ResetIdx] = (R600InstrInfo::BankSwizzle)NextSwizzle; 5108f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return true; 5118f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune} 5128f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune 5138f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// Enumerate all possible Swizzle sequence to find one that can meet all 5148f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// read port requirements. 5158f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunebool R600InstrInfo::FindSwizzleForVectorSlot( 5168f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::vector<std::vector<std::pair<int, unsigned> > > &IGSrcs, 5178f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune std::vector<R600InstrInfo::BankSwizzle> &SwzCandidate, 5188f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::vector<std::pair<int, unsigned> > &TransSrcs, 5198f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune R600InstrInfo::BankSwizzle TransSwz) const { 5208f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned ValidUpTo = 0; 5218f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune do { 5228f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ValidUpTo = isLegalUpTo(IGSrcs, SwzCandidate, TransSrcs, TransSwz); 5238f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (ValidUpTo == IGSrcs.size()) 52425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return true; 5258f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } while (NextPossibleSolution(SwzCandidate, ValidUpTo)); 52625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune return false; 52725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 52825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 5298f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// Instructions in Trans slot can't read gpr at cycle 0 if they also read 5308f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/// a const, and can't read a gpr at cycle 1 if they read 2 const. 5318f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunestatic bool 5328f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent LejeuneisConstCompatible(R600InstrInfo::BankSwizzle TransSwz, 5338f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::vector<std::pair<int, unsigned> > &TransOps, 5348f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned ConstCount) { 535bb25a01d232257b134f1f6a5810116cbb04b95b1Vincent Lejeune // TransALU can't read 3 constants 536bb25a01d232257b134f1f6a5810116cbb04b95b1Vincent Lejeune if (ConstCount > 2) 537bb25a01d232257b134f1f6a5810116cbb04b95b1Vincent Lejeune return false; 5388f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune for (unsigned i = 0, e = TransOps.size(); i < e; ++i) { 5398f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const std::pair<int, unsigned> &Src = TransOps[i]; 5408f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned Cycle = getTransSwizzle(TransSwz, i); 5418f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Src.first < 0) 5428f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune continue; 5438f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (ConstCount > 0 && Cycle == 0) 5448f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return false; 5458f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (ConstCount > 1 && Cycle == 1) 5468f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return false; 5478f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 5488f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return true; 5498f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune} 5508f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune 55125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunebool 55225c209e9a262b623deca60fb6b886907e22c941bVincent LejeuneR600InstrInfo::fitsReadPortLimitations(const std::vector<MachineInstr *> &IG, 5538f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const DenseMap<unsigned, unsigned> &PV, 5548f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune std::vector<BankSwizzle> &ValidSwizzle, 5558f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune bool isLastAluTrans) 55625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune const { 55725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune //Todo : support shared src0 - src1 operand 55825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 55925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::vector<std::vector<std::pair<int, unsigned> > > IGSrcs; 56025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune ValidSwizzle.clear(); 5618f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune unsigned ConstCount; 562c36a8d2b3d6e543de8d9f210ecd39a9a0641d826Vincent Lejeune BankSwizzle TransBS = ALU_VEC_012_SCL_210; 56325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned i = 0, e = IG.size(); i < e; ++i) { 5648f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune IGSrcs.push_back(ExtractSrcs(IG[i], PV, ConstCount)); 56525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Op = getOperandIdx(IG[i]->getOpcode(), 5665e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::bank_swizzle); 56725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune ValidSwizzle.push_back( (R600InstrInfo::BankSwizzle) 56825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune IG[i]->getOperand(Op).getImm()); 56925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune } 5708f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune std::vector<std::pair<int, unsigned> > TransOps; 5718f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (!isLastAluTrans) 5728f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return FindSwizzleForVectorSlot(IGSrcs, ValidSwizzle, TransOps, TransBS); 5738f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune 5748f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune TransOps = IGSrcs.back(); 5758f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune IGSrcs.pop_back(); 5768f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ValidSwizzle.pop_back(); 5778f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune 5788f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune static const R600InstrInfo::BankSwizzle TransSwz[] = { 5798f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ALU_VEC_012_SCL_210, 5808f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ALU_VEC_021_SCL_122, 5818f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ALU_VEC_120_SCL_212, 5828f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ALU_VEC_102_SCL_221 5838f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune }; 5848f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune for (unsigned i = 0; i < 4; i++) { 5858f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune TransBS = TransSwz[i]; 5868f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (!isConstCompatible(TransBS, TransOps, ConstCount)) 5878f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune continue; 5888f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune bool Result = FindSwizzleForVectorSlot(IGSrcs, ValidSwizzle, TransOps, 5898f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune TransBS); 5908f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune if (Result) { 5918f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune ValidSwizzle.push_back(TransBS); 5928f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return true; 5938f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 5948f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune } 5958f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune 5968f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune return false; 59725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune} 59825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 59925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 6003ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeunebool 6013ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent LejeuneR600InstrInfo::fitsConstReadLimitations(const std::vector<unsigned> &Consts) 6023ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune const { 6033ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune assert (Consts.size() <= 12 && "Too many operands in instructions group"); 6043ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned Pair1 = 0, Pair2 = 0; 6053ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune for (unsigned i = 0, n = Consts.size(); i < n; ++i) { 6063ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned ReadConstHalf = Consts[i] & 2; 6073ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned ReadConstIndex = Consts[i] & (~3); 6083ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune unsigned ReadHalfConst = ReadConstIndex | ReadConstHalf; 6093ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (!Pair1) { 6103ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune Pair1 = ReadHalfConst; 6113ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 6123ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 6133ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (Pair1 == ReadHalfConst) 6143ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 6153ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (!Pair2) { 6163ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune Pair2 = ReadHalfConst; 6173ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 6183ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 6193ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (Pair2 != ReadHalfConst) 6203ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune return false; 6213ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 6223ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune return true; 6233ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune} 6243ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 6253ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeunebool 6268f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent LejeuneR600InstrInfo::fitsConstReadLimitations(const std::vector<MachineInstr *> &MIs) 6278f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune const { 6283ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune std::vector<unsigned> Consts; 6298e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune SmallSet<int64_t, 4> Literals; 6303ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune for (unsigned i = 0, n = MIs.size(); i < n; i++) { 63125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune MachineInstr *MI = MIs[i]; 6323ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune if (!isALUInstr(MI->getOpcode())) 6333ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune continue; 6343ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 635a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper const SmallVectorImpl<std::pair<MachineOperand *, int64_t> > &Srcs = 63625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune getSrcs(MI); 63725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune 63825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune for (unsigned j = 0, e = Srcs.size(); j < e; j++) { 63925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune std::pair<MachineOperand *, unsigned> Src = Srcs[j]; 6408e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune if (Src.first->getReg() == AMDGPU::ALU_LITERAL_X) 6418e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune Literals.insert(Src.second); 6428e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune if (Literals.size() > 4) 6438e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune return false; 64425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (Src.first->getReg() == AMDGPU::ALU_CONST) 64525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune Consts.push_back(Src.second); 64625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune if (AMDGPU::R600_KC0RegClass.contains(Src.first->getReg()) || 64725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune AMDGPU::R600_KC1RegClass.contains(Src.first->getReg())) { 64825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Index = RI.getEncodingValue(Src.first->getReg()) & 0xff; 64925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune unsigned Chan = RI.getHWRegChan(Src.first->getReg()); 65025f259cde28860ea76c2f5628010968945a28edbVincent Lejeune Consts.push_back((Index << 2) | Chan); 6513ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 6523ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 6533ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune } 6543ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune return fitsConstReadLimitations(Consts); 6553ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune} 6563ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune 657f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardDFAPacketizer *R600InstrInfo::CreateTargetScheduleState(const TargetMachine *TM, 658f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const ScheduleDAG *DAG) const { 659f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const InstrItineraryData *II = TM->getInstrItineraryData(); 660f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return TM->getSubtarget<AMDGPUSubtarget>().createDFAPacketizer(II); 661f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 662f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 663f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic bool 664f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardisPredicateSetter(unsigned Opcode) { 665f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Opcode) { 666f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_X: 667f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 668f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 669f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 670f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 671f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 672f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 673f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic MachineInstr * 674f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardfindFirstPredicateSetterFrom(MachineBasicBlock &MBB, 675f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I) { 676f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard while (I != MBB.begin()) { 677f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 678f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *MI = I; 679f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isPredicateSetter(MI->getOpcode())) 680f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MI; 681f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 682f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 683dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 684f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 685f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 686fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeunestatic 687fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeunebool isJump(unsigned Opcode) { 688fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune return Opcode == AMDGPU::JUMP || Opcode == AMDGPU::JUMP_COND; 689fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune} 690fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune 6915b00e833fabbf5bdf2973c63c39d4a0d0143853aVincent Lejeunestatic bool isBranch(unsigned Opcode) { 6925b00e833fabbf5bdf2973c63c39d4a0d0143853aVincent Lejeune return Opcode == AMDGPU::BRANCH || Opcode == AMDGPU::BRANCH_COND_i32 || 6935b00e833fabbf5bdf2973c63c39d4a0d0143853aVincent Lejeune Opcode == AMDGPU::BRANCH_COND_f32; 6945b00e833fabbf5bdf2973c63c39d4a0d0143853aVincent Lejeune} 6955b00e833fabbf5bdf2973c63c39d4a0d0143853aVincent Lejeune 696f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 697f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 698f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *&TBB, 699f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *&FBB, 700f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<MachineOperand> &Cond, 701f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool AllowModify) const { 702f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Most of the following comes from the ARM implementation of AnalyzeBranch 703f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 704f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If the block has no terminators, it just falls into the block after it. 705f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I = MBB.end(); 706f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) 707f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 708f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 709f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard while (I->isDebugValue()) { 710f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) 711f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 712f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 713f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 7145b00e833fabbf5bdf2973c63c39d4a0d0143853aVincent Lejeune // AMDGPU::BRANCH* instructions are only available after isel and are not 7155b00e833fabbf5bdf2973c63c39d4a0d0143853aVincent Lejeune // handled 7165b00e833fabbf5bdf2973c63c39d4a0d0143853aVincent Lejeune if (isBranch(I->getOpcode())) 7175b00e833fabbf5bdf2973c63c39d4a0d0143853aVincent Lejeune return true; 718fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune if (!isJump(static_cast<MachineInstr *>(I)->getOpcode())) { 719f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 720f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 721f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Remove successive JUMP 72336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines while (I != MBB.begin() && std::prev(I)->getOpcode() == AMDGPU::JUMP) { 72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineBasicBlock::iterator PriorI = std::prev(I); 72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (AllowModify) 72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I->removeFromParent(); 72736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I = PriorI; 72836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 729f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *LastInst = I; 730f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 731f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If there is only one terminator instruction, process it. 732f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned LastOpc = LastInst->getOpcode(); 733f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin() || 734fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune !isJump(static_cast<MachineInstr *>(--I)->getOpcode())) { 735f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (LastOpc == AMDGPU::JUMP) { 736fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune TBB = LastInst->getOperand(0).getMBB(); 737fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune return false; 738fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune } else if (LastOpc == AMDGPU::JUMP_COND) { 739fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune MachineInstr *predSet = I; 740fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune while (!isPredicateSetter(predSet->getOpcode())) { 741fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune predSet = --I; 742f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 743fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune TBB = LastInst->getOperand(0).getMBB(); 744fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune Cond.push_back(predSet->getOperand(1)); 745fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune Cond.push_back(predSet->getOperand(2)); 746fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune Cond.push_back(MachineOperand::CreateReg(AMDGPU::PRED_SEL_ONE, false)); 747fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune return false; 748f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 749f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; // Can't handle indirect branch. 750f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 751f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 752f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Get the instruction before it if it is a terminator. 753f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *SecondLastInst = I; 754f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned SecondLastOpc = SecondLastInst->getOpcode(); 755f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 756f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If the block ends with a B and a Bcc, handle it. 757fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune if (SecondLastOpc == AMDGPU::JUMP_COND && LastOpc == AMDGPU::JUMP) { 758f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *predSet = --I; 759f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard while (!isPredicateSetter(predSet->getOpcode())) { 760f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard predSet = --I; 761f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 762f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TBB = SecondLastInst->getOperand(0).getMBB(); 763f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FBB = LastInst->getOperand(0).getMBB(); 764f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond.push_back(predSet->getOperand(1)); 765f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond.push_back(predSet->getOperand(2)); 766f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Cond.push_back(MachineOperand::CreateReg(AMDGPU::PRED_SEL_ONE, false)); 767f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 768f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 769f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 770f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Otherwise, can't handle this. 771f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 772f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 773f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 774f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeunestatic 775f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent LejeuneMachineBasicBlock::iterator FindLastAluClause(MachineBasicBlock &MBB) { 776f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune for (MachineBasicBlock::reverse_iterator It = MBB.rbegin(), E = MBB.rend(); 777f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune It != E; ++It) { 778f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (It->getOpcode() == AMDGPU::CF_ALU || 779f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune It->getOpcode() == AMDGPU::CF_ALU_PUSH_BEFORE) 78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return std::prev(It.base()); 781f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune } 782f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return MBB.end(); 783f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune} 784f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune 785f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned 786f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::InsertBranch(MachineBasicBlock &MBB, 787f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *TBB, 788f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock *FBB, 789f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SmallVectorImpl<MachineOperand> &Cond, 790f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DebugLoc DL) const { 791f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 792f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 793dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!FBB) { 794f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Cond.empty()) { 795fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP)).addMBB(TBB); 796f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 797f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 798f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end()); 799f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(PredSet && "No previous predicate !"); 800f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addFlag(PredSet, 0, MO_FLAG_PUSH); 801f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PredSet->getOperand(2).setImm(Cond[1].getImm()); 802f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 803fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP_COND)) 804f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addMBB(TBB) 805f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); 806f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB); 807f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (CfAlu == MBB.end()) 808f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return 1; 809f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune assert (CfAlu->getOpcode() == AMDGPU::CF_ALU); 810f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune CfAlu->setDesc(get(AMDGPU::CF_ALU_PUSH_BEFORE)); 811f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 812f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 813f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 814f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *PredSet = findFirstPredicateSetterFrom(MBB, MBB.end()); 815f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(PredSet && "No previous predicate !"); 816f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addFlag(PredSet, 0, MO_FLAG_PUSH); 817f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PredSet->getOperand(2).setImm(Cond[1].getImm()); 818fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP_COND)) 819f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addMBB(TBB) 820f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); 821fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune BuildMI(&MBB, DL, get(AMDGPU::JUMP)).addMBB(FBB); 822f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB); 823f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (CfAlu == MBB.end()) 824f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return 2; 825f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune assert (CfAlu->getOpcode() == AMDGPU::CF_ALU); 826f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune CfAlu->setDesc(get(AMDGPU::CF_ALU_PUSH_BEFORE)); 827f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 2; 828f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 829f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 830f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 831f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned 832f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 833f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 834f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Note : we leave PRED* instructions there. 835f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // They may be needed when predicating instructions. 836f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 837f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I = MBB.end(); 838f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 839f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) { 840f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 0; 841f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 842f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 843f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (I->getOpcode()) { 844f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 845f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 0; 846fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune case AMDGPU::JUMP_COND: { 847fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I); 848fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune clearFlag(predSet, 0, MO_FLAG_PUSH); 849fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune I->eraseFromParent(); 850f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB); 851f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (CfAlu == MBB.end()) 852f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune break; 853f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune assert (CfAlu->getOpcode() == AMDGPU::CF_ALU_PUSH_BEFORE); 854f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune CfAlu->setDesc(get(AMDGPU::CF_ALU)); 855fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune break; 856fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune } 857f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::JUMP: 858f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard I->eraseFromParent(); 859f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 860f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 861f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard I = MBB.end(); 862f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 863f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (I == MBB.begin()) { 864f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 865f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 866f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard --I; 867f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (I->getOpcode()) { 868f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // FIXME: only one case?? 869f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 870f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 1; 871fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune case AMDGPU::JUMP_COND: { 872fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I); 873fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune clearFlag(predSet, 0, MO_FLAG_PUSH); 874fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune I->eraseFromParent(); 875f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune MachineBasicBlock::iterator CfAlu = FindLastAluClause(MBB); 876f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (CfAlu == MBB.end()) 877f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune break; 878f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune assert (CfAlu->getOpcode() == AMDGPU::CF_ALU_PUSH_BEFORE); 879f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune CfAlu->setDesc(get(AMDGPU::CF_ALU)); 880fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune break; 881fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune } 882f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::JUMP: 883f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard I->eraseFromParent(); 884f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 885f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 886f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 2; 887f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 888f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 889f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 890f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isPredicated(const MachineInstr *MI) const { 891f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int idx = MI->findFirstPredOperandIdx(); 892f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (idx < 0) 893f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 894f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 895f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Reg = MI->getOperand(idx).getReg(); 896f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Reg) { 897f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: return false; 898f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ONE: 899f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ZERO: 900f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PREDICATE_BIT: 901f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 902f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 903f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 904f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 905f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 906f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isPredicable(MachineInstr *MI) const { 907f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // XXX: KILL* instructions can be predicated, but they must be the last 908f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // instruction in a clause, so this means any instructions after them cannot 909f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // be predicated. Until we have proper support for instruction clauses in the 910f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // backend, we will mark KILL* instructions as unpredicable. 911f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 912f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (MI->getOpcode() == AMDGPU::KILLGT) { 913f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 914f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune } else if (MI->getOpcode() == AMDGPU::CF_ALU) { 915f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune // If the clause start in the middle of MBB then the MBB has more 916f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune // than a single clause, unable to predicate several clauses. 917f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (MI->getParent()->begin() != MachineBasicBlock::iterator(MI)) 918f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return false; 919f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune // TODO: We don't support KC merging atm 920f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (MI->getOperand(3).getImm() != 0 || MI->getOperand(4).getImm() != 0) 921f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return false; 922f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return true; 92362b0a9b1e6189947b7e46df1b64968e66476c912Vincent Lejeune } else if (isVector(*MI)) { 92462b0a9b1e6189947b7e46df1b64968e66476c912Vincent Lejeune return false; 925f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 926f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return AMDGPUInstrInfo::isPredicable(MI); 927f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 928f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 929f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 930f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 931f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 932f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB, 933f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumCyles, 934f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ExtraPredCycles, 935f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const BranchProbability &Probability) const{ 936f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 937f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 938f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 939f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 940f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB, 941f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumTCycles, 942f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ExtraTCycles, 943f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock &FMBB, 944f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumFCycles, 945f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned ExtraFCycles, 946f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const BranchProbability &Probability) const { 947f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 948f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 949f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 950f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 951f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB, 952f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned NumCyles, 953f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const BranchProbability &Probability) 954f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const { 955f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 956f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 957f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 958f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 959f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::isProfitableToUnpredicate(MachineBasicBlock &TMBB, 960f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock &FMBB) const { 961f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 962f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 963f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 964f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 965f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 966f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 967f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &MO = Cond[1]; 968f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (MO.getImm()) { 969f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_ZERO_INT: 970f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_NOT_ZERO_INT); 971f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 972f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_NOT_ZERO_INT: 973f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_ZERO_INT); 974f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 975f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_ZERO: 976f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_NOT_ZERO); 977f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 978f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case OPCODE_IS_NOT_ZERO: 979f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO.setImm(OPCODE_IS_ZERO); 980f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 981f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 982f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 983f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 984f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 985f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &MO2 = Cond[2]; 986f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (MO2.getReg()) { 987f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ZERO: 988f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO2.setReg(AMDGPU::PRED_SEL_ONE); 989f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 990f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::PRED_SEL_ONE: 991f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MO2.setReg(AMDGPU::PRED_SEL_ZERO); 992f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 993f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 994f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 995f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 996f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 997f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 998f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 999f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 1000f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::DefinesPredicate(MachineInstr *MI, 1001f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard std::vector<MachineOperand> &Pred) const { 1002f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return isPredicateSetter(MI->getOpcode()); 1003f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1004f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1005f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1006f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 1007f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 1008f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SmallVectorImpl<MachineOperand> &Pred2) const { 1009f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 1010f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1011f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1012f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1013f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 1014f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardR600InstrInfo::PredicateInstruction(MachineInstr *MI, 1015f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SmallVectorImpl<MachineOperand> &Pred) const { 1016f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int PIdx = MI->findFirstPredOperandIdx(); 1017f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1018f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (MI->getOpcode() == AMDGPU::CF_ALU) { 1019f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune MI->getOperand(8).setImm(0); 1020f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune return true; 1021f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune } 1022f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune 1023411079785388290738049dd099bff8755e6a2c8dVincent Lejeune if (MI->getOpcode() == AMDGPU::DOT_4) { 1024411079785388290738049dd099bff8755e6a2c8dVincent Lejeune MI->getOperand(getOperandIdx(*MI, AMDGPU::OpName::pred_sel_X)) 1025411079785388290738049dd099bff8755e6a2c8dVincent Lejeune .setReg(Pred[2].getReg()); 1026411079785388290738049dd099bff8755e6a2c8dVincent Lejeune MI->getOperand(getOperandIdx(*MI, AMDGPU::OpName::pred_sel_Y)) 1027411079785388290738049dd099bff8755e6a2c8dVincent Lejeune .setReg(Pred[2].getReg()); 1028411079785388290738049dd099bff8755e6a2c8dVincent Lejeune MI->getOperand(getOperandIdx(*MI, AMDGPU::OpName::pred_sel_Z)) 1029411079785388290738049dd099bff8755e6a2c8dVincent Lejeune .setReg(Pred[2].getReg()); 1030411079785388290738049dd099bff8755e6a2c8dVincent Lejeune MI->getOperand(getOperandIdx(*MI, AMDGPU::OpName::pred_sel_W)) 1031411079785388290738049dd099bff8755e6a2c8dVincent Lejeune .setReg(Pred[2].getReg()); 1032411079785388290738049dd099bff8755e6a2c8dVincent Lejeune MachineInstrBuilder MIB(*MI->getParent()->getParent(), MI); 1033411079785388290738049dd099bff8755e6a2c8dVincent Lejeune MIB.addReg(AMDGPU::PREDICATE_BIT, RegState::Implicit); 1034411079785388290738049dd099bff8755e6a2c8dVincent Lejeune return true; 1035411079785388290738049dd099bff8755e6a2c8dVincent Lejeune } 1036411079785388290738049dd099bff8755e6a2c8dVincent Lejeune 1037f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (PIdx != -1) { 1038f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &PMO = MI->getOperand(PIdx); 1039f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard PMO.setReg(Pred[2].getReg()); 10406b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MachineInstrBuilder MIB(*MI->getParent()->getParent(), MI); 10416b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi MIB.addReg(AMDGPU::PREDICATE_BIT, RegState::Implicit); 1042f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return true; 1043f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1044f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1045f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 1046f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1047f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1048d42730dc712026cbfb1322a979e0ac72cd31a19eArnold Schwaighoferunsigned int R600InstrInfo::getPredicationCost(const MachineInstr *) const { 1049d42730dc712026cbfb1322a979e0ac72cd31a19eArnold Schwaighofer return 2; 1050d42730dc712026cbfb1322a979e0ac72cd31a19eArnold Schwaighofer} 1051d42730dc712026cbfb1322a979e0ac72cd31a19eArnold Schwaighofer 1052f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned int R600InstrInfo::getInstrLatency(const InstrItineraryData *ItinData, 1053f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MachineInstr *MI, 1054f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned *PredCost) const { 1055f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (PredCost) 1056f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard *PredCost = 2; 1057f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 2; 1058f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1059f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1060cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool R600InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { 1061cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1062cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines switch(MI->getOpcode()) { 1063cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines default: return AMDGPUInstrInfo::expandPostRAPseudo(MI); 1064cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case AMDGPU::R600_EXTRACT_ELT_V2: 1065cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case AMDGPU::R600_EXTRACT_ELT_V4: 1066cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines buildIndirectRead(MI->getParent(), MI, MI->getOperand(0).getReg(), 1067cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RI.getHWRegIndex(MI->getOperand(1).getReg()), // Address 1068cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MI->getOperand(2).getReg(), 1069cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RI.getHWRegChan(MI->getOperand(1).getReg())); 1070cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines break; 1071cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case AMDGPU::R600_INSERT_ELT_V2: 1072cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case AMDGPU::R600_INSERT_ELT_V4: 1073cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines buildIndirectWrite(MI->getParent(), MI, MI->getOperand(2).getReg(), // Value 1074cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RI.getHWRegIndex(MI->getOperand(1).getReg()), // Address 1075cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MI->getOperand(3).getReg(), // Offset 1076cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RI.getHWRegChan(MI->getOperand(1).getReg())); // Channel 1077cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines break; 1078cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1079cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MI->eraseFromParent(); 1080cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return true; 1081cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 1082cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1083a2b4eb6d15a13de257319ac6231b5ab622cd02b1Tom Stellardvoid R600InstrInfo::reserveIndirectRegisters(BitVector &Reserved, 1084c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineFunction &MF) const { 1085c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const AMDGPUFrameLowering *TFL = 1086cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static_cast<const AMDGPUFrameLowering*>( 1087cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MF.getTarget().getFrameLowering()); 1088c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1089c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned StackWidth = TFL->getStackWidth(MF); 1090c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard int End = getIndirectIndexEnd(MF); 1091c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1092a2b4eb6d15a13de257319ac6231b5ab622cd02b1Tom Stellard if (End == -1) 1093a2b4eb6d15a13de257319ac6231b5ab622cd02b1Tom Stellard return; 1094c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1095c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (int Index = getIndirectIndexBegin(MF); Index <= End; ++Index) { 1096c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned SuperReg = AMDGPU::R600_Reg128RegClass.getRegister(Index); 1097a2b4eb6d15a13de257319ac6231b5ab622cd02b1Tom Stellard Reserved.set(SuperReg); 1098c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (unsigned Chan = 0; Chan < StackWidth; ++Chan) { 1099c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister((4 * Index) + Chan); 1100a2b4eb6d15a13de257319ac6231b5ab622cd02b1Tom Stellard Reserved.set(Reg); 1101c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 1102c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 1103c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 1104c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1105c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardunsigned R600InstrInfo::calculateIndirectAddress(unsigned RegIndex, 1106c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned Channel) const { 1107c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // XXX: Remove when we support a stack width > 2 1108c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard assert(Channel == 0); 1109c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return RegIndex; 1110c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 1111c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 111204c559569f87d755c3f2828a765f5eb7308e6753Tom Stellardconst TargetRegisterClass *R600InstrInfo::getIndirectAddrRegClass() const { 111304c559569f87d755c3f2828a765f5eb7308e6753Tom Stellard return &AMDGPU::R600_TReg32_XRegClass; 1114c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 1115c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1116c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardMachineInstrBuilder R600InstrInfo::buildIndirectWrite(MachineBasicBlock *MBB, 1117c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineBasicBlock::iterator I, 1118c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned ValueReg, unsigned Address, 1119c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned OffsetReg) const { 1120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return buildIndirectWrite(MBB, I, ValueReg, Address, OffsetReg, 0); 1121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 1122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1123cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMachineInstrBuilder R600InstrInfo::buildIndirectWrite(MachineBasicBlock *MBB, 1124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachineBasicBlock::iterator I, 1125cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned ValueReg, unsigned Address, 1126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned OffsetReg, 1127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned AddrChan) const { 1128cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned AddrReg; 1129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines switch (AddrChan) { 1130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines default: llvm_unreachable("Invalid Channel"); 1131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case 0: AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address); break; 1132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case 1: AddrReg = AMDGPU::R600_Addr_YRegClass.getRegister(Address); break; 1133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case 2: AddrReg = AMDGPU::R600_Addr_ZRegClass.getRegister(Address); break; 1134cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case 3: AddrReg = AMDGPU::R600_Addr_WRegClass.getRegister(Address); break; 1135cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1136c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, AMDGPU::MOVA_INT_eg, 1137c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AMDGPU::AR_X, OffsetReg); 11385e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(MOVA, AMDGPU::OpName::write, 0); 1139c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1140c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, AMDGPU::MOV, 1141c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AddrReg, ValueReg) 1142ad7ecc65b1b1d6466ff035168c86f208a91aa1b4Tom Stellard .addReg(AMDGPU::AR_X, 1143ad7ecc65b1b1d6466ff035168c86f208a91aa1b4Tom Stellard RegState::Implicit | RegState::Kill); 11445e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(Mov, AMDGPU::OpName::dst_rel, 1); 1145c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Mov; 1146c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 1147c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1148c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardMachineInstrBuilder R600InstrInfo::buildIndirectRead(MachineBasicBlock *MBB, 1149c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineBasicBlock::iterator I, 1150c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned ValueReg, unsigned Address, 1151c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned OffsetReg) const { 1152cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return buildIndirectRead(MBB, I, ValueReg, Address, OffsetReg, 0); 1153cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 1154cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1155cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMachineInstrBuilder R600InstrInfo::buildIndirectRead(MachineBasicBlock *MBB, 1156cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachineBasicBlock::iterator I, 1157cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned ValueReg, unsigned Address, 1158cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned OffsetReg, 1159cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned AddrChan) const { 1160cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned AddrReg; 1161cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines switch (AddrChan) { 1162cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines default: llvm_unreachable("Invalid Channel"); 1163cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case 0: AddrReg = AMDGPU::R600_AddrRegClass.getRegister(Address); break; 1164cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case 1: AddrReg = AMDGPU::R600_Addr_YRegClass.getRegister(Address); break; 1165cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case 2: AddrReg = AMDGPU::R600_Addr_ZRegClass.getRegister(Address); break; 1166cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case 3: AddrReg = AMDGPU::R600_Addr_WRegClass.getRegister(Address); break; 1167cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1168c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstr *MOVA = buildDefaultInstruction(*MBB, I, AMDGPU::MOVA_INT_eg, 1169c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AMDGPU::AR_X, 1170c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard OffsetReg); 11715e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(MOVA, AMDGPU::OpName::write, 0); 1172c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineInstrBuilder Mov = buildDefaultInstruction(*MBB, I, AMDGPU::MOV, 1173c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard ValueReg, 1174c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard AddrReg) 1175ad7ecc65b1b1d6466ff035168c86f208a91aa1b4Tom Stellard .addReg(AMDGPU::AR_X, 1176ad7ecc65b1b1d6466ff035168c86f208a91aa1b4Tom Stellard RegState::Implicit | RegState::Kill); 11775e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(Mov, AMDGPU::OpName::src0_rel, 1); 1178c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1179c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Mov; 1180c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 1181c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1182dae2a20a56b28b4685249982a80a0043b7673e09Vincent Lejeuneunsigned R600InstrInfo::getMaxAlusPerClause() const { 1183dae2a20a56b28b4685249982a80a0043b7673e09Vincent Lejeune return 115; 1184dae2a20a56b28b4685249982a80a0043b7673e09Vincent Lejeune} 1185c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 1186f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineInstrBuilder R600InstrInfo::buildDefaultInstruction(MachineBasicBlock &MBB, 1187f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I, 1188f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Opcode, 1189f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned DstReg, 1190f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Src0Reg, 1191f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Src1Reg) const { 1192f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstrBuilder MIB = BuildMI(MBB, I, MBB.findDebugLoc(I), get(Opcode), 1193f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard DstReg); // $dst 1194f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1195f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Src1Reg) { 1196f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addImm(0) // $update_exec_mask 1197f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0); // $update_predicate 1198f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1199f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addImm(1) // $write 1200f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $omod 1201f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $dst_rel 1202f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $dst_clamp 1203f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(Src0Reg) // $src0 1204f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src0_neg 1205f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src0_rel 12069f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(0) // $src0_abs 12079f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(-1); // $src0_sel 1208f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1209f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Src1Reg) { 1210f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addReg(Src1Reg) // $src1 1211f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src1_neg 1212f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addImm(0) // $src1_rel 12139f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(0) // $src1_abs 12149f7818d9bdfce2e9c7a2cbe31490a135aa6d1211Tom Stellard .addImm(-1); // $src1_sel 1215f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1216f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1217f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard //XXX: The r600g finalizer expects this to be 1, once we've moved the 1218f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard //scheduling to the backend, we can change the default to 0. 1219f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MIB.addImm(1) // $last 1220f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard .addReg(AMDGPU::PRED_SEL_OFF) // $pred_sel 1221e332e3559b5c09040de1528920006756e0962d6aVincent Lejeune .addImm(0) // $literal 1222e332e3559b5c09040de1528920006756e0962d6aVincent Lejeune .addImm(0); // $bank_swizzle 1223f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1224f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MIB; 1225f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1226f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 12274ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune#define OPERAND_CASE(Label) \ 12284ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune case Label: { \ 12295e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard static const unsigned Ops[] = \ 12304ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune { \ 12314ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Label##_X, \ 12324ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Label##_Y, \ 12334ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Label##_Z, \ 12344ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Label##_W \ 12354ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune }; \ 12364ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune return Ops[Slot]; \ 12374ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune } 12384ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 12395e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellardstatic unsigned getSlotedOps(unsigned Op, unsigned Slot) { 12404ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune switch (Op) { 12415e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::update_exec_mask) 12425e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::update_pred) 12435e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::write) 12445e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::omod) 12455e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::dst_rel) 12465e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::clamp) 12475e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0) 12485e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0_neg) 12495e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0_rel) 12505e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0_abs) 12515e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src0_sel) 12525e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1) 12535e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1_neg) 12545e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1_rel) 12555e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1_abs) 12565e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::src1_sel) 12575e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard OPERAND_CASE(AMDGPU::OpName::pred_sel) 12584ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune default: 12594ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune llvm_unreachable("Wrong Operand"); 12604ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune } 12614ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune} 12624ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 12634ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune#undef OPERAND_CASE 12644ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 12654ed9917147b1d1f2616f7c941bbe6999b979f510Vincent LejeuneMachineInstr *R600InstrInfo::buildSlotOfVectorInstruction( 12664ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineBasicBlock &MBB, MachineInstr *MI, unsigned Slot, unsigned DstReg) 12674ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune const { 12684ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune assert (MI->getOpcode() == AMDGPU::DOT_4 && "Not Implemented"); 12694ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune unsigned Opcode; 12703ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard if (ST.getGeneration() <= AMDGPUSubtarget::R700) 12714ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Opcode = AMDGPU::DOT4_r600; 12724ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune else 12734ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune Opcode = AMDGPU::DOT4_eg; 12744ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineBasicBlock::iterator I = MI; 12754ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineOperand &Src0 = MI->getOperand( 12765e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard getOperandIdx(MI->getOpcode(), getSlotedOps(AMDGPU::OpName::src0, Slot))); 12774ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineOperand &Src1 = MI->getOperand( 12785e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard getOperandIdx(MI->getOpcode(), getSlotedOps(AMDGPU::OpName::src1, Slot))); 12794ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineInstr *MIB = buildDefaultInstruction( 12804ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MBB, I, Opcode, DstReg, Src0.getReg(), Src1.getReg()); 12815e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard static const unsigned Operands[14] = { 12825e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::update_exec_mask, 12835e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::update_pred, 12845e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::write, 12855e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::omod, 12865e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::dst_rel, 12875e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::clamp, 12885e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src0_neg, 12895e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src0_rel, 12905e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src0_abs, 12915e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src0_sel, 12925e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src1_neg, 12935e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src1_rel, 12945e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src1_abs, 12955e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard AMDGPU::OpName::src1_sel, 12964ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune }; 12974ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 1298411079785388290738049dd099bff8755e6a2c8dVincent Lejeune MachineOperand &MO = MI->getOperand(getOperandIdx(MI->getOpcode(), 1299411079785388290738049dd099bff8755e6a2c8dVincent Lejeune getSlotedOps(AMDGPU::OpName::pred_sel, Slot))); 1300411079785388290738049dd099bff8755e6a2c8dVincent Lejeune MIB->getOperand(getOperandIdx(Opcode, AMDGPU::OpName::pred_sel)) 1301411079785388290738049dd099bff8755e6a2c8dVincent Lejeune .setReg(MO.getReg()); 1302411079785388290738049dd099bff8755e6a2c8dVincent Lejeune 13034ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune for (unsigned i = 0; i < 14; i++) { 13044ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MachineOperand &MO = MI->getOperand( 13055e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard getOperandIdx(MI->getOpcode(), getSlotedOps(Operands[i], Slot))); 13064ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune assert (MO.isImm()); 13074ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune setImmOperand(MIB, Operands[i], MO.getImm()); 13084ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune } 13094ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune MIB->getOperand(20).setImm(0); 13104ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune return MIB; 13114ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune} 13124ed9917147b1d1f2616f7c941bbe6999b979f510Vincent Lejeune 1313f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineInstr *R600InstrInfo::buildMovImm(MachineBasicBlock &BB, 1314f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock::iterator I, 1315f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned DstReg, 1316f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard uint64_t Imm) const { 1317f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr *MovImm = buildDefaultInstruction(BB, I, AMDGPU::MOV, DstReg, 1318f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPU::ALU_LITERAL_X); 13195e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard setImmOperand(MovImm, AMDGPU::OpName::literal, Imm); 1320f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MovImm; 1321f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1322f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 132304c559569f87d755c3f2828a765f5eb7308e6753Tom StellardMachineInstr *R600InstrInfo::buildMovInstr(MachineBasicBlock *MBB, 132404c559569f87d755c3f2828a765f5eb7308e6753Tom Stellard MachineBasicBlock::iterator I, 132504c559569f87d755c3f2828a765f5eb7308e6753Tom Stellard unsigned DstReg, unsigned SrcReg) const { 132604c559569f87d755c3f2828a765f5eb7308e6753Tom Stellard return buildDefaultInstruction(*MBB, I, AMDGPU::MOV, DstReg, SrcReg); 132704c559569f87d755c3f2828a765f5eb7308e6753Tom Stellard} 132804c559569f87d755c3f2828a765f5eb7308e6753Tom Stellard 13295e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellardint R600InstrInfo::getOperandIdx(const MachineInstr &MI, unsigned Op) const { 1330e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune return getOperandIdx(MI.getOpcode(), Op); 1331e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune} 1332e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 13335e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellardint R600InstrInfo::getOperandIdx(unsigned Opcode, unsigned Op) const { 13345e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard return AMDGPU::getNamedOperandIdx(Opcode, Op); 1335e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune} 1336e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune 13375e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellardvoid R600InstrInfo::setImmOperand(MachineInstr *MI, unsigned Op, 1338f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int64_t Imm) const { 1339f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int Idx = getOperandIdx(*MI, Op); 1340f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(Idx != -1 && "Operand not supported for this instruction."); 1341f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(MI->getOperand(Idx).isImm()); 1342f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MI->getOperand(Idx).setImm(Imm); 1343f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1344f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1345f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 1346f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Instruction flag getters/setters 1347f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 1348f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1349f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool R600InstrInfo::hasFlagOperand(const MachineInstr &MI) const { 1350f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return GET_FLAG_OPERAND_IDX(get(MI.getOpcode()).TSFlags) != 0; 1351f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1352f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1353f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMachineOperand &R600InstrInfo::getFlagOp(MachineInstr *MI, unsigned SrcIdx, 1354f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Flag) const { 1355f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(MI->getOpcode()).TSFlags; 1356f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard int FlagIndex = 0; 1357f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Flag != 0) { 1358f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // If we pass something other than the default value of Flag to this 1359f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // function, it means we are want to set a flag on an instruction 1360f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // that uses native encoding. 1361f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(HAS_NATIVE_OPERANDS(TargetFlags)); 1362f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool IsOP3 = (TargetFlags & R600_InstFlag::OP3) == R600_InstFlag::OP3; 1363f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (Flag) { 1364f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_CLAMP: 13655e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::clamp); 1366f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1367f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_MASK: 13685e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::write); 1369f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1370f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_NOT_LAST: 1371f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_LAST: 13725e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::last); 1373f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1374f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_NEG: 1375f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (SrcIdx) { 13765e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 0: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src0_neg); break; 13775e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 1: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src1_neg); break; 13785e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 2: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src2_neg); break; 1379f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1380f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1381f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1382f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case MO_FLAG_ABS: 1383f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!IsOP3 && "Cannot set absolute value modifier for OP3 " 1384f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard "instructions."); 138508f2d9379c486a0e4b950e476913ee97b38ec333Tom Stellard (void)IsOP3; 1386f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (SrcIdx) { 13875e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 0: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src0_abs); break; 13885e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard case 1: FlagIndex = getOperandIdx(*MI, AMDGPU::OpName::src1_abs); break; 1389f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1390f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1391f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1392f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: 1393f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagIndex = -1; 1394f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard break; 1395f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1396f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(FlagIndex != -1 && "Flag not supported for this instruction"); 1397f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 1398f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagIndex = GET_FLAG_OPERAND_IDX(TargetFlags); 1399f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(FlagIndex != 0 && 1400f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard "Instruction flags not supported for this instruction"); 1401f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1402f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1403f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = MI->getOperand(FlagIndex); 1404f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(FlagOp.isImm()); 1405f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return FlagOp; 1406f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1407f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1408f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid R600InstrInfo::addFlag(MachineInstr *MI, unsigned Operand, 1409f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Flag) const { 1410f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(MI->getOpcode()).TSFlags; 1411f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Flag == 0) { 1412f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return; 1413f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1414f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (HAS_NATIVE_OPERANDS(TargetFlags)) { 1415f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag); 1416f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (Flag == MO_FLAG_NOT_LAST) { 1417f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard clearFlag(MI, Operand, MO_FLAG_LAST); 1418f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (Flag == MO_FLAG_MASK) { 1419f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard clearFlag(MI, Operand, Flag); 1420f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 1421f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(1); 1422f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1423f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 1424f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI, Operand); 1425f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(FlagOp.getImm() | (Flag << (NUM_MO_FLAGS * Operand))); 1426f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1427f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1428f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 1429f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid R600InstrInfo::clearFlag(MachineInstr *MI, unsigned Operand, 1430f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned Flag) const { 1431f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned TargetFlags = get(MI->getOpcode()).TSFlags; 1432f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (HAS_NATIVE_OPERANDS(TargetFlags)) { 1433f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI, Operand, Flag); 1434f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(0); 1435f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 1436f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand &FlagOp = getFlagOp(MI); 1437f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned InstFlags = FlagOp.getImm(); 1438f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard InstFlags &= ~(Flag << (NUM_MO_FLAGS * Operand)); 1439f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard FlagOp.setImm(InstFlags); 1440f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 1441f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 1442