12ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard//===-- AMDGPUAsmPrinter.cpp - AMDGPU Assebly printer  --------------------===//
22ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard//
32ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard//                     The LLVM Compiler Infrastructure
42ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard//
52ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard// This file is distributed under the University of Illinois Open Source
62ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard// License. See LICENSE.TXT for details.
72ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard//
82ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard//===----------------------------------------------------------------------===//
92ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard//
102ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard// The AMDGPUAsmPrinter is used to print both assembly string and also binary
112ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard// code.  When passed an MCAsmStreamer it prints assembly and when passed
122ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard// an MCObjectStreamer it outputs binary code.
132ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard//
142ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard//===----------------------------------------------------------------------===//
152ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard//
162ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard
17e30b4644b613a130318cdf240ad237b0afbc525aTom Stellard
18e30b4644b613a130318cdf240ad237b0afbc525aTom Stellard#include "AMDGPUAsmPrinter.h"
19e30b4644b613a130318cdf240ad237b0afbc525aTom Stellard#include "AMDGPU.h"
20235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#include "SIMachineFunctionInfo.h"
21235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#include "SIRegisterInfo.h"
22235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#include "llvm/MC/MCStreamer.h"
23cb5227b403a9c78a734e5e67657da6c485881cbbTom Stellard#include "llvm/Target/TargetLoweringObjectFile.h"
24e30b4644b613a130318cdf240ad237b0afbc525aTom Stellard#include "llvm/Support/TargetRegistry.h"
25e30b4644b613a130318cdf240ad237b0afbc525aTom Stellard
26e30b4644b613a130318cdf240ad237b0afbc525aTom Stellardusing namespace llvm;
27e30b4644b613a130318cdf240ad237b0afbc525aTom Stellard
28e30b4644b613a130318cdf240ad237b0afbc525aTom Stellard
29e30b4644b613a130318cdf240ad237b0afbc525aTom Stellardstatic AsmPrinter *createAMDGPUAsmPrinterPass(TargetMachine &tm,
30e30b4644b613a130318cdf240ad237b0afbc525aTom Stellard                                              MCStreamer &Streamer) {
31e30b4644b613a130318cdf240ad237b0afbc525aTom Stellard  return new AMDGPUAsmPrinter(tm, Streamer);
32e30b4644b613a130318cdf240ad237b0afbc525aTom Stellard}
33e30b4644b613a130318cdf240ad237b0afbc525aTom Stellard
34e30b4644b613a130318cdf240ad237b0afbc525aTom Stellardextern "C" void LLVMInitializeAMDGPUAsmPrinter() {
35e30b4644b613a130318cdf240ad237b0afbc525aTom Stellard  TargetRegistry::RegisterAsmPrinter(TheAMDGPUTarget, createAMDGPUAsmPrinterPass);
36e30b4644b613a130318cdf240ad237b0afbc525aTom Stellard}
37235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard
38235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard/// runOnMachineFunction - We need to override this function so we can avoid
39235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard/// the call to EmitFunctionHeader(), which the MCPureStreamer can't handle.
40235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardbool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
41235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  const AMDGPUSubtarget &STM = TM.getSubtarget<AMDGPUSubtarget>();
42235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  if (STM.dumpCode()) {
43235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard    MF.dump();
44235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  }
45235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  SetupMachineFunction(MF);
46235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  if (STM.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
47235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard    EmitProgramInfo(MF);
48235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  }
49cb5227b403a9c78a734e5e67657da6c485881cbbTom Stellard  OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
50235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  EmitFunctionBody();
51235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  return false;
52235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard}
53235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard
54235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardvoid AMDGPUAsmPrinter::EmitProgramInfo(MachineFunction &MF) {
55235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  unsigned MaxSGPR = 0;
56235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  unsigned MaxVGPR = 0;
57235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  bool VCCUsed = false;
58235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  const SIRegisterInfo * RI =
59235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard                static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
60235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard
61235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
62235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard                                                  BB != BB_E; ++BB) {
63235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard    MachineBasicBlock &MBB = *BB;
64235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard    for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
65235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard                                                    I != E; ++I) {
66235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard      MachineInstr &MI = *I;
67235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard
68235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard      unsigned numOperands = MI.getNumOperands();
69235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard      for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) {
70235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        MachineOperand & MO = MI.getOperand(op_idx);
71235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        unsigned maxUsed;
72235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        unsigned width = 0;
73235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        bool isSGPR = false;
74235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        unsigned reg;
75235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        unsigned hwReg;
76235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        if (!MO.isReg()) {
77235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          continue;
78235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        }
79235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        reg = MO.getReg();
80235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        if (reg == AMDGPU::VCC) {
81235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          VCCUsed = true;
82235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          continue;
83235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        }
8416e42a5dd065c09f6d561537009639906b22ce45Michel Dänzer        if (reg == AMDGPU::EXEC) {
8516e42a5dd065c09f6d561537009639906b22ce45Michel Dänzer          continue;
8616e42a5dd065c09f6d561537009639906b22ce45Michel Dänzer        }
87235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        if (AMDGPU::SReg_32RegClass.contains(reg)) {
88235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          isSGPR = true;
89235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          width = 1;
90235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        } else if (AMDGPU::VReg_32RegClass.contains(reg)) {
91235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          isSGPR = false;
92235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          width = 1;
93235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        } else if (AMDGPU::SReg_64RegClass.contains(reg)) {
94235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          isSGPR = true;
95235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          width = 2;
96235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        } else if (AMDGPU::VReg_64RegClass.contains(reg)) {
97235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          isSGPR = false;
98235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          width = 2;
99235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        } else if (AMDGPU::SReg_128RegClass.contains(reg)) {
100235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          isSGPR = true;
101235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          width = 4;
102235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        } else if (AMDGPU::VReg_128RegClass.contains(reg)) {
103235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          isSGPR = false;
104235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          width = 4;
105235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        } else if (AMDGPU::SReg_256RegClass.contains(reg)) {
106235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          isSGPR = true;
107235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          width = 8;
108235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        } else {
109235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          assert("!Unknown register class");
110235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        }
111235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        hwReg = RI->getHWRegNum(reg);
112235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        maxUsed = hwReg + width - 1;
113235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        if (isSGPR) {
114235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          MaxSGPR = maxUsed > MaxSGPR ? maxUsed : MaxSGPR;
115235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        } else {
116235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard          MaxVGPR = maxUsed > MaxVGPR ? maxUsed : MaxVGPR;
117235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard        }
118235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard      }
119235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard    }
120235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  }
121235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  if (VCCUsed) {
122235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard    MaxSGPR += 2;
123235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  }
124235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  SIMachineFunctionInfo * MFI = MF.getInfo<SIMachineFunctionInfo>();
125235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  OutStreamer.EmitIntValue(MaxSGPR + 1, 4);
126235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  OutStreamer.EmitIntValue(MaxVGPR + 1, 4);
127235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard  OutStreamer.EmitIntValue(MFI->spi_ps_input_addr, 4);
128235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard}
129