gpu_static_inst.hh (11697:c63431b7bbeb) gpu_static_inst.hh (11699:c7453f485a5f)
1/*
2 * Copyright (c) 2015 Advanced Micro Devices, Inc.
3 * All rights reserved.
4 *
5 * For use for simulation and test purposes only
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Author: Anthony Gutierrez
34 */
35
36#ifndef __GPU_STATIC_INST_HH__
37#define __GPU_STATIC_INST_HH__
38
39/*
40 * @file gpu_static_inst.hh
41 *
42 * Defines the base class representing static instructions for the GPU. The
43 * instructions are "static" because they contain no dynamic instruction
44 * information. GPUStaticInst corresponds to the StaticInst class for the CPU
45 * models.
46 */
47
48#include <cstdint>
49#include <string>
50
51#include "enums/GPUStaticInstFlags.hh"
52#include "enums/StorageClassType.hh"
53#include "gpu-compute/gpu_dyn_inst.hh"
54#include "gpu-compute/misc.hh"
55
56class BaseOperand;
57class BaseRegOperand;
58class Wavefront;
59
60class GPUStaticInst : public GPUStaticInstFlags
61{
62 public:
63 GPUStaticInst(const std::string &opcode);
64 void instAddr(int inst_addr) { _instAddr = inst_addr; }
65 int instAddr() const { return _instAddr; }
66 int nextInstAddr() const { return _instAddr + instSize(); }
67
68 void instNum(int num) { _instNum = num; }
69
70 int instNum() { return _instNum; }
71
72 void ipdInstNum(int num) { _ipdInstNum = num; }
73
74 int ipdInstNum() const { return _ipdInstNum; }
75
76 virtual void execute(GPUDynInstPtr gpuDynInst) = 0;
77 virtual void generateDisassembly() = 0;
78 const std::string& disassemble();
79 virtual int getNumOperands() = 0;
80 virtual bool isCondRegister(int operandIndex) = 0;
81 virtual bool isScalarRegister(int operandIndex) = 0;
82 virtual bool isVectorRegister(int operandIndex) = 0;
83 virtual bool isSrcOperand(int operandIndex) = 0;
84 virtual bool isDstOperand(int operandIndex) = 0;
85 virtual int getOperandSize(int operandIndex) = 0;
1/*
2 * Copyright (c) 2015 Advanced Micro Devices, Inc.
3 * All rights reserved.
4 *
5 * For use for simulation and test purposes only
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Author: Anthony Gutierrez
34 */
35
36#ifndef __GPU_STATIC_INST_HH__
37#define __GPU_STATIC_INST_HH__
38
39/*
40 * @file gpu_static_inst.hh
41 *
42 * Defines the base class representing static instructions for the GPU. The
43 * instructions are "static" because they contain no dynamic instruction
44 * information. GPUStaticInst corresponds to the StaticInst class for the CPU
45 * models.
46 */
47
48#include <cstdint>
49#include <string>
50
51#include "enums/GPUStaticInstFlags.hh"
52#include "enums/StorageClassType.hh"
53#include "gpu-compute/gpu_dyn_inst.hh"
54#include "gpu-compute/misc.hh"
55
56class BaseOperand;
57class BaseRegOperand;
58class Wavefront;
59
60class GPUStaticInst : public GPUStaticInstFlags
61{
62 public:
63 GPUStaticInst(const std::string &opcode);
64 void instAddr(int inst_addr) { _instAddr = inst_addr; }
65 int instAddr() const { return _instAddr; }
66 int nextInstAddr() const { return _instAddr + instSize(); }
67
68 void instNum(int num) { _instNum = num; }
69
70 int instNum() { return _instNum; }
71
72 void ipdInstNum(int num) { _ipdInstNum = num; }
73
74 int ipdInstNum() const { return _ipdInstNum; }
75
76 virtual void execute(GPUDynInstPtr gpuDynInst) = 0;
77 virtual void generateDisassembly() = 0;
78 const std::string& disassemble();
79 virtual int getNumOperands() = 0;
80 virtual bool isCondRegister(int operandIndex) = 0;
81 virtual bool isScalarRegister(int operandIndex) = 0;
82 virtual bool isVectorRegister(int operandIndex) = 0;
83 virtual bool isSrcOperand(int operandIndex) = 0;
84 virtual bool isDstOperand(int operandIndex) = 0;
85 virtual int getOperandSize(int operandIndex) = 0;
86 virtual int getRegisterIndex(int operandIndex) = 0;
86
87 virtual int getRegisterIndex(int operandIndex,
88 GPUDynInstPtr gpuDynInst) = 0;
89
87 virtual int numDstRegOperands() = 0;
88 virtual int numSrcRegOperands() = 0;
89
90 virtual bool isValid() const = 0;
91
92 bool isALU() const { return _flags[ALU]; }
93 bool isBranch() const { return _flags[Branch]; }
94 bool isNop() const { return _flags[Nop]; }
95 bool isReturn() const { return _flags[Return]; }
96
97 bool
98 isUnconditionalJump() const
99 {
100 return _flags[UnconditionalJump];
101 }
102
103 bool isSpecialOp() const { return _flags[SpecialOp]; }
104 bool isWaitcnt() const { return _flags[Waitcnt]; }
105
106 bool isBarrier() const { return _flags[MemBarrier]; }
107 bool isMemFence() const { return _flags[MemFence]; }
108 bool isMemRef() const { return _flags[MemoryRef]; }
109 bool isFlat() const { return _flags[Flat]; }
110 bool isLoad() const { return _flags[Load]; }
111 bool isStore() const { return _flags[Store]; }
112
113 bool
114 isAtomic() const
115 {
116 return _flags[AtomicReturn] || _flags[AtomicNoReturn];
117 }
118
119 bool isAtomicNoRet() const { return _flags[AtomicNoReturn]; }
120 bool isAtomicRet() const { return _flags[AtomicReturn]; }
121
122 bool isScalar() const { return _flags[Scalar]; }
123 bool readsSCC() const { return _flags[ReadsSCC]; }
124 bool writesSCC() const { return _flags[WritesSCC]; }
125 bool readsVCC() const { return _flags[ReadsVCC]; }
126 bool writesVCC() const { return _flags[WritesVCC]; }
127
128 bool isAtomicAnd() const { return _flags[AtomicAnd]; }
129 bool isAtomicOr() const { return _flags[AtomicOr]; }
130 bool isAtomicXor() const { return _flags[AtomicXor]; }
131 bool isAtomicCAS() const { return _flags[AtomicCAS]; }
132 bool isAtomicExch() const { return _flags[AtomicExch]; }
133 bool isAtomicAdd() const { return _flags[AtomicAdd]; }
134 bool isAtomicSub() const { return _flags[AtomicSub]; }
135 bool isAtomicInc() const { return _flags[AtomicInc]; }
136 bool isAtomicDec() const { return _flags[AtomicDec]; }
137 bool isAtomicMax() const { return _flags[AtomicMax]; }
138 bool isAtomicMin() const { return _flags[AtomicMin]; }
139
140 bool
141 isArgLoad() const
142 {
143 return (_flags[KernArgSegment] || _flags[ArgSegment]) && _flags[Load];
144 }
145
146 bool
147 isGlobalMem() const
148 {
149 return _flags[MemoryRef] && (_flags[GlobalSegment] ||
150 _flags[PrivateSegment] || _flags[ReadOnlySegment] ||
151 _flags[SpillSegment]);
152 }
153
154 bool
155 isLocalMem() const
156 {
157 return _flags[MemoryRef] && _flags[GroupSegment];
158 }
159
160 bool isArgSeg() const { return _flags[ArgSegment]; }
161 bool isGlobalSeg() const { return _flags[GlobalSegment]; }
162 bool isGroupSeg() const { return _flags[GroupSegment]; }
163 bool isKernArgSeg() const { return _flags[KernArgSegment]; }
164 bool isPrivateSeg() const { return _flags[PrivateSegment]; }
165 bool isReadOnlySeg() const { return _flags[ReadOnlySegment]; }
166 bool isSpillSeg() const { return _flags[SpillSegment]; }
167
168 bool isWorkitemScope() const { return _flags[WorkitemScope]; }
169 bool isWavefrontScope() const { return _flags[WavefrontScope]; }
170 bool isWorkgroupScope() const { return _flags[WorkgroupScope]; }
171 bool isDeviceScope() const { return _flags[DeviceScope]; }
172 bool isSystemScope() const { return _flags[SystemScope]; }
173 bool isNoScope() const { return _flags[NoScope]; }
174
175 bool isRelaxedOrder() const { return _flags[RelaxedOrder]; }
176 bool isAcquire() const { return _flags[Acquire]; }
177 bool isRelease() const { return _flags[Release]; }
178 bool isAcquireRelease() const { return _flags[AcquireRelease]; }
179 bool isNoOrder() const { return _flags[NoOrder]; }
180
181 /**
182 * Coherence domain of a memory instruction. Only valid for
183 * machine ISA. The coherence domain specifies where it is
184 * possible to perform memory synchronization, e.g., acquire
185 * or release, from the shader kernel.
186 *
187 * isGloballyCoherent(): returns true if kernel is sharing memory
188 * with other work-items on the same device (GPU)
189 *
190 * isSystemCoherent(): returns true if kernel is sharing memory
191 * with other work-items on a different device (GPU) or the host (CPU)
192 */
193 bool isGloballyCoherent() const { return _flags[GloballyCoherent]; }
194 bool isSystemCoherent() const { return _flags[SystemCoherent]; }
195
196 virtual int instSize() const = 0;
197
198 // only used for memory instructions
199 virtual void
200 initiateAcc(GPUDynInstPtr gpuDynInst)
201 {
202 fatal("calling initiateAcc() on a non-memory instruction.\n");
203 }
204
205 // only used for memory instructions
206 virtual void
207 completeAcc(GPUDynInstPtr gpuDynInst)
208 {
209 fatal("calling completeAcc() on a non-memory instruction.\n");
210 }
211
212 virtual uint32_t getTargetPc() { return 0; }
213
214 static uint64_t dynamic_id_count;
215
216 // For flat memory accesses
217 Enums::StorageClassType executed_as;
218
219 void setFlag(Flags flag) { _flags[flag] = true; }
220
221 protected:
222 virtual void
223 execLdAcq(GPUDynInstPtr gpuDynInst)
224 {
225 fatal("calling execLdAcq() on a non-load instruction.\n");
226 }
227
228 virtual void
229 execSt(GPUDynInstPtr gpuDynInst)
230 {
231 fatal("calling execLdAcq() on a non-load instruction.\n");
232 }
233
234 virtual void
235 execAtomic(GPUDynInstPtr gpuDynInst)
236 {
237 fatal("calling execAtomic() on a non-atomic instruction.\n");
238 }
239
240 virtual void
241 execAtomicAcq(GPUDynInstPtr gpuDynInst)
242 {
243 fatal("calling execAtomicAcq() on a non-atomic instruction.\n");
244 }
245
246 const std::string opcode;
247 std::string disassembly;
248 int _instNum;
249 int _instAddr;
250 /**
251 * Identifier of the immediate post-dominator instruction.
252 */
253 int _ipdInstNum;
254
255 std::bitset<Num_Flags> _flags;
256};
257
258class KernelLaunchStaticInst : public GPUStaticInst
259{
260 public:
261 KernelLaunchStaticInst() : GPUStaticInst("kernel_launch")
262 {
263 setFlag(Nop);
264 setFlag(Scalar);
265 setFlag(Acquire);
266 setFlag(SystemScope);
267 setFlag(GlobalSegment);
268 }
269
270 void
271 execute(GPUDynInstPtr gpuDynInst)
272 {
273 fatal("kernel launch instruction should not be executed\n");
274 }
275
276 void
277 generateDisassembly()
278 {
279 disassembly = opcode;
280 }
281
282 int getNumOperands() { return 0; }
283 bool isCondRegister(int operandIndex) { return false; }
284 bool isScalarRegister(int operandIndex) { return false; }
285 bool isVectorRegister(int operandIndex) { return false; }
286 bool isSrcOperand(int operandIndex) { return false; }
287 bool isDstOperand(int operandIndex) { return false; }
288 int getOperandSize(int operandIndex) { return 0; }
90 virtual int numDstRegOperands() = 0;
91 virtual int numSrcRegOperands() = 0;
92
93 virtual bool isValid() const = 0;
94
95 bool isALU() const { return _flags[ALU]; }
96 bool isBranch() const { return _flags[Branch]; }
97 bool isNop() const { return _flags[Nop]; }
98 bool isReturn() const { return _flags[Return]; }
99
100 bool
101 isUnconditionalJump() const
102 {
103 return _flags[UnconditionalJump];
104 }
105
106 bool isSpecialOp() const { return _flags[SpecialOp]; }
107 bool isWaitcnt() const { return _flags[Waitcnt]; }
108
109 bool isBarrier() const { return _flags[MemBarrier]; }
110 bool isMemFence() const { return _flags[MemFence]; }
111 bool isMemRef() const { return _flags[MemoryRef]; }
112 bool isFlat() const { return _flags[Flat]; }
113 bool isLoad() const { return _flags[Load]; }
114 bool isStore() const { return _flags[Store]; }
115
116 bool
117 isAtomic() const
118 {
119 return _flags[AtomicReturn] || _flags[AtomicNoReturn];
120 }
121
122 bool isAtomicNoRet() const { return _flags[AtomicNoReturn]; }
123 bool isAtomicRet() const { return _flags[AtomicReturn]; }
124
125 bool isScalar() const { return _flags[Scalar]; }
126 bool readsSCC() const { return _flags[ReadsSCC]; }
127 bool writesSCC() const { return _flags[WritesSCC]; }
128 bool readsVCC() const { return _flags[ReadsVCC]; }
129 bool writesVCC() const { return _flags[WritesVCC]; }
130
131 bool isAtomicAnd() const { return _flags[AtomicAnd]; }
132 bool isAtomicOr() const { return _flags[AtomicOr]; }
133 bool isAtomicXor() const { return _flags[AtomicXor]; }
134 bool isAtomicCAS() const { return _flags[AtomicCAS]; }
135 bool isAtomicExch() const { return _flags[AtomicExch]; }
136 bool isAtomicAdd() const { return _flags[AtomicAdd]; }
137 bool isAtomicSub() const { return _flags[AtomicSub]; }
138 bool isAtomicInc() const { return _flags[AtomicInc]; }
139 bool isAtomicDec() const { return _flags[AtomicDec]; }
140 bool isAtomicMax() const { return _flags[AtomicMax]; }
141 bool isAtomicMin() const { return _flags[AtomicMin]; }
142
143 bool
144 isArgLoad() const
145 {
146 return (_flags[KernArgSegment] || _flags[ArgSegment]) && _flags[Load];
147 }
148
149 bool
150 isGlobalMem() const
151 {
152 return _flags[MemoryRef] && (_flags[GlobalSegment] ||
153 _flags[PrivateSegment] || _flags[ReadOnlySegment] ||
154 _flags[SpillSegment]);
155 }
156
157 bool
158 isLocalMem() const
159 {
160 return _flags[MemoryRef] && _flags[GroupSegment];
161 }
162
163 bool isArgSeg() const { return _flags[ArgSegment]; }
164 bool isGlobalSeg() const { return _flags[GlobalSegment]; }
165 bool isGroupSeg() const { return _flags[GroupSegment]; }
166 bool isKernArgSeg() const { return _flags[KernArgSegment]; }
167 bool isPrivateSeg() const { return _flags[PrivateSegment]; }
168 bool isReadOnlySeg() const { return _flags[ReadOnlySegment]; }
169 bool isSpillSeg() const { return _flags[SpillSegment]; }
170
171 bool isWorkitemScope() const { return _flags[WorkitemScope]; }
172 bool isWavefrontScope() const { return _flags[WavefrontScope]; }
173 bool isWorkgroupScope() const { return _flags[WorkgroupScope]; }
174 bool isDeviceScope() const { return _flags[DeviceScope]; }
175 bool isSystemScope() const { return _flags[SystemScope]; }
176 bool isNoScope() const { return _flags[NoScope]; }
177
178 bool isRelaxedOrder() const { return _flags[RelaxedOrder]; }
179 bool isAcquire() const { return _flags[Acquire]; }
180 bool isRelease() const { return _flags[Release]; }
181 bool isAcquireRelease() const { return _flags[AcquireRelease]; }
182 bool isNoOrder() const { return _flags[NoOrder]; }
183
184 /**
185 * Coherence domain of a memory instruction. Only valid for
186 * machine ISA. The coherence domain specifies where it is
187 * possible to perform memory synchronization, e.g., acquire
188 * or release, from the shader kernel.
189 *
190 * isGloballyCoherent(): returns true if kernel is sharing memory
191 * with other work-items on the same device (GPU)
192 *
193 * isSystemCoherent(): returns true if kernel is sharing memory
194 * with other work-items on a different device (GPU) or the host (CPU)
195 */
196 bool isGloballyCoherent() const { return _flags[GloballyCoherent]; }
197 bool isSystemCoherent() const { return _flags[SystemCoherent]; }
198
199 virtual int instSize() const = 0;
200
201 // only used for memory instructions
202 virtual void
203 initiateAcc(GPUDynInstPtr gpuDynInst)
204 {
205 fatal("calling initiateAcc() on a non-memory instruction.\n");
206 }
207
208 // only used for memory instructions
209 virtual void
210 completeAcc(GPUDynInstPtr gpuDynInst)
211 {
212 fatal("calling completeAcc() on a non-memory instruction.\n");
213 }
214
215 virtual uint32_t getTargetPc() { return 0; }
216
217 static uint64_t dynamic_id_count;
218
219 // For flat memory accesses
220 Enums::StorageClassType executed_as;
221
222 void setFlag(Flags flag) { _flags[flag] = true; }
223
224 protected:
225 virtual void
226 execLdAcq(GPUDynInstPtr gpuDynInst)
227 {
228 fatal("calling execLdAcq() on a non-load instruction.\n");
229 }
230
231 virtual void
232 execSt(GPUDynInstPtr gpuDynInst)
233 {
234 fatal("calling execLdAcq() on a non-load instruction.\n");
235 }
236
237 virtual void
238 execAtomic(GPUDynInstPtr gpuDynInst)
239 {
240 fatal("calling execAtomic() on a non-atomic instruction.\n");
241 }
242
243 virtual void
244 execAtomicAcq(GPUDynInstPtr gpuDynInst)
245 {
246 fatal("calling execAtomicAcq() on a non-atomic instruction.\n");
247 }
248
249 const std::string opcode;
250 std::string disassembly;
251 int _instNum;
252 int _instAddr;
253 /**
254 * Identifier of the immediate post-dominator instruction.
255 */
256 int _ipdInstNum;
257
258 std::bitset<Num_Flags> _flags;
259};
260
261class KernelLaunchStaticInst : public GPUStaticInst
262{
263 public:
264 KernelLaunchStaticInst() : GPUStaticInst("kernel_launch")
265 {
266 setFlag(Nop);
267 setFlag(Scalar);
268 setFlag(Acquire);
269 setFlag(SystemScope);
270 setFlag(GlobalSegment);
271 }
272
273 void
274 execute(GPUDynInstPtr gpuDynInst)
275 {
276 fatal("kernel launch instruction should not be executed\n");
277 }
278
279 void
280 generateDisassembly()
281 {
282 disassembly = opcode;
283 }
284
285 int getNumOperands() { return 0; }
286 bool isCondRegister(int operandIndex) { return false; }
287 bool isScalarRegister(int operandIndex) { return false; }
288 bool isVectorRegister(int operandIndex) { return false; }
289 bool isSrcOperand(int operandIndex) { return false; }
290 bool isDstOperand(int operandIndex) { return false; }
291 int getOperandSize(int operandIndex) { return 0; }
289 int getRegisterIndex(int operandIndex) { return 0; }
292
293 int
294 getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst) override
295 {
296 return 0;
297 }
298
290 int numDstRegOperands() { return 0; }
291 int numSrcRegOperands() { return 0; }
292 bool isValid() const { return true; }
293 int instSize() const override { return 0; }
294};
295
296#endif // __GPU_STATIC_INST_HH__
299 int numDstRegOperands() { return 0; }
300 int numSrcRegOperands() { return 0; }
301 bool isValid() const { return true; }
302 int instSize() const override { return 0; }
303};
304
305#endif // __GPU_STATIC_INST_HH__