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
27 writes_reg(uint64_t inst
, uint32_t w
)
29 return (QPU_GET_FIELD(inst
, QPU_WADDR_ADD
) == w
||
30 QPU_GET_FIELD(inst
, QPU_WADDR_MUL
) == w
);
34 _reads_reg(uint64_t inst
, uint32_t r
, bool ignore_a
, bool ignore_b
)
39 { QPU_GET_FIELD(inst
, QPU_ADD_A
) },
40 { QPU_GET_FIELD(inst
, QPU_ADD_B
) },
41 { QPU_GET_FIELD(inst
, QPU_MUL_A
) },
42 { QPU_GET_FIELD(inst
, QPU_MUL_B
) },
45 for (int i
= 0; i
< ARRAY_SIZE(src_regs
); i
++) {
47 src_regs
[i
].mux
== QPU_MUX_A
&&
48 (QPU_GET_FIELD(inst
, QPU_RADDR_A
) == r
))
52 src_regs
[i
].mux
== QPU_MUX_B
&&
53 (QPU_GET_FIELD(inst
, QPU_RADDR_B
) == r
))
61 reads_reg(uint64_t inst
, uint32_t r
)
63 return _reads_reg(inst
, r
, false, false);
67 reads_a_reg(uint64_t inst
, uint32_t r
)
69 return _reads_reg(inst
, r
, false, true);
73 writes_sfu(uint64_t inst
)
75 return (writes_reg(inst
, QPU_W_SFU_RECIP
) ||
76 writes_reg(inst
, QPU_W_SFU_RECIPSQRT
) ||
77 writes_reg(inst
, QPU_W_SFU_EXP
) ||
78 writes_reg(inst
, QPU_W_SFU_LOG
));
82 * Checks for the instruction restrictions from page 37 ("Summary of
83 * Instruction Restrictions").
86 vc4_qpu_validate(uint64_t *insts
, uint32_t num_inst
)
88 for (int i
= 0; i
< num_inst
; i
++) {
89 uint64_t inst
= insts
[i
];
91 if (QPU_GET_FIELD(inst
, QPU_SIG
) != QPU_SIG_PROG_END
)
94 /* "The Thread End instruction must not write to either physical
97 assert(QPU_GET_FIELD(inst
, QPU_WADDR_ADD
) >= 32);
98 assert(QPU_GET_FIELD(inst
, QPU_WADDR_MUL
) >= 32);
100 /* Two delay slots will be executed. */
101 assert(i
+ 2 <= num_inst
);
103 for (int j
= i
; j
< i
+ 2; j
++) {
104 /* "The last three instructions of any program
105 * (Thread End plus the following two delay-slot
106 * instructions) must not do varyings read, uniforms
107 * read or any kind of VPM, VDR, or VDW read or
110 assert(!writes_reg(insts
[j
], QPU_W_VPM
));
111 assert(!reads_reg(insts
[j
], QPU_R_VARY
));
112 assert(!reads_reg(insts
[j
], QPU_R_UNIF
));
113 assert(!reads_reg(insts
[j
], QPU_R_VPM
));
115 /* "The Thread End instruction and the following two
116 * delay slot instructions must not write or read
117 * address 14 in either regfile A or B."
119 assert(!writes_reg(insts
[j
], 14));
120 assert(!reads_reg(insts
[j
], 14));
124 /* "The final program instruction (the second delay slot
125 * instruction) must not do a TLB Z write."
127 assert(!writes_reg(insts
[i
+ 2], QPU_W_TLB_Z
));
130 /* "A scoreboard wait must not occur in the first two instructions of
131 * a fragment shader. This is either the explicit Wait for Scoreboard
132 * signal or an implicit wait with the first tile-buffer read or
133 * write instruction."
135 for (int i
= 0; i
< 2; i
++) {
136 uint64_t inst
= insts
[i
];
138 assert(QPU_GET_FIELD(inst
, QPU_SIG
) != QPU_SIG_COLOR_LOAD
);
139 assert(QPU_GET_FIELD(inst
, QPU_SIG
) !=
140 QPU_SIG_WAIT_FOR_SCOREBOARD
);
141 assert(!writes_reg(inst
, QPU_W_TLB_COLOR_MS
));
142 assert(!writes_reg(inst
, QPU_W_TLB_COLOR_ALL
));
143 assert(!writes_reg(inst
, QPU_W_TLB_Z
));
147 /* "If TMU_NOSWAP is written, the write must be three instructions
148 * before the first TMU write instruction. For example, if
149 * TMU_NOSWAP is written in the first shader instruction, the first
150 * TMU write cannot occur before the 4th shader instruction."
152 int last_tmu_noswap
= -10;
153 for (int i
= 0; i
< num_inst
; i
++) {
154 uint64_t inst
= insts
[i
];
156 assert((i
- last_tmu_noswap
) > 3 ||
157 (!writes_reg(inst
, QPU_W_TMU0_S
) &&
158 !writes_reg(inst
, QPU_W_TMU1_S
)));
160 if (writes_reg(inst
, QPU_W_TMU_NOSWAP
))
164 /* "An instruction must not read from a location in physical regfile A
165 * or B that was written to by the previous instruction."
167 for (int i
= 0; i
< num_inst
- 1; i
++) {
168 uint64_t inst
= insts
[i
];
169 uint32_t add_waddr
= QPU_GET_FIELD(inst
, QPU_WADDR_ADD
);
170 uint32_t mul_waddr
= QPU_GET_FIELD(inst
, QPU_WADDR_ADD
);
172 assert(add_waddr
>= 32 || !reads_reg(insts
[i
+ 1], add_waddr
));
173 assert(mul_waddr
>= 32 || !reads_reg(insts
[i
+ 1], mul_waddr
));
176 /* "After an SFU lookup instruction, accumulator r4 must not be read
177 * in the following two instructions. Any other instruction that
178 * results in r4 being written (that is, TMU read, TLB read, SFU
179 * lookup) cannot occur in the two instructions following an SFU
182 int last_sfu_inst
= -10;
183 for (int i
= 0; i
< num_inst
- 1; i
++) {
184 uint64_t inst
= insts
[i
];
186 assert(i
- last_sfu_inst
> 2 ||
187 (!writes_sfu(inst
) &&
188 !writes_reg(inst
, QPU_W_TMU0_S
) &&
189 !writes_reg(inst
, QPU_W_TMU1_S
) &&
190 QPU_GET_FIELD(inst
, QPU_SIG
) != QPU_SIG_COLOR_LOAD
));
192 if (writes_sfu(inst
))
196 int last_r5_write
= -10;
197 for (int i
= 0; i
< num_inst
- 1; i
++) {
198 uint64_t inst
= insts
[i
];
200 /* "An instruction that does a vector rotate by r5 must not
201 * immediately follow an instruction that writes to r5."
203 assert(last_r5_write
!= i
- 1 ||
204 QPU_GET_FIELD(inst
, QPU_SIG
) != QPU_SIG_SMALL_IMM
||
205 QPU_GET_FIELD(inst
, QPU_SMALL_IMM
) != 48);
208 /* "An instruction that does a vector rotate must not immediately
209 * follow an instruction that writes to the accumulator that is being
215 /* "After an instruction that does a TLB Z write, the multisample mask
216 * must not be read as an instruction input argument in the following
217 * two instruction. The TLB Z write instruction can, however, be
218 * followed immediately by a TLB color write."
220 for (int i
= 0; i
< num_inst
- 1; i
++) {
221 uint64_t inst
= insts
[i
];
222 if (writes_reg(inst
, QPU_W_TLB_Z
)) {
223 assert(!reads_a_reg(insts
[i
+ 1], QPU_R_MS_REV_FLAGS
));
224 assert(!reads_a_reg(insts
[i
+ 2], QPU_R_MS_REV_FLAGS
));
229 * "A single instruction can only perform a maximum of one of the
230 * following closely coupled peripheral accesses in a single
231 * instruction: TMU write, TMU read, TLB write, TLB read, TLB
232 * combined color read and write, SFU write, Mutex read or Semaphore
235 for (int i
= 0; i
< num_inst
- 1; i
++) {
236 uint64_t inst
= insts
[i
];
238 static const uint32_t specials
[] = {
256 for (int j
= 0; j
< ARRAY_SIZE(specials
); j
++) {
257 if (writes_reg(inst
, specials
[j
]))
261 if (reads_reg(inst
, QPU_R_MUTEX_ACQUIRE
))
264 /* XXX: semaphore, combined color read/write? */
265 switch (QPU_GET_FIELD(inst
, QPU_SIG
)) {
266 case QPU_SIG_COLOR_LOAD
:
267 case QPU_SIG_COLOR_LOAD_END
:
268 case QPU_SIG_LOAD_TMU0
:
269 case QPU_SIG_LOAD_TMU1
:
273 assert(accesses
<= 1);