AMDGPUAsmPrinter.cpp revision 58a2cbef4aac9ee7d530dfb690c78d6fc11a2371
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" 22f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "SIMachineFunctionInfo.h" 23f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "SIRegisterInfo.h" 24f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/MC/MCStreamer.h" 25f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Support/TargetRegistry.h" 2658a2cbef4aac9ee7d530dfb690c78d6fc11a2371Chandler Carruth#include "llvm/Target/TargetLoweringObjectFile.h" 27f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 28f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm; 29f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 30f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 31f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic AsmPrinter *createAMDGPUAsmPrinterPass(TargetMachine &tm, 32f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MCStreamer &Streamer) { 33f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return new AMDGPUAsmPrinter(tm, Streamer); 34f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 35f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 36f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardextern "C" void LLVMInitializeR600AsmPrinter() { 37f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TargetRegistry::RegisterAsmPrinter(TheAMDGPUTarget, createAMDGPUAsmPrinterPass); 38f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 39f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 40f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// We need to override this function so we can avoid 41f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// the call to EmitFunctionHeader(), which the MCPureStreamer can't handle. 42f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 43f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const AMDGPUSubtarget &STM = TM.getSubtarget<AMDGPUSubtarget>(); 44f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (STM.dumpCode()) { 45f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 46f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MF.dump(); 47f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#endif 48f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 49f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SetupMachineFunction(MF); 50f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 51f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (STM.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) { 52f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EmitProgramInfo(MF); 53f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 54f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard EmitFunctionBody(); 55f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 56f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 57f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 58f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid AMDGPUAsmPrinter::EmitProgramInfo(MachineFunction &MF) { 59f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned MaxSGPR = 0; 60f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned MaxVGPR = 0; 61f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool VCCUsed = false; 62f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const SIRegisterInfo * RI = 63f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard static_cast<const SIRegisterInfo*>(TM.getRegisterInfo()); 64f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 65f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end(); 66f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard BB != BB_E; ++BB) { 67f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineBasicBlock &MBB = *BB; 68f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); 69f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard I != E; ++I) { 70f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineInstr &MI = *I; 71f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 72f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned numOperands = MI.getNumOperands(); 73f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) { 74f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MachineOperand & MO = MI.getOperand(op_idx); 75f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned maxUsed; 76f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned width = 0; 77f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard bool isSGPR = false; 78f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned reg; 79f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned hwReg; 80f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (!MO.isReg()) { 81f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard continue; 82f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 83f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard reg = MO.getReg(); 84f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (reg == AMDGPU::VCC) { 85f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard VCCUsed = true; 86f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard continue; 87f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 88f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard switch (reg) { 89f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard default: break; 90f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::EXEC: 91f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::SI_LITERAL_CONSTANT: 92f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::SREG_LIT_0: 93f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard case AMDGPU::M0: 94f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard continue; 95f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 96f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 97f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (AMDGPU::SReg_32RegClass.contains(reg)) { 98f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard isSGPR = true; 99f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard width = 1; 100f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (AMDGPU::VReg_32RegClass.contains(reg)) { 101f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard isSGPR = false; 102f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard width = 1; 103f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (AMDGPU::SReg_64RegClass.contains(reg)) { 104f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard isSGPR = true; 105f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard width = 2; 106f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (AMDGPU::VReg_64RegClass.contains(reg)) { 107f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard isSGPR = false; 108f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard width = 2; 109f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (AMDGPU::SReg_128RegClass.contains(reg)) { 110f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard isSGPR = true; 111f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard width = 4; 112f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (AMDGPU::VReg_128RegClass.contains(reg)) { 113f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard isSGPR = false; 114f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard width = 4; 115f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (AMDGPU::SReg_256RegClass.contains(reg)) { 116f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard isSGPR = true; 117f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard width = 8; 118f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 119f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard assert(!"Unknown register class"); 120f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 121f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard hwReg = RI->getEncodingValue(reg); 122f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard maxUsed = hwReg + width - 1; 123f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (isSGPR) { 124f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MaxSGPR = maxUsed > MaxSGPR ? maxUsed : MaxSGPR; 125f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 126f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MaxVGPR = maxUsed > MaxVGPR ? maxUsed : MaxVGPR; 127f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 128f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 130f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 131f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (VCCUsed) { 132f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MaxSGPR += 2; 133f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 134f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SIMachineFunctionInfo * MFI = MF.getInfo<SIMachineFunctionInfo>(); 135f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard OutStreamer.EmitIntValue(MaxSGPR + 1, 4); 136f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard OutStreamer.EmitIntValue(MaxVGPR + 1, 4); 137f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard OutStreamer.EmitIntValue(MFI->SPIPSInputAddr, 4); 138f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 139