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