gpu_static_inst.hh revision 11697:c63431b7bbeb
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;
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; }
289    int getRegisterIndex(int operandIndex) { return 0; }
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__
297