2 * Copyright © 2016 Intel Corporation
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
24 #include <gtest/gtest.h>
26 #include "util/ralloc.h"
28 static const struct gen_info
{
52 class validation_test
: public ::testing::TestWithParam
<struct gen_info
> {
57 virtual ~validation_test();
59 struct brw_codegen
*p
;
60 struct gen_device_info devinfo
;
63 validation_test::validation_test()
65 p
= rzalloc(NULL
, struct brw_codegen
);
66 memset(&devinfo
, 0, sizeof(devinfo
));
69 validation_test::~validation_test()
74 void validation_test::SetUp()
76 struct gen_info info
= GetParam();
77 int devid
= gen_device_name_to_pci_device_id(info
.name
);
79 gen_get_device_info_from_pci_id(devid
, &devinfo
);
81 brw_init_codegen(&devinfo
, p
, p
);
85 template <class ParamType
>
87 operator()(const ::testing::TestParamInfo
<ParamType
>& info
) const {
88 return info
.param
.name
;
92 INSTANTIATE_TEST_CASE_P(eu_assembly
, validation_test
,
93 ::testing::ValuesIn(gens
),
97 validate(struct brw_codegen
*p
)
99 const bool print
= getenv("TEST_DEBUG");
100 struct disasm_info
*disasm
= disasm_initialize(p
->devinfo
, NULL
);
103 disasm_new_inst_group(disasm
, 0);
104 disasm_new_inst_group(disasm
, p
->next_insn_offset
);
107 bool ret
= brw_validate_instructions(p
->devinfo
, p
->store
, 0,
108 p
->next_insn_offset
, disasm
);
111 dump_assembly(p
->store
, disasm
);
118 #define last_inst (&p->store[p->nr_insn - 1])
119 #define g0 brw_vec8_grf(0, 0)
120 #define acc0 brw_acc_reg(8)
121 #define null brw_null_reg()
122 #define zero brw_imm_f(0.0f)
125 clear_instructions(struct brw_codegen
*p
)
127 p
->next_insn_offset
= 0;
131 TEST_P(validation_test
, sanity
)
133 brw_ADD(p
, g0
, g0
, g0
);
135 EXPECT_TRUE(validate(p
));
138 TEST_P(validation_test
, src0_null_reg
)
140 brw_MOV(p
, g0
, null
);
142 EXPECT_FALSE(validate(p
));
145 TEST_P(validation_test
, src1_null_reg
)
147 brw_ADD(p
, g0
, g0
, null
);
149 EXPECT_FALSE(validate(p
));
152 TEST_P(validation_test
, math_src0_null_reg
)
154 if (devinfo
.gen
>= 6) {
155 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, null
, null
);
157 gen4_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, 0, null
, BRW_MATH_PRECISION_FULL
);
160 EXPECT_FALSE(validate(p
));
163 TEST_P(validation_test
, math_src1_null_reg
)
165 if (devinfo
.gen
>= 6) {
166 gen6_math(p
, g0
, BRW_MATH_FUNCTION_POW
, g0
, null
);
167 EXPECT_FALSE(validate(p
));
169 /* Math instructions on Gen4/5 are actually SEND messages with payloads.
170 * src1 is an immediate message descriptor set by gen4_math.
175 TEST_P(validation_test
, opcode46
)
177 /* opcode 46 is "push" on Gen 4 and 5
182 brw_next_insn(p
, brw_opcode_decode(&devinfo
, 46));
184 if (devinfo
.gen
== 7) {
185 EXPECT_FALSE(validate(p
));
187 EXPECT_TRUE(validate(p
));
191 /* When the Execution Data Type is wider than the destination data type, the
192 * destination must [...] specify a HorzStride equal to the ratio in sizes of
193 * the two data types.
195 TEST_P(validation_test
, dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size
)
197 brw_ADD(p
, g0
, g0
, g0
);
198 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
199 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
200 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
202 EXPECT_FALSE(validate(p
));
204 clear_instructions(p
);
206 brw_ADD(p
, g0
, g0
, g0
);
207 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
208 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
209 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
210 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
212 EXPECT_TRUE(validate(p
));
215 /* When the Execution Data Type is wider than the destination data type, the
216 * destination must be aligned as required by the wider execution data type
219 TEST_P(validation_test
, dst_subreg_must_be_aligned_to_exec_type_size
)
221 brw_ADD(p
, g0
, g0
, g0
);
222 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 2);
223 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
224 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
225 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
226 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
228 EXPECT_FALSE(validate(p
));
230 clear_instructions(p
);
232 brw_ADD(p
, g0
, g0
, g0
);
233 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
234 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 8);
235 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
236 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
237 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
238 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
239 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
240 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
241 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
242 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
243 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
244 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
246 EXPECT_TRUE(validate(p
));
249 /* ExecSize must be greater than or equal to Width. */
250 TEST_P(validation_test
, exec_size_less_than_width
)
252 brw_ADD(p
, g0
, g0
, g0
);
253 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
255 EXPECT_FALSE(validate(p
));
257 clear_instructions(p
);
259 brw_ADD(p
, g0
, g0
, g0
);
260 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
262 EXPECT_FALSE(validate(p
));
265 /* If ExecSize = Width and HorzStride ≠ 0,
266 * VertStride must be set to Width * HorzStride.
268 TEST_P(validation_test
, vertical_stride_is_width_by_horizontal_stride
)
270 brw_ADD(p
, g0
, g0
, g0
);
271 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
273 EXPECT_FALSE(validate(p
));
275 clear_instructions(p
);
277 brw_ADD(p
, g0
, g0
, g0
);
278 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
280 EXPECT_FALSE(validate(p
));
283 /* If Width = 1, HorzStride must be 0 regardless of the values
284 * of ExecSize and VertStride.
286 TEST_P(validation_test
, horizontal_stride_must_be_0_if_width_is_1
)
288 brw_ADD(p
, g0
, g0
, g0
);
289 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
290 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
291 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
293 EXPECT_FALSE(validate(p
));
295 clear_instructions(p
);
297 brw_ADD(p
, g0
, g0
, g0
);
298 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
299 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
300 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
302 EXPECT_FALSE(validate(p
));
305 /* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */
306 TEST_P(validation_test
, scalar_region_must_be_0_1_0
)
308 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
310 brw_ADD(p
, g0
, g0
, g0_0
);
311 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
312 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
313 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
314 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
316 EXPECT_FALSE(validate(p
));
318 clear_instructions(p
);
320 brw_ADD(p
, g0
, g0_0
, g0
);
321 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
322 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
323 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
324 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
326 EXPECT_FALSE(validate(p
));
329 /* If VertStride = HorzStride = 0, Width must be 1 regardless of the value
332 TEST_P(validation_test
, zero_stride_implies_0_1_0
)
334 brw_ADD(p
, g0
, g0
, g0
);
335 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
336 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
337 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
339 EXPECT_FALSE(validate(p
));
341 clear_instructions(p
);
343 brw_ADD(p
, g0
, g0
, g0
);
344 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
345 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
346 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
348 EXPECT_FALSE(validate(p
));
351 /* Dst.HorzStride must not be 0. */
352 TEST_P(validation_test
, dst_horizontal_stride_0
)
354 brw_ADD(p
, g0
, g0
, g0
);
355 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
357 EXPECT_FALSE(validate(p
));
359 clear_instructions(p
);
361 /* Align16 does not exist on Gen11+ */
362 if (devinfo
.gen
>= 11)
365 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
367 brw_ADD(p
, g0
, g0
, g0
);
368 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
370 EXPECT_FALSE(validate(p
));
373 /* VertStride must be used to cross BRW_GENERAL_REGISTER_FILE register boundaries. This rule implies
374 * that elements within a 'Width' cannot cross BRW_GENERAL_REGISTER_FILE boundaries.
376 TEST_P(validation_test
, must_not_cross_grf_boundary_in_a_width
)
378 brw_ADD(p
, g0
, g0
, g0
);
379 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 4);
381 EXPECT_FALSE(validate(p
));
383 clear_instructions(p
);
385 brw_ADD(p
, g0
, g0
, g0
);
386 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 4);
388 EXPECT_FALSE(validate(p
));
390 clear_instructions(p
);
392 brw_ADD(p
, g0
, g0
, g0
);
393 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
394 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
395 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
397 EXPECT_FALSE(validate(p
));
399 clear_instructions(p
);
401 brw_ADD(p
, g0
, g0
, g0
);
402 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
403 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
404 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
406 EXPECT_FALSE(validate(p
));
409 /* Destination Horizontal must be 1 in Align16 */
410 TEST_P(validation_test
, dst_hstride_on_align16_must_be_1
)
412 /* Align16 does not exist on Gen11+ */
413 if (devinfo
.gen
>= 11)
416 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
418 brw_ADD(p
, g0
, g0
, g0
);
419 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
421 EXPECT_FALSE(validate(p
));
423 clear_instructions(p
);
425 brw_ADD(p
, g0
, g0
, g0
);
426 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
428 EXPECT_TRUE(validate(p
));
431 /* VertStride must be 0 or 4 in Align16 */
432 TEST_P(validation_test
, vstride_on_align16_must_be_0_or_4
)
434 /* Align16 does not exist on Gen11+ */
435 if (devinfo
.gen
>= 11)
439 enum brw_vertical_stride vstride
;
440 bool expected_result
;
442 { BRW_VERTICAL_STRIDE_0
, true },
443 { BRW_VERTICAL_STRIDE_1
, false },
444 { BRW_VERTICAL_STRIDE_2
, devinfo
.is_haswell
|| devinfo
.gen
>= 8 },
445 { BRW_VERTICAL_STRIDE_4
, true },
446 { BRW_VERTICAL_STRIDE_8
, false },
447 { BRW_VERTICAL_STRIDE_16
, false },
448 { BRW_VERTICAL_STRIDE_32
, false },
449 { BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL
, false },
452 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
454 for (unsigned i
= 0; i
< sizeof(vstride
) / sizeof(vstride
[0]); i
++) {
455 brw_ADD(p
, g0
, g0
, g0
);
456 brw_inst_set_src0_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
458 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
460 clear_instructions(p
);
463 for (unsigned i
= 0; i
< sizeof(vstride
) / sizeof(vstride
[0]); i
++) {
464 brw_ADD(p
, g0
, g0
, g0
);
465 brw_inst_set_src1_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
467 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
469 clear_instructions(p
);
473 /* In Direct Addressing mode, a source cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE
476 TEST_P(validation_test
, source_cannot_span_more_than_2_registers
)
478 brw_ADD(p
, g0
, g0
, g0
);
479 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
480 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
481 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
482 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
483 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
484 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
485 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
487 EXPECT_FALSE(validate(p
));
489 clear_instructions(p
);
491 brw_ADD(p
, g0
, g0
, g0
);
492 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
493 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
494 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
495 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
496 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
497 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
498 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
499 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 2);
501 EXPECT_TRUE(validate(p
));
503 clear_instructions(p
);
505 brw_ADD(p
, g0
, g0
, g0
);
506 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
508 EXPECT_TRUE(validate(p
));
511 /* A destination cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE registers. */
512 TEST_P(validation_test
, destination_cannot_span_more_than_2_registers
)
514 brw_ADD(p
, g0
, g0
, g0
);
515 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
516 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
517 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
518 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
519 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
521 EXPECT_FALSE(validate(p
));
523 clear_instructions(p
);
525 brw_ADD(p
, g0
, g0
, g0
);
526 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_8
);
527 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 6);
528 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
529 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
530 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
531 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
532 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
533 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
534 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
535 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
536 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
537 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
539 EXPECT_TRUE(validate(p
));
542 TEST_P(validation_test
, src_region_spans_two_regs_dst_region_spans_one
)
544 /* Writes to dest are to the lower OWord */
545 brw_ADD(p
, g0
, g0
, g0
);
546 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
547 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
548 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
549 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
550 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
551 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
553 EXPECT_TRUE(validate(p
));
555 clear_instructions(p
);
557 /* Writes to dest are to the upper OWord */
558 brw_ADD(p
, g0
, g0
, g0
);
559 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 16);
560 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
561 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
562 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
563 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
564 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
565 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
567 EXPECT_TRUE(validate(p
));
569 clear_instructions(p
);
571 /* Writes to dest are evenly split between OWords */
572 brw_ADD(p
, g0
, g0
, g0
);
573 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
574 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
575 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
576 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
577 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
578 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
579 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
581 EXPECT_TRUE(validate(p
));
583 clear_instructions(p
);
585 /* Writes to dest are uneven between OWords */
586 brw_ADD(p
, g0
, g0
, g0
);
587 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
588 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 10);
589 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
590 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
591 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
592 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
593 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
594 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
595 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
596 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
597 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
599 if (devinfo
.gen
>= 9) {
600 EXPECT_TRUE(validate(p
));
602 EXPECT_FALSE(validate(p
));
606 TEST_P(validation_test
, dst_elements_must_be_evenly_split_between_registers
)
608 brw_ADD(p
, g0
, g0
, g0
);
609 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
611 if (devinfo
.gen
>= 9) {
612 EXPECT_TRUE(validate(p
));
614 EXPECT_FALSE(validate(p
));
617 clear_instructions(p
);
619 brw_ADD(p
, g0
, g0
, g0
);
620 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
622 EXPECT_TRUE(validate(p
));
624 clear_instructions(p
);
626 if (devinfo
.gen
>= 6) {
627 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
629 EXPECT_TRUE(validate(p
));
631 clear_instructions(p
);
633 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
634 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
636 EXPECT_FALSE(validate(p
));
640 TEST_P(validation_test
, two_src_two_dst_source_offsets_must_be_same
)
642 brw_ADD(p
, g0
, g0
, g0
);
643 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
644 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
645 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 16);
646 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_2
);
647 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
648 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
649 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
650 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
651 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
653 if (devinfo
.gen
<= 7) {
654 EXPECT_FALSE(validate(p
));
656 EXPECT_TRUE(validate(p
));
659 clear_instructions(p
);
661 brw_ADD(p
, g0
, g0
, g0
);
662 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
663 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
664 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
665 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
666 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
667 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_8
);
668 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
669 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
671 EXPECT_TRUE(validate(p
));
674 TEST_P(validation_test
, two_src_two_dst_each_dst_must_be_derived_from_one_src
)
677 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
678 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
679 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
680 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
681 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 8);
682 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
683 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
684 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
686 if (devinfo
.gen
<= 7) {
687 EXPECT_FALSE(validate(p
));
689 EXPECT_TRUE(validate(p
));
692 clear_instructions(p
);
695 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 16);
696 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 8);
697 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_2
);
698 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
699 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
701 if (devinfo
.gen
<= 7) {
702 EXPECT_FALSE(validate(p
));
704 EXPECT_TRUE(validate(p
));
708 TEST_P(validation_test
, one_src_two_dst
)
710 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
712 brw_ADD(p
, g0
, g0_0
, g0_0
);
713 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
715 EXPECT_TRUE(validate(p
));
717 clear_instructions(p
);
719 brw_ADD(p
, g0
, g0
, g0
);
720 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
721 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
722 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
723 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
725 EXPECT_TRUE(validate(p
));
727 clear_instructions(p
);
729 brw_ADD(p
, g0
, g0
, g0
);
730 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
731 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
732 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
733 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
734 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
735 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
736 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
737 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
739 if (devinfo
.gen
>= 8) {
740 EXPECT_TRUE(validate(p
));
742 EXPECT_FALSE(validate(p
));
745 clear_instructions(p
);
747 brw_ADD(p
, g0
, g0
, g0
);
748 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
749 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
750 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
751 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
752 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
753 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
754 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
755 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
757 if (devinfo
.gen
>= 8) {
758 EXPECT_TRUE(validate(p
));
760 EXPECT_FALSE(validate(p
));
764 TEST_P(validation_test
, packed_byte_destination
)
766 static const struct {
767 enum brw_reg_type dst_type
;
768 enum brw_reg_type src_type
;
770 bool expected_result
;
772 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 0, 0, true },
773 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 0, 0, true },
774 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 0, 0, true },
775 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 0, 0, true },
777 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 1, 0, 0, false },
778 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 1, 0, 0, false },
779 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 1, 0, 0, false },
780 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 1, 0, 0, false },
782 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 1, 0, false },
783 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 1, 0, false },
784 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 1, 0, false },
785 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 1, 0, false },
787 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 0, 1, false },
788 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 0, 1, false },
789 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 0, 1, false },
790 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 0, 1, false },
792 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UW
, 0, 0, 0, false },
793 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_W
, 0, 0, 0, false },
794 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UD
, 0, 0, 0, false },
795 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_D
, 0, 0, 0, false },
798 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
799 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(g0
, move
[i
].src_type
));
800 brw_inst_set_src0_negate(&devinfo
, last_inst
, move
[i
].neg
);
801 brw_inst_set_src0_abs(&devinfo
, last_inst
, move
[i
].abs
);
802 brw_inst_set_saturate(&devinfo
, last_inst
, move
[i
].sat
);
804 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
806 clear_instructions(p
);
809 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_UB
),
810 retype(g0
, BRW_REGISTER_TYPE_UB
),
811 retype(g0
, BRW_REGISTER_TYPE_UB
));
812 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
814 EXPECT_FALSE(validate(p
));
816 clear_instructions(p
);
818 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
819 retype(g0
, BRW_REGISTER_TYPE_B
),
820 retype(g0
, BRW_REGISTER_TYPE_B
));
821 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
823 EXPECT_FALSE(validate(p
));
826 TEST_P(validation_test
, byte_destination_relaxed_alignment
)
828 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
829 retype(g0
, BRW_REGISTER_TYPE_W
),
830 retype(g0
, BRW_REGISTER_TYPE_W
));
831 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
832 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
834 EXPECT_TRUE(validate(p
));
836 clear_instructions(p
);
838 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
839 retype(g0
, BRW_REGISTER_TYPE_W
),
840 retype(g0
, BRW_REGISTER_TYPE_W
));
841 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
842 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
843 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 1);
845 if (devinfo
.gen
> 4 || devinfo
.is_g4x
) {
846 EXPECT_TRUE(validate(p
));
848 EXPECT_FALSE(validate(p
));
852 TEST_P(validation_test
, byte_64bit_conversion
)
854 static const struct {
855 enum brw_reg_type dst_type
;
856 enum brw_reg_type src_type
;
858 bool expected_result
;
860 #define INST(dst_type, src_type, dst_stride, expected_result) \
862 BRW_REGISTER_TYPE_##dst_type, \
863 BRW_REGISTER_TYPE_##src_type, \
864 BRW_HORIZONTAL_STRIDE_##dst_stride, \
868 INST(B
, Q
, 1, false),
869 INST(B
, UQ
, 1, false),
870 INST(B
, DF
, 1, false),
871 INST(UB
, Q
, 1, false),
872 INST(UB
, UQ
, 1, false),
873 INST(UB
, DF
, 1, false),
875 INST(B
, Q
, 2, false),
876 INST(B
, UQ
, 2, false),
877 INST(B
, DF
, 2, false),
878 INST(UB
, Q
, 2, false),
879 INST(UB
, UQ
, 2, false),
880 INST(UB
, DF
, 2, false),
882 INST(B
, Q
, 4, false),
883 INST(B
, UQ
, 4, false),
884 INST(B
, DF
, 4, false),
885 INST(UB
, Q
, 4, false),
886 INST(UB
, UQ
, 4, false),
887 INST(UB
, DF
, 4, false),
895 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
896 if (!devinfo
.has_64bit_types
&& type_sz(inst
[i
].src_type
) == 8)
899 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
), retype(g0
, inst
[i
].src_type
));
900 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
901 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
903 clear_instructions(p
);
907 TEST_P(validation_test
, half_float_conversion
)
909 static const struct {
910 enum brw_reg_type dst_type
;
911 enum brw_reg_type src_type
;
914 bool expected_result_bdw
;
915 bool expected_result_chv_gen9
;
917 #define INST_C(dst_type, src_type, dst_stride, dst_subnr, expected_result) \
919 BRW_REGISTER_TYPE_##dst_type, \
920 BRW_REGISTER_TYPE_##src_type, \
921 BRW_HORIZONTAL_STRIDE_##dst_stride, \
926 #define INST_S(dst_type, src_type, dst_stride, dst_subnr, \
927 expected_result_bdw, expected_result_chv_gen9) \
929 BRW_REGISTER_TYPE_##dst_type, \
930 BRW_REGISTER_TYPE_##src_type, \
931 BRW_HORIZONTAL_STRIDE_##dst_stride, \
933 expected_result_bdw, \
934 expected_result_chv_gen9, \
937 /* MOV to half-float destination */
938 INST_C(HF
, B
, 1, 0, false),
939 INST_C(HF
, W
, 1, 0, false),
940 INST_C(HF
, HF
, 1, 0, true),
941 INST_C(HF
, HF
, 1, 2, true),
942 INST_C(HF
, D
, 1, 0, false),
943 INST_S(HF
, F
, 1, 0, false, true),
944 INST_C(HF
, Q
, 1, 0, false),
945 INST_C(HF
, B
, 2, 0, true),
946 INST_C(HF
, B
, 2, 2, false),
947 INST_C(HF
, W
, 2, 0, true),
948 INST_C(HF
, W
, 2, 2, false),
949 INST_C(HF
, HF
, 2, 0, true),
950 INST_C(HF
, HF
, 2, 2, true),
951 INST_C(HF
, D
, 2, 0, true),
952 INST_C(HF
, D
, 2, 2, false),
953 INST_C(HF
, F
, 2, 0, true),
954 INST_S(HF
, F
, 2, 2, false, true),
955 INST_C(HF
, Q
, 2, 0, false),
956 INST_C(HF
, DF
, 2, 0, false),
957 INST_C(HF
, B
, 4, 0, false),
958 INST_C(HF
, W
, 4, 0, false),
959 INST_C(HF
, HF
, 4, 0, true),
960 INST_C(HF
, HF
, 4, 2, true),
961 INST_C(HF
, D
, 4, 0, false),
962 INST_C(HF
, F
, 4, 0, false),
963 INST_C(HF
, Q
, 4, 0, false),
964 INST_C(HF
, DF
, 4, 0, false),
966 /* MOV from half-float source */
967 INST_C( B
, HF
, 1, 0, false),
968 INST_C( W
, HF
, 1, 0, false),
969 INST_C( D
, HF
, 1, 0, true),
970 INST_C( D
, HF
, 1, 4, true),
971 INST_C( F
, HF
, 1, 0, true),
972 INST_C( F
, HF
, 1, 4, true),
973 INST_C( Q
, HF
, 1, 0, false),
974 INST_C(DF
, HF
, 1, 0, false),
975 INST_C( B
, HF
, 2, 0, false),
976 INST_C( W
, HF
, 2, 0, true),
977 INST_C( W
, HF
, 2, 2, false),
978 INST_C( D
, HF
, 2, 0, false),
979 INST_C( F
, HF
, 2, 0, true),
980 INST_C( B
, HF
, 4, 0, true),
981 INST_C( B
, HF
, 4, 1, false),
982 INST_C( W
, HF
, 4, 0, false),
991 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
992 if (!devinfo
.has_64bit_types
&&
993 (type_sz(inst
[i
].src_type
) == 8 || type_sz(inst
[i
].dst_type
) == 8)) {
997 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
), retype(g0
, inst
[i
].src_type
));
999 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
1001 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1002 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].dst_subnr
);
1004 if (inst
[i
].src_type
== BRW_REGISTER_TYPE_B
) {
1005 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1006 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
1007 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
1009 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1010 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
1011 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
1014 if (devinfo
.is_cherryview
|| devinfo
.gen
>= 9)
1015 EXPECT_EQ(inst
[i
].expected_result_chv_gen9
, validate(p
));
1017 EXPECT_EQ(inst
[i
].expected_result_bdw
, validate(p
));
1019 clear_instructions(p
);
1023 TEST_P(validation_test
, mixed_float_source_indirect_addressing
)
1025 static const struct {
1026 enum brw_reg_type dst_type
;
1027 enum brw_reg_type src0_type
;
1028 enum brw_reg_type src1_type
;
1029 unsigned dst_stride
;
1032 bool expected_result
;
1034 #define INST(dst_type, src0_type, src1_type, \
1035 dst_stride, dst_indirect, src0_indirect, expected_result) \
1037 BRW_REGISTER_TYPE_##dst_type, \
1038 BRW_REGISTER_TYPE_##src0_type, \
1039 BRW_REGISTER_TYPE_##src1_type, \
1040 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1046 /* Source and dest are mixed float: indirect src addressing not allowed */
1047 INST(HF
, F
, F
, 2, false, false, true),
1048 INST(HF
, F
, F
, 2, true, false, true),
1049 INST(HF
, F
, F
, 2, false, true, false),
1050 INST(HF
, F
, F
, 2, true, true, false),
1051 INST( F
, HF
, F
, 1, false, false, true),
1052 INST( F
, HF
, F
, 1, true, false, true),
1053 INST( F
, HF
, F
, 1, false, true, false),
1054 INST( F
, HF
, F
, 1, true, true, false),
1056 INST(HF
, HF
, F
, 2, false, false, true),
1057 INST(HF
, HF
, F
, 2, true, false, true),
1058 INST(HF
, HF
, F
, 2, false, true, false),
1059 INST(HF
, HF
, F
, 2, true, true, false),
1060 INST( F
, F
, HF
, 1, false, false, true),
1061 INST( F
, F
, HF
, 1, true, false, true),
1062 INST( F
, F
, HF
, 1, false, true, false),
1063 INST( F
, F
, HF
, 1, true, true, false),
1068 if (devinfo
.gen
< 8)
1071 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1072 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1073 retype(g0
, inst
[i
].src0_type
),
1074 retype(g0
, inst
[i
].src1_type
));
1076 brw_inst_set_dst_address_mode(&devinfo
, last_inst
, inst
[i
].dst_indirect
);
1077 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1078 brw_inst_set_src0_address_mode(&devinfo
, last_inst
, inst
[i
].src0_indirect
);
1080 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1082 clear_instructions(p
);
1086 TEST_P(validation_test
, mixed_float_align1_simd16
)
1088 static const struct {
1090 enum brw_reg_type dst_type
;
1091 enum brw_reg_type src0_type
;
1092 enum brw_reg_type src1_type
;
1093 unsigned dst_stride
;
1094 bool expected_result
;
1096 #define INST(exec_size, dst_type, src0_type, src1_type, \
1097 dst_stride, expected_result) \
1099 BRW_EXECUTE_##exec_size, \
1100 BRW_REGISTER_TYPE_##dst_type, \
1101 BRW_REGISTER_TYPE_##src0_type, \
1102 BRW_REGISTER_TYPE_##src1_type, \
1103 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1107 /* No SIMD16 in mixed mode when destination is packed f16 */
1108 INST( 8, HF
, F
, HF
, 2, true),
1109 INST(16, HF
, HF
, F
, 2, true),
1110 INST(16, HF
, HF
, F
, 1, false),
1111 INST(16, HF
, F
, HF
, 1, false),
1113 /* No SIMD16 in mixed mode when destination is f32 */
1114 INST( 8, F
, HF
, F
, 1, true),
1115 INST( 8, F
, F
, HF
, 1, true),
1116 INST(16, F
, HF
, F
, 1, false),
1117 INST(16, F
, F
, HF
, 1, false),
1122 if (devinfo
.gen
< 8)
1125 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1126 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1127 retype(g0
, inst
[i
].src0_type
),
1128 retype(g0
, inst
[i
].src1_type
));
1130 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1132 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1134 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1136 clear_instructions(p
);
1140 TEST_P(validation_test
, mixed_float_align1_packed_fp16_dst_acc_read_offset_0
)
1142 static const struct {
1143 enum brw_reg_type dst_type
;
1144 enum brw_reg_type src0_type
;
1145 enum brw_reg_type src1_type
;
1146 unsigned dst_stride
;
1149 bool expected_result_bdw
;
1150 bool expected_result_chv_skl
;
1152 #define INST(dst_type, src0_type, src1_type, dst_stride, read_acc, subnr, \
1153 expected_result_bdw, expected_result_chv_skl) \
1155 BRW_REGISTER_TYPE_##dst_type, \
1156 BRW_REGISTER_TYPE_##src0_type, \
1157 BRW_REGISTER_TYPE_##src1_type, \
1158 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1161 expected_result_bdw, \
1162 expected_result_chv_skl, \
1165 /* Destination is not packed */
1166 INST(HF
, HF
, F
, 2, true, 0, true, true),
1167 INST(HF
, HF
, F
, 2, true, 2, true, true),
1168 INST(HF
, HF
, F
, 2, true, 4, true, true),
1169 INST(HF
, HF
, F
, 2, true, 8, true, true),
1170 INST(HF
, HF
, F
, 2, true, 16, true, true),
1172 /* Destination is packed, we don't read acc */
1173 INST(HF
, HF
, F
, 1, false, 0, false, true),
1174 INST(HF
, HF
, F
, 1, false, 2, false, true),
1175 INST(HF
, HF
, F
, 1, false, 4, false, true),
1176 INST(HF
, HF
, F
, 1, false, 8, false, true),
1177 INST(HF
, HF
, F
, 1, false, 16, false, true),
1179 /* Destination is packed, we read acc */
1180 INST(HF
, HF
, F
, 1, true, 0, false, false),
1181 INST(HF
, HF
, F
, 1, true, 2, false, false),
1182 INST(HF
, HF
, F
, 1, true, 4, false, false),
1183 INST(HF
, HF
, F
, 1, true, 8, false, false),
1184 INST(HF
, HF
, F
, 1, true, 16, false, false),
1189 if (devinfo
.gen
< 8)
1192 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1193 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1194 retype(inst
[i
].read_acc
? acc0
: g0
, inst
[i
].src0_type
),
1195 retype(g0
, inst
[i
].src1_type
));
1197 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1199 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].subnr
);
1201 if (devinfo
.is_cherryview
|| devinfo
.gen
>= 9)
1202 EXPECT_EQ(inst
[i
].expected_result_chv_skl
, validate(p
));
1204 EXPECT_EQ(inst
[i
].expected_result_bdw
, validate(p
));
1206 clear_instructions(p
);
1210 TEST_P(validation_test
, mixed_float_fp16_dest_with_acc
)
1212 static const struct {
1215 enum brw_reg_type dst_type
;
1216 enum brw_reg_type src0_type
;
1217 enum brw_reg_type src1_type
;
1218 unsigned dst_stride
;
1220 bool expected_result_bdw
;
1221 bool expected_result_chv_skl
;
1223 #define INST(exec_size, opcode, dst_type, src0_type, src1_type, \
1224 dst_stride, read_acc,expected_result_bdw, \
1225 expected_result_chv_skl) \
1227 BRW_EXECUTE_##exec_size, \
1228 BRW_OPCODE_##opcode, \
1229 BRW_REGISTER_TYPE_##dst_type, \
1230 BRW_REGISTER_TYPE_##src0_type, \
1231 BRW_REGISTER_TYPE_##src1_type, \
1232 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1234 expected_result_bdw, \
1235 expected_result_chv_skl, \
1238 /* Packed fp16 dest with implicit acc needs hstride=2 */
1239 INST(8, MAC
, HF
, HF
, F
, 1, false, false, false),
1240 INST(8, MAC
, HF
, HF
, F
, 2, false, true, true),
1241 INST(8, MAC
, HF
, F
, HF
, 1, false, false, false),
1242 INST(8, MAC
, HF
, F
, HF
, 2, false, true, true),
1244 /* Packed fp16 dest with explicit acc needs hstride=2 */
1245 INST(8, ADD
, HF
, HF
, F
, 1, true, false, false),
1246 INST(8, ADD
, HF
, HF
, F
, 2, true, true, true),
1247 INST(8, ADD
, HF
, F
, HF
, 1, true, false, false),
1248 INST(8, ADD
, HF
, F
, HF
, 2, true, true, true),
1250 /* If destination is not fp16, restriction doesn't apply */
1251 INST(8, MAC
, F
, HF
, F
, 1, false, true, true),
1252 INST(8, MAC
, F
, HF
, F
, 2, false, true, true),
1254 /* If there is no implicit/explicit acc, restriction doesn't apply */
1255 INST(8, ADD
, HF
, HF
, F
, 1, false, false, true),
1256 INST(8, ADD
, HF
, HF
, F
, 2, false, true, true),
1257 INST(8, ADD
, HF
, F
, HF
, 1, false, false, true),
1258 INST(8, ADD
, HF
, F
, HF
, 2, false, true, true),
1259 INST(8, ADD
, F
, HF
, F
, 1, false, true, true),
1260 INST(8, ADD
, F
, HF
, F
, 2, false, true, true),
1265 if (devinfo
.gen
< 8)
1268 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1269 if (inst
[i
].opcode
== BRW_OPCODE_MAC
) {
1270 brw_MAC(p
, retype(g0
, inst
[i
].dst_type
),
1271 retype(g0
, inst
[i
].src0_type
),
1272 retype(g0
, inst
[i
].src1_type
));
1274 assert(inst
[i
].opcode
== BRW_OPCODE_ADD
);
1275 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1276 retype(inst
[i
].read_acc
? acc0
: g0
, inst
[i
].src0_type
),
1277 retype(g0
, inst
[i
].src1_type
));
1280 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1282 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1284 if (devinfo
.is_cherryview
|| devinfo
.gen
>= 9)
1285 EXPECT_EQ(inst
[i
].expected_result_chv_skl
, validate(p
));
1287 EXPECT_EQ(inst
[i
].expected_result_bdw
, validate(p
));
1289 clear_instructions(p
);
1293 TEST_P(validation_test
, mixed_float_align1_math_strided_fp16_inputs
)
1295 static const struct {
1296 enum brw_reg_type dst_type
;
1297 enum brw_reg_type src0_type
;
1298 enum brw_reg_type src1_type
;
1299 unsigned dst_stride
;
1300 unsigned src0_stride
;
1301 unsigned src1_stride
;
1302 bool expected_result
;
1304 #define INST(dst_type, src0_type, src1_type, \
1305 dst_stride, src0_stride, src1_stride, expected_result) \
1307 BRW_REGISTER_TYPE_##dst_type, \
1308 BRW_REGISTER_TYPE_##src0_type, \
1309 BRW_REGISTER_TYPE_##src1_type, \
1310 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1311 BRW_HORIZONTAL_STRIDE_##src0_stride, \
1312 BRW_HORIZONTAL_STRIDE_##src1_stride, \
1316 INST(HF
, HF
, F
, 2, 2, 1, true),
1317 INST(HF
, F
, HF
, 2, 1, 2, true),
1318 INST(HF
, F
, HF
, 1, 1, 2, true),
1319 INST(HF
, F
, HF
, 2, 1, 1, false),
1320 INST(HF
, HF
, F
, 2, 1, 1, false),
1321 INST(HF
, HF
, F
, 1, 1, 1, false),
1322 INST(HF
, HF
, F
, 2, 1, 1, false),
1323 INST( F
, HF
, F
, 1, 1, 1, false),
1324 INST( F
, F
, HF
, 1, 1, 2, true),
1325 INST( F
, HF
, HF
, 1, 2, 1, false),
1326 INST( F
, HF
, HF
, 1, 2, 2, true),
1331 /* No half-float math in gen8 */
1332 if (devinfo
.gen
< 9)
1335 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1336 gen6_math(p
, retype(g0
, inst
[i
].dst_type
),
1337 BRW_MATH_FUNCTION_POW
,
1338 retype(g0
, inst
[i
].src0_type
),
1339 retype(g0
, inst
[i
].src1_type
));
1341 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1343 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1344 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
1345 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src0_stride
);
1347 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1348 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
1349 brw_inst_set_src1_hstride(&devinfo
, last_inst
, inst
[i
].src1_stride
);
1351 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1353 clear_instructions(p
);
1357 TEST_P(validation_test
, mixed_float_align1_packed_fp16_dst
)
1359 static const struct {
1361 enum brw_reg_type dst_type
;
1362 enum brw_reg_type src0_type
;
1363 enum brw_reg_type src1_type
;
1364 unsigned dst_stride
;
1366 bool expected_result_bdw
;
1367 bool expected_result_chv_skl
;
1369 #define INST(exec_size, dst_type, src0_type, src1_type, dst_stride, dst_subnr, \
1370 expected_result_bdw, expected_result_chv_skl) \
1372 BRW_EXECUTE_##exec_size, \
1373 BRW_REGISTER_TYPE_##dst_type, \
1374 BRW_REGISTER_TYPE_##src0_type, \
1375 BRW_REGISTER_TYPE_##src1_type, \
1376 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1378 expected_result_bdw, \
1379 expected_result_chv_skl \
1382 /* SIMD8 packed fp16 dst won't cross oword boundaries if region is
1385 INST( 8, HF
, HF
, F
, 1, 0, false, true),
1386 INST( 8, HF
, HF
, F
, 1, 2, false, false),
1387 INST( 8, HF
, HF
, F
, 1, 4, false, false),
1388 INST( 8, HF
, HF
, F
, 1, 8, false, false),
1389 INST( 8, HF
, HF
, F
, 1, 16, false, true),
1391 /* SIMD16 packed fp16 always crosses oword boundaries */
1392 INST(16, HF
, HF
, F
, 1, 0, false, false),
1393 INST(16, HF
, HF
, F
, 1, 2, false, false),
1394 INST(16, HF
, HF
, F
, 1, 4, false, false),
1395 INST(16, HF
, HF
, F
, 1, 8, false, false),
1396 INST(16, HF
, HF
, F
, 1, 16, false, false),
1398 /* If destination is not packed (or not fp16) we can cross oword
1401 INST( 8, HF
, HF
, F
, 2, 0, true, true),
1402 INST( 8, F
, HF
, F
, 1, 0, true, true),
1407 if (devinfo
.gen
< 8)
1410 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1411 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1412 retype(g0
, inst
[i
].src0_type
),
1413 retype(g0
, inst
[i
].src1_type
));
1415 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1416 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].dst_subnr
);
1418 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1419 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
1420 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
1422 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1423 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
1424 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
1426 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1428 if (devinfo
.is_cherryview
|| devinfo
.gen
>= 9)
1429 EXPECT_EQ(inst
[i
].expected_result_chv_skl
, validate(p
));
1431 EXPECT_EQ(inst
[i
].expected_result_bdw
, validate(p
));
1433 clear_instructions(p
);
1437 TEST_P(validation_test
, mixed_float_align16_packed_data
)
1439 static const struct {
1440 enum brw_reg_type dst_type
;
1441 enum brw_reg_type src0_type
;
1442 enum brw_reg_type src1_type
;
1443 unsigned src0_vstride
;
1444 unsigned src1_vstride
;
1445 bool expected_result
;
1447 #define INST(dst_type, src0_type, src1_type, \
1448 src0_vstride, src1_vstride, expected_result) \
1450 BRW_REGISTER_TYPE_##dst_type, \
1451 BRW_REGISTER_TYPE_##src0_type, \
1452 BRW_REGISTER_TYPE_##src1_type, \
1453 BRW_VERTICAL_STRIDE_##src0_vstride, \
1454 BRW_VERTICAL_STRIDE_##src1_vstride, \
1458 /* We only test with F destination because there is a restriction
1459 * by which F->HF conversions need to be DWord aligned but Align16 also
1460 * requires that destination horizontal stride is 1.
1462 INST(F
, F
, HF
, 4, 4, true),
1463 INST(F
, F
, HF
, 2, 4, false),
1464 INST(F
, F
, HF
, 4, 2, false),
1465 INST(F
, F
, HF
, 0, 4, false),
1466 INST(F
, F
, HF
, 4, 0, false),
1467 INST(F
, HF
, F
, 4, 4, true),
1468 INST(F
, HF
, F
, 4, 2, false),
1469 INST(F
, HF
, F
, 2, 4, false),
1470 INST(F
, HF
, F
, 0, 4, false),
1471 INST(F
, HF
, F
, 4, 0, false),
1476 if (devinfo
.gen
< 8 || devinfo
.gen
>= 11)
1479 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
1481 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1482 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1483 retype(g0
, inst
[i
].src0_type
),
1484 retype(g0
, inst
[i
].src1_type
));
1486 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src0_vstride
);
1487 brw_inst_set_src1_vstride(&devinfo
, last_inst
, inst
[i
].src1_vstride
);
1489 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1491 clear_instructions(p
);
1495 TEST_P(validation_test
, mixed_float_align16_no_simd16
)
1497 static const struct {
1499 enum brw_reg_type dst_type
;
1500 enum brw_reg_type src0_type
;
1501 enum brw_reg_type src1_type
;
1502 bool expected_result
;
1504 #define INST(exec_size, dst_type, src0_type, src1_type, expected_result) \
1506 BRW_EXECUTE_##exec_size, \
1507 BRW_REGISTER_TYPE_##dst_type, \
1508 BRW_REGISTER_TYPE_##src0_type, \
1509 BRW_REGISTER_TYPE_##src1_type, \
1513 /* We only test with F destination because there is a restriction
1514 * by which F->HF conversions need to be DWord aligned but Align16 also
1515 * requires that destination horizontal stride is 1.
1517 INST( 8, F
, F
, HF
, true),
1518 INST( 8, F
, HF
, F
, true),
1519 INST( 8, F
, F
, HF
, true),
1520 INST(16, F
, F
, HF
, false),
1521 INST(16, F
, HF
, F
, false),
1522 INST(16, F
, F
, HF
, false),
1527 if (devinfo
.gen
< 8 || devinfo
.gen
>= 11)
1530 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
1532 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1533 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1534 retype(g0
, inst
[i
].src0_type
),
1535 retype(g0
, inst
[i
].src1_type
));
1537 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1539 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1540 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1542 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1544 clear_instructions(p
);
1548 TEST_P(validation_test
, mixed_float_align16_no_acc_read
)
1550 static const struct {
1551 enum brw_reg_type dst_type
;
1552 enum brw_reg_type src0_type
;
1553 enum brw_reg_type src1_type
;
1555 bool expected_result
;
1557 #define INST(dst_type, src0_type, src1_type, read_acc, expected_result) \
1559 BRW_REGISTER_TYPE_##dst_type, \
1560 BRW_REGISTER_TYPE_##src0_type, \
1561 BRW_REGISTER_TYPE_##src1_type, \
1566 /* We only test with F destination because there is a restriction
1567 * by which F->HF conversions need to be DWord aligned but Align16 also
1568 * requires that destination horizontal stride is 1.
1570 INST( F
, F
, HF
, false, true),
1571 INST( F
, F
, HF
, true, false),
1572 INST( F
, HF
, F
, false, true),
1573 INST( F
, HF
, F
, true, false),
1578 if (devinfo
.gen
< 8 || devinfo
.gen
>= 11)
1581 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
1583 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1584 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1585 retype(inst
[i
].read_acc
? acc0
: g0
, inst
[i
].src0_type
),
1586 retype(g0
, inst
[i
].src1_type
));
1588 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1589 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1591 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1593 clear_instructions(p
);
1597 TEST_P(validation_test
, mixed_float_align16_math_packed_format
)
1599 static const struct {
1600 enum brw_reg_type dst_type
;
1601 enum brw_reg_type src0_type
;
1602 enum brw_reg_type src1_type
;
1603 unsigned src0_vstride
;
1604 unsigned src1_vstride
;
1605 bool expected_result
;
1607 #define INST(dst_type, src0_type, src1_type, \
1608 src0_vstride, src1_vstride, expected_result) \
1610 BRW_REGISTER_TYPE_##dst_type, \
1611 BRW_REGISTER_TYPE_##src0_type, \
1612 BRW_REGISTER_TYPE_##src1_type, \
1613 BRW_VERTICAL_STRIDE_##src0_vstride, \
1614 BRW_VERTICAL_STRIDE_##src1_vstride, \
1618 /* We only test with F destination because there is a restriction
1619 * by which F->HF conversions need to be DWord aligned but Align16 also
1620 * requires that destination horizontal stride is 1.
1622 INST( F
, HF
, F
, 4, 0, false),
1623 INST( F
, HF
, HF
, 4, 4, true),
1624 INST( F
, F
, HF
, 4, 0, false),
1625 INST( F
, F
, HF
, 2, 4, false),
1626 INST( F
, F
, HF
, 4, 2, false),
1627 INST( F
, HF
, HF
, 0, 4, false),
1632 /* Align16 Math for mixed float mode is not supported in gen8 */
1633 if (devinfo
.gen
< 9 || devinfo
.gen
>= 11)
1636 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
1638 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1639 gen6_math(p
, retype(g0
, inst
[i
].dst_type
),
1640 BRW_MATH_FUNCTION_POW
,
1641 retype(g0
, inst
[i
].src0_type
),
1642 retype(g0
, inst
[i
].src1_type
));
1644 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src0_vstride
);
1645 brw_inst_set_src1_vstride(&devinfo
, last_inst
, inst
[i
].src1_vstride
);
1647 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1649 clear_instructions(p
);
1653 TEST_P(validation_test
, vector_immediate_destination_alignment
)
1655 static const struct {
1656 enum brw_reg_type dst_type
;
1657 enum brw_reg_type src_type
;
1660 bool expected_result
;
1662 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 0, BRW_EXECUTE_4
, true },
1663 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 16, BRW_EXECUTE_4
, true },
1664 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 1, BRW_EXECUTE_4
, false },
1666 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 0, BRW_EXECUTE_8
, true },
1667 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 16, BRW_EXECUTE_8
, true },
1668 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 1, BRW_EXECUTE_8
, false },
1670 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 0, BRW_EXECUTE_8
, true },
1671 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 16, BRW_EXECUTE_8
, true },
1672 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 1, BRW_EXECUTE_8
, false },
1675 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
1676 /* UV type is Gen6+ */
1677 if (devinfo
.gen
< 6 &&
1678 move
[i
].src_type
== BRW_REGISTER_TYPE_UV
)
1681 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(zero
, move
[i
].src_type
));
1682 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, move
[i
].subnr
);
1683 brw_inst_set_exec_size(&devinfo
, last_inst
, move
[i
].exec_size
);
1685 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
1687 clear_instructions(p
);
1691 TEST_P(validation_test
, vector_immediate_destination_stride
)
1693 static const struct {
1694 enum brw_reg_type dst_type
;
1695 enum brw_reg_type src_type
;
1697 bool expected_result
;
1699 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_1
, true },
1700 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, false },
1701 { BRW_REGISTER_TYPE_D
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_1
, true },
1702 { BRW_REGISTER_TYPE_D
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, false },
1703 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, true },
1704 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_4
, true },
1706 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_1
, true },
1707 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_2
, false },
1708 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_4
, false },
1709 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_2
, true },
1711 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_1
, true },
1712 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_2
, false },
1713 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_4
, false },
1714 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_2
, true },
1717 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
1718 /* UV type is Gen6+ */
1719 if (devinfo
.gen
< 6 &&
1720 move
[i
].src_type
== BRW_REGISTER_TYPE_UV
)
1723 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(zero
, move
[i
].src_type
));
1724 brw_inst_set_dst_hstride(&devinfo
, last_inst
, move
[i
].stride
);
1726 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
1728 clear_instructions(p
);
1732 TEST_P(validation_test
, qword_low_power_align1_regioning_restrictions
)
1734 static const struct {
1738 enum brw_reg_type dst_type
;
1739 unsigned dst_subreg
;
1740 unsigned dst_stride
;
1742 enum brw_reg_type src_type
;
1743 unsigned src_subreg
;
1744 unsigned src_vstride
;
1746 unsigned src_hstride
;
1748 bool expected_result
;
1750 #define INST(opcode, exec_size, dst_type, dst_subreg, dst_stride, src_type, \
1751 src_subreg, src_vstride, src_width, src_hstride, expected_result) \
1753 BRW_OPCODE_##opcode, \
1754 BRW_EXECUTE_##exec_size, \
1755 BRW_REGISTER_TYPE_##dst_type, \
1757 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1758 BRW_REGISTER_TYPE_##src_type, \
1760 BRW_VERTICAL_STRIDE_##src_vstride, \
1761 BRW_WIDTH_##src_width, \
1762 BRW_HORIZONTAL_STRIDE_##src_hstride, \
1766 /* Some instruction that violate no restrictions, as a control */
1767 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 4, 4, 1, true ),
1768 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 4, 4, 1, true ),
1769 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 4, 4, 1, true ),
1771 INST(MOV
, 4, DF
, 0, 1, F
, 0, 8, 4, 2, true ),
1772 INST(MOV
, 4, Q
, 0, 1, D
, 0, 8, 4, 2, true ),
1773 INST(MOV
, 4, UQ
, 0, 1, UD
, 0, 8, 4, 2, true ),
1775 INST(MOV
, 4, F
, 0, 2, DF
, 0, 4, 4, 1, true ),
1776 INST(MOV
, 4, D
, 0, 2, Q
, 0, 4, 4, 1, true ),
1777 INST(MOV
, 4, UD
, 0, 2, UQ
, 0, 4, 4, 1, true ),
1779 INST(MUL
, 8, D
, 0, 2, D
, 0, 8, 4, 2, true ),
1780 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 8, 4, 2, true ),
1782 /* Something with subreg nrs */
1783 INST(MOV
, 2, DF
, 8, 1, DF
, 8, 2, 2, 1, true ),
1784 INST(MOV
, 2, Q
, 8, 1, Q
, 8, 2, 2, 1, true ),
1785 INST(MOV
, 2, UQ
, 8, 1, UQ
, 8, 2, 2, 1, true ),
1787 INST(MUL
, 2, D
, 4, 2, D
, 4, 4, 2, 2, true ),
1788 INST(MUL
, 2, UD
, 4, 2, UD
, 4, 4, 2, 2, true ),
1790 /* The PRMs say that for CHV, BXT:
1792 * When source or destination datatype is 64b or operation is integer
1793 * DWord multiply, regioning in Align1 must follow these rules:
1795 * 1. Source and Destination horizontal stride must be aligned to the
1798 INST(MOV
, 4, DF
, 0, 2, DF
, 0, 4, 4, 1, false),
1799 INST(MOV
, 4, Q
, 0, 2, Q
, 0, 4, 4, 1, false),
1800 INST(MOV
, 4, UQ
, 0, 2, UQ
, 0, 4, 4, 1, false),
1802 INST(MOV
, 4, DF
, 0, 2, F
, 0, 8, 4, 2, false),
1803 INST(MOV
, 4, Q
, 0, 2, D
, 0, 8, 4, 2, false),
1804 INST(MOV
, 4, UQ
, 0, 2, UD
, 0, 8, 4, 2, false),
1806 INST(MOV
, 4, DF
, 0, 2, F
, 0, 4, 4, 1, false),
1807 INST(MOV
, 4, Q
, 0, 2, D
, 0, 4, 4, 1, false),
1808 INST(MOV
, 4, UQ
, 0, 2, UD
, 0, 4, 4, 1, false),
1810 INST(MUL
, 4, D
, 0, 2, D
, 0, 4, 4, 1, false),
1811 INST(MUL
, 4, UD
, 0, 2, UD
, 0, 4, 4, 1, false),
1813 INST(MUL
, 4, D
, 0, 1, D
, 0, 8, 4, 2, false),
1814 INST(MUL
, 4, UD
, 0, 1, UD
, 0, 8, 4, 2, false),
1816 /* 2. Regioning must ensure Src.Vstride = Src.Width * Src.Hstride. */
1817 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 0, 2, 1, false),
1818 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 0, 2, 1, false),
1819 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 0, 2, 1, false),
1821 INST(MOV
, 4, DF
, 0, 1, F
, 0, 0, 2, 2, false),
1822 INST(MOV
, 4, Q
, 0, 1, D
, 0, 0, 2, 2, false),
1823 INST(MOV
, 4, UQ
, 0, 1, UD
, 0, 0, 2, 2, false),
1825 INST(MOV
, 8, F
, 0, 2, DF
, 0, 0, 2, 1, false),
1826 INST(MOV
, 8, D
, 0, 2, Q
, 0, 0, 2, 1, false),
1827 INST(MOV
, 8, UD
, 0, 2, UQ
, 0, 0, 2, 1, false),
1829 INST(MUL
, 8, D
, 0, 2, D
, 0, 0, 4, 2, false),
1830 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 0, 4, 2, false),
1832 INST(MUL
, 8, D
, 0, 2, D
, 0, 0, 4, 2, false),
1833 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 0, 4, 2, false),
1835 /* 3. Source and Destination offset must be the same, except the case
1838 INST(MOV
, 2, DF
, 8, 1, DF
, 0, 2, 2, 1, false),
1839 INST(MOV
, 2, Q
, 8, 1, Q
, 0, 2, 2, 1, false),
1840 INST(MOV
, 2, UQ
, 8, 1, UQ
, 0, 2, 2, 1, false),
1842 INST(MOV
, 2, DF
, 0, 1, DF
, 8, 2, 2, 1, false),
1843 INST(MOV
, 2, Q
, 0, 1, Q
, 8, 2, 2, 1, false),
1844 INST(MOV
, 2, UQ
, 0, 1, UQ
, 8, 2, 2, 1, false),
1846 INST(MUL
, 4, D
, 4, 2, D
, 0, 4, 2, 2, false),
1847 INST(MUL
, 4, UD
, 4, 2, UD
, 0, 4, 2, 2, false),
1849 INST(MUL
, 4, D
, 0, 2, D
, 4, 4, 2, 2, false),
1850 INST(MUL
, 4, UD
, 0, 2, UD
, 4, 4, 2, 2, false),
1852 INST(MOV
, 2, DF
, 8, 1, DF
, 0, 0, 1, 0, true ),
1853 INST(MOV
, 2, Q
, 8, 1, Q
, 0, 0, 1, 0, true ),
1854 INST(MOV
, 2, UQ
, 8, 1, UQ
, 0, 0, 1, 0, true ),
1856 INST(MOV
, 2, DF
, 8, 1, F
, 4, 0, 1, 0, true ),
1857 INST(MOV
, 2, Q
, 8, 1, D
, 4, 0, 1, 0, true ),
1858 INST(MOV
, 2, UQ
, 8, 1, UD
, 4, 0, 1, 0, true ),
1860 INST(MUL
, 4, D
, 4, 1, D
, 0, 0, 1, 0, true ),
1861 INST(MUL
, 4, UD
, 4, 1, UD
, 0, 0, 1, 0, true ),
1863 INST(MUL
, 4, D
, 0, 1, D
, 4, 0, 1, 0, true ),
1864 INST(MUL
, 4, UD
, 0, 1, UD
, 4, 0, 1, 0, true ),
1869 /* These restrictions only apply to Gen8+ */
1870 if (devinfo
.gen
< 8)
1873 /* NoDDChk/NoDDClr does not exist on Gen12+ */
1874 if (devinfo
.gen
>= 12)
1877 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1878 if (!devinfo
.has_64bit_types
&&
1879 (type_sz(inst
[i
].dst_type
) == 8 || type_sz(inst
[i
].src_type
) == 8))
1882 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1883 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
1884 retype(g0
, inst
[i
].src_type
));
1886 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
1887 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
1888 retype(g0
, inst
[i
].src_type
),
1889 retype(zero
, inst
[i
].src_type
));
1891 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1893 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].dst_subreg
);
1894 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].src_subreg
);
1896 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1898 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
1899 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
1900 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
1902 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1903 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1905 EXPECT_TRUE(validate(p
));
1908 clear_instructions(p
);
1912 TEST_P(validation_test
, qword_low_power_no_indirect_addressing
)
1914 static const struct {
1918 enum brw_reg_type dst_type
;
1919 bool dst_is_indirect
;
1920 unsigned dst_stride
;
1922 enum brw_reg_type src_type
;
1923 bool src_is_indirect
;
1924 unsigned src_vstride
;
1926 unsigned src_hstride
;
1928 bool expected_result
;
1930 #define INST(opcode, exec_size, dst_type, dst_is_indirect, dst_stride, \
1931 src_type, src_is_indirect, src_vstride, src_width, src_hstride, \
1934 BRW_OPCODE_##opcode, \
1935 BRW_EXECUTE_##exec_size, \
1936 BRW_REGISTER_TYPE_##dst_type, \
1938 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1939 BRW_REGISTER_TYPE_##src_type, \
1941 BRW_VERTICAL_STRIDE_##src_vstride, \
1942 BRW_WIDTH_##src_width, \
1943 BRW_HORIZONTAL_STRIDE_##src_hstride, \
1947 /* Some instruction that violate no restrictions, as a control */
1948 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 4, 4, 1, true ),
1949 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 4, 4, 1, true ),
1950 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 4, 4, 1, true ),
1952 INST(MUL
, 8, D
, 0, 2, D
, 0, 8, 4, 2, true ),
1953 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 8, 4, 2, true ),
1955 INST(MOV
, 4, F
, 1, 1, F
, 0, 4, 4, 1, true ),
1956 INST(MOV
, 4, F
, 0, 1, F
, 1, 4, 4, 1, true ),
1957 INST(MOV
, 4, F
, 1, 1, F
, 1, 4, 4, 1, true ),
1959 /* The PRMs say that for CHV, BXT:
1961 * When source or destination datatype is 64b or operation is integer
1962 * DWord multiply, indirect addressing must not be used.
1964 INST(MOV
, 4, DF
, 1, 1, DF
, 0, 4, 4, 1, false),
1965 INST(MOV
, 4, Q
, 1, 1, Q
, 0, 4, 4, 1, false),
1966 INST(MOV
, 4, UQ
, 1, 1, UQ
, 0, 4, 4, 1, false),
1968 INST(MOV
, 4, DF
, 0, 1, DF
, 1, 4, 4, 1, false),
1969 INST(MOV
, 4, Q
, 0, 1, Q
, 1, 4, 4, 1, false),
1970 INST(MOV
, 4, UQ
, 0, 1, UQ
, 1, 4, 4, 1, false),
1972 INST(MOV
, 4, DF
, 1, 1, F
, 0, 8, 4, 2, false),
1973 INST(MOV
, 4, Q
, 1, 1, D
, 0, 8, 4, 2, false),
1974 INST(MOV
, 4, UQ
, 1, 1, UD
, 0, 8, 4, 2, false),
1976 INST(MOV
, 4, DF
, 0, 1, F
, 1, 8, 4, 2, false),
1977 INST(MOV
, 4, Q
, 0, 1, D
, 1, 8, 4, 2, false),
1978 INST(MOV
, 4, UQ
, 0, 1, UD
, 1, 8, 4, 2, false),
1980 INST(MOV
, 4, F
, 1, 2, DF
, 0, 4, 4, 1, false),
1981 INST(MOV
, 4, D
, 1, 2, Q
, 0, 4, 4, 1, false),
1982 INST(MOV
, 4, UD
, 1, 2, UQ
, 0, 4, 4, 1, false),
1984 INST(MOV
, 4, F
, 0, 2, DF
, 1, 4, 4, 1, false),
1985 INST(MOV
, 4, D
, 0, 2, Q
, 1, 4, 4, 1, false),
1986 INST(MOV
, 4, UD
, 0, 2, UQ
, 1, 4, 4, 1, false),
1988 INST(MUL
, 8, D
, 1, 2, D
, 0, 8, 4, 2, false),
1989 INST(MUL
, 8, UD
, 1, 2, UD
, 0, 8, 4, 2, false),
1991 INST(MUL
, 8, D
, 0, 2, D
, 1, 8, 4, 2, false),
1992 INST(MUL
, 8, UD
, 0, 2, UD
, 1, 8, 4, 2, false),
1997 /* These restrictions only apply to Gen8+ */
1998 if (devinfo
.gen
< 8)
2001 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
2002 if (!devinfo
.has_64bit_types
&&
2003 (type_sz(inst
[i
].dst_type
) == 8 || type_sz(inst
[i
].src_type
) == 8))
2006 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
2007 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
2008 retype(g0
, inst
[i
].src_type
));
2010 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
2011 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
2012 retype(g0
, inst
[i
].src_type
),
2013 retype(zero
, inst
[i
].src_type
));
2015 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
2017 brw_inst_set_dst_address_mode(&devinfo
, last_inst
, inst
[i
].dst_is_indirect
);
2018 brw_inst_set_src0_address_mode(&devinfo
, last_inst
, inst
[i
].src_is_indirect
);
2020 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
2022 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
2023 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
2024 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
2026 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
2027 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
2029 EXPECT_TRUE(validate(p
));
2032 clear_instructions(p
);
2036 TEST_P(validation_test
, qword_low_power_no_64bit_arf
)
2038 static const struct {
2043 enum brw_reg_type dst_type
;
2044 unsigned dst_stride
;
2047 enum brw_reg_type src_type
;
2048 unsigned src_vstride
;
2050 unsigned src_hstride
;
2053 bool expected_result
;
2055 #define INST(opcode, exec_size, dst, dst_type, dst_stride, \
2056 src, src_type, src_vstride, src_width, src_hstride, \
2057 acc_wr, expected_result) \
2059 BRW_OPCODE_##opcode, \
2060 BRW_EXECUTE_##exec_size, \
2062 BRW_REGISTER_TYPE_##dst_type, \
2063 BRW_HORIZONTAL_STRIDE_##dst_stride, \
2065 BRW_REGISTER_TYPE_##src_type, \
2066 BRW_VERTICAL_STRIDE_##src_vstride, \
2067 BRW_WIDTH_##src_width, \
2068 BRW_HORIZONTAL_STRIDE_##src_hstride, \
2073 /* Some instruction that violate no restrictions, as a control */
2074 INST(MOV
, 4, g0
, DF
, 1, g0
, F
, 4, 2, 2, 0, true ),
2075 INST(MOV
, 4, g0
, F
, 2, g0
, DF
, 4, 4, 1, 0, true ),
2077 INST(MOV
, 4, g0
, Q
, 1, g0
, D
, 4, 2, 2, 0, true ),
2078 INST(MOV
, 4, g0
, D
, 2, g0
, Q
, 4, 4, 1, 0, true ),
2080 INST(MOV
, 4, g0
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, true ),
2081 INST(MOV
, 4, g0
, UD
, 2, g0
, UQ
, 4, 4, 1, 0, true ),
2083 INST(MOV
, 4, null
, F
, 1, g0
, F
, 4, 4, 1, 0, true ),
2084 INST(MOV
, 4, acc0
, F
, 1, g0
, F
, 4, 4, 1, 0, true ),
2085 INST(MOV
, 4, g0
, F
, 1, acc0
, F
, 4, 4, 1, 0, true ),
2087 INST(MOV
, 4, null
, D
, 1, g0
, D
, 4, 4, 1, 0, true ),
2088 INST(MOV
, 4, acc0
, D
, 1, g0
, D
, 4, 4, 1, 0, true ),
2089 INST(MOV
, 4, g0
, D
, 1, acc0
, D
, 4, 4, 1, 0, true ),
2091 INST(MOV
, 4, null
, UD
, 1, g0
, UD
, 4, 4, 1, 0, true ),
2092 INST(MOV
, 4, acc0
, UD
, 1, g0
, UD
, 4, 4, 1, 0, true ),
2093 INST(MOV
, 4, g0
, UD
, 1, acc0
, UD
, 4, 4, 1, 0, true ),
2095 INST(MUL
, 4, g0
, D
, 2, g0
, D
, 4, 2, 2, 0, true ),
2096 INST(MUL
, 4, g0
, UD
, 2, g0
, UD
, 4, 2, 2, 0, true ),
2098 /* The PRMs say that for CHV, BXT:
2100 * ARF registers must never be used with 64b datatype or when
2101 * operation is integer DWord multiply.
2103 INST(MOV
, 4, acc0
, DF
, 1, g0
, F
, 4, 2, 2, 0, false),
2104 INST(MOV
, 4, g0
, DF
, 1, acc0
, F
, 4, 2, 2, 0, false),
2106 INST(MOV
, 4, acc0
, Q
, 1, g0
, D
, 4, 2, 2, 0, false),
2107 INST(MOV
, 4, g0
, Q
, 1, acc0
, D
, 4, 2, 2, 0, false),
2109 INST(MOV
, 4, acc0
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, false),
2110 INST(MOV
, 4, g0
, UQ
, 1, acc0
, UD
, 4, 2, 2, 0, false),
2112 INST(MOV
, 4, acc0
, F
, 2, g0
, DF
, 4, 4, 1, 0, false),
2113 INST(MOV
, 4, g0
, F
, 2, acc0
, DF
, 4, 4, 1, 0, false),
2115 INST(MOV
, 4, acc0
, D
, 2, g0
, Q
, 4, 4, 1, 0, false),
2116 INST(MOV
, 4, g0
, D
, 2, acc0
, Q
, 4, 4, 1, 0, false),
2118 INST(MOV
, 4, acc0
, UD
, 2, g0
, UQ
, 4, 4, 1, 0, false),
2119 INST(MOV
, 4, g0
, UD
, 2, acc0
, UQ
, 4, 4, 1, 0, false),
2121 INST(MUL
, 4, acc0
, D
, 2, g0
, D
, 4, 2, 2, 0, false),
2122 INST(MUL
, 4, acc0
, UD
, 2, g0
, UD
, 4, 2, 2, 0, false),
2123 /* MUL cannot have integer accumulator sources, so don't test that */
2125 /* We assume that the restriction does not apply to the null register */
2126 INST(MOV
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 0, true ),
2127 INST(MOV
, 4, null
, Q
, 1, g0
, D
, 4, 2, 2, 0, true ),
2128 INST(MOV
, 4, null
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, true ),
2130 /* Check implicit accumulator write control */
2131 INST(MOV
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 1, false),
2132 INST(MUL
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 1, false),
2137 /* These restrictions only apply to Gen8+ */
2138 if (devinfo
.gen
< 8)
2141 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
2142 if (!devinfo
.has_64bit_types
&&
2143 (type_sz(inst
[i
].dst_type
) == 8 || type_sz(inst
[i
].src_type
) == 8))
2146 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
2147 brw_MOV(p
, retype(inst
[i
].dst
, inst
[i
].dst_type
),
2148 retype(inst
[i
].src
, inst
[i
].src_type
));
2150 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
2151 brw_MUL(p
, retype(inst
[i
].dst
, inst
[i
].dst_type
),
2152 retype(inst
[i
].src
, inst
[i
].src_type
),
2153 retype(zero
, inst
[i
].src_type
));
2154 brw_inst_set_opcode(&devinfo
, last_inst
, inst
[i
].opcode
);
2156 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
2157 brw_inst_set_acc_wr_control(&devinfo
, last_inst
, inst
[i
].acc_wr
);
2159 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
2161 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
2162 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
2163 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
2165 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
2166 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
2168 EXPECT_TRUE(validate(p
));
2171 clear_instructions(p
);
2174 if (!devinfo
.has_64bit_types
)
2177 /* MAC implicitly reads the accumulator */
2178 brw_MAC(p
, retype(g0
, BRW_REGISTER_TYPE_DF
),
2179 retype(stride(g0
, 4, 4, 1), BRW_REGISTER_TYPE_DF
),
2180 retype(stride(g0
, 4, 4, 1), BRW_REGISTER_TYPE_DF
));
2181 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
2182 EXPECT_FALSE(validate(p
));
2184 EXPECT_TRUE(validate(p
));
2188 TEST_P(validation_test
, align16_64_bit_integer
)
2190 static const struct {
2194 enum brw_reg_type dst_type
;
2195 enum brw_reg_type src_type
;
2197 bool expected_result
;
2199 #define INST(opcode, exec_size, dst_type, src_type, expected_result) \
2201 BRW_OPCODE_##opcode, \
2202 BRW_EXECUTE_##exec_size, \
2203 BRW_REGISTER_TYPE_##dst_type, \
2204 BRW_REGISTER_TYPE_##src_type, \
2208 /* Some instruction that violate no restrictions, as a control */
2209 INST(MOV
, 2, Q
, D
, true ),
2210 INST(MOV
, 2, UQ
, UD
, true ),
2211 INST(MOV
, 2, DF
, F
, true ),
2213 INST(ADD
, 2, Q
, D
, true ),
2214 INST(ADD
, 2, UQ
, UD
, true ),
2215 INST(ADD
, 2, DF
, F
, true ),
2217 /* The PRMs say that for BDW, SKL:
2219 * If Align16 is required for an operation with QW destination and non-QW
2220 * source datatypes, the execution size cannot exceed 2.
2223 INST(MOV
, 4, Q
, D
, false),
2224 INST(MOV
, 4, UQ
, UD
, false),
2225 INST(MOV
, 4, DF
, F
, false),
2227 INST(ADD
, 4, Q
, D
, false),
2228 INST(ADD
, 4, UQ
, UD
, false),
2229 INST(ADD
, 4, DF
, F
, false),
2234 /* 64-bit integer types exist on Gen8+ */
2235 if (devinfo
.gen
< 8)
2238 /* Align16 does not exist on Gen11+ */
2239 if (devinfo
.gen
>= 11)
2242 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
2244 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
2245 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
2246 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
2247 retype(g0
, inst
[i
].src_type
));
2249 assert(inst
[i
].opcode
== BRW_OPCODE_ADD
);
2250 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
2251 retype(g0
, inst
[i
].src_type
),
2252 retype(g0
, inst
[i
].src_type
));
2254 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
2256 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
2258 clear_instructions(p
);
2262 TEST_P(validation_test
, qword_low_power_no_depctrl
)
2264 static const struct {
2268 enum brw_reg_type dst_type
;
2269 unsigned dst_stride
;
2271 enum brw_reg_type src_type
;
2272 unsigned src_vstride
;
2274 unsigned src_hstride
;
2279 bool expected_result
;
2281 #define INST(opcode, exec_size, dst_type, dst_stride, \
2282 src_type, src_vstride, src_width, src_hstride, \
2283 no_dd_check, no_dd_clear, expected_result) \
2285 BRW_OPCODE_##opcode, \
2286 BRW_EXECUTE_##exec_size, \
2287 BRW_REGISTER_TYPE_##dst_type, \
2288 BRW_HORIZONTAL_STRIDE_##dst_stride, \
2289 BRW_REGISTER_TYPE_##src_type, \
2290 BRW_VERTICAL_STRIDE_##src_vstride, \
2291 BRW_WIDTH_##src_width, \
2292 BRW_HORIZONTAL_STRIDE_##src_hstride, \
2298 /* Some instruction that violate no restrictions, as a control */
2299 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 0, 0, true ),
2300 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 0, 0, true ),
2301 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 0, 0, true ),
2303 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 0, 0, true ),
2304 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 0, 0, true ),
2305 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 0, 0, true ),
2307 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 0, 0, true ),
2308 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 0, 0, true ),
2310 INST(MOV
, 4, F
, 1, F
, 4, 4, 1, 1, 1, true ),
2312 /* The PRMs say that for CHV, BXT:
2314 * When source or destination datatype is 64b or operation is integer
2315 * DWord multiply, DepCtrl must not be used.
2317 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 1, 0, false),
2318 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 1, 0, false),
2319 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 1, 0, false),
2321 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 1, 0, false),
2322 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 1, 0, false),
2323 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 1, 0, false),
2325 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 0, 1, false),
2326 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 0, 1, false),
2327 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 0, 1, false),
2329 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 0, 1, false),
2330 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 0, 1, false),
2331 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 0, 1, false),
2333 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 1, 0, false),
2334 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 1, 0, false),
2336 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 0, 1, false),
2337 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 0, 1, false),
2342 /* These restrictions only apply to Gen8+ */
2343 if (devinfo
.gen
< 8)
2346 /* NoDDChk/NoDDClr does not exist on Gen12+ */
2347 if (devinfo
.gen
>= 12)
2350 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
2351 if (!devinfo
.has_64bit_types
&&
2352 (type_sz(inst
[i
].dst_type
) == 8 || type_sz(inst
[i
].src_type
) == 8))
2355 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
2356 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
2357 retype(g0
, inst
[i
].src_type
));
2359 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
2360 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
2361 retype(g0
, inst
[i
].src_type
),
2362 retype(zero
, inst
[i
].src_type
));
2364 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
2366 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
2368 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
2369 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
2370 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
2372 brw_inst_set_no_dd_check(&devinfo
, last_inst
, inst
[i
].no_dd_check
);
2373 brw_inst_set_no_dd_clear(&devinfo
, last_inst
, inst
[i
].no_dd_clear
);
2375 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
2376 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
2378 EXPECT_TRUE(validate(p
));
2381 clear_instructions(p
);
2385 TEST_P(validation_test
, gen11_no_byte_src_1_2
)
2387 static const struct {
2389 unsigned access_mode
;
2391 enum brw_reg_type dst_type
;
2393 enum brw_reg_type type
;
2400 bool expected_result
;
2402 #define INST(opcode, access_mode, dst_type, \
2403 src0_type, src0_vstride, src0_width, src0_hstride, \
2404 src1_type, src1_vstride, src1_width, src1_hstride, \
2406 gen, expected_result) \
2408 BRW_OPCODE_##opcode, \
2409 BRW_ALIGN_##access_mode, \
2410 BRW_REGISTER_TYPE_##dst_type, \
2413 BRW_REGISTER_TYPE_##src0_type, \
2414 BRW_VERTICAL_STRIDE_##src0_vstride, \
2415 BRW_WIDTH_##src0_width, \
2416 BRW_HORIZONTAL_STRIDE_##src0_hstride, \
2419 BRW_REGISTER_TYPE_##src1_type, \
2420 BRW_VERTICAL_STRIDE_##src1_vstride, \
2421 BRW_WIDTH_##src1_width, \
2422 BRW_HORIZONTAL_STRIDE_##src1_hstride, \
2425 BRW_REGISTER_TYPE_##src2_type, \
2432 /* Passes on < 11 */
2433 INST(MOV
, 16, F
, B
, 2, 4, 0, UD
, 0, 4, 0, D
, 8, true ),
2434 INST(ADD
, 16, UD
, F
, 0, 4, 0, UB
, 0, 1, 0, D
, 7, true ),
2435 INST(MAD
, 16, D
, B
, 0, 4, 0, UB
, 0, 1, 0, B
, 10, true ),
2438 INST(MAD
, 1, UB
, W
, 1, 1, 0, D
, 0, 4, 0, B
, 11, false ),
2439 INST(MAD
, 1, UB
, W
, 1, 1, 1, UB
, 1, 1, 0, W
, 11, false ),
2440 INST(ADD
, 1, W
, W
, 1, 4, 1, B
, 1, 1, 0, D
, 11, false ),
2443 INST(MOV
, 1, W
, B
, 8, 8, 1, D
, 8, 8, 1, D
, 11, true ),
2444 INST(ADD
, 1, UD
, B
, 8, 8, 1, W
, 8, 8, 1, D
, 11, true ),
2445 INST(MAD
, 1, B
, B
, 0, 1, 0, D
, 0, 4, 0, W
, 11, true ),
2451 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
2452 /* Skip instruction not meant for this gen. */
2453 if (devinfo
.gen
!= inst
[i
].gen
)
2456 brw_push_insn_state(p
);
2458 brw_set_default_exec_size(p
, BRW_EXECUTE_8
);
2459 brw_set_default_access_mode(p
, inst
[i
].access_mode
);
2461 switch (inst
[i
].opcode
) {
2462 case BRW_OPCODE_MOV
:
2463 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
2464 retype(g0
, inst
[i
].srcs
[0].type
));
2465 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].vstride
);
2466 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].hstride
);
2468 case BRW_OPCODE_ADD
:
2469 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
2470 retype(g0
, inst
[i
].srcs
[0].type
),
2471 retype(g0
, inst
[i
].srcs
[1].type
));
2472 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].vstride
);
2473 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].srcs
[0].width
);
2474 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].hstride
);
2475 brw_inst_set_src1_vstride(&devinfo
, last_inst
, inst
[i
].srcs
[1].vstride
);
2476 brw_inst_set_src1_width(&devinfo
, last_inst
, inst
[i
].srcs
[1].width
);
2477 brw_inst_set_src1_hstride(&devinfo
, last_inst
, inst
[i
].srcs
[1].hstride
);
2479 case BRW_OPCODE_MAD
:
2480 brw_MAD(p
, retype(g0
, inst
[i
].dst_type
),
2481 retype(g0
, inst
[i
].srcs
[0].type
),
2482 retype(g0
, inst
[i
].srcs
[1].type
),
2483 retype(g0
, inst
[i
].srcs
[2].type
));
2484 brw_inst_set_3src_a1_src0_vstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].vstride
);
2485 brw_inst_set_3src_a1_src0_hstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].hstride
);
2486 brw_inst_set_3src_a1_src1_vstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].vstride
);
2487 brw_inst_set_3src_a1_src1_hstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].hstride
);
2490 unreachable("invalid opcode");
2493 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
2495 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].srcs
[0].width
);
2496 brw_inst_set_src1_width(&devinfo
, last_inst
, inst
[i
].srcs
[1].width
);
2498 brw_pop_insn_state(p
);
2500 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
2502 clear_instructions(p
);