2 * Copyright © 2014 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
25 #include "util/ralloc.h"
29 #define QPU_MUX(mux, muxfield) \
30 QPU_SET_FIELD(mux != QPU_MUX_SMALL_IMM ? mux : QPU_MUX_B, muxfield)
33 set_src_raddr(uint64_t inst
, struct qpu_reg src
)
35 if (src
.mux
== QPU_MUX_A
) {
36 assert(QPU_GET_FIELD(inst
, QPU_RADDR_A
) == QPU_R_NOP
||
37 QPU_GET_FIELD(inst
, QPU_RADDR_A
) == src
.addr
);
38 return QPU_UPDATE_FIELD(inst
, src
.addr
, QPU_RADDR_A
);
41 if (src
.mux
== QPU_MUX_B
) {
42 assert((QPU_GET_FIELD(inst
, QPU_RADDR_B
) == QPU_R_NOP
||
43 QPU_GET_FIELD(inst
, QPU_RADDR_B
) == src
.addr
) &&
44 QPU_GET_FIELD(inst
, QPU_SIG
) != QPU_SIG_SMALL_IMM
);
45 return QPU_UPDATE_FIELD(inst
, src
.addr
, QPU_RADDR_B
);
48 if (src
.mux
== QPU_MUX_SMALL_IMM
) {
49 if (QPU_GET_FIELD(inst
, QPU_SIG
) == QPU_SIG_SMALL_IMM
) {
50 assert(QPU_GET_FIELD(inst
, QPU_RADDR_B
) == src
.addr
);
52 inst
= qpu_set_sig(inst
, QPU_SIG_SMALL_IMM
);
53 assert(QPU_GET_FIELD(inst
, QPU_RADDR_B
) == QPU_R_NOP
);
55 return ((inst
& ~QPU_RADDR_B_MASK
) |
56 QPU_SET_FIELD(src
.addr
, QPU_RADDR_B
));
67 inst
|= QPU_SET_FIELD(QPU_A_NOP
, QPU_OP_ADD
);
68 inst
|= QPU_SET_FIELD(QPU_M_NOP
, QPU_OP_MUL
);
70 /* Note: These field values are actually non-zero */
71 inst
|= QPU_SET_FIELD(QPU_W_NOP
, QPU_WADDR_ADD
);
72 inst
|= QPU_SET_FIELD(QPU_W_NOP
, QPU_WADDR_MUL
);
73 inst
|= QPU_SET_FIELD(QPU_R_NOP
, QPU_RADDR_A
);
74 inst
|= QPU_SET_FIELD(QPU_R_NOP
, QPU_RADDR_B
);
75 inst
|= QPU_SET_FIELD(QPU_SIG_NONE
, QPU_SIG
);
81 qpu_a_dst(struct qpu_reg dst
)
85 if (dst
.mux
<= QPU_MUX_R5
) {
86 /* Translate the mux to the ACCn values. */
87 inst
|= QPU_SET_FIELD(32 + dst
.mux
, QPU_WADDR_ADD
);
89 inst
|= QPU_SET_FIELD(dst
.addr
, QPU_WADDR_ADD
);
90 if (dst
.mux
== QPU_MUX_B
)
98 qpu_m_dst(struct qpu_reg dst
)
102 if (dst
.mux
<= QPU_MUX_R5
) {
103 /* Translate the mux to the ACCn values. */
104 inst
|= QPU_SET_FIELD(32 + dst
.mux
, QPU_WADDR_MUL
);
106 inst
|= QPU_SET_FIELD(dst
.addr
, QPU_WADDR_MUL
);
107 if (dst
.mux
== QPU_MUX_A
)
115 qpu_a_MOV(struct qpu_reg dst
, struct qpu_reg src
)
119 inst
|= QPU_SET_FIELD(QPU_SIG_NONE
, QPU_SIG
);
120 inst
|= QPU_SET_FIELD(QPU_A_OR
, QPU_OP_ADD
);
121 inst
|= QPU_SET_FIELD(QPU_R_NOP
, QPU_RADDR_A
);
122 inst
|= QPU_SET_FIELD(QPU_R_NOP
, QPU_RADDR_B
);
123 inst
|= qpu_a_dst(dst
);
124 inst
|= QPU_SET_FIELD(QPU_COND_ALWAYS
, QPU_COND_ADD
);
125 inst
|= QPU_MUX(src
.mux
, QPU_ADD_A
);
126 inst
|= QPU_MUX(src
.mux
, QPU_ADD_B
);
127 inst
= set_src_raddr(inst
, src
);
128 inst
|= QPU_SET_FIELD(QPU_W_NOP
, QPU_WADDR_MUL
);
134 qpu_m_MOV(struct qpu_reg dst
, struct qpu_reg src
)
138 inst
|= QPU_SET_FIELD(QPU_SIG_NONE
, QPU_SIG
);
139 inst
|= QPU_SET_FIELD(QPU_M_V8MIN
, QPU_OP_MUL
);
140 inst
|= QPU_SET_FIELD(QPU_R_NOP
, QPU_RADDR_A
);
141 inst
|= QPU_SET_FIELD(QPU_R_NOP
, QPU_RADDR_B
);
142 inst
|= qpu_m_dst(dst
);
143 inst
|= QPU_SET_FIELD(QPU_COND_ALWAYS
, QPU_COND_MUL
);
144 inst
|= QPU_MUX(src
.mux
, QPU_MUL_A
);
145 inst
|= QPU_MUX(src
.mux
, QPU_MUL_B
);
146 inst
= set_src_raddr(inst
, src
);
147 inst
|= QPU_SET_FIELD(QPU_W_NOP
, QPU_WADDR_ADD
);
153 qpu_load_imm_ui(struct qpu_reg dst
, uint32_t val
)
157 inst
|= qpu_a_dst(dst
);
158 inst
|= QPU_SET_FIELD(QPU_W_NOP
, QPU_WADDR_MUL
);
159 inst
|= QPU_SET_FIELD(QPU_COND_ALWAYS
, QPU_COND_ADD
);
160 inst
|= QPU_SET_FIELD(QPU_COND_ALWAYS
, QPU_COND_MUL
);
161 inst
|= QPU_SET_FIELD(QPU_SIG_LOAD_IMM
, QPU_SIG
);
168 qpu_load_imm_u2(struct qpu_reg dst
, uint32_t val
)
170 return qpu_load_imm_ui(dst
, val
) | QPU_SET_FIELD(QPU_LOAD_IMM_MODE_U2
,
175 qpu_load_imm_i2(struct qpu_reg dst
, uint32_t val
)
177 return qpu_load_imm_ui(dst
, val
) | QPU_SET_FIELD(QPU_LOAD_IMM_MODE_I2
,
182 qpu_branch(uint32_t cond
, uint32_t target
)
186 inst
|= qpu_a_dst(qpu_ra(QPU_W_NOP
));
187 inst
|= qpu_m_dst(qpu_rb(QPU_W_NOP
));
188 inst
|= QPU_SET_FIELD(cond
, QPU_BRANCH_COND
);
189 inst
|= QPU_SET_FIELD(QPU_SIG_BRANCH
, QPU_SIG
);
190 inst
|= QPU_SET_FIELD(target
, QPU_BRANCH_TARGET
);
196 qpu_a_alu2(enum qpu_op_add op
,
197 struct qpu_reg dst
, struct qpu_reg src0
, struct qpu_reg src1
)
201 inst
|= QPU_SET_FIELD(QPU_SIG_NONE
, QPU_SIG
);
202 inst
|= QPU_SET_FIELD(op
, QPU_OP_ADD
);
203 inst
|= QPU_SET_FIELD(QPU_R_NOP
, QPU_RADDR_A
);
204 inst
|= QPU_SET_FIELD(QPU_R_NOP
, QPU_RADDR_B
);
205 inst
|= qpu_a_dst(dst
);
206 inst
|= QPU_SET_FIELD(QPU_COND_ALWAYS
, QPU_COND_ADD
);
207 inst
|= QPU_MUX(src0
.mux
, QPU_ADD_A
);
208 inst
= set_src_raddr(inst
, src0
);
209 inst
|= QPU_MUX(src1
.mux
, QPU_ADD_B
);
210 inst
= set_src_raddr(inst
, src1
);
211 inst
|= QPU_SET_FIELD(QPU_W_NOP
, QPU_WADDR_MUL
);
217 qpu_m_alu2(enum qpu_op_mul op
,
218 struct qpu_reg dst
, struct qpu_reg src0
, struct qpu_reg src1
)
222 inst
|= QPU_SET_FIELD(QPU_SIG_NONE
, QPU_SIG
);
223 inst
|= QPU_SET_FIELD(op
, QPU_OP_MUL
);
224 inst
|= QPU_SET_FIELD(QPU_R_NOP
, QPU_RADDR_A
);
225 inst
|= QPU_SET_FIELD(QPU_R_NOP
, QPU_RADDR_B
);
226 inst
|= qpu_m_dst(dst
);
227 inst
|= QPU_SET_FIELD(QPU_COND_ALWAYS
, QPU_COND_MUL
);
228 inst
|= QPU_MUX(src0
.mux
, QPU_MUL_A
);
229 inst
= set_src_raddr(inst
, src0
);
230 inst
|= QPU_MUX(src1
.mux
, QPU_MUL_B
);
231 inst
= set_src_raddr(inst
, src1
);
232 inst
|= QPU_SET_FIELD(QPU_W_NOP
, QPU_WADDR_ADD
);
238 qpu_m_rot(struct qpu_reg dst
, struct qpu_reg src0
, int rot
)
241 inst
= qpu_m_alu2(QPU_M_V8MIN
, dst
, src0
, src0
);
243 inst
= QPU_UPDATE_FIELD(inst
, QPU_SIG_SMALL_IMM
, QPU_SIG
);
244 inst
= QPU_UPDATE_FIELD(inst
, QPU_SMALL_IMM_MUL_ROT
+ rot
,
251 merge_fields(uint64_t *merge
,
252 uint64_t a
, uint64_t b
,
253 uint64_t mask
, uint64_t ignore
)
255 if ((a
& mask
) == ignore
) {
256 *merge
= (*merge
& ~mask
) | (b
& mask
);
257 } else if ((b
& mask
) == ignore
) {
258 *merge
= (*merge
& ~mask
) | (a
& mask
);
260 if ((a
& mask
) != (b
& mask
))
268 qpu_num_sf_accesses(uint64_t inst
)
271 static const uint32_t specials
[] = {
288 uint32_t waddr_add
= QPU_GET_FIELD(inst
, QPU_WADDR_ADD
);
289 uint32_t waddr_mul
= QPU_GET_FIELD(inst
, QPU_WADDR_MUL
);
290 uint32_t raddr_a
= QPU_GET_FIELD(inst
, QPU_RADDR_A
);
291 uint32_t raddr_b
= QPU_GET_FIELD(inst
, QPU_RADDR_B
);
293 for (int j
= 0; j
< ARRAY_SIZE(specials
); j
++) {
294 if (waddr_add
== specials
[j
])
296 if (waddr_mul
== specials
[j
])
300 if (raddr_a
== QPU_R_MUTEX_ACQUIRE
)
302 if (raddr_b
== QPU_R_MUTEX_ACQUIRE
&&
303 QPU_GET_FIELD(inst
, QPU_SIG
) != QPU_SIG_SMALL_IMM
)
306 /* XXX: semaphore, combined color read/write? */
307 switch (QPU_GET_FIELD(inst
, QPU_SIG
)) {
308 case QPU_SIG_COLOR_LOAD
:
309 case QPU_SIG_COLOR_LOAD_END
:
310 case QPU_SIG_LOAD_TMU0
:
311 case QPU_SIG_LOAD_TMU1
:
319 qpu_waddr_ignores_ws(uint32_t waddr
)
327 case QPU_W_TLB_COLOR_MS
:
328 case QPU_W_TLB_COLOR_ALL
:
329 case QPU_W_TLB_ALPHA_MASK
:
331 case QPU_W_SFU_RECIP
:
332 case QPU_W_SFU_RECIPSQRT
:
350 swap_ra_file_mux_helper(uint64_t *merge
, uint64_t *a
, uint32_t mux_shift
)
352 uint64_t mux_mask
= (uint64_t)0x7 << mux_shift
;
353 uint64_t mux_a_val
= (uint64_t)QPU_MUX_A
<< mux_shift
;
354 uint64_t mux_b_val
= (uint64_t)QPU_MUX_B
<< mux_shift
;
356 if ((*a
& mux_mask
) == mux_a_val
) {
357 *a
= (*a
& ~mux_mask
) | mux_b_val
;
358 *merge
= (*merge
& ~mux_mask
) | mux_b_val
;
363 try_swap_ra_file(uint64_t *merge
, uint64_t *a
, uint64_t *b
)
365 uint32_t raddr_a_a
= QPU_GET_FIELD(*a
, QPU_RADDR_A
);
366 uint32_t raddr_a_b
= QPU_GET_FIELD(*a
, QPU_RADDR_B
);
367 uint32_t raddr_b_a
= QPU_GET_FIELD(*b
, QPU_RADDR_A
);
368 uint32_t raddr_b_b
= QPU_GET_FIELD(*b
, QPU_RADDR_B
);
370 if (raddr_a_b
!= QPU_R_NOP
)
381 if (!(*merge
& QPU_PM
) &&
382 QPU_GET_FIELD(*merge
, QPU_UNPACK
) != QPU_UNPACK_NOP
) {
386 if (raddr_b_b
!= QPU_R_NOP
&&
387 raddr_b_b
!= raddr_a_a
)
390 /* Move raddr A to B in instruction a. */
391 *a
= (*a
& ~QPU_RADDR_A_MASK
) | QPU_SET_FIELD(QPU_R_NOP
, QPU_RADDR_A
);
392 *a
= (*a
& ~QPU_RADDR_B_MASK
) | QPU_SET_FIELD(raddr_a_a
, QPU_RADDR_B
);
393 *merge
= QPU_UPDATE_FIELD(*merge
, raddr_b_a
, QPU_RADDR_A
);
394 *merge
= QPU_UPDATE_FIELD(*merge
, raddr_a_a
, QPU_RADDR_B
);
395 swap_ra_file_mux_helper(merge
, a
, QPU_ADD_A_SHIFT
);
396 swap_ra_file_mux_helper(merge
, a
, QPU_ADD_B_SHIFT
);
397 swap_ra_file_mux_helper(merge
, a
, QPU_MUL_A_SHIFT
);
398 swap_ra_file_mux_helper(merge
, a
, QPU_MUL_B_SHIFT
);
404 convert_mov(uint64_t *inst
)
406 uint32_t add_a
= QPU_GET_FIELD(*inst
, QPU_ADD_A
);
407 uint32_t waddr_add
= QPU_GET_FIELD(*inst
, QPU_WADDR_ADD
);
408 uint32_t cond_add
= QPU_GET_FIELD(*inst
, QPU_COND_ADD
);
411 if (QPU_GET_FIELD(*inst
, QPU_OP_ADD
) != QPU_A_OR
||
412 (add_a
!= QPU_GET_FIELD(*inst
, QPU_ADD_B
))) {
416 if (QPU_GET_FIELD(*inst
, QPU_SIG
) != QPU_SIG_NONE
)
419 /* We could maybe support this in the .8888 and .8a-.8d cases. */
423 *inst
= QPU_UPDATE_FIELD(*inst
, QPU_A_NOP
, QPU_OP_ADD
);
424 *inst
= QPU_UPDATE_FIELD(*inst
, QPU_M_V8MIN
, QPU_OP_MUL
);
426 *inst
= QPU_UPDATE_FIELD(*inst
, add_a
, QPU_MUL_A
);
427 *inst
= QPU_UPDATE_FIELD(*inst
, add_a
, QPU_MUL_B
);
428 *inst
= QPU_UPDATE_FIELD(*inst
, QPU_MUX_R0
, QPU_ADD_A
);
429 *inst
= QPU_UPDATE_FIELD(*inst
, QPU_MUX_R0
, QPU_ADD_B
);
431 *inst
= QPU_UPDATE_FIELD(*inst
, waddr_add
, QPU_WADDR_MUL
);
432 *inst
= QPU_UPDATE_FIELD(*inst
, QPU_W_NOP
, QPU_WADDR_ADD
);
434 *inst
= QPU_UPDATE_FIELD(*inst
, cond_add
, QPU_COND_MUL
);
435 *inst
= QPU_UPDATE_FIELD(*inst
, QPU_COND_NEVER
, QPU_COND_ADD
);
437 if (!qpu_waddr_ignores_ws(waddr_add
))
444 writes_a_file(uint64_t inst
)
446 if (!(inst
& QPU_WS
))
447 return QPU_GET_FIELD(inst
, QPU_WADDR_ADD
) < 32;
449 return QPU_GET_FIELD(inst
, QPU_WADDR_MUL
) < 32;
453 reads_r4(uint64_t inst
)
455 return (QPU_GET_FIELD(inst
, QPU_ADD_A
) == QPU_MUX_R4
||
456 QPU_GET_FIELD(inst
, QPU_ADD_B
) == QPU_MUX_R4
||
457 QPU_GET_FIELD(inst
, QPU_MUL_A
) == QPU_MUX_R4
||
458 QPU_GET_FIELD(inst
, QPU_MUL_B
) == QPU_MUX_R4
);
462 qpu_merge_inst(uint64_t a
, uint64_t b
)
464 uint64_t merge
= a
| b
;
466 uint32_t a_sig
= QPU_GET_FIELD(a
, QPU_SIG
);
467 uint32_t b_sig
= QPU_GET_FIELD(b
, QPU_SIG
);
469 if (QPU_GET_FIELD(a
, QPU_OP_ADD
) != QPU_A_NOP
&&
470 QPU_GET_FIELD(b
, QPU_OP_ADD
) != QPU_A_NOP
) {
471 if (QPU_GET_FIELD(a
, QPU_OP_MUL
) != QPU_M_NOP
||
472 QPU_GET_FIELD(b
, QPU_OP_MUL
) != QPU_M_NOP
||
473 !(convert_mov(&a
) || convert_mov(&b
))) {
480 if (QPU_GET_FIELD(a
, QPU_OP_MUL
) != QPU_M_NOP
&&
481 QPU_GET_FIELD(b
, QPU_OP_MUL
) != QPU_M_NOP
)
484 if (qpu_num_sf_accesses(a
) && qpu_num_sf_accesses(b
))
487 if (a_sig
== QPU_SIG_LOAD_IMM
||
488 b_sig
== QPU_SIG_LOAD_IMM
||
489 a_sig
== QPU_SIG_SMALL_IMM
||
490 b_sig
== QPU_SIG_SMALL_IMM
||
491 a_sig
== QPU_SIG_BRANCH
||
492 b_sig
== QPU_SIG_BRANCH
) {
496 ok
= ok
&& merge_fields(&merge
, a
, b
, QPU_SIG_MASK
,
497 QPU_SET_FIELD(QPU_SIG_NONE
, QPU_SIG
));
499 /* Misc fields that have to match exactly. */
500 ok
= ok
&& merge_fields(&merge
, a
, b
, QPU_SF
, ~0);
502 if (!merge_fields(&merge
, a
, b
, QPU_RADDR_A_MASK
,
503 QPU_SET_FIELD(QPU_R_NOP
, QPU_RADDR_A
))) {
504 /* Since we tend to use regfile A by default both for register
505 * allocation and for our special values (uniforms and
506 * varyings), try swapping uniforms and varyings to regfile B
507 * to resolve raddr A conflicts.
509 if (!try_swap_ra_file(&merge
, &a
, &b
) &&
510 !try_swap_ra_file(&merge
, &b
, &a
)) {
515 ok
= ok
&& merge_fields(&merge
, a
, b
, QPU_RADDR_B_MASK
,
516 QPU_SET_FIELD(QPU_R_NOP
, QPU_RADDR_B
));
518 ok
= ok
&& merge_fields(&merge
, a
, b
, QPU_WADDR_ADD_MASK
,
519 QPU_SET_FIELD(QPU_W_NOP
, QPU_WADDR_ADD
));
520 ok
= ok
&& merge_fields(&merge
, a
, b
, QPU_WADDR_MUL_MASK
,
521 QPU_SET_FIELD(QPU_W_NOP
, QPU_WADDR_MUL
));
523 /* Allow disagreement on WS (swapping A vs B physical reg file as the
524 * destination for ADD/MUL) if one of the original instructions
525 * ignores it (probably because it's just writing to accumulators).
527 if (qpu_waddr_ignores_ws(QPU_GET_FIELD(a
, QPU_WADDR_ADD
)) &&
528 qpu_waddr_ignores_ws(QPU_GET_FIELD(a
, QPU_WADDR_MUL
))) {
529 merge
= (merge
& ~QPU_WS
) | (b
& QPU_WS
);
530 } else if (qpu_waddr_ignores_ws(QPU_GET_FIELD(b
, QPU_WADDR_ADD
)) &&
531 qpu_waddr_ignores_ws(QPU_GET_FIELD(b
, QPU_WADDR_MUL
))) {
532 merge
= (merge
& ~QPU_WS
) | (a
& QPU_WS
);
534 if ((a
& QPU_WS
) != (b
& QPU_WS
))
538 if (!merge_fields(&merge
, a
, b
, QPU_PM
, ~0)) {
539 /* If one instruction has PM bit set and the other not, the
540 * one without PM shouldn't do packing/unpacking, and we
541 * have to make sure non-NOP packing/unpacking from PM
542 * instruction aren't added to it.
546 /* Let a be the one with PM bit */
553 if ((b
& (QPU_PACK_MASK
| QPU_UNPACK_MASK
)) != 0)
556 if ((a
& QPU_PACK_MASK
) != 0 &&
557 QPU_GET_FIELD(b
, QPU_OP_MUL
) != QPU_M_NOP
)
560 if ((a
& QPU_UNPACK_MASK
) != 0 && reads_r4(b
))
563 /* packing: Make sure that non-NOP packs agree, then deal with
564 * special-case failing of adding a non-NOP pack to something
567 if (!merge_fields(&merge
, a
, b
, QPU_PACK_MASK
, 0))
569 bool new_a_pack
= (QPU_GET_FIELD(a
, QPU_PACK
) !=
570 QPU_GET_FIELD(merge
, QPU_PACK
));
571 bool new_b_pack
= (QPU_GET_FIELD(b
, QPU_PACK
) !=
572 QPU_GET_FIELD(merge
, QPU_PACK
));
573 if (!(merge
& QPU_PM
)) {
574 /* Make sure we're not going to be putting a new
575 * a-file packing on either half.
577 if (new_a_pack
&& writes_a_file(a
))
580 if (new_b_pack
&& writes_a_file(b
))
583 /* Make sure we're not going to be putting new MUL
584 * packing oneither half.
587 QPU_GET_FIELD(a
, QPU_OP_MUL
) != QPU_M_NOP
)
591 QPU_GET_FIELD(b
, QPU_OP_MUL
) != QPU_M_NOP
)
595 /* unpacking: Make sure that non-NOP unpacks agree, then deal
596 * with special-case failing of adding a non-NOP unpack to
597 * something with a NOP unpack.
599 if (!merge_fields(&merge
, a
, b
, QPU_UNPACK_MASK
, 0))
601 bool new_a_unpack
= (QPU_GET_FIELD(a
, QPU_UNPACK
) !=
602 QPU_GET_FIELD(merge
, QPU_UNPACK
));
603 bool new_b_unpack
= (QPU_GET_FIELD(b
, QPU_UNPACK
) !=
604 QPU_GET_FIELD(merge
, QPU_UNPACK
));
605 if (!(merge
& QPU_PM
)) {
606 /* Make sure we're not going to be putting a new
607 * a-file packing on either half.
610 QPU_GET_FIELD(a
, QPU_RADDR_A
) != QPU_R_NOP
)
614 QPU_GET_FIELD(b
, QPU_RADDR_A
) != QPU_R_NOP
)
617 /* Make sure we're not going to be putting new r4
618 * unpack on either half.
620 if (new_a_unpack
&& reads_r4(a
))
623 if (new_b_unpack
&& reads_r4(b
))
635 qpu_set_sig(uint64_t inst
, uint32_t sig
)
637 assert(QPU_GET_FIELD(inst
, QPU_SIG
) == QPU_SIG_NONE
);
638 return QPU_UPDATE_FIELD(inst
, sig
, QPU_SIG
);
642 qpu_set_cond_add(uint64_t inst
, uint32_t cond
)
644 assert(QPU_GET_FIELD(inst
, QPU_COND_ADD
) == QPU_COND_ALWAYS
);
645 return QPU_UPDATE_FIELD(inst
, cond
, QPU_COND_ADD
);
649 qpu_set_cond_mul(uint64_t inst
, uint32_t cond
)
651 assert(QPU_GET_FIELD(inst
, QPU_COND_MUL
) == QPU_COND_ALWAYS
);
652 return QPU_UPDATE_FIELD(inst
, cond
, QPU_COND_MUL
);
656 qpu_waddr_is_tlb(uint32_t waddr
)
659 case QPU_W_TLB_COLOR_ALL
:
660 case QPU_W_TLB_COLOR_MS
:
669 qpu_inst_is_tlb(uint64_t inst
)
671 uint32_t sig
= QPU_GET_FIELD(inst
, QPU_SIG
);
673 return (qpu_waddr_is_tlb(QPU_GET_FIELD(inst
, QPU_WADDR_ADD
)) ||
674 qpu_waddr_is_tlb(QPU_GET_FIELD(inst
, QPU_WADDR_MUL
)) ||
675 sig
== QPU_SIG_COLOR_LOAD
||
676 sig
== QPU_SIG_WAIT_FOR_SCOREBOARD
);
680 * Returns the small immediate value to be encoded in to the raddr b field if
681 * the argument can be represented as one, or ~0 otherwise.
684 qpu_encode_small_immediate(uint32_t i
)
688 if ((int)i
< 0 && (int)i
>= -16)
730 qpu_serialize_one_inst(struct vc4_compile
*c
, uint64_t inst
)
732 if (c
->qpu_inst_count
>= c
->qpu_inst_size
) {
733 c
->qpu_inst_size
= MAX2(16, c
->qpu_inst_size
* 2);
734 c
->qpu_insts
= reralloc(c
, c
->qpu_insts
,
735 uint64_t, c
->qpu_inst_size
);
737 c
->qpu_insts
[c
->qpu_inst_count
++] = inst
;