broadcom/vc5: Add a test for .ifb in ADD ops.
[mesa.git] / src / broadcom / qpu / qpu_instr.h
1 /*
2 * Copyright © 2016 Broadcom
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is 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
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 /**
25 * @file qpu_instr.h
26 *
27 * Definitions of the unpacked form of QPU instructions. Assembly and
28 * disassembly will use this for talking about instructions, with qpu_encode.c
29 * and qpu_decode.c handling the pack and unpack of the actual 64-bit QPU
30 * instruction.
31 */
32
33 #ifndef QPU_INSTR_H
34 #define QPU_INSTR_H
35
36 #include <stdbool.h>
37 #include <stdint.h>
38 #include "util/macros.h"
39
40 struct v3d_device_info;
41
42 struct v3d_qpu_sig {
43 bool thrsw:1;
44 bool ldunif:1;
45 bool ldunifa:1;
46 bool ldunifrf:1;
47 bool ldunifarf:1;
48 bool ldtmu:1;
49 bool ldvary:1;
50 bool ldvpm:1;
51 bool ldtlb:1;
52 bool ldtlbu:1;
53 bool small_imm:1;
54 bool ucb:1;
55 bool rotate:1;
56 bool wrtmuc:1;
57 };
58
59 enum v3d_qpu_cond {
60 V3D_QPU_COND_NONE,
61 V3D_QPU_COND_IFA,
62 V3D_QPU_COND_IFB,
63 V3D_QPU_COND_IFNA,
64 V3D_QPU_COND_IFNB,
65 };
66
67 enum v3d_qpu_pf {
68 V3D_QPU_PF_NONE,
69 V3D_QPU_PF_PUSHZ,
70 V3D_QPU_PF_PUSHN,
71 V3D_QPU_PF_PUSHC,
72 };
73
74 enum v3d_qpu_uf {
75 V3D_QPU_UF_NONE,
76 V3D_QPU_UF_ANDZ,
77 V3D_QPU_UF_ANDNZ,
78 V3D_QPU_UF_NORNZ,
79 V3D_QPU_UF_NORZ,
80 V3D_QPU_UF_ANDN,
81 V3D_QPU_UF_ANDNN,
82 V3D_QPU_UF_NORNN,
83 V3D_QPU_UF_NORN,
84 V3D_QPU_UF_ANDC,
85 V3D_QPU_UF_ANDNC,
86 V3D_QPU_UF_NORNC,
87 V3D_QPU_UF_NORC,
88 };
89
90 enum v3d_qpu_waddr {
91 V3D_QPU_WADDR_R0 = 0,
92 V3D_QPU_WADDR_R1 = 1,
93 V3D_QPU_WADDR_R2 = 2,
94 V3D_QPU_WADDR_R3 = 3,
95 V3D_QPU_WADDR_R4 = 4,
96 V3D_QPU_WADDR_R5 = 5,
97 /* 6 is reserved, but note 3.2.2.8: "Result Writes" */
98 V3D_QPU_WADDR_NOP = 6,
99 V3D_QPU_WADDR_TLB = 7,
100 V3D_QPU_WADDR_TLBU = 8,
101 V3D_QPU_WADDR_TMU = 9,
102 V3D_QPU_WADDR_TMUL = 10,
103 V3D_QPU_WADDR_TMUD = 11,
104 V3D_QPU_WADDR_TMUA = 12,
105 V3D_QPU_WADDR_TMUAU = 13,
106 V3D_QPU_WADDR_VPM = 14,
107 V3D_QPU_WADDR_VPMU = 15,
108 V3D_QPU_WADDR_SYNC = 16,
109 V3D_QPU_WADDR_SYNCU = 17,
110 /* reserved */
111 V3D_QPU_WADDR_RECIP = 19,
112 V3D_QPU_WADDR_RSQRT = 20,
113 V3D_QPU_WADDR_EXP = 21,
114 V3D_QPU_WADDR_LOG = 22,
115 V3D_QPU_WADDR_SIN = 23,
116 V3D_QPU_WADDR_RSQRT2 = 24,
117 };
118
119 struct v3d_qpu_flags {
120 enum v3d_qpu_cond ac, mc;
121 enum v3d_qpu_pf apf, mpf;
122 enum v3d_qpu_uf auf, muf;
123 };
124
125 enum v3d_qpu_add_op {
126 V3D_QPU_A_FADD,
127 V3D_QPU_A_FADDNF,
128 V3D_QPU_A_VFPACK,
129 V3D_QPU_A_ADD,
130 V3D_QPU_A_SUB,
131 V3D_QPU_A_FSUB,
132 V3D_QPU_A_MIN,
133 V3D_QPU_A_MAX,
134 V3D_QPU_A_UMIN,
135 V3D_QPU_A_UMAX,
136 V3D_QPU_A_SHL,
137 V3D_QPU_A_SHR,
138 V3D_QPU_A_ASR,
139 V3D_QPU_A_ROR,
140 V3D_QPU_A_FMIN,
141 V3D_QPU_A_FMAX,
142 V3D_QPU_A_VFMIN,
143 V3D_QPU_A_AND,
144 V3D_QPU_A_OR,
145 V3D_QPU_A_XOR,
146 V3D_QPU_A_VADD,
147 V3D_QPU_A_VSUB,
148 V3D_QPU_A_NOT,
149 V3D_QPU_A_NEG,
150 V3D_QPU_A_FLAPUSH,
151 V3D_QPU_A_FLBPUSH,
152 V3D_QPU_A_FLBPOP,
153 V3D_QPU_A_SETMSF,
154 V3D_QPU_A_SETREVF,
155 V3D_QPU_A_NOP,
156 V3D_QPU_A_TIDX,
157 V3D_QPU_A_EIDX,
158 V3D_QPU_A_LR,
159 V3D_QPU_A_VFLA,
160 V3D_QPU_A_VFLNA,
161 V3D_QPU_A_VFLB,
162 V3D_QPU_A_VFLNB,
163 V3D_QPU_A_FXCD,
164 V3D_QPU_A_XCD,
165 V3D_QPU_A_FYCD,
166 V3D_QPU_A_YCD,
167 V3D_QPU_A_MSF,
168 V3D_QPU_A_REVF,
169 V3D_QPU_A_VDWWT,
170 V3D_QPU_A_IID,
171 V3D_QPU_A_SAMPID,
172 V3D_QPU_A_PATCHID,
173 V3D_QPU_A_TMUWT,
174 V3D_QPU_A_VPMSETUP,
175 V3D_QPU_A_VPMWT,
176 V3D_QPU_A_LDVPMV_IN,
177 V3D_QPU_A_LDVPMV_OUT,
178 V3D_QPU_A_LDVPMD_IN,
179 V3D_QPU_A_LDVPMD_OUT,
180 V3D_QPU_A_LDVPMP,
181 V3D_QPU_A_LDVPMG_IN,
182 V3D_QPU_A_LDVPMG_OUT,
183 V3D_QPU_A_FCMP,
184 V3D_QPU_A_VFMAX,
185 V3D_QPU_A_FROUND,
186 V3D_QPU_A_FTOIN,
187 V3D_QPU_A_FTRUNC,
188 V3D_QPU_A_FTOIZ,
189 V3D_QPU_A_FFLOOR,
190 V3D_QPU_A_FTOUZ,
191 V3D_QPU_A_FCEIL,
192 V3D_QPU_A_FTOC,
193 V3D_QPU_A_FDX,
194 V3D_QPU_A_FDY,
195 V3D_QPU_A_STVPMV,
196 V3D_QPU_A_STVPMD,
197 V3D_QPU_A_STVPMP,
198 V3D_QPU_A_ITOF,
199 V3D_QPU_A_CLZ,
200 V3D_QPU_A_UTOF,
201 };
202
203 enum v3d_qpu_mul_op {
204 V3D_QPU_M_ADD,
205 V3D_QPU_M_SUB,
206 V3D_QPU_M_UMUL24,
207 V3D_QPU_M_VFMUL,
208 V3D_QPU_M_SMUL24,
209 V3D_QPU_M_MULTOP,
210 V3D_QPU_M_FMOV,
211 V3D_QPU_M_MOV,
212 V3D_QPU_M_NOP,
213 V3D_QPU_M_FMUL,
214 };
215
216 enum v3d_qpu_output_pack {
217 V3D_QPU_PACK_NONE,
218 /**
219 * Convert to 16-bit float, put in low 16 bits of destination leaving
220 * high unmodified.
221 */
222 V3D_QPU_PACK_L,
223 /**
224 * Convert to 16-bit float, put in high 16 bits of destination leaving
225 * low unmodified.
226 */
227 V3D_QPU_PACK_H,
228 };
229
230 enum v3d_qpu_input_unpack {
231 /**
232 * No-op input unpacking. Note that this enum's value doesn't match
233 * the packed QPU instruction value of the field (we use 0 so that the
234 * default on new instruction creation is no-op).
235 */
236 V3D_QPU_UNPACK_NONE,
237 /** Absolute value. Only available for some operations. */
238 V3D_QPU_UNPACK_ABS,
239 /** Convert low 16 bits from 16-bit float to 32-bit float. */
240 V3D_QPU_UNPACK_L,
241 /** Convert high 16 bits from 16-bit float to 32-bit float. */
242 V3D_QPU_UNPACK_H,
243
244 /** Convert to 16f and replicate it to the high bits. */
245 V3D_QPU_UNPACK_REPLICATE_32F_16,
246
247 /** Replicate low 16 bits to high */
248 V3D_QPU_UNPACK_REPLICATE_L_16,
249
250 /** Replicate high 16 bits to low */
251 V3D_QPU_UNPACK_REPLICATE_H_16,
252
253 /** Swap high and low 16 bits */
254 V3D_QPU_UNPACK_SWAP_16,
255 };
256
257 enum v3d_qpu_mux {
258 V3D_QPU_MUX_R0,
259 V3D_QPU_MUX_R1,
260 V3D_QPU_MUX_R2,
261 V3D_QPU_MUX_R3,
262 V3D_QPU_MUX_R4,
263 V3D_QPU_MUX_R5,
264 V3D_QPU_MUX_A,
265 V3D_QPU_MUX_B,
266 };
267
268 struct v3d_qpu_alu_instr {
269 struct {
270 enum v3d_qpu_add_op op;
271 enum v3d_qpu_mux a, b;
272 uint8_t waddr;
273 bool magic_write;
274 enum v3d_qpu_output_pack output_pack;
275 enum v3d_qpu_input_unpack a_unpack;
276 enum v3d_qpu_input_unpack b_unpack;
277 } add;
278
279 struct {
280 enum v3d_qpu_mul_op op;
281 enum v3d_qpu_mux a, b;
282 uint8_t waddr;
283 bool magic_write;
284 enum v3d_qpu_output_pack output_pack;
285 enum v3d_qpu_input_unpack a_unpack;
286 enum v3d_qpu_input_unpack b_unpack;
287 } mul;
288 };
289
290 enum v3d_qpu_branch_cond {
291 V3D_QPU_BRANCH_COND_ALWAYS,
292 V3D_QPU_BRANCH_COND_A0,
293 V3D_QPU_BRANCH_COND_NA0,
294 V3D_QPU_BRANCH_COND_ALLA,
295 V3D_QPU_BRANCH_COND_ANYNA,
296 V3D_QPU_BRANCH_COND_ANYA,
297 V3D_QPU_BRANCH_COND_ALLNA,
298 };
299
300 enum v3d_qpu_msfign {
301 /** Ignore multisample flags when determining branch condition. */
302 V3D_QPU_MSFIGN_NONE,
303 /**
304 * If no multisample flags are set in the lane (a pixel in the FS, a
305 * vertex in the VS), ignore the lane's condition when computing the
306 * branch condition.
307 */
308 V3D_QPU_MSFIGN_P,
309 /**
310 * If no multisample flags are set in a 2x2 quad in the FS, ignore the
311 * quad's a/b conditions.
312 */
313 V3D_QPU_MSFIGN_Q,
314 };
315
316 enum v3d_qpu_branch_dest {
317 V3D_QPU_BRANCH_DEST_ABS,
318 V3D_QPU_BRANCH_DEST_REL,
319 V3D_QPU_BRANCH_DEST_LINK_REG,
320 V3D_QPU_BRANCH_DEST_REGFILE,
321 };
322
323 struct v3d_qpu_branch_instr {
324 enum v3d_qpu_branch_cond cond;
325 enum v3d_qpu_msfign msfign;
326
327 /** Selects how to compute the new IP if the branch is taken. */
328 enum v3d_qpu_branch_dest bdi;
329
330 /**
331 * Selects how to compute the new uniforms pointer if the branch is
332 * taken. (ABS/REL implicitly load a uniform and use that)
333 */
334 enum v3d_qpu_branch_dest bdu;
335
336 /**
337 * If set, then udest determines how the uniform stream will branch,
338 * otherwise the uniform stream is left as is.
339 */
340 bool ub;
341
342 uint8_t raddr_a;
343
344 uint32_t offset;
345 };
346
347 enum v3d_qpu_instr_type {
348 V3D_QPU_INSTR_TYPE_ALU,
349 V3D_QPU_INSTR_TYPE_BRANCH,
350 };
351
352 struct v3d_qpu_instr {
353 enum v3d_qpu_instr_type type;
354
355 struct v3d_qpu_sig sig;
356 uint8_t sig_addr;
357 bool sig_magic; /* If the signal writes to a magic address */
358 uint8_t raddr_a;
359 uint8_t raddr_b;
360 struct v3d_qpu_flags flags;
361
362 union {
363 struct v3d_qpu_alu_instr alu;
364 struct v3d_qpu_branch_instr branch;
365 };
366 };
367
368 const char *v3d_qpu_magic_waddr_name(enum v3d_qpu_waddr waddr);
369 const char *v3d_qpu_add_op_name(enum v3d_qpu_add_op op);
370 const char *v3d_qpu_mul_op_name(enum v3d_qpu_mul_op op);
371 const char *v3d_qpu_cond_name(enum v3d_qpu_cond cond);
372 const char *v3d_qpu_pf_name(enum v3d_qpu_pf pf);
373 const char *v3d_qpu_uf_name(enum v3d_qpu_uf uf);
374 const char *v3d_qpu_pack_name(enum v3d_qpu_output_pack pack);
375 const char *v3d_qpu_unpack_name(enum v3d_qpu_input_unpack unpack);
376 const char *v3d_qpu_branch_cond_name(enum v3d_qpu_branch_cond cond);
377 const char *v3d_qpu_msfign_name(enum v3d_qpu_msfign msfign);
378
379 bool v3d_qpu_add_op_has_dst(enum v3d_qpu_add_op op);
380 bool v3d_qpu_mul_op_has_dst(enum v3d_qpu_mul_op op);
381 int v3d_qpu_add_op_num_src(enum v3d_qpu_add_op op);
382 int v3d_qpu_mul_op_num_src(enum v3d_qpu_mul_op op);
383
384 bool v3d_qpu_sig_pack(const struct v3d_device_info *devinfo,
385 const struct v3d_qpu_sig *sig,
386 uint32_t *packed_sig);
387 bool v3d_qpu_sig_unpack(const struct v3d_device_info *devinfo,
388 uint32_t packed_sig,
389 struct v3d_qpu_sig *sig);
390
391 bool
392 v3d_qpu_flags_pack(const struct v3d_device_info *devinfo,
393 const struct v3d_qpu_flags *cond,
394 uint32_t *packed_cond);
395 bool
396 v3d_qpu_flags_unpack(const struct v3d_device_info *devinfo,
397 uint32_t packed_cond,
398 struct v3d_qpu_flags *cond);
399
400 bool
401 v3d_qpu_small_imm_pack(const struct v3d_device_info *devinfo,
402 uint32_t value,
403 uint32_t *packed_small_immediate);
404
405 bool
406 v3d_qpu_small_imm_unpack(const struct v3d_device_info *devinfo,
407 uint32_t packed_small_immediate,
408 uint32_t *small_immediate);
409
410 bool
411 v3d_qpu_instr_pack(const struct v3d_device_info *devinfo,
412 const struct v3d_qpu_instr *instr,
413 uint64_t *packed_instr);
414 bool
415 v3d_qpu_instr_unpack(const struct v3d_device_info *devinfo,
416 uint64_t packed_instr,
417 struct v3d_qpu_instr *instr);
418
419 bool v3d_qpu_magic_waddr_is_sfu(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
420 bool v3d_qpu_magic_waddr_is_tmu(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
421 bool v3d_qpu_magic_waddr_is_tlb(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
422 bool v3d_qpu_magic_waddr_is_vpm(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
423 bool v3d_qpu_magic_waddr_is_tsy(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST;
424 bool v3d_qpu_writes_r3(const struct v3d_device_info *devinfo,
425 const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST;
426 bool v3d_qpu_writes_r4(const struct v3d_device_info *devinfo,
427 const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST;
428 bool v3d_qpu_writes_r5(const struct v3d_device_info *devinfo,
429 const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST;
430 bool v3d_qpu_uses_mux(const struct v3d_qpu_instr *inst, enum v3d_qpu_mux mux);
431 bool v3d_qpu_uses_vpm(const struct v3d_qpu_instr *inst);
432 bool v3d_qpu_sig_writes_address(const struct v3d_device_info *devinfo,
433 const struct v3d_qpu_sig *sig) ATTRIBUTE_CONST;
434
435 #endif