xref: /aosp_15_r20/external/mesa3d/src/imagination/vulkan/pds/pvr_rogue_pds_disasm.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2022 Imagination Technologies Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #ifndef PVR_ROGUE_PDS_DISASM_H
25 #define PVR_ROGUE_PDS_DISASM_H
26 
27 #include <stdbool.h>
28 #include <stdint.h>
29 
30 #include "util/log.h"
31 
32 /* Type of operand for an instruction. */
33 #define PVR_PDS_OPERAND_TYPES   \
34    X(TEMP32, temp, 32)          \
35    X(PTEMP32, ptemp, 32)        \
36    X(CONST32, const, 32)        \
37    X(TEMP64, temp, 64)          \
38    X(PTEMP64, ptemp, 64)        \
39    X(CONST64, const, 64)        \
40    X(UNRESOLVED, UNRESOLVED, 0) \
41    X(LITERAL_NUM, literal, 0)
42 
43 #define X(enum, str, size) enum,
44 enum pvr_operand_type { PVR_PDS_OPERAND_TYPES };
45 #undef X
46 
47 #if defined(DUMP_PDS)
48 #   define PVR_PDS_PRINT_INST(X) pvr_pds_print_instruction(X)
49 #   define PVR_PDS_PRINT_DATA(X, Y, Z) \
50       mesa_logd("\t%s   : DATA = 0x%lX ADDRESS = 0x%X\n", X, (uint64_t)(Y), Z)
51 #else
52 #   define PVR_PDS_PRINT_INST(X)
53 #   define PVR_PDS_PRINT_DATA(X, Y, Z)
54 #endif
55 
56 #define PVR_INSTRUCTION_STMP
57 #define PVR_INSTRUCTION_IDIV
58 #define PVR_INSTRUCTION_AA
59 #define PVR_INSTRUCTION_POL
60 #define PVR_INSTRUCTION_IDF
61 
62 #define PVR_INSTRUCTIONS \
63    X(STM)                \
64    PVR_INSTRUCTION_STMP  \
65    PVR_INSTRUCTION_IDIV  \
66    PVR_INSTRUCTION_AA    \
67    PVR_INSTRUCTION_IDF   \
68    PVR_INSTRUCTION_POL   \
69    X(STMC)               \
70    X(LD)                 \
71    X(ST)                 \
72    X(ADD32)              \
73    X(ADD64)              \
74    X(MAD)                \
75    X(DDMAD)              \
76    X(DOUT)               \
77    X(CMP)                \
78    X(BRA)                \
79    X(LIMM)               \
80    X(SFTLP32)            \
81    X(SFTLP64)            \
82    X(WDF)                \
83    X(LOCK)               \
84    X(RELEASE)            \
85    X(HALT)               \
86    X(NOP)
87 
88 #define X(a) INS_##a,
89 enum pvr_instruction_type { PVR_INSTRUCTIONS };
90 #undef X
91 
92 struct pvr_predicate {
93    uint32_t predicate;
94    bool negate;
95 };
96 
97 struct pvr_instruction;
98 
99 /* Operands are either sources or dst of an instruction. */
100 struct pvr_operand {
101    enum pvr_operand_type type;
102 
103    struct pvr_instruction *instruction;
104    uint64_t literal; /* Literal value if type == LITERAL_NUM */
105    int address; /* Address in word-sizes. */
106    unsigned absolute_address; /* Address in segment, */
107    unsigned index; /* Index within instruction, 0 = dst, 1 = src0 .. */
108    bool negate; /* True if the literal is negative. */
109 };
110 
111 #define PVR_PDS_LOP  \
112    X(LOP_NONE, none) \
113    X(LOP_NOT, ~)     \
114    X(LOP_AND, &)     \
115    X(LOP_OR, |)      \
116    X(LOP_XOR, xor)   \
117    X(LOP_XNOR, xnor) \
118    X(LOP_NAND, nand) \
119    X(LOP_NOR, nor)
120 
121 #define X(lop, str) lop,
122 enum pvr_pds_lop { PVR_PDS_LOP };
123 #undef X
124 
125 #define PVR_PDS_DOUT_DSTS \
126    X(DOUT_D, doutd)       \
127    X(DOUT_W, doutw)       \
128    X(DOUT_U, doutu)       \
129    X(DOUT_V, doutv)       \
130    X(DOUT_I, douti)       \
131    X(DOUT_C, doutc)       \
132    X(DOUT_R, doutr)       \
133    X(DOUT_INVALID0, invalid)
134 
135 #define X(dout_dst, str) dout_dst,
136 enum pvr_dout_type { PVR_PDS_DOUT_DSTS };
137 #undef X
138 
139 #define PVR_PDS_MAX_INST_STR_LEN 256
140 
141 enum pvr_cop { COP_EQ, COP_GT, COP_LT, COP_NE };
142 
143 struct pvr_instruction {
144    enum pvr_instruction_type type;
145    struct pvr_instruction *next;
146 };
147 
148 struct pvr_add {
149    struct pvr_instruction instruction;
150    struct pvr_operand *dst;
151    struct pvr_operand *src1;
152    struct pvr_operand *src0;
153    bool cc;
154    bool sna;
155    bool alum;
156 };
157 
158 struct pvr_simple {
159    struct pvr_instruction instruction;
160    bool cc;
161 };
162 
163 struct pvr_ldst {
164    struct pvr_instruction instruction;
165    bool cc;
166    struct pvr_operand *src0;
167    bool st;
168 };
169 
170 struct pvr_mad {
171    struct pvr_instruction instruction;
172    struct pvr_operand *dst;
173    struct pvr_operand *src0;
174    struct pvr_operand *src1;
175    struct pvr_operand *src2;
176    bool cc;
177    bool sna;
178    bool alum;
179 };
180 
181 struct pvr_stm {
182    struct pvr_instruction instruction;
183    struct pvr_operand *src0;
184    struct pvr_operand *src1;
185    struct pvr_operand *src2;
186    struct pvr_operand *src3;
187    unsigned stream_out;
188    bool tst;
189    bool cc;
190    bool ccs_global;
191    bool ccs_so;
192 };
193 
194 struct pvr_stmc {
195    struct pvr_instruction instruction;
196    struct pvr_operand *src0;
197    bool cc;
198 };
199 
200 struct pvr_bra {
201    struct pvr_instruction instruction;
202    struct pvr_predicate *srcc;
203    struct pvr_predicate *setc; /* negate ignored */
204    char *target;
205    signed address; /* signed relative address */
206 };
207 
208 struct pvr_dout {
209    struct pvr_instruction instruction;
210    struct pvr_operand *src0;
211    struct pvr_operand *src1;
212    enum pvr_dout_type dst;
213    bool cc;
214    bool END;
215 };
216 
217 struct pvr_ddmad {
218    struct pvr_instruction instruction;
219    struct pvr_operand *src0;
220    struct pvr_operand *src1;
221    struct pvr_operand *src2;
222    struct pvr_operand *src3;
223    bool cc;
224    bool END;
225 };
226 
227 struct pvr_sftlp {
228    struct pvr_instruction instruction;
229    enum pvr_pds_lop lop;
230    struct pvr_operand *dst;
231    struct pvr_operand *src0;
232    struct pvr_operand *src1;
233    struct pvr_operand *src2;
234    bool cc;
235    bool IM;
236 };
237 
238 struct pvr_limm {
239    struct pvr_instruction instruction;
240    bool cc;
241    bool GR;
242    struct pvr_operand *dst;
243    struct pvr_operand *src0;
244 };
245 
246 struct pvr_cmp {
247    struct pvr_instruction instruction;
248    enum pvr_cop cop;
249    bool IM;
250    bool cc;
251    struct pvr_operand *src0;
252    struct pvr_operand *src1;
253 };
254 
255 #define PVR_PDS_ERR_PARAM_RANGE 0 /* Error when register is out of range. */
256 #define PVR_PDS_ERR_SP_UNKNOWN \
257    1 /* Error when opcode for sp instruction is unknown. */
258 
259 struct pvr_dissassembler_error {
260    uint32_t type; /* One of PDS_ERR_* */
261    enum pvr_instruction_type instruction; /* The type of instruction where
262                                              the error occurred. */
263    char *text; /* A string representation of the error. */
264    uint32_t parameter; /* The parameter of the instruction, 0 = dst,
265                           1 = src0.. */
266    uint32_t raw; /* The raw value that caused the error. */
267 
268    void *context; /* The passed in context. */
269 };
270 
271 /* Callback when an error happens. */
272 typedef void (*PVR_ERR_CALLBACK)(struct pvr_dissassembler_error);
273 
274 void pvr_pds_free_instruction(struct pvr_instruction *inst);
275 struct pvr_instruction *
276 pvr_pds_disassemble_instruction2(void *context,
277                                  PVR_ERR_CALLBACK error_call_back,
278                                  uint32_t instruction);
279 void pvr_pds_disassemble_instruction(char *buffer,
280                                      size_t instr_len,
281                                      struct pvr_instruction *instruction);
282 
283 #if defined(DUMP_PDS)
284 void pvr_pds_print_instruction(uint32_t instr);
285 #endif
286 
287 #endif /* PVR_ROGUE_PDS_DISASM_H */
288