AMDGPUAsmPrinter.cpp revision 141ca7fc6488bfb20ad59854cc12039e16688ed3
1f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===-- AMDGPUAsmPrinter.cpp - AMDGPU Assebly printer --------------------===// 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/// 12f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// The AMDGPUAsmPrinter is used to print both assembly string and also binary 13f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// code. When passed an MCAsmStreamer it prints assembly and when passed 14f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// an MCObjectStreamer it outputs binary code. 15f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 16f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 17f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 18f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 19f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 20f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDGPUAsmPrinter.h" 21f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDGPU.h" 229a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard#include "SIDefines.h" 23f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "SIMachineFunctionInfo.h" 24f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "SIRegisterInfo.h" 25141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune#include "R600RegisterInfo.h" 26bf1efe642111043eeb7ccaf3da759f4d2d1e4647Tom Stellard#include "llvm/MC/MCContext.h" 27bf1efe642111043eeb7ccaf3da759f4d2d1e4647Tom Stellard#include "llvm/MC/MCSectionELF.h" 28f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/MC/MCStreamer.h" 29bf1efe642111043eeb7ccaf3da759f4d2d1e4647Tom Stellard#include "llvm/Support/ELF.h" 30f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Support/TargetRegistry.h" 3158a2cbef4aac9ee7d530dfb690c78d6fc11a2371Chandler Carruth#include "llvm/Target/TargetLoweringObjectFile.h" 32f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 33f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm; 34f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 35f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 36f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic AsmPrinter *createAMDGPUAsmPrinterPass(TargetMachine &tm, 37f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MCStreamer &Streamer) { 38f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return new AMDGPUAsmPrinter(tm, Streamer); 39f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 40f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 41f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardextern "C" void LLVMInitializeR600AsmPrinter() { 42f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TargetRegistry::RegisterAsmPrinter(TheAMDGPUTarget, createAMDGPUAsmPrinterPass); 43f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 44f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 45f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// We need to override this function so we can avoid 46f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// the call to EmitFunctionHeader(), which the MCPureStreamer can't handle. 47f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 48f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const AMDGPUSubtarget &STM = TM.getSubtarget<AMDGPUSubtarget>(); 49f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (STM.dumpCode()) { 50f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 51f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MF.dump(); 52f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#endif 53f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 54f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SetupMachineFunction(MF); 553ce2ec847885b004c768869b825be1ff9d98eca3Tom Stellard if (OutStreamer.hasRawTextSupport()) { 563ce2ec847885b004c768869b825be1ff9d98eca3Tom Stellard OutStreamer.EmitRawText("@" + MF.getName() + ":"); 573ce2ec847885b004c768869b825be1ff9d98eca3Tom Stellard } 58141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune 59141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune const MCSectionELF *ConfigSection = getObjFileLowering().getContext() 60141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune .getELFSection(".AMDGPU.config", 61141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune ELF::SHT_NULL, 0, 62141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune SectionKind::getReadOnly()); 63141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune OutStreamer.SwitchSection(ConfigSection); 64f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (STM.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) { 65141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune EmitProgramInfoSI(MF); 66141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune } else { 67141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune EmitProgramInfoR600(MF); 68f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 69bf1efe642111043eeb7ccaf3da759f4d2d1e4647Tom Stellard OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 70f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EmitFunctionBody(); 71f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 72f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 73f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 74141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeunevoid AMDGPUAsmPrinter::EmitProgramInfoR600(MachineFunction &MF) { 75141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune unsigned MaxGPR = 0; 76141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune const R600RegisterInfo * RI = 77141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune static_cast<const R600RegisterInfo*>(TM.getRegisterInfo()); 78141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune 79141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end(); 80141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune BB != BB_E; ++BB) { 81141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune MachineBasicBlock &MBB = *BB; 82141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); 83141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune I != E; ++I) { 84141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune MachineInstr &MI = *I; 85141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune unsigned numOperands = MI.getNumOperands(); 86141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) { 87141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune MachineOperand & MO = MI.getOperand(op_idx); 88141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune if (!MO.isReg()) 89141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune continue; 90141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune unsigned HWReg = RI->getEncodingValue(MO.getReg()) & 0xff; 91141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune 92141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune // Register with value > 127 aren't GPR 93141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune if (HWReg > 127) 94141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune continue; 95141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune MaxGPR = std::max(MaxGPR, HWReg); 96141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune } 97141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune } 98141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune } 99141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune OutStreamer.EmitIntValue(MaxGPR + 1, 4); 100141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune} 101141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeune 102141ca7fc6488bfb20ad59854cc12039e16688ed3Vincent Lejeunevoid AMDGPUAsmPrinter::EmitProgramInfoSI(MachineFunction &MF) { 103f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned MaxSGPR = 0; 104f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned MaxVGPR = 0; 105f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool VCCUsed = false; 106f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SIRegisterInfo * RI = 107f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static_cast<const SIRegisterInfo*>(TM.getRegisterInfo()); 108f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 109f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end(); 110f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BB != BB_E; ++BB) { 111f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock &MBB = *BB; 112f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); 113f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard I != E; ++I) { 114f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr &MI = *I; 115f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 116f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned numOperands = MI.getNumOperands(); 117f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) { 118f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand & MO = MI.getOperand(op_idx); 119f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned maxUsed; 120f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned width = 0; 121f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool isSGPR = false; 122f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned reg; 123f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned hwReg; 124f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (!MO.isReg()) { 125f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard continue; 126f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 127f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard reg = MO.getReg(); 128f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (reg == AMDGPU::VCC) { 129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard VCCUsed = true; 130f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard continue; 131f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 132f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (reg) { 133f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: break; 134f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::EXEC: 135f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::M0: 136f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard continue; 137f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 138f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 139f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (AMDGPU::SReg_32RegClass.contains(reg)) { 140f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard isSGPR = true; 141f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard width = 1; 142f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (AMDGPU::VReg_32RegClass.contains(reg)) { 143f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard isSGPR = false; 144f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard width = 1; 145f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (AMDGPU::SReg_64RegClass.contains(reg)) { 146f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard isSGPR = true; 147f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard width = 2; 148f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (AMDGPU::VReg_64RegClass.contains(reg)) { 149f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard isSGPR = false; 150f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard width = 2; 1514d0e8a8a3e2e5b98f598acad4d57452b99d52e74Christian Konig } else if (AMDGPU::VReg_96RegClass.contains(reg)) { 1524d0e8a8a3e2e5b98f598acad4d57452b99d52e74Christian Konig isSGPR = false; 1534d0e8a8a3e2e5b98f598acad4d57452b99d52e74Christian Konig width = 3; 154f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (AMDGPU::SReg_128RegClass.contains(reg)) { 155f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard isSGPR = true; 156f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard width = 4; 157f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (AMDGPU::VReg_128RegClass.contains(reg)) { 158f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard isSGPR = false; 159f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard width = 4; 160f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (AMDGPU::SReg_256RegClass.contains(reg)) { 161f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard isSGPR = true; 162f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard width = 8; 16336ba9091843bd1205fe3499ba4b55bbedc6583c9Tom Stellard } else if (AMDGPU::VReg_256RegClass.contains(reg)) { 16436ba9091843bd1205fe3499ba4b55bbedc6583c9Tom Stellard isSGPR = false; 16536ba9091843bd1205fe3499ba4b55bbedc6583c9Tom Stellard width = 8; 16636ba9091843bd1205fe3499ba4b55bbedc6583c9Tom Stellard } else if (AMDGPU::VReg_512RegClass.contains(reg)) { 16736ba9091843bd1205fe3499ba4b55bbedc6583c9Tom Stellard isSGPR = false; 16836ba9091843bd1205fe3499ba4b55bbedc6583c9Tom Stellard width = 16; 169f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 170f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!"Unknown register class"); 171f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 172184f5c1545e06a99951f14d846a1d853ff19a2b8Tom Stellard hwReg = RI->getEncodingValue(reg) & 0xff; 173f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard maxUsed = hwReg + width - 1; 174f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isSGPR) { 175f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MaxSGPR = maxUsed > MaxSGPR ? maxUsed : MaxSGPR; 176f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 177f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MaxVGPR = maxUsed > MaxVGPR ? maxUsed : MaxVGPR; 178f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 179f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 180f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 181f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 182f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (VCCUsed) { 183f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MaxSGPR += 2; 184f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 185f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SIMachineFunctionInfo * MFI = MF.getInfo<SIMachineFunctionInfo>(); 1869a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard unsigned RsrcReg; 1879a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard switch (MFI->ShaderType) { 1889a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard default: // Fall through 1899a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard case ShaderType::COMPUTE: RsrcReg = R_00B848_COMPUTE_PGM_RSRC1; break; 1909a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard case ShaderType::GEOMETRY: RsrcReg = R_00B228_SPI_SHADER_PGM_RSRC1_GS; break; 1919a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard case ShaderType::PIXEL: RsrcReg = R_00B028_SPI_SHADER_PGM_RSRC1_PS; break; 1929a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard case ShaderType::VERTEX: RsrcReg = R_00B128_SPI_SHADER_PGM_RSRC1_VS; break; 1939a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard } 1949a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard 1959a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard OutStreamer.EmitIntValue(RsrcReg, 4); 1969a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard OutStreamer.EmitIntValue(S_00B028_VGPRS(MaxVGPR / 4) | S_00B028_SGPRS(MaxSGPR / 8), 4); 1979a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard if (MFI->ShaderType == ShaderType::PIXEL) { 1989a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard OutStreamer.EmitIntValue(R_0286CC_SPI_PS_INPUT_ENA, 4); 1999a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard OutStreamer.EmitIntValue(MFI->PSInputAddr, 4); 2009a256300f8f61937f5f7a148b9cb09936d103a97Tom Stellard } 201f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 202