2 * Copyright © 2016 Broadcom
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:
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
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
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
38 #include "util/macros.h"
40 struct v3d_device_info
;
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 V3D_QPU_WADDR_SYNCB
= 18,
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 V3D_QPU_WADDR_TMUC
= 32,
118 V3D_QPU_WADDR_TMUS
= 33,
119 V3D_QPU_WADDR_TMUT
= 34,
120 V3D_QPU_WADDR_TMUR
= 35,
121 V3D_QPU_WADDR_TMUI
= 36,
122 V3D_QPU_WADDR_TMUB
= 37,
123 V3D_QPU_WADDR_TMUDREF
= 38,
124 V3D_QPU_WADDR_TMUOFF
= 39,
125 V3D_QPU_WADDR_TMUSCM
= 40,
126 V3D_QPU_WADDR_TMUSF
= 41,
127 V3D_QPU_WADDR_TMUSLOD
= 42,
128 V3D_QPU_WADDR_TMUHS
= 43,
129 V3D_QPU_WADDR_TMUHSCM
= 44,
130 V3D_QPU_WADDR_TMUHSF
= 45,
131 V3D_QPU_WADDR_TMUHSLOD
= 46,
132 V3D_QPU_WADDR_R5REP
= 55,
135 struct v3d_qpu_flags
{
136 enum v3d_qpu_cond ac
, mc
;
137 enum v3d_qpu_pf apf
, mpf
;
138 enum v3d_qpu_uf auf
, muf
;
141 enum v3d_qpu_add_op
{
194 V3D_QPU_A_LDVPMV_OUT
,
196 V3D_QPU_A_LDVPMD_OUT
,
204 V3D_QPU_A_LDVPMG_OUT
,
225 enum v3d_qpu_mul_op
{
238 enum v3d_qpu_output_pack
{
241 * Convert to 16-bit float, put in low 16 bits of destination leaving
246 * Convert to 16-bit float, put in high 16 bits of destination leaving
252 enum v3d_qpu_input_unpack
{
254 * No-op input unpacking. Note that this enum's value doesn't match
255 * the packed QPU instruction value of the field (we use 0 so that the
256 * default on new instruction creation is no-op).
259 /** Absolute value. Only available for some operations. */
261 /** Convert low 16 bits from 16-bit float to 32-bit float. */
263 /** Convert high 16 bits from 16-bit float to 32-bit float. */
266 /** Convert to 16f and replicate it to the high bits. */
267 V3D_QPU_UNPACK_REPLICATE_32F_16
,
269 /** Replicate low 16 bits to high */
270 V3D_QPU_UNPACK_REPLICATE_L_16
,
272 /** Replicate high 16 bits to low */
273 V3D_QPU_UNPACK_REPLICATE_H_16
,
275 /** Swap high and low 16 bits */
276 V3D_QPU_UNPACK_SWAP_16
,
290 struct v3d_qpu_alu_instr
{
292 enum v3d_qpu_add_op op
;
293 enum v3d_qpu_mux a
, b
;
296 enum v3d_qpu_output_pack output_pack
;
297 enum v3d_qpu_input_unpack a_unpack
;
298 enum v3d_qpu_input_unpack b_unpack
;
302 enum v3d_qpu_mul_op op
;
303 enum v3d_qpu_mux a
, b
;
306 enum v3d_qpu_output_pack output_pack
;
307 enum v3d_qpu_input_unpack a_unpack
;
308 enum v3d_qpu_input_unpack b_unpack
;
312 enum v3d_qpu_branch_cond
{
313 V3D_QPU_BRANCH_COND_ALWAYS
,
314 V3D_QPU_BRANCH_COND_A0
,
315 V3D_QPU_BRANCH_COND_NA0
,
316 V3D_QPU_BRANCH_COND_ALLA
,
317 V3D_QPU_BRANCH_COND_ANYNA
,
318 V3D_QPU_BRANCH_COND_ANYA
,
319 V3D_QPU_BRANCH_COND_ALLNA
,
322 enum v3d_qpu_msfign
{
323 /** Ignore multisample flags when determining branch condition. */
326 * If no multisample flags are set in the lane (a pixel in the FS, a
327 * vertex in the VS), ignore the lane's condition when computing the
332 * If no multisample flags are set in a 2x2 quad in the FS, ignore the
333 * quad's a/b conditions.
338 enum v3d_qpu_branch_dest
{
339 V3D_QPU_BRANCH_DEST_ABS
,
340 V3D_QPU_BRANCH_DEST_REL
,
341 V3D_QPU_BRANCH_DEST_LINK_REG
,
342 V3D_QPU_BRANCH_DEST_REGFILE
,
345 struct v3d_qpu_branch_instr
{
346 enum v3d_qpu_branch_cond cond
;
347 enum v3d_qpu_msfign msfign
;
349 /** Selects how to compute the new IP if the branch is taken. */
350 enum v3d_qpu_branch_dest bdi
;
353 * Selects how to compute the new uniforms pointer if the branch is
354 * taken. (ABS/REL implicitly load a uniform and use that)
356 enum v3d_qpu_branch_dest bdu
;
359 * If set, then udest determines how the uniform stream will branch,
360 * otherwise the uniform stream is left as is.
369 enum v3d_qpu_instr_type
{
370 V3D_QPU_INSTR_TYPE_ALU
,
371 V3D_QPU_INSTR_TYPE_BRANCH
,
374 struct v3d_qpu_instr
{
375 enum v3d_qpu_instr_type type
;
377 struct v3d_qpu_sig sig
;
379 bool sig_magic
; /* If the signal writes to a magic address */
382 struct v3d_qpu_flags flags
;
385 struct v3d_qpu_alu_instr alu
;
386 struct v3d_qpu_branch_instr branch
;
390 const char *v3d_qpu_magic_waddr_name(enum v3d_qpu_waddr waddr
);
391 const char *v3d_qpu_add_op_name(enum v3d_qpu_add_op op
);
392 const char *v3d_qpu_mul_op_name(enum v3d_qpu_mul_op op
);
393 const char *v3d_qpu_cond_name(enum v3d_qpu_cond cond
);
394 const char *v3d_qpu_pf_name(enum v3d_qpu_pf pf
);
395 const char *v3d_qpu_uf_name(enum v3d_qpu_uf uf
);
396 const char *v3d_qpu_pack_name(enum v3d_qpu_output_pack pack
);
397 const char *v3d_qpu_unpack_name(enum v3d_qpu_input_unpack unpack
);
398 const char *v3d_qpu_branch_cond_name(enum v3d_qpu_branch_cond cond
);
399 const char *v3d_qpu_msfign_name(enum v3d_qpu_msfign msfign
);
401 enum v3d_qpu_cond
v3d_qpu_cond_invert(enum v3d_qpu_cond cond
) ATTRIBUTE_CONST
;
403 bool v3d_qpu_add_op_has_dst(enum v3d_qpu_add_op op
);
404 bool v3d_qpu_mul_op_has_dst(enum v3d_qpu_mul_op op
);
405 int v3d_qpu_add_op_num_src(enum v3d_qpu_add_op op
);
406 int v3d_qpu_mul_op_num_src(enum v3d_qpu_mul_op op
);
408 bool v3d_qpu_sig_pack(const struct v3d_device_info
*devinfo
,
409 const struct v3d_qpu_sig
*sig
,
410 uint32_t *packed_sig
);
411 bool v3d_qpu_sig_unpack(const struct v3d_device_info
*devinfo
,
413 struct v3d_qpu_sig
*sig
);
416 v3d_qpu_flags_pack(const struct v3d_device_info
*devinfo
,
417 const struct v3d_qpu_flags
*cond
,
418 uint32_t *packed_cond
);
420 v3d_qpu_flags_unpack(const struct v3d_device_info
*devinfo
,
421 uint32_t packed_cond
,
422 struct v3d_qpu_flags
*cond
);
425 v3d_qpu_small_imm_pack(const struct v3d_device_info
*devinfo
,
427 uint32_t *packed_small_immediate
);
430 v3d_qpu_small_imm_unpack(const struct v3d_device_info
*devinfo
,
431 uint32_t packed_small_immediate
,
432 uint32_t *small_immediate
);
435 v3d_qpu_instr_pack(const struct v3d_device_info
*devinfo
,
436 const struct v3d_qpu_instr
*instr
,
437 uint64_t *packed_instr
);
439 v3d_qpu_instr_unpack(const struct v3d_device_info
*devinfo
,
440 uint64_t packed_instr
,
441 struct v3d_qpu_instr
*instr
);
443 bool v3d_qpu_magic_waddr_is_sfu(enum v3d_qpu_waddr waddr
) ATTRIBUTE_CONST
;
444 bool v3d_qpu_magic_waddr_is_tmu(enum v3d_qpu_waddr waddr
) ATTRIBUTE_CONST
;
445 bool v3d_qpu_magic_waddr_is_tlb(enum v3d_qpu_waddr waddr
) ATTRIBUTE_CONST
;
446 bool v3d_qpu_magic_waddr_is_vpm(enum v3d_qpu_waddr waddr
) ATTRIBUTE_CONST
;
447 bool v3d_qpu_magic_waddr_is_tsy(enum v3d_qpu_waddr waddr
) ATTRIBUTE_CONST
;
448 bool v3d_qpu_magic_waddr_loads_unif(enum v3d_qpu_waddr waddr
) ATTRIBUTE_CONST
;
449 bool v3d_qpu_uses_tlb(const struct v3d_qpu_instr
*inst
) ATTRIBUTE_CONST
;
450 bool v3d_qpu_instr_is_sfu(const struct v3d_qpu_instr
*inst
) ATTRIBUTE_CONST
;
451 bool v3d_qpu_uses_sfu(const struct v3d_qpu_instr
*inst
) ATTRIBUTE_CONST
;
452 bool v3d_qpu_writes_tmu(const struct v3d_qpu_instr
*inst
) ATTRIBUTE_CONST
;
453 bool v3d_qpu_writes_tmu_not_tmuc(const struct v3d_qpu_instr
*inst
) ATTRIBUTE_CONST
;
454 bool v3d_qpu_writes_r3(const struct v3d_device_info
*devinfo
,
455 const struct v3d_qpu_instr
*instr
) ATTRIBUTE_CONST
;
456 bool v3d_qpu_writes_r4(const struct v3d_device_info
*devinfo
,
457 const struct v3d_qpu_instr
*instr
) ATTRIBUTE_CONST
;
458 bool v3d_qpu_writes_r5(const struct v3d_device_info
*devinfo
,
459 const struct v3d_qpu_instr
*instr
) ATTRIBUTE_CONST
;
460 bool v3d_qpu_waits_on_tmu(const struct v3d_qpu_instr
*inst
) ATTRIBUTE_CONST
;
461 bool v3d_qpu_uses_mux(const struct v3d_qpu_instr
*inst
, enum v3d_qpu_mux mux
);
462 bool v3d_qpu_uses_vpm(const struct v3d_qpu_instr
*inst
) ATTRIBUTE_CONST
;
463 bool v3d_qpu_reads_vpm(const struct v3d_qpu_instr
*inst
) ATTRIBUTE_CONST
;
464 bool v3d_qpu_writes_vpm(const struct v3d_qpu_instr
*inst
) ATTRIBUTE_CONST
;
465 bool v3d_qpu_reads_or_writes_vpm(const struct v3d_qpu_instr
*inst
) ATTRIBUTE_CONST
;
466 bool v3d_qpu_reads_flags(const struct v3d_qpu_instr
*inst
) ATTRIBUTE_CONST
;
467 bool v3d_qpu_writes_flags(const struct v3d_qpu_instr
*inst
) ATTRIBUTE_CONST
;
468 bool v3d_qpu_sig_writes_address(const struct v3d_device_info
*devinfo
,
469 const struct v3d_qpu_sig
*sig
) ATTRIBUTE_CONST
;
470 bool v3d_qpu_unpacks_f32(const struct v3d_qpu_instr
*inst
) ATTRIBUTE_CONST
;
471 bool v3d_qpu_unpacks_f16(const struct v3d_qpu_instr
*inst
) ATTRIBUTE_CONST
;