blob: d957ebe2fe0bbf73d561cad0979ec6a829c33037 [file] [log] [blame]
Matt Arsenaultd82c1832013-11-10 01:03:59 +00001//===-- AMDGPUAsmPrinter.h - Print AMDGPU assembly code ---------*- C++ -*-===//
Tom Stellard75aadc22012-12-11 21:25:42 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10/// \file
11/// \brief AMDGPU Assembly printer class.
12//
13//===----------------------------------------------------------------------===//
14
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000015#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUASMPRINTER_H
16#define LLVM_LIB_TARGET_AMDGPU_AMDGPUASMPRINTER_H
Tom Stellard75aadc22012-12-11 21:25:42 +000017
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000018#include "llvm/ADT/StringRef.h"
Tom Stellard75aadc22012-12-11 21:25:42 +000019#include "llvm/CodeGen/AsmPrinter.h"
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000020#include <cstddef>
21#include <cstdint>
22#include <limits>
23#include <memory>
24#include <string>
Tom Stellarded699252013-10-12 05:02:51 +000025#include <vector>
Tom Stellard75aadc22012-12-11 21:25:42 +000026
27namespace llvm {
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000028
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +000029class AMDGPUTargetStreamer;
Matt Arsenault11f74022016-10-06 17:19:11 +000030class MCOperand;
Tom Stellard75aadc22012-12-11 21:25:42 +000031
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000032class AMDGPUAsmPrinter final : public AsmPrinter {
Matt Arsenault89cc49f2013-12-05 05:15:35 +000033private:
34 struct SIProgramInfo {
Matt Arsenault0989d512014-06-26 17:22:30 +000035 // Fields set in PGM_RSRC1 pm4 packet.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000036 uint32_t VGPRBlocks = 0;
37 uint32_t SGPRBlocks = 0;
38 uint32_t Priority = 0;
39 uint32_t FloatMode = 0;
40 uint32_t Priv = 0;
41 uint32_t DX10Clamp = 0;
42 uint32_t DebugMode = 0;
43 uint32_t IEEEMode = 0;
44 uint32_t ScratchSize = 0;
Matt Arsenault0989d512014-06-26 17:22:30 +000045
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000046 uint64_t ComputePGMRSrc1 = 0;
Tom Stellard4df465b2014-12-02 21:28:53 +000047
48 // Fields set in PGM_RSRC2 pm4 packet.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000049 uint32_t LDSBlocks = 0;
50 uint32_t ScratchBlocks = 0;
Tom Stellard4df465b2014-12-02 21:28:53 +000051
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000052 uint64_t ComputePGMRSrc2 = 0;
Tom Stellard4df465b2014-12-02 21:28:53 +000053
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000054 uint32_t NumVGPR = 0;
55 uint32_t NumSGPR = 0;
Tom Stellard4df465b2014-12-02 21:28:53 +000056 uint32_t LDSSize;
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000057 bool FlatUsed = false;
Matt Arsenault3f981402014-09-15 15:41:53 +000058
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +000059 // Number of SGPRs that meets number of waves per execution unit request.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000060 uint32_t NumSGPRsForWavesPerEU = 0;
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +000061
62 // Number of VGPRs that meets number of waves per execution unit request.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000063 uint32_t NumVGPRsForWavesPerEU = 0;
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +000064
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +000065 // If ReservedVGPRCount is 0 then must be 0. Otherwise, this is the first
66 // fixed VGPR number reserved.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000067 uint16_t ReservedVGPRFirst = 0;
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +000068
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +000069 // The number of consecutive VGPRs reserved.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000070 uint16_t ReservedVGPRCount = 0;
Konstantin Zhuravlyov1d99c4d2016-04-26 15:43:14 +000071
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +000072 // Fixed SGPR number used to hold wave scratch offset for entire kernel
Eugene Zelenkoa63528c2017-01-23 23:41:16 +000073 // execution, or std::numeric_limits<uint16_t>::max() if the register is not
74 // used or not known.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000075 uint16_t DebuggerWavefrontPrivateSegmentOffsetSGPR =
76 std::numeric_limits<uint16_t>::max();
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +000077
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +000078 // Fixed SGPR number of the first 4 SGPRs used to hold scratch V# for entire
Eugene Zelenkoa63528c2017-01-23 23:41:16 +000079 // kernel execution, or std::numeric_limits<uint16_t>::max() if the register
80 // is not used or not known.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000081 uint16_t DebuggerPrivateSegmentBufferSGPR =
82 std::numeric_limits<uint16_t>::max();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +000083
Matt Arsenault0989d512014-06-26 17:22:30 +000084 // Bonus information for debugging.
Eugene Zelenko734bb7b2017-01-20 17:52:16 +000085 bool VCCUsed = false;
86 uint64_t CodeLen = 0;
87
88 SIProgramInfo() = default;
Matt Arsenault89cc49f2013-12-05 05:15:35 +000089 };
90
Matt Arsenaultd32dbb62014-07-13 03:06:43 +000091 void getSIProgramInfo(SIProgramInfo &Out, const MachineFunction &MF) const;
92 void findNumUsedRegistersSI(const MachineFunction &MF,
Matt Arsenault89cc49f2013-12-05 05:15:35 +000093 unsigned &NumSGPR,
94 unsigned &NumVGPR) const;
95
96 /// \brief Emit register usage information so that the GPU driver
97 /// can correctly setup the GPU state.
Matt Arsenaultd32dbb62014-07-13 03:06:43 +000098 void EmitProgramInfoR600(const MachineFunction &MF);
99 void EmitProgramInfoSI(const MachineFunction &MF, const SIProgramInfo &KernelInfo);
Tom Stellardb8fd6ef2014-12-02 22:00:07 +0000100 void EmitAmdKernelCodeT(const MachineFunction &MF,
101 const SIProgramInfo &KernelInfo) const;
Tom Stellard75aadc22012-12-11 21:25:42 +0000102
103public:
David Blaikie94598322015-01-18 20:29:04 +0000104 explicit AMDGPUAsmPrinter(TargetMachine &TM,
105 std::unique_ptr<MCStreamer> Streamer);
Tom Stellard75aadc22012-12-11 21:25:42 +0000106
Mehdi Amini117296c2016-10-01 02:56:57 +0000107 StringRef getPassName() const override;
Tom Stellard75aadc22012-12-11 21:25:42 +0000108
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000109 const MCSubtargetInfo* getSTI() const;
110
111 AMDGPUTargetStreamer& getTargetStreamer() const;
112
113 bool runOnMachineFunction(MachineFunction &MF) override;
114
Matt Arsenault11f74022016-10-06 17:19:11 +0000115 /// \brief Wrapper for MCInstLowering.lowerOperand() for the tblgen'erated
116 /// pseudo lowering.
117 bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const;
118
Yaxun Liu8f844f32017-02-07 00:43:21 +0000119 /// \brief Lower the specified LLVM Constant to an MCExpr.
120 /// The AsmPrinter::lowerConstantof does not know how to lower
121 /// addrspacecast, therefore they should be lowered by this function.
122 const MCExpr *lowerConstant(const Constant *CV) override;
123
Matt Arsenault11f74022016-10-06 17:19:11 +0000124 /// \brief tblgen'erated driver function for lowering simple MI->MC pseudo
125 /// instructions.
126 bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
127 const MachineInstr *MI);
128
Tom Stellard75aadc22012-12-11 21:25:42 +0000129 /// Implemented in AMDGPUMCInstLower.cpp
Craig Topper5656db42014-04-29 07:57:24 +0000130 void EmitInstruction(const MachineInstr *MI) override;
Tom Stellarded699252013-10-12 05:02:51 +0000131
Tom Stellardf151a452015-06-26 21:14:58 +0000132 void EmitFunctionBodyStart() override;
133
Tom Stellard1e1b05d2015-11-06 11:45:14 +0000134 void EmitFunctionEntryLabel() override;
135
Tom Stellarde3b5aea2015-12-02 17:00:42 +0000136 void EmitGlobalVariable(const GlobalVariable *GV) override;
137
Tom Stellardf4218372016-01-12 17:18:17 +0000138 void EmitStartOfAsmFile(Module &M) override;
139
Konstantin Zhuravlyov7498cd62017-03-22 22:32:22 +0000140 void EmitEndOfAsmFile(Module &M) override;
141
Matt Arsenault6bc43d82016-10-06 16:20:41 +0000142 bool isBlockOnlyReachableByFallthrough(
143 const MachineBasicBlock *MBB) const override;
144
Tom Stellardd7e6f132015-04-08 01:09:26 +0000145 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
146 unsigned AsmVariant, const char *ExtraCode,
Tom Stellard80e169a2015-04-08 02:07:05 +0000147 raw_ostream &O) override;
Tom Stellardd7e6f132015-04-08 01:09:26 +0000148
Tom Stellarded699252013-10-12 05:02:51 +0000149protected:
Tom Stellarded699252013-10-12 05:02:51 +0000150 std::vector<std::string> DisasmLines, HexLines;
151 size_t DisasmLineMaxLen;
Tom Stellard75aadc22012-12-11 21:25:42 +0000152};
153
Eugene Zelenko734bb7b2017-01-20 17:52:16 +0000154} // end namespace llvm
Tom Stellard75aadc22012-12-11 21:25:42 +0000155
Eugene Zelenko734bb7b2017-01-20 17:52:16 +0000156#endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUASMPRINTER_H