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 "brw_eu_defines.h"
27 #include "util/bitset.h"
28 #include "util/ralloc.h"
30 static const struct gen_info
{
54 class validation_test
: public ::testing::TestWithParam
<struct gen_info
> {
59 virtual ~validation_test();
61 struct brw_codegen
*p
;
62 struct gen_device_info devinfo
;
65 validation_test::validation_test()
67 p
= rzalloc(NULL
, struct brw_codegen
);
68 memset(&devinfo
, 0, sizeof(devinfo
));
71 validation_test::~validation_test()
76 void validation_test::SetUp()
78 struct gen_info info
= GetParam();
79 int devid
= gen_device_name_to_pci_device_id(info
.name
);
81 gen_get_device_info_from_pci_id(devid
, &devinfo
);
83 brw_init_codegen(&devinfo
, p
, p
);
87 template <class ParamType
>
89 operator()(const ::testing::TestParamInfo
<ParamType
>& info
) const {
90 return info
.param
.name
;
94 INSTANTIATE_TEST_CASE_P(eu_assembly
, validation_test
,
95 ::testing::ValuesIn(gens
),
99 validate(struct brw_codegen
*p
)
101 const bool print
= getenv("TEST_DEBUG");
102 struct disasm_info
*disasm
= disasm_initialize(p
->devinfo
, NULL
);
105 disasm_new_inst_group(disasm
, 0);
106 disasm_new_inst_group(disasm
, p
->next_insn_offset
);
109 bool ret
= brw_validate_instructions(p
->devinfo
, p
->store
, 0,
110 p
->next_insn_offset
, disasm
);
113 dump_assembly(p
->store
, disasm
);
120 #define last_inst (&p->store[p->nr_insn - 1])
121 #define g0 brw_vec8_grf(0, 0)
122 #define acc0 brw_acc_reg(8)
123 #define null brw_null_reg()
124 #define zero brw_imm_f(0.0f)
127 clear_instructions(struct brw_codegen
*p
)
129 p
->next_insn_offset
= 0;
133 TEST_P(validation_test
, sanity
)
135 brw_ADD(p
, g0
, g0
, g0
);
137 EXPECT_TRUE(validate(p
));
140 TEST_P(validation_test
, src0_null_reg
)
142 brw_MOV(p
, g0
, null
);
144 EXPECT_FALSE(validate(p
));
147 TEST_P(validation_test
, src1_null_reg
)
149 brw_ADD(p
, g0
, g0
, null
);
151 EXPECT_FALSE(validate(p
));
154 TEST_P(validation_test
, math_src0_null_reg
)
156 if (devinfo
.gen
>= 6) {
157 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, null
, null
);
159 gen4_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, 0, null
, BRW_MATH_PRECISION_FULL
);
162 EXPECT_FALSE(validate(p
));
165 TEST_P(validation_test
, math_src1_null_reg
)
167 if (devinfo
.gen
>= 6) {
168 gen6_math(p
, g0
, BRW_MATH_FUNCTION_POW
, g0
, null
);
169 EXPECT_FALSE(validate(p
));
171 /* Math instructions on Gen4/5 are actually SEND messages with payloads.
172 * src1 is an immediate message descriptor set by gen4_math.
177 TEST_P(validation_test
, opcode46
)
179 /* opcode 46 is "push" on Gen 4 and 5
184 brw_next_insn(p
, brw_opcode_decode(&devinfo
, 46));
186 if (devinfo
.gen
== 7) {
187 EXPECT_FALSE(validate(p
));
189 EXPECT_TRUE(validate(p
));
193 TEST_P(validation_test
, invalid_exec_size_encoding
)
196 enum brw_execution_size exec_size
;
197 bool expected_result
;
199 { BRW_EXECUTE_1
, true },
200 { BRW_EXECUTE_2
, true },
201 { BRW_EXECUTE_4
, true },
202 { BRW_EXECUTE_8
, true },
203 { BRW_EXECUTE_16
, true },
204 { BRW_EXECUTE_32
, true },
206 { (enum brw_execution_size
)((int)BRW_EXECUTE_32
+ 1), false },
207 { (enum brw_execution_size
)((int)BRW_EXECUTE_32
+ 2), false },
210 for (unsigned i
= 0; i
< ARRAY_SIZE(test_case
); i
++) {
213 brw_inst_set_exec_size(&devinfo
, last_inst
, test_case
[i
].exec_size
);
214 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
215 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
217 if (test_case
[i
].exec_size
== BRW_EXECUTE_1
) {
218 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
219 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
220 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
222 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_2
);
223 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
224 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
227 EXPECT_EQ(test_case
[i
].expected_result
, validate(p
));
229 clear_instructions(p
);
233 TEST_P(validation_test
, invalid_file_encoding
)
235 /* Register file on Gen12 is only one bit */
236 if (devinfo
.gen
>= 12)
240 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_MESSAGE_REGISTER_FILE
, BRW_REGISTER_TYPE_F
);
242 if (devinfo
.gen
> 6) {
243 EXPECT_FALSE(validate(p
));
245 EXPECT_TRUE(validate(p
));
248 clear_instructions(p
);
250 if (devinfo
.gen
< 6) {
251 gen4_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, 0, g0
, BRW_MATH_PRECISION_FULL
);
253 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
255 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_MESSAGE_REGISTER_FILE
, BRW_REGISTER_TYPE_F
);
257 if (devinfo
.gen
> 6) {
258 EXPECT_FALSE(validate(p
));
260 EXPECT_TRUE(validate(p
));
264 TEST_P(validation_test
, invalid_type_encoding
)
266 enum brw_reg_file files
[2] = {
267 BRW_GENERAL_REGISTER_FILE
,
271 for (unsigned i
= 0; i
< ARRAY_SIZE(files
); i
++) {
272 const enum brw_reg_file file
= files
[i
];
273 const int num_bits
= devinfo
.gen
>= 8 ? 4 : 3;
274 const int num_encodings
= 1 << num_bits
;
276 /* The data types are encoded into <num_bits> bits to be used in hardware
277 * instructions, so keep a record in a bitset the invalid patterns so
278 * they can be verified to be invalid when used.
280 BITSET_DECLARE(invalid_encodings
, num_encodings
);
283 enum brw_reg_type type
;
284 bool expected_result
;
286 { BRW_REGISTER_TYPE_NF
, devinfo
.gen
== 11 && file
!= IMM
},
287 { BRW_REGISTER_TYPE_DF
, devinfo
.has_64bit_float
&& (devinfo
.gen
>= 8 || file
!= IMM
) },
288 { BRW_REGISTER_TYPE_F
, true },
289 { BRW_REGISTER_TYPE_HF
, devinfo
.gen
>= 8 },
290 { BRW_REGISTER_TYPE_VF
, file
== IMM
},
291 { BRW_REGISTER_TYPE_Q
, devinfo
.has_64bit_int
},
292 { BRW_REGISTER_TYPE_UQ
, devinfo
.has_64bit_int
},
293 { BRW_REGISTER_TYPE_D
, true },
294 { BRW_REGISTER_TYPE_UD
, true },
295 { BRW_REGISTER_TYPE_W
, true },
296 { BRW_REGISTER_TYPE_UW
, true },
297 { BRW_REGISTER_TYPE_B
, file
== FIXED_GRF
},
298 { BRW_REGISTER_TYPE_UB
, file
== FIXED_GRF
},
299 { BRW_REGISTER_TYPE_V
, file
== IMM
},
300 { BRW_REGISTER_TYPE_UV
, devinfo
.gen
>= 6 && file
== IMM
},
303 /* Initially assume all hardware encodings are invalid */
304 BITSET_ONES(invalid_encodings
);
306 brw_set_default_exec_size(p
, BRW_EXECUTE_4
);
308 for (unsigned i
= 0; i
< ARRAY_SIZE(test_case
); i
++) {
309 if (test_case
[i
].expected_result
) {
310 unsigned hw_type
= brw_reg_type_to_hw_type(&devinfo
, file
, test_case
[i
].type
);
311 if (hw_type
!= INVALID_REG_TYPE
) {
312 /* ... and remove valid encodings from the set */
313 assert(BITSET_TEST(invalid_encodings
, hw_type
));
314 BITSET_CLEAR(invalid_encodings
, hw_type
);
317 if (file
== FIXED_GRF
) {
318 struct brw_reg g
= retype(g0
, test_case
[i
].type
);
320 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
321 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
322 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
326 switch (test_case
[i
].type
) {
327 case BRW_REGISTER_TYPE_V
:
328 t
= BRW_REGISTER_TYPE_W
;
330 case BRW_REGISTER_TYPE_UV
:
331 t
= BRW_REGISTER_TYPE_UW
;
333 case BRW_REGISTER_TYPE_VF
:
334 t
= BRW_REGISTER_TYPE_F
;
337 t
= test_case
[i
].type
;
341 struct brw_reg g
= retype(g0
, t
);
342 brw_MOV(p
, g
, retype(brw_imm_w(0), test_case
[i
].type
));
345 EXPECT_TRUE(validate(p
));
347 clear_instructions(p
);
351 /* The remaining encodings in invalid_encodings do not have a mapping
352 * from BRW_REGISTER_TYPE_* and must be invalid. Verify that invalid
353 * encodings are rejected by the validator.
356 BITSET_FOREACH_SET(e
, invalid_encodings
, num_encodings
) {
357 if (file
== FIXED_GRF
) {
359 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
360 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
361 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
363 brw_MOV(p
, g0
, brw_imm_w(0));
365 brw_inst_set_dst_reg_hw_type(&devinfo
, last_inst
, e
);
366 brw_inst_set_src0_reg_hw_type(&devinfo
, last_inst
, e
);
368 EXPECT_FALSE(validate(p
));
370 clear_instructions(p
);
375 TEST_P(validation_test
, invalid_type_encoding_3src_a16
)
377 /* 3-src instructions in align16 mode only supported on Gen6-10 */
378 if (devinfo
.gen
< 6 || devinfo
.gen
> 10)
381 const int num_bits
= devinfo
.gen
>= 8 ? 3 : 2;
382 const int num_encodings
= 1 << num_bits
;
384 /* The data types are encoded into <num_bits> bits to be used in hardware
385 * instructions, so keep a record in a bitset the invalid patterns so
386 * they can be verified to be invalid when used.
388 BITSET_DECLARE(invalid_encodings
, num_encodings
);
391 enum brw_reg_type type
;
392 bool expected_result
;
394 { BRW_REGISTER_TYPE_DF
, devinfo
.gen
>= 7 },
395 { BRW_REGISTER_TYPE_F
, true },
396 { BRW_REGISTER_TYPE_HF
, devinfo
.gen
>= 8 },
397 { BRW_REGISTER_TYPE_D
, devinfo
.gen
>= 7 },
398 { BRW_REGISTER_TYPE_UD
, devinfo
.gen
>= 7 },
401 /* Initially assume all hardware encodings are invalid */
402 BITSET_ONES(invalid_encodings
);
404 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
405 brw_set_default_exec_size(p
, BRW_EXECUTE_4
);
407 for (unsigned i
= 0; i
< ARRAY_SIZE(test_case
); i
++) {
408 if (test_case
[i
].expected_result
) {
409 unsigned hw_type
= brw_reg_type_to_a16_hw_3src_type(&devinfo
, test_case
[i
].type
);
410 if (hw_type
!= INVALID_HW_REG_TYPE
) {
411 /* ... and remove valid encodings from the set */
412 assert(BITSET_TEST(invalid_encodings
, hw_type
));
413 BITSET_CLEAR(invalid_encodings
, hw_type
);
416 struct brw_reg g
= retype(g0
, test_case
[i
].type
);
417 if (!brw_reg_type_is_integer(test_case
[i
].type
)) {
418 brw_MAD(p
, g
, g
, g
, g
);
420 brw_BFE(p
, g
, g
, g
, g
);
423 EXPECT_TRUE(validate(p
));
425 clear_instructions(p
);
429 /* The remaining encodings in invalid_encodings do not have a mapping
430 * from BRW_REGISTER_TYPE_* and must be invalid. Verify that invalid
431 * encodings are rejected by the validator.
434 BITSET_FOREACH_SET(e
, invalid_encodings
, num_encodings
) {
435 for (unsigned i
= 0; i
< 2; i
++) {
437 brw_MAD(p
, g0
, g0
, g0
, g0
);
439 brw_BFE(p
, g0
, g0
, g0
, g0
);
442 brw_inst_set_3src_a16_dst_hw_type(&devinfo
, last_inst
, e
);
443 brw_inst_set_3src_a16_src_hw_type(&devinfo
, last_inst
, e
);
445 EXPECT_FALSE(validate(p
));
447 clear_instructions(p
);
449 if (devinfo
.gen
== 6)
455 TEST_P(validation_test
, invalid_type_encoding_3src_a1
)
457 /* 3-src instructions in align1 mode only supported on Gen10+ */
458 if (devinfo
.gen
< 10)
461 const int num_bits
= 3 + 1 /* for exec_type */;
462 const int num_encodings
= 1 << num_bits
;
464 /* The data types are encoded into <num_bits> bits to be used in hardware
465 * instructions, so keep a record in a bitset the invalid patterns so
466 * they can be verified to be invalid when used.
468 BITSET_DECLARE(invalid_encodings
, num_encodings
);
471 enum brw_reg_type type
;
473 bool expected_result
;
475 #define E(x) ((unsigned)BRW_ALIGN1_3SRC_EXEC_TYPE_##x)
476 { BRW_REGISTER_TYPE_NF
, E(FLOAT
), devinfo
.gen
== 11 },
477 { BRW_REGISTER_TYPE_DF
, E(FLOAT
), devinfo
.has_64bit_float
},
478 { BRW_REGISTER_TYPE_F
, E(FLOAT
), true },
479 { BRW_REGISTER_TYPE_HF
, E(FLOAT
), true },
480 { BRW_REGISTER_TYPE_D
, E(INT
), true },
481 { BRW_REGISTER_TYPE_UD
, E(INT
), true },
482 { BRW_REGISTER_TYPE_W
, E(INT
), true },
483 { BRW_REGISTER_TYPE_UW
, E(INT
), true },
485 /* There are no ternary instructions that can operate on B-type sources
486 * on Gen11-12. Src1/Src2 cannot be B-typed either.
488 { BRW_REGISTER_TYPE_B
, E(INT
), devinfo
.gen
== 10 },
489 { BRW_REGISTER_TYPE_UB
, E(INT
), devinfo
.gen
== 10 },
492 /* Initially assume all hardware encodings are invalid */
493 BITSET_ONES(invalid_encodings
);
495 brw_set_default_access_mode(p
, BRW_ALIGN_1
);
496 brw_set_default_exec_size(p
, BRW_EXECUTE_4
);
498 for (unsigned i
= 0; i
< ARRAY_SIZE(test_case
); i
++) {
499 if (test_case
[i
].expected_result
) {
500 unsigned hw_type
= brw_reg_type_to_a1_hw_3src_type(&devinfo
, test_case
[i
].type
);
501 unsigned hw_exec_type
= hw_type
| (test_case
[i
].exec_type
<< 3);
502 if (hw_type
!= INVALID_HW_REG_TYPE
) {
503 /* ... and remove valid encodings from the set */
504 assert(BITSET_TEST(invalid_encodings
, hw_exec_type
));
505 BITSET_CLEAR(invalid_encodings
, hw_exec_type
);
508 struct brw_reg g
= retype(g0
, test_case
[i
].type
);
509 if (!brw_reg_type_is_integer(test_case
[i
].type
)) {
510 brw_MAD(p
, g
, g
, g
, g
);
512 brw_BFE(p
, g
, g
, g
, g
);
515 EXPECT_TRUE(validate(p
));
517 clear_instructions(p
);
521 /* The remaining encodings in invalid_encodings do not have a mapping
522 * from BRW_REGISTER_TYPE_* and must be invalid. Verify that invalid
523 * encodings are rejected by the validator.
526 BITSET_FOREACH_SET(e
, invalid_encodings
, num_encodings
) {
527 const unsigned hw_type
= e
& 0x7;
528 const unsigned exec_type
= e
>> 3;
530 for (unsigned i
= 0; i
< 2; i
++) {
532 brw_MAD(p
, g0
, g0
, g0
, g0
);
533 brw_inst_set_3src_a1_exec_type(&devinfo
, last_inst
, BRW_ALIGN1_3SRC_EXEC_TYPE_FLOAT
);
535 brw_CSEL(p
, g0
, g0
, g0
, g0
);
536 brw_inst_set_3src_cond_modifier(&devinfo
, last_inst
, BRW_CONDITIONAL_NZ
);
537 brw_inst_set_3src_a1_exec_type(&devinfo
, last_inst
, BRW_ALIGN1_3SRC_EXEC_TYPE_INT
);
540 brw_inst_set_3src_a1_exec_type(&devinfo
, last_inst
, exec_type
);
541 brw_inst_set_3src_a1_dst_hw_type (&devinfo
, last_inst
, hw_type
);
542 brw_inst_set_3src_a1_src0_hw_type(&devinfo
, last_inst
, hw_type
);
543 brw_inst_set_3src_a1_src1_hw_type(&devinfo
, last_inst
, hw_type
);
544 brw_inst_set_3src_a1_src2_hw_type(&devinfo
, last_inst
, hw_type
);
546 EXPECT_FALSE(validate(p
));
548 clear_instructions(p
);
553 TEST_P(validation_test
, 3src_inst_access_mode
)
555 /* 3-src instructions only supported on Gen6+ */
559 /* No access mode bit on Gen12+ */
560 if (devinfo
.gen
>= 12)
565 bool expected_result
;
567 { BRW_ALIGN_1
, devinfo
.gen
>= 10 },
568 { BRW_ALIGN_16
, devinfo
.gen
<= 10 },
571 for (unsigned i
= 0; i
< ARRAY_SIZE(test_case
); i
++) {
572 if (devinfo
.gen
< 10)
573 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
575 brw_MAD(p
, g0
, g0
, g0
, g0
);
576 brw_inst_set_access_mode(&devinfo
, last_inst
, test_case
[i
].mode
);
578 EXPECT_EQ(test_case
[i
].expected_result
, validate(p
));
580 clear_instructions(p
);
584 /* When the Execution Data Type is wider than the destination data type, the
585 * destination must [...] specify a HorzStride equal to the ratio in sizes of
586 * the two data types.
588 TEST_P(validation_test
, dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size
)
590 brw_ADD(p
, g0
, g0
, g0
);
591 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
592 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
593 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
595 EXPECT_FALSE(validate(p
));
597 clear_instructions(p
);
599 brw_ADD(p
, g0
, g0
, g0
);
600 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
601 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
602 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
603 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
605 EXPECT_TRUE(validate(p
));
608 /* When the Execution Data Type is wider than the destination data type, the
609 * destination must be aligned as required by the wider execution data type
612 TEST_P(validation_test
, dst_subreg_must_be_aligned_to_exec_type_size
)
614 brw_ADD(p
, g0
, g0
, g0
);
615 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 2);
616 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
617 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
618 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
619 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
621 EXPECT_FALSE(validate(p
));
623 clear_instructions(p
);
625 brw_ADD(p
, g0
, g0
, g0
);
626 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
627 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 8);
628 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
629 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
630 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
631 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
632 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
633 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
634 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
635 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
636 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
637 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
639 EXPECT_TRUE(validate(p
));
642 /* ExecSize must be greater than or equal to Width. */
643 TEST_P(validation_test
, exec_size_less_than_width
)
645 brw_ADD(p
, g0
, g0
, g0
);
646 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
648 EXPECT_FALSE(validate(p
));
650 clear_instructions(p
);
652 brw_ADD(p
, g0
, g0
, g0
);
653 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
655 EXPECT_FALSE(validate(p
));
658 /* If ExecSize = Width and HorzStride ≠ 0,
659 * VertStride must be set to Width * HorzStride.
661 TEST_P(validation_test
, vertical_stride_is_width_by_horizontal_stride
)
663 brw_ADD(p
, g0
, g0
, g0
);
664 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
666 EXPECT_FALSE(validate(p
));
668 clear_instructions(p
);
670 brw_ADD(p
, g0
, g0
, g0
);
671 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
673 EXPECT_FALSE(validate(p
));
676 /* If Width = 1, HorzStride must be 0 regardless of the values
677 * of ExecSize and VertStride.
679 TEST_P(validation_test
, horizontal_stride_must_be_0_if_width_is_1
)
681 brw_ADD(p
, g0
, g0
, g0
);
682 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
683 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
684 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
686 EXPECT_FALSE(validate(p
));
688 clear_instructions(p
);
690 brw_ADD(p
, g0
, g0
, g0
);
691 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
692 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
693 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
695 EXPECT_FALSE(validate(p
));
698 /* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */
699 TEST_P(validation_test
, scalar_region_must_be_0_1_0
)
701 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
703 brw_ADD(p
, g0
, g0
, g0_0
);
704 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
705 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
706 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
707 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
709 EXPECT_FALSE(validate(p
));
711 clear_instructions(p
);
713 brw_ADD(p
, g0
, g0_0
, g0
);
714 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
715 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
716 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
717 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
719 EXPECT_FALSE(validate(p
));
722 /* If VertStride = HorzStride = 0, Width must be 1 regardless of the value
725 TEST_P(validation_test
, zero_stride_implies_0_1_0
)
727 brw_ADD(p
, g0
, g0
, g0
);
728 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
729 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
730 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
732 EXPECT_FALSE(validate(p
));
734 clear_instructions(p
);
736 brw_ADD(p
, g0
, g0
, g0
);
737 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
738 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
739 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
741 EXPECT_FALSE(validate(p
));
744 /* Dst.HorzStride must not be 0. */
745 TEST_P(validation_test
, dst_horizontal_stride_0
)
747 brw_ADD(p
, g0
, g0
, g0
);
748 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
750 EXPECT_FALSE(validate(p
));
752 clear_instructions(p
);
754 /* Align16 does not exist on Gen11+ */
755 if (devinfo
.gen
>= 11)
758 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
760 brw_ADD(p
, g0
, g0
, g0
);
761 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
763 EXPECT_FALSE(validate(p
));
766 /* VertStride must be used to cross BRW_GENERAL_REGISTER_FILE register boundaries. This rule implies
767 * that elements within a 'Width' cannot cross BRW_GENERAL_REGISTER_FILE boundaries.
769 TEST_P(validation_test
, must_not_cross_grf_boundary_in_a_width
)
771 brw_ADD(p
, g0
, g0
, g0
);
772 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 4);
774 EXPECT_FALSE(validate(p
));
776 clear_instructions(p
);
778 brw_ADD(p
, g0
, g0
, g0
);
779 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 4);
781 EXPECT_FALSE(validate(p
));
783 clear_instructions(p
);
785 brw_ADD(p
, g0
, g0
, g0
);
786 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
787 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
788 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
790 EXPECT_FALSE(validate(p
));
792 clear_instructions(p
);
794 brw_ADD(p
, g0
, g0
, g0
);
795 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
796 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
797 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
799 EXPECT_FALSE(validate(p
));
802 /* Destination Horizontal must be 1 in Align16 */
803 TEST_P(validation_test
, dst_hstride_on_align16_must_be_1
)
805 /* Align16 does not exist on Gen11+ */
806 if (devinfo
.gen
>= 11)
809 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
811 brw_ADD(p
, g0
, g0
, g0
);
812 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
814 EXPECT_FALSE(validate(p
));
816 clear_instructions(p
);
818 brw_ADD(p
, g0
, g0
, g0
);
819 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
821 EXPECT_TRUE(validate(p
));
824 /* VertStride must be 0 or 4 in Align16 */
825 TEST_P(validation_test
, vstride_on_align16_must_be_0_or_4
)
827 /* Align16 does not exist on Gen11+ */
828 if (devinfo
.gen
>= 11)
832 enum brw_vertical_stride vstride
;
833 bool expected_result
;
835 { BRW_VERTICAL_STRIDE_0
, true },
836 { BRW_VERTICAL_STRIDE_1
, false },
837 { BRW_VERTICAL_STRIDE_2
, devinfo
.is_haswell
|| devinfo
.gen
>= 8 },
838 { BRW_VERTICAL_STRIDE_4
, true },
839 { BRW_VERTICAL_STRIDE_8
, false },
840 { BRW_VERTICAL_STRIDE_16
, false },
841 { BRW_VERTICAL_STRIDE_32
, false },
842 { BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL
, false },
845 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
847 for (unsigned i
= 0; i
< ARRAY_SIZE(vstride
); i
++) {
848 brw_ADD(p
, g0
, g0
, g0
);
849 brw_inst_set_src0_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
851 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
853 clear_instructions(p
);
856 for (unsigned i
= 0; i
< ARRAY_SIZE(vstride
); i
++) {
857 brw_ADD(p
, g0
, g0
, g0
);
858 brw_inst_set_src1_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
860 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
862 clear_instructions(p
);
866 /* In Direct Addressing mode, a source cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE
869 TEST_P(validation_test
, source_cannot_span_more_than_2_registers
)
871 brw_ADD(p
, g0
, g0
, g0
);
872 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
873 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
874 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
875 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
876 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
877 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
878 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
880 EXPECT_FALSE(validate(p
));
882 clear_instructions(p
);
884 brw_ADD(p
, g0
, g0
, g0
);
885 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
886 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
887 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
888 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
889 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
890 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
891 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
892 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 2);
894 EXPECT_TRUE(validate(p
));
896 clear_instructions(p
);
898 brw_ADD(p
, g0
, g0
, g0
);
899 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
901 EXPECT_TRUE(validate(p
));
904 /* A destination cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE registers. */
905 TEST_P(validation_test
, destination_cannot_span_more_than_2_registers
)
907 brw_ADD(p
, g0
, g0
, g0
);
908 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
909 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
910 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
911 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
912 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
914 EXPECT_FALSE(validate(p
));
916 clear_instructions(p
);
918 brw_ADD(p
, g0
, g0
, g0
);
919 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_8
);
920 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 6);
921 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
922 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
923 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
924 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
925 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
926 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
927 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
928 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
929 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
930 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
932 EXPECT_TRUE(validate(p
));
935 TEST_P(validation_test
, src_region_spans_two_regs_dst_region_spans_one
)
937 /* Writes to dest are to the lower OWord */
938 brw_ADD(p
, g0
, g0
, g0
);
939 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
940 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
941 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
942 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
943 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
944 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
946 EXPECT_TRUE(validate(p
));
948 clear_instructions(p
);
950 /* Writes to dest are to the upper OWord */
951 brw_ADD(p
, g0
, g0
, g0
);
952 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 16);
953 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
954 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
955 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
956 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
957 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
958 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
960 EXPECT_TRUE(validate(p
));
962 clear_instructions(p
);
964 /* Writes to dest are evenly split between OWords */
965 brw_ADD(p
, g0
, g0
, g0
);
966 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
967 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
968 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
969 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
970 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
971 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
972 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
974 EXPECT_TRUE(validate(p
));
976 clear_instructions(p
);
978 /* Writes to dest are uneven between OWords */
979 brw_ADD(p
, g0
, g0
, g0
);
980 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
981 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 10);
982 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
983 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
984 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
985 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
986 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
987 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
988 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
989 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
990 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
992 if (devinfo
.gen
>= 9) {
993 EXPECT_TRUE(validate(p
));
995 EXPECT_FALSE(validate(p
));
999 TEST_P(validation_test
, dst_elements_must_be_evenly_split_between_registers
)
1001 brw_ADD(p
, g0
, g0
, g0
);
1002 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
1004 if (devinfo
.gen
>= 9) {
1005 EXPECT_TRUE(validate(p
));
1007 EXPECT_FALSE(validate(p
));
1010 clear_instructions(p
);
1012 brw_ADD(p
, g0
, g0
, g0
);
1013 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
1015 EXPECT_TRUE(validate(p
));
1017 clear_instructions(p
);
1019 if (devinfo
.gen
>= 6) {
1020 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
1022 EXPECT_TRUE(validate(p
));
1024 clear_instructions(p
);
1026 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
1027 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
1029 EXPECT_FALSE(validate(p
));
1033 TEST_P(validation_test
, two_src_two_dst_source_offsets_must_be_same
)
1035 brw_ADD(p
, g0
, g0
, g0
);
1036 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
1037 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
1038 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 16);
1039 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_2
);
1040 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
1041 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
1042 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1043 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
1044 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
1046 if (devinfo
.gen
<= 7) {
1047 EXPECT_FALSE(validate(p
));
1049 EXPECT_TRUE(validate(p
));
1052 clear_instructions(p
);
1054 brw_ADD(p
, g0
, g0
, g0
);
1055 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
1056 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
1057 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1058 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
1059 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
1060 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_8
);
1061 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
1062 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
1064 EXPECT_TRUE(validate(p
));
1067 TEST_P(validation_test
, two_src_two_dst_each_dst_must_be_derived_from_one_src
)
1070 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
1071 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
1072 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
1073 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
1074 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 8);
1075 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1076 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
1077 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
1079 if (devinfo
.gen
<= 7) {
1080 EXPECT_FALSE(validate(p
));
1082 EXPECT_TRUE(validate(p
));
1085 clear_instructions(p
);
1088 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 16);
1089 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 8);
1090 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_2
);
1091 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
1092 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
1094 if (devinfo
.gen
<= 7) {
1095 EXPECT_FALSE(validate(p
));
1097 EXPECT_TRUE(validate(p
));
1101 TEST_P(validation_test
, one_src_two_dst
)
1103 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
1105 brw_ADD(p
, g0
, g0_0
, g0_0
);
1106 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
1108 EXPECT_TRUE(validate(p
));
1110 clear_instructions(p
);
1112 brw_ADD(p
, g0
, g0
, g0
);
1113 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
1114 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
1115 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
1116 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
1118 EXPECT_TRUE(validate(p
));
1120 clear_instructions(p
);
1122 brw_ADD(p
, g0
, g0
, g0
);
1123 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
1124 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
1125 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
1126 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
1127 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
1128 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
1129 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
1130 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
1132 if (devinfo
.gen
>= 8) {
1133 EXPECT_TRUE(validate(p
));
1135 EXPECT_FALSE(validate(p
));
1138 clear_instructions(p
);
1140 brw_ADD(p
, g0
, g0
, g0
);
1141 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
1142 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
1143 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
1144 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
1145 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
1146 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
1147 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
1148 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
1150 if (devinfo
.gen
>= 8) {
1151 EXPECT_TRUE(validate(p
));
1153 EXPECT_FALSE(validate(p
));
1157 TEST_P(validation_test
, packed_byte_destination
)
1159 static const struct {
1160 enum brw_reg_type dst_type
;
1161 enum brw_reg_type src_type
;
1163 bool expected_result
;
1165 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 0, 0, true },
1166 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 0, 0, true },
1167 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 0, 0, true },
1168 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 0, 0, true },
1170 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 1, 0, 0, false },
1171 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 1, 0, 0, false },
1172 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 1, 0, 0, false },
1173 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 1, 0, 0, false },
1175 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 1, 0, false },
1176 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 1, 0, false },
1177 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 1, 0, false },
1178 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 1, 0, false },
1180 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 0, 1, false },
1181 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 0, 1, false },
1182 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 0, 1, false },
1183 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 0, 1, false },
1185 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UW
, 0, 0, 0, false },
1186 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_W
, 0, 0, 0, false },
1187 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UD
, 0, 0, 0, false },
1188 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_D
, 0, 0, 0, false },
1191 for (unsigned i
= 0; i
< ARRAY_SIZE(move
); i
++) {
1192 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(g0
, move
[i
].src_type
));
1193 brw_inst_set_src0_negate(&devinfo
, last_inst
, move
[i
].neg
);
1194 brw_inst_set_src0_abs(&devinfo
, last_inst
, move
[i
].abs
);
1195 brw_inst_set_saturate(&devinfo
, last_inst
, move
[i
].sat
);
1197 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
1199 clear_instructions(p
);
1202 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_UB
),
1203 retype(g0
, BRW_REGISTER_TYPE_UB
),
1204 retype(g0
, BRW_REGISTER_TYPE_UB
));
1205 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
1207 EXPECT_FALSE(validate(p
));
1209 clear_instructions(p
);
1211 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
1212 retype(g0
, BRW_REGISTER_TYPE_B
),
1213 retype(g0
, BRW_REGISTER_TYPE_B
));
1214 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
1216 EXPECT_FALSE(validate(p
));
1219 TEST_P(validation_test
, byte_destination_relaxed_alignment
)
1221 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
1222 retype(g0
, BRW_REGISTER_TYPE_W
),
1223 retype(g0
, BRW_REGISTER_TYPE_W
));
1224 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
1225 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
1227 EXPECT_TRUE(validate(p
));
1229 clear_instructions(p
);
1231 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
1232 retype(g0
, BRW_REGISTER_TYPE_W
),
1233 retype(g0
, BRW_REGISTER_TYPE_W
));
1234 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
1235 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
1236 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 1);
1238 if (devinfo
.gen
> 4 || devinfo
.is_g4x
) {
1239 EXPECT_TRUE(validate(p
));
1241 EXPECT_FALSE(validate(p
));
1245 TEST_P(validation_test
, byte_64bit_conversion
)
1247 static const struct {
1248 enum brw_reg_type dst_type
;
1249 enum brw_reg_type src_type
;
1250 unsigned dst_stride
;
1251 bool expected_result
;
1253 #define INST(dst_type, src_type, dst_stride, expected_result) \
1255 BRW_REGISTER_TYPE_##dst_type, \
1256 BRW_REGISTER_TYPE_##src_type, \
1257 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1261 INST(B
, Q
, 1, false),
1262 INST(B
, UQ
, 1, false),
1263 INST(B
, DF
, 1, false),
1264 INST(UB
, Q
, 1, false),
1265 INST(UB
, UQ
, 1, false),
1266 INST(UB
, DF
, 1, false),
1268 INST(B
, Q
, 2, false),
1269 INST(B
, UQ
, 2, false),
1270 INST(B
, DF
, 2, false),
1271 INST(UB
, Q
, 2, false),
1272 INST(UB
, UQ
, 2, false),
1273 INST(UB
, DF
, 2, false),
1275 INST(B
, Q
, 4, false),
1276 INST(B
, UQ
, 4, false),
1277 INST(B
, DF
, 4, false),
1278 INST(UB
, Q
, 4, false),
1279 INST(UB
, UQ
, 4, false),
1280 INST(UB
, DF
, 4, false),
1285 if (devinfo
.gen
< 8)
1288 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
1289 if (!devinfo
.has_64bit_float
&&
1290 inst
[i
].src_type
== BRW_REGISTER_TYPE_DF
)
1293 if (!devinfo
.has_64bit_int
&&
1294 (inst
[i
].src_type
== BRW_REGISTER_TYPE_Q
||
1295 inst
[i
].src_type
== BRW_REGISTER_TYPE_UQ
))
1298 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
), retype(g0
, inst
[i
].src_type
));
1299 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1300 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1302 clear_instructions(p
);
1306 TEST_P(validation_test
, half_float_conversion
)
1308 static const struct {
1309 enum brw_reg_type dst_type
;
1310 enum brw_reg_type src_type
;
1311 unsigned dst_stride
;
1313 bool expected_result_bdw
;
1314 bool expected_result_chv_gen9
;
1316 #define INST_C(dst_type, src_type, dst_stride, dst_subnr, expected_result) \
1318 BRW_REGISTER_TYPE_##dst_type, \
1319 BRW_REGISTER_TYPE_##src_type, \
1320 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1325 #define INST_S(dst_type, src_type, dst_stride, dst_subnr, \
1326 expected_result_bdw, expected_result_chv_gen9) \
1328 BRW_REGISTER_TYPE_##dst_type, \
1329 BRW_REGISTER_TYPE_##src_type, \
1330 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1332 expected_result_bdw, \
1333 expected_result_chv_gen9, \
1336 /* MOV to half-float destination */
1337 INST_C(HF
, B
, 1, 0, false),
1338 INST_C(HF
, W
, 1, 0, false),
1339 INST_C(HF
, HF
, 1, 0, true),
1340 INST_C(HF
, HF
, 1, 2, true),
1341 INST_C(HF
, D
, 1, 0, false),
1342 INST_S(HF
, F
, 1, 0, false, true),
1343 INST_C(HF
, Q
, 1, 0, false),
1344 INST_C(HF
, B
, 2, 0, true),
1345 INST_C(HF
, B
, 2, 2, false),
1346 INST_C(HF
, W
, 2, 0, true),
1347 INST_C(HF
, W
, 2, 2, false),
1348 INST_C(HF
, HF
, 2, 0, true),
1349 INST_C(HF
, HF
, 2, 2, true),
1350 INST_C(HF
, D
, 2, 0, true),
1351 INST_C(HF
, D
, 2, 2, false),
1352 INST_C(HF
, F
, 2, 0, true),
1353 INST_S(HF
, F
, 2, 2, false, true),
1354 INST_C(HF
, Q
, 2, 0, false),
1355 INST_C(HF
, DF
, 2, 0, false),
1356 INST_C(HF
, B
, 4, 0, false),
1357 INST_C(HF
, W
, 4, 0, false),
1358 INST_C(HF
, HF
, 4, 0, true),
1359 INST_C(HF
, HF
, 4, 2, true),
1360 INST_C(HF
, D
, 4, 0, false),
1361 INST_C(HF
, F
, 4, 0, false),
1362 INST_C(HF
, Q
, 4, 0, false),
1363 INST_C(HF
, DF
, 4, 0, false),
1365 /* MOV from half-float source */
1366 INST_C( B
, HF
, 1, 0, false),
1367 INST_C( W
, HF
, 1, 0, false),
1368 INST_C( D
, HF
, 1, 0, true),
1369 INST_C( D
, HF
, 1, 4, true),
1370 INST_C( F
, HF
, 1, 0, true),
1371 INST_C( F
, HF
, 1, 4, true),
1372 INST_C( Q
, HF
, 1, 0, false),
1373 INST_C(DF
, HF
, 1, 0, false),
1374 INST_C( B
, HF
, 2, 0, false),
1375 INST_C( W
, HF
, 2, 0, true),
1376 INST_C( W
, HF
, 2, 2, false),
1377 INST_C( D
, HF
, 2, 0, false),
1378 INST_C( F
, HF
, 2, 0, true),
1379 INST_C( B
, HF
, 4, 0, true),
1380 INST_C( B
, HF
, 4, 1, false),
1381 INST_C( W
, HF
, 4, 0, false),
1387 if (devinfo
.gen
< 8)
1390 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
1391 if (!devinfo
.has_64bit_float
&&
1392 (inst
[i
].dst_type
== BRW_REGISTER_TYPE_DF
||
1393 inst
[i
].src_type
== BRW_REGISTER_TYPE_DF
))
1396 if (!devinfo
.has_64bit_int
&&
1397 (inst
[i
].dst_type
== BRW_REGISTER_TYPE_Q
||
1398 inst
[i
].dst_type
== BRW_REGISTER_TYPE_UQ
||
1399 inst
[i
].src_type
== BRW_REGISTER_TYPE_Q
||
1400 inst
[i
].src_type
== BRW_REGISTER_TYPE_UQ
))
1403 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
), retype(g0
, inst
[i
].src_type
));
1405 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
1407 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1408 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].dst_subnr
);
1410 if (inst
[i
].src_type
== BRW_REGISTER_TYPE_B
) {
1411 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1412 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
1413 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
1415 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1416 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
1417 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
1420 if (devinfo
.is_cherryview
|| devinfo
.gen
>= 9)
1421 EXPECT_EQ(inst
[i
].expected_result_chv_gen9
, validate(p
));
1423 EXPECT_EQ(inst
[i
].expected_result_bdw
, validate(p
));
1425 clear_instructions(p
);
1429 TEST_P(validation_test
, mixed_float_source_indirect_addressing
)
1431 static const struct {
1432 enum brw_reg_type dst_type
;
1433 enum brw_reg_type src0_type
;
1434 enum brw_reg_type src1_type
;
1435 unsigned dst_stride
;
1438 bool expected_result
;
1440 #define INST(dst_type, src0_type, src1_type, \
1441 dst_stride, dst_indirect, src0_indirect, expected_result) \
1443 BRW_REGISTER_TYPE_##dst_type, \
1444 BRW_REGISTER_TYPE_##src0_type, \
1445 BRW_REGISTER_TYPE_##src1_type, \
1446 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1452 /* Source and dest are mixed float: indirect src addressing not allowed */
1453 INST(HF
, F
, F
, 2, false, false, true),
1454 INST(HF
, F
, F
, 2, true, false, true),
1455 INST(HF
, F
, F
, 2, false, true, false),
1456 INST(HF
, F
, F
, 2, true, true, false),
1457 INST( F
, HF
, F
, 1, false, false, true),
1458 INST( F
, HF
, F
, 1, true, false, true),
1459 INST( F
, HF
, F
, 1, false, true, false),
1460 INST( F
, HF
, F
, 1, true, true, false),
1462 INST(HF
, HF
, F
, 2, false, false, true),
1463 INST(HF
, HF
, F
, 2, true, false, true),
1464 INST(HF
, HF
, F
, 2, false, true, false),
1465 INST(HF
, HF
, F
, 2, true, true, false),
1466 INST( F
, F
, HF
, 1, false, false, true),
1467 INST( F
, F
, HF
, 1, true, false, true),
1468 INST( F
, F
, HF
, 1, false, true, false),
1469 INST( F
, F
, HF
, 1, true, true, false),
1474 if (devinfo
.gen
< 8)
1477 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
1478 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1479 retype(g0
, inst
[i
].src0_type
),
1480 retype(g0
, inst
[i
].src1_type
));
1482 brw_inst_set_dst_address_mode(&devinfo
, last_inst
, inst
[i
].dst_indirect
);
1483 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1484 brw_inst_set_src0_address_mode(&devinfo
, last_inst
, inst
[i
].src0_indirect
);
1486 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1488 clear_instructions(p
);
1492 TEST_P(validation_test
, mixed_float_align1_simd16
)
1494 static const struct {
1496 enum brw_reg_type dst_type
;
1497 enum brw_reg_type src0_type
;
1498 enum brw_reg_type src1_type
;
1499 unsigned dst_stride
;
1500 bool expected_result
;
1502 #define INST(exec_size, dst_type, src0_type, src1_type, \
1503 dst_stride, expected_result) \
1505 BRW_EXECUTE_##exec_size, \
1506 BRW_REGISTER_TYPE_##dst_type, \
1507 BRW_REGISTER_TYPE_##src0_type, \
1508 BRW_REGISTER_TYPE_##src1_type, \
1509 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1513 /* No SIMD16 in mixed mode when destination is packed f16 */
1514 INST( 8, HF
, F
, HF
, 2, true),
1515 INST(16, HF
, HF
, F
, 2, true),
1516 INST(16, HF
, HF
, F
, 1, false),
1517 INST(16, HF
, F
, HF
, 1, false),
1519 /* No SIMD16 in mixed mode when destination is f32 */
1520 INST( 8, F
, HF
, F
, 1, true),
1521 INST( 8, F
, F
, HF
, 1, true),
1522 INST(16, F
, HF
, F
, 1, false),
1523 INST(16, F
, F
, HF
, 1, false),
1528 if (devinfo
.gen
< 8)
1531 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
1532 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1533 retype(g0
, inst
[i
].src0_type
),
1534 retype(g0
, inst
[i
].src1_type
));
1536 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1538 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1540 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1542 clear_instructions(p
);
1546 TEST_P(validation_test
, mixed_float_align1_packed_fp16_dst_acc_read_offset_0
)
1548 static const struct {
1549 enum brw_reg_type dst_type
;
1550 enum brw_reg_type src0_type
;
1551 enum brw_reg_type src1_type
;
1552 unsigned dst_stride
;
1555 bool expected_result_bdw
;
1556 bool expected_result_chv_skl
;
1558 #define INST(dst_type, src0_type, src1_type, dst_stride, read_acc, subnr, \
1559 expected_result_bdw, expected_result_chv_skl) \
1561 BRW_REGISTER_TYPE_##dst_type, \
1562 BRW_REGISTER_TYPE_##src0_type, \
1563 BRW_REGISTER_TYPE_##src1_type, \
1564 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1567 expected_result_bdw, \
1568 expected_result_chv_skl, \
1571 /* Destination is not packed */
1572 INST(HF
, HF
, F
, 2, true, 0, true, true),
1573 INST(HF
, HF
, F
, 2, true, 2, true, true),
1574 INST(HF
, HF
, F
, 2, true, 4, true, true),
1575 INST(HF
, HF
, F
, 2, true, 8, true, true),
1576 INST(HF
, HF
, F
, 2, true, 16, true, true),
1578 /* Destination is packed, we don't read acc */
1579 INST(HF
, HF
, F
, 1, false, 0, false, true),
1580 INST(HF
, HF
, F
, 1, false, 2, false, true),
1581 INST(HF
, HF
, F
, 1, false, 4, false, true),
1582 INST(HF
, HF
, F
, 1, false, 8, false, true),
1583 INST(HF
, HF
, F
, 1, false, 16, false, true),
1585 /* Destination is packed, we read acc */
1586 INST(HF
, HF
, F
, 1, true, 0, false, false),
1587 INST(HF
, HF
, F
, 1, true, 2, false, false),
1588 INST(HF
, HF
, F
, 1, true, 4, false, false),
1589 INST(HF
, HF
, F
, 1, true, 8, false, false),
1590 INST(HF
, HF
, F
, 1, true, 16, false, false),
1595 if (devinfo
.gen
< 8)
1598 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
1599 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1600 retype(inst
[i
].read_acc
? acc0
: g0
, inst
[i
].src0_type
),
1601 retype(g0
, inst
[i
].src1_type
));
1603 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1605 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].subnr
);
1607 if (devinfo
.is_cherryview
|| devinfo
.gen
>= 9)
1608 EXPECT_EQ(inst
[i
].expected_result_chv_skl
, validate(p
));
1610 EXPECT_EQ(inst
[i
].expected_result_bdw
, validate(p
));
1612 clear_instructions(p
);
1616 TEST_P(validation_test
, mixed_float_fp16_dest_with_acc
)
1618 static const struct {
1621 enum brw_reg_type dst_type
;
1622 enum brw_reg_type src0_type
;
1623 enum brw_reg_type src1_type
;
1624 unsigned dst_stride
;
1626 bool expected_result_bdw
;
1627 bool expected_result_chv_skl
;
1629 #define INST(exec_size, opcode, dst_type, src0_type, src1_type, \
1630 dst_stride, read_acc,expected_result_bdw, \
1631 expected_result_chv_skl) \
1633 BRW_EXECUTE_##exec_size, \
1634 BRW_OPCODE_##opcode, \
1635 BRW_REGISTER_TYPE_##dst_type, \
1636 BRW_REGISTER_TYPE_##src0_type, \
1637 BRW_REGISTER_TYPE_##src1_type, \
1638 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1640 expected_result_bdw, \
1641 expected_result_chv_skl, \
1644 /* Packed fp16 dest with implicit acc needs hstride=2 */
1645 INST(8, MAC
, HF
, HF
, F
, 1, false, false, false),
1646 INST(8, MAC
, HF
, HF
, F
, 2, false, true, true),
1647 INST(8, MAC
, HF
, F
, HF
, 1, false, false, false),
1648 INST(8, MAC
, HF
, F
, HF
, 2, false, true, true),
1650 /* Packed fp16 dest with explicit acc needs hstride=2 */
1651 INST(8, ADD
, HF
, HF
, F
, 1, true, false, false),
1652 INST(8, ADD
, HF
, HF
, F
, 2, true, true, true),
1653 INST(8, ADD
, HF
, F
, HF
, 1, true, false, false),
1654 INST(8, ADD
, HF
, F
, HF
, 2, true, true, true),
1656 /* If destination is not fp16, restriction doesn't apply */
1657 INST(8, MAC
, F
, HF
, F
, 1, false, true, true),
1658 INST(8, MAC
, F
, HF
, F
, 2, false, true, true),
1660 /* If there is no implicit/explicit acc, restriction doesn't apply */
1661 INST(8, ADD
, HF
, HF
, F
, 1, false, false, true),
1662 INST(8, ADD
, HF
, HF
, F
, 2, false, true, true),
1663 INST(8, ADD
, HF
, F
, HF
, 1, false, false, true),
1664 INST(8, ADD
, HF
, F
, HF
, 2, false, true, true),
1665 INST(8, ADD
, F
, HF
, F
, 1, false, true, true),
1666 INST(8, ADD
, F
, HF
, F
, 2, false, true, true),
1671 if (devinfo
.gen
< 8)
1674 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
1675 if (inst
[i
].opcode
== BRW_OPCODE_MAC
) {
1676 brw_MAC(p
, retype(g0
, inst
[i
].dst_type
),
1677 retype(g0
, inst
[i
].src0_type
),
1678 retype(g0
, inst
[i
].src1_type
));
1680 assert(inst
[i
].opcode
== BRW_OPCODE_ADD
);
1681 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1682 retype(inst
[i
].read_acc
? acc0
: g0
, inst
[i
].src0_type
),
1683 retype(g0
, inst
[i
].src1_type
));
1686 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1688 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1690 if (devinfo
.is_cherryview
|| devinfo
.gen
>= 9)
1691 EXPECT_EQ(inst
[i
].expected_result_chv_skl
, validate(p
));
1693 EXPECT_EQ(inst
[i
].expected_result_bdw
, validate(p
));
1695 clear_instructions(p
);
1699 TEST_P(validation_test
, mixed_float_align1_math_strided_fp16_inputs
)
1701 static const struct {
1702 enum brw_reg_type dst_type
;
1703 enum brw_reg_type src0_type
;
1704 enum brw_reg_type src1_type
;
1705 unsigned dst_stride
;
1706 unsigned src0_stride
;
1707 unsigned src1_stride
;
1708 bool expected_result
;
1710 #define INST(dst_type, src0_type, src1_type, \
1711 dst_stride, src0_stride, src1_stride, expected_result) \
1713 BRW_REGISTER_TYPE_##dst_type, \
1714 BRW_REGISTER_TYPE_##src0_type, \
1715 BRW_REGISTER_TYPE_##src1_type, \
1716 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1717 BRW_HORIZONTAL_STRIDE_##src0_stride, \
1718 BRW_HORIZONTAL_STRIDE_##src1_stride, \
1722 INST(HF
, HF
, F
, 2, 2, 1, true),
1723 INST(HF
, F
, HF
, 2, 1, 2, true),
1724 INST(HF
, F
, HF
, 1, 1, 2, true),
1725 INST(HF
, F
, HF
, 2, 1, 1, false),
1726 INST(HF
, HF
, F
, 2, 1, 1, false),
1727 INST(HF
, HF
, F
, 1, 1, 1, false),
1728 INST(HF
, HF
, F
, 2, 1, 1, false),
1729 INST( F
, HF
, F
, 1, 1, 1, false),
1730 INST( F
, F
, HF
, 1, 1, 2, true),
1731 INST( F
, HF
, HF
, 1, 2, 1, false),
1732 INST( F
, HF
, HF
, 1, 2, 2, true),
1737 /* No half-float math in gen8 */
1738 if (devinfo
.gen
< 9)
1741 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
1742 gen6_math(p
, retype(g0
, inst
[i
].dst_type
),
1743 BRW_MATH_FUNCTION_POW
,
1744 retype(g0
, inst
[i
].src0_type
),
1745 retype(g0
, inst
[i
].src1_type
));
1747 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1749 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1750 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
1751 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src0_stride
);
1753 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1754 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
1755 brw_inst_set_src1_hstride(&devinfo
, last_inst
, inst
[i
].src1_stride
);
1757 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1759 clear_instructions(p
);
1763 TEST_P(validation_test
, mixed_float_align1_packed_fp16_dst
)
1765 static const struct {
1767 enum brw_reg_type dst_type
;
1768 enum brw_reg_type src0_type
;
1769 enum brw_reg_type src1_type
;
1770 unsigned dst_stride
;
1772 bool expected_result_bdw
;
1773 bool expected_result_chv_skl
;
1775 #define INST(exec_size, dst_type, src0_type, src1_type, dst_stride, dst_subnr, \
1776 expected_result_bdw, expected_result_chv_skl) \
1778 BRW_EXECUTE_##exec_size, \
1779 BRW_REGISTER_TYPE_##dst_type, \
1780 BRW_REGISTER_TYPE_##src0_type, \
1781 BRW_REGISTER_TYPE_##src1_type, \
1782 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1784 expected_result_bdw, \
1785 expected_result_chv_skl \
1788 /* SIMD8 packed fp16 dst won't cross oword boundaries if region is
1791 INST( 8, HF
, HF
, F
, 1, 0, false, true),
1792 INST( 8, HF
, HF
, F
, 1, 2, false, false),
1793 INST( 8, HF
, HF
, F
, 1, 4, false, false),
1794 INST( 8, HF
, HF
, F
, 1, 8, false, false),
1795 INST( 8, HF
, HF
, F
, 1, 16, false, true),
1797 /* SIMD16 packed fp16 always crosses oword boundaries */
1798 INST(16, HF
, HF
, F
, 1, 0, false, false),
1799 INST(16, HF
, HF
, F
, 1, 2, false, false),
1800 INST(16, HF
, HF
, F
, 1, 4, false, false),
1801 INST(16, HF
, HF
, F
, 1, 8, false, false),
1802 INST(16, HF
, HF
, F
, 1, 16, false, false),
1804 /* If destination is not packed (or not fp16) we can cross oword
1807 INST( 8, HF
, HF
, F
, 2, 0, true, true),
1808 INST( 8, F
, HF
, F
, 1, 0, true, true),
1813 if (devinfo
.gen
< 8)
1816 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
1817 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1818 retype(g0
, inst
[i
].src0_type
),
1819 retype(g0
, inst
[i
].src1_type
));
1821 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1822 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].dst_subnr
);
1824 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1825 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
1826 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
1828 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1829 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
1830 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
1832 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1834 if (devinfo
.is_cherryview
|| devinfo
.gen
>= 9)
1835 EXPECT_EQ(inst
[i
].expected_result_chv_skl
, validate(p
));
1837 EXPECT_EQ(inst
[i
].expected_result_bdw
, validate(p
));
1839 clear_instructions(p
);
1843 TEST_P(validation_test
, mixed_float_align16_packed_data
)
1845 static const struct {
1846 enum brw_reg_type dst_type
;
1847 enum brw_reg_type src0_type
;
1848 enum brw_reg_type src1_type
;
1849 unsigned src0_vstride
;
1850 unsigned src1_vstride
;
1851 bool expected_result
;
1853 #define INST(dst_type, src0_type, src1_type, \
1854 src0_vstride, src1_vstride, expected_result) \
1856 BRW_REGISTER_TYPE_##dst_type, \
1857 BRW_REGISTER_TYPE_##src0_type, \
1858 BRW_REGISTER_TYPE_##src1_type, \
1859 BRW_VERTICAL_STRIDE_##src0_vstride, \
1860 BRW_VERTICAL_STRIDE_##src1_vstride, \
1864 /* We only test with F destination because there is a restriction
1865 * by which F->HF conversions need to be DWord aligned but Align16 also
1866 * requires that destination horizontal stride is 1.
1868 INST(F
, F
, HF
, 4, 4, true),
1869 INST(F
, F
, HF
, 2, 4, false),
1870 INST(F
, F
, HF
, 4, 2, false),
1871 INST(F
, F
, HF
, 0, 4, false),
1872 INST(F
, F
, HF
, 4, 0, false),
1873 INST(F
, HF
, F
, 4, 4, true),
1874 INST(F
, HF
, F
, 4, 2, false),
1875 INST(F
, HF
, F
, 2, 4, false),
1876 INST(F
, HF
, F
, 0, 4, false),
1877 INST(F
, HF
, F
, 4, 0, false),
1882 if (devinfo
.gen
< 8 || devinfo
.gen
>= 11)
1885 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
1887 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
1888 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1889 retype(g0
, inst
[i
].src0_type
),
1890 retype(g0
, inst
[i
].src1_type
));
1892 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src0_vstride
);
1893 brw_inst_set_src1_vstride(&devinfo
, last_inst
, inst
[i
].src1_vstride
);
1895 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1897 clear_instructions(p
);
1901 TEST_P(validation_test
, mixed_float_align16_no_simd16
)
1903 static const struct {
1905 enum brw_reg_type dst_type
;
1906 enum brw_reg_type src0_type
;
1907 enum brw_reg_type src1_type
;
1908 bool expected_result
;
1910 #define INST(exec_size, dst_type, src0_type, src1_type, expected_result) \
1912 BRW_EXECUTE_##exec_size, \
1913 BRW_REGISTER_TYPE_##dst_type, \
1914 BRW_REGISTER_TYPE_##src0_type, \
1915 BRW_REGISTER_TYPE_##src1_type, \
1919 /* We only test with F destination because there is a restriction
1920 * by which F->HF conversions need to be DWord aligned but Align16 also
1921 * requires that destination horizontal stride is 1.
1923 INST( 8, F
, F
, HF
, true),
1924 INST( 8, F
, HF
, F
, true),
1925 INST( 8, F
, F
, HF
, true),
1926 INST(16, F
, F
, HF
, false),
1927 INST(16, F
, HF
, F
, false),
1928 INST(16, F
, F
, HF
, false),
1933 if (devinfo
.gen
< 8 || devinfo
.gen
>= 11)
1936 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
1938 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
1939 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1940 retype(g0
, inst
[i
].src0_type
),
1941 retype(g0
, inst
[i
].src1_type
));
1943 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1945 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1946 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1948 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1950 clear_instructions(p
);
1954 TEST_P(validation_test
, mixed_float_align16_no_acc_read
)
1956 static const struct {
1957 enum brw_reg_type dst_type
;
1958 enum brw_reg_type src0_type
;
1959 enum brw_reg_type src1_type
;
1961 bool expected_result
;
1963 #define INST(dst_type, src0_type, src1_type, read_acc, expected_result) \
1965 BRW_REGISTER_TYPE_##dst_type, \
1966 BRW_REGISTER_TYPE_##src0_type, \
1967 BRW_REGISTER_TYPE_##src1_type, \
1972 /* We only test with F destination because there is a restriction
1973 * by which F->HF conversions need to be DWord aligned but Align16 also
1974 * requires that destination horizontal stride is 1.
1976 INST( F
, F
, HF
, false, true),
1977 INST( F
, F
, HF
, true, false),
1978 INST( F
, HF
, F
, false, true),
1979 INST( F
, HF
, F
, true, false),
1984 if (devinfo
.gen
< 8 || devinfo
.gen
>= 11)
1987 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
1989 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
1990 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1991 retype(inst
[i
].read_acc
? acc0
: g0
, inst
[i
].src0_type
),
1992 retype(g0
, inst
[i
].src1_type
));
1994 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1995 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
1997 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1999 clear_instructions(p
);
2003 TEST_P(validation_test
, mixed_float_align16_math_packed_format
)
2005 static const struct {
2006 enum brw_reg_type dst_type
;
2007 enum brw_reg_type src0_type
;
2008 enum brw_reg_type src1_type
;
2009 unsigned src0_vstride
;
2010 unsigned src1_vstride
;
2011 bool expected_result
;
2013 #define INST(dst_type, src0_type, src1_type, \
2014 src0_vstride, src1_vstride, expected_result) \
2016 BRW_REGISTER_TYPE_##dst_type, \
2017 BRW_REGISTER_TYPE_##src0_type, \
2018 BRW_REGISTER_TYPE_##src1_type, \
2019 BRW_VERTICAL_STRIDE_##src0_vstride, \
2020 BRW_VERTICAL_STRIDE_##src1_vstride, \
2024 /* We only test with F destination because there is a restriction
2025 * by which F->HF conversions need to be DWord aligned but Align16 also
2026 * requires that destination horizontal stride is 1.
2028 INST( F
, HF
, F
, 4, 0, false),
2029 INST( F
, HF
, HF
, 4, 4, true),
2030 INST( F
, F
, HF
, 4, 0, false),
2031 INST( F
, F
, HF
, 2, 4, false),
2032 INST( F
, F
, HF
, 4, 2, false),
2033 INST( F
, HF
, HF
, 0, 4, false),
2038 /* Align16 Math for mixed float mode is not supported in gen8 */
2039 if (devinfo
.gen
< 9 || devinfo
.gen
>= 11)
2042 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
2044 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
2045 gen6_math(p
, retype(g0
, inst
[i
].dst_type
),
2046 BRW_MATH_FUNCTION_POW
,
2047 retype(g0
, inst
[i
].src0_type
),
2048 retype(g0
, inst
[i
].src1_type
));
2050 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src0_vstride
);
2051 brw_inst_set_src1_vstride(&devinfo
, last_inst
, inst
[i
].src1_vstride
);
2053 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
2055 clear_instructions(p
);
2059 TEST_P(validation_test
, vector_immediate_destination_alignment
)
2061 static const struct {
2062 enum brw_reg_type dst_type
;
2063 enum brw_reg_type src_type
;
2066 bool expected_result
;
2068 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 0, BRW_EXECUTE_4
, true },
2069 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 16, BRW_EXECUTE_4
, true },
2070 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 1, BRW_EXECUTE_4
, false },
2072 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 0, BRW_EXECUTE_8
, true },
2073 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 16, BRW_EXECUTE_8
, true },
2074 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 1, BRW_EXECUTE_8
, false },
2076 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 0, BRW_EXECUTE_8
, true },
2077 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 16, BRW_EXECUTE_8
, true },
2078 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 1, BRW_EXECUTE_8
, false },
2081 for (unsigned i
= 0; i
< ARRAY_SIZE(move
); i
++) {
2082 /* UV type is Gen6+ */
2083 if (devinfo
.gen
< 6 &&
2084 move
[i
].src_type
== BRW_REGISTER_TYPE_UV
)
2087 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(zero
, move
[i
].src_type
));
2088 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, move
[i
].subnr
);
2089 brw_inst_set_exec_size(&devinfo
, last_inst
, move
[i
].exec_size
);
2091 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
2093 clear_instructions(p
);
2097 TEST_P(validation_test
, vector_immediate_destination_stride
)
2099 static const struct {
2100 enum brw_reg_type dst_type
;
2101 enum brw_reg_type src_type
;
2103 bool expected_result
;
2105 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_1
, true },
2106 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, false },
2107 { BRW_REGISTER_TYPE_D
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_1
, true },
2108 { BRW_REGISTER_TYPE_D
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, false },
2109 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, true },
2110 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_4
, true },
2112 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_1
, true },
2113 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_2
, false },
2114 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_4
, false },
2115 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_2
, true },
2117 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_1
, true },
2118 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_2
, false },
2119 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_4
, false },
2120 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_2
, true },
2123 for (unsigned i
= 0; i
< ARRAY_SIZE(move
); i
++) {
2124 /* UV type is Gen6+ */
2125 if (devinfo
.gen
< 6 &&
2126 move
[i
].src_type
== BRW_REGISTER_TYPE_UV
)
2129 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(zero
, move
[i
].src_type
));
2130 brw_inst_set_dst_hstride(&devinfo
, last_inst
, move
[i
].stride
);
2132 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
2134 clear_instructions(p
);
2138 TEST_P(validation_test
, qword_low_power_align1_regioning_restrictions
)
2140 static const struct {
2144 enum brw_reg_type dst_type
;
2145 unsigned dst_subreg
;
2146 unsigned dst_stride
;
2148 enum brw_reg_type src_type
;
2149 unsigned src_subreg
;
2150 unsigned src_vstride
;
2152 unsigned src_hstride
;
2154 bool expected_result
;
2156 #define INST(opcode, exec_size, dst_type, dst_subreg, dst_stride, src_type, \
2157 src_subreg, src_vstride, src_width, src_hstride, expected_result) \
2159 BRW_OPCODE_##opcode, \
2160 BRW_EXECUTE_##exec_size, \
2161 BRW_REGISTER_TYPE_##dst_type, \
2163 BRW_HORIZONTAL_STRIDE_##dst_stride, \
2164 BRW_REGISTER_TYPE_##src_type, \
2166 BRW_VERTICAL_STRIDE_##src_vstride, \
2167 BRW_WIDTH_##src_width, \
2168 BRW_HORIZONTAL_STRIDE_##src_hstride, \
2172 /* Some instruction that violate no restrictions, as a control */
2173 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 4, 4, 1, true ),
2174 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 4, 4, 1, true ),
2175 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 4, 4, 1, true ),
2177 INST(MOV
, 4, DF
, 0, 1, F
, 0, 8, 4, 2, true ),
2178 INST(MOV
, 4, Q
, 0, 1, D
, 0, 8, 4, 2, true ),
2179 INST(MOV
, 4, UQ
, 0, 1, UD
, 0, 8, 4, 2, true ),
2181 INST(MOV
, 4, F
, 0, 2, DF
, 0, 4, 4, 1, true ),
2182 INST(MOV
, 4, D
, 0, 2, Q
, 0, 4, 4, 1, true ),
2183 INST(MOV
, 4, UD
, 0, 2, UQ
, 0, 4, 4, 1, true ),
2185 INST(MUL
, 8, D
, 0, 2, D
, 0, 8, 4, 2, true ),
2186 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 8, 4, 2, true ),
2188 /* Something with subreg nrs */
2189 INST(MOV
, 2, DF
, 8, 1, DF
, 8, 2, 2, 1, true ),
2190 INST(MOV
, 2, Q
, 8, 1, Q
, 8, 2, 2, 1, true ),
2191 INST(MOV
, 2, UQ
, 8, 1, UQ
, 8, 2, 2, 1, true ),
2193 INST(MUL
, 2, D
, 4, 2, D
, 4, 4, 2, 2, true ),
2194 INST(MUL
, 2, UD
, 4, 2, UD
, 4, 4, 2, 2, true ),
2196 /* The PRMs say that for CHV, BXT:
2198 * When source or destination datatype is 64b or operation is integer
2199 * DWord multiply, regioning in Align1 must follow these rules:
2201 * 1. Source and Destination horizontal stride must be aligned to the
2204 INST(MOV
, 4, DF
, 0, 2, DF
, 0, 4, 4, 1, false),
2205 INST(MOV
, 4, Q
, 0, 2, Q
, 0, 4, 4, 1, false),
2206 INST(MOV
, 4, UQ
, 0, 2, UQ
, 0, 4, 4, 1, false),
2208 INST(MOV
, 4, DF
, 0, 2, F
, 0, 8, 4, 2, false),
2209 INST(MOV
, 4, Q
, 0, 2, D
, 0, 8, 4, 2, false),
2210 INST(MOV
, 4, UQ
, 0, 2, UD
, 0, 8, 4, 2, false),
2212 INST(MOV
, 4, DF
, 0, 2, F
, 0, 4, 4, 1, false),
2213 INST(MOV
, 4, Q
, 0, 2, D
, 0, 4, 4, 1, false),
2214 INST(MOV
, 4, UQ
, 0, 2, UD
, 0, 4, 4, 1, false),
2216 INST(MUL
, 4, D
, 0, 2, D
, 0, 4, 4, 1, false),
2217 INST(MUL
, 4, UD
, 0, 2, UD
, 0, 4, 4, 1, false),
2219 INST(MUL
, 4, D
, 0, 1, D
, 0, 8, 4, 2, false),
2220 INST(MUL
, 4, UD
, 0, 1, UD
, 0, 8, 4, 2, false),
2222 /* 2. Regioning must ensure Src.Vstride = Src.Width * Src.Hstride. */
2223 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 0, 2, 1, false),
2224 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 0, 2, 1, false),
2225 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 0, 2, 1, false),
2227 INST(MOV
, 4, DF
, 0, 1, F
, 0, 0, 2, 2, false),
2228 INST(MOV
, 4, Q
, 0, 1, D
, 0, 0, 2, 2, false),
2229 INST(MOV
, 4, UQ
, 0, 1, UD
, 0, 0, 2, 2, false),
2231 INST(MOV
, 8, F
, 0, 2, DF
, 0, 0, 2, 1, false),
2232 INST(MOV
, 8, D
, 0, 2, Q
, 0, 0, 2, 1, false),
2233 INST(MOV
, 8, UD
, 0, 2, UQ
, 0, 0, 2, 1, false),
2235 INST(MUL
, 8, D
, 0, 2, D
, 0, 0, 4, 2, false),
2236 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 0, 4, 2, false),
2238 INST(MUL
, 8, D
, 0, 2, D
, 0, 0, 4, 2, false),
2239 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 0, 4, 2, false),
2241 /* 3. Source and Destination offset must be the same, except the case
2244 INST(MOV
, 2, DF
, 8, 1, DF
, 0, 2, 2, 1, false),
2245 INST(MOV
, 2, Q
, 8, 1, Q
, 0, 2, 2, 1, false),
2246 INST(MOV
, 2, UQ
, 8, 1, UQ
, 0, 2, 2, 1, false),
2248 INST(MOV
, 2, DF
, 0, 1, DF
, 8, 2, 2, 1, false),
2249 INST(MOV
, 2, Q
, 0, 1, Q
, 8, 2, 2, 1, false),
2250 INST(MOV
, 2, UQ
, 0, 1, UQ
, 8, 2, 2, 1, false),
2252 INST(MUL
, 4, D
, 4, 2, D
, 0, 4, 2, 2, false),
2253 INST(MUL
, 4, UD
, 4, 2, UD
, 0, 4, 2, 2, false),
2255 INST(MUL
, 4, D
, 0, 2, D
, 4, 4, 2, 2, false),
2256 INST(MUL
, 4, UD
, 0, 2, UD
, 4, 4, 2, 2, false),
2258 INST(MOV
, 2, DF
, 8, 1, DF
, 0, 0, 1, 0, true ),
2259 INST(MOV
, 2, Q
, 8, 1, Q
, 0, 0, 1, 0, true ),
2260 INST(MOV
, 2, UQ
, 8, 1, UQ
, 0, 0, 1, 0, true ),
2262 INST(MOV
, 2, DF
, 8, 1, F
, 4, 0, 1, 0, true ),
2263 INST(MOV
, 2, Q
, 8, 1, D
, 4, 0, 1, 0, true ),
2264 INST(MOV
, 2, UQ
, 8, 1, UD
, 4, 0, 1, 0, true ),
2266 INST(MUL
, 4, D
, 4, 1, D
, 0, 0, 1, 0, true ),
2267 INST(MUL
, 4, UD
, 4, 1, UD
, 0, 0, 1, 0, true ),
2269 INST(MUL
, 4, D
, 0, 1, D
, 4, 0, 1, 0, true ),
2270 INST(MUL
, 4, UD
, 0, 1, UD
, 4, 0, 1, 0, true ),
2275 /* These restrictions only apply to Gen8+ */
2276 if (devinfo
.gen
< 8)
2279 /* NoDDChk/NoDDClr does not exist on Gen12+ */
2280 if (devinfo
.gen
>= 12)
2283 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
2284 if (!devinfo
.has_64bit_float
&&
2285 (inst
[i
].dst_type
== BRW_REGISTER_TYPE_DF
||
2286 inst
[i
].src_type
== BRW_REGISTER_TYPE_DF
))
2289 if (!devinfo
.has_64bit_int
&&
2290 (inst
[i
].dst_type
== BRW_REGISTER_TYPE_Q
||
2291 inst
[i
].dst_type
== BRW_REGISTER_TYPE_UQ
||
2292 inst
[i
].src_type
== BRW_REGISTER_TYPE_Q
||
2293 inst
[i
].src_type
== BRW_REGISTER_TYPE_UQ
))
2296 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
2297 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
2298 retype(g0
, inst
[i
].src_type
));
2300 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
2301 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
2302 retype(g0
, inst
[i
].src_type
),
2303 retype(zero
, inst
[i
].src_type
));
2305 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
2307 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].dst_subreg
);
2308 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].src_subreg
);
2310 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
2312 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
2313 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
2314 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
2316 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
2317 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
2319 EXPECT_TRUE(validate(p
));
2322 clear_instructions(p
);
2326 TEST_P(validation_test
, qword_low_power_no_indirect_addressing
)
2328 static const struct {
2332 enum brw_reg_type dst_type
;
2333 bool dst_is_indirect
;
2334 unsigned dst_stride
;
2336 enum brw_reg_type src_type
;
2337 bool src_is_indirect
;
2338 unsigned src_vstride
;
2340 unsigned src_hstride
;
2342 bool expected_result
;
2344 #define INST(opcode, exec_size, dst_type, dst_is_indirect, dst_stride, \
2345 src_type, src_is_indirect, src_vstride, src_width, src_hstride, \
2348 BRW_OPCODE_##opcode, \
2349 BRW_EXECUTE_##exec_size, \
2350 BRW_REGISTER_TYPE_##dst_type, \
2352 BRW_HORIZONTAL_STRIDE_##dst_stride, \
2353 BRW_REGISTER_TYPE_##src_type, \
2355 BRW_VERTICAL_STRIDE_##src_vstride, \
2356 BRW_WIDTH_##src_width, \
2357 BRW_HORIZONTAL_STRIDE_##src_hstride, \
2361 /* Some instruction that violate no restrictions, as a control */
2362 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 4, 4, 1, true ),
2363 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 4, 4, 1, true ),
2364 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 4, 4, 1, true ),
2366 INST(MUL
, 8, D
, 0, 2, D
, 0, 8, 4, 2, true ),
2367 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 8, 4, 2, true ),
2369 INST(MOV
, 4, F
, 1, 1, F
, 0, 4, 4, 1, true ),
2370 INST(MOV
, 4, F
, 0, 1, F
, 1, 4, 4, 1, true ),
2371 INST(MOV
, 4, F
, 1, 1, F
, 1, 4, 4, 1, true ),
2373 /* The PRMs say that for CHV, BXT:
2375 * When source or destination datatype is 64b or operation is integer
2376 * DWord multiply, indirect addressing must not be used.
2378 INST(MOV
, 4, DF
, 1, 1, DF
, 0, 4, 4, 1, false),
2379 INST(MOV
, 4, Q
, 1, 1, Q
, 0, 4, 4, 1, false),
2380 INST(MOV
, 4, UQ
, 1, 1, UQ
, 0, 4, 4, 1, false),
2382 INST(MOV
, 4, DF
, 0, 1, DF
, 1, 4, 4, 1, false),
2383 INST(MOV
, 4, Q
, 0, 1, Q
, 1, 4, 4, 1, false),
2384 INST(MOV
, 4, UQ
, 0, 1, UQ
, 1, 4, 4, 1, false),
2386 INST(MOV
, 4, DF
, 1, 1, F
, 0, 8, 4, 2, false),
2387 INST(MOV
, 4, Q
, 1, 1, D
, 0, 8, 4, 2, false),
2388 INST(MOV
, 4, UQ
, 1, 1, UD
, 0, 8, 4, 2, false),
2390 INST(MOV
, 4, DF
, 0, 1, F
, 1, 8, 4, 2, false),
2391 INST(MOV
, 4, Q
, 0, 1, D
, 1, 8, 4, 2, false),
2392 INST(MOV
, 4, UQ
, 0, 1, UD
, 1, 8, 4, 2, false),
2394 INST(MOV
, 4, F
, 1, 2, DF
, 0, 4, 4, 1, false),
2395 INST(MOV
, 4, D
, 1, 2, Q
, 0, 4, 4, 1, false),
2396 INST(MOV
, 4, UD
, 1, 2, UQ
, 0, 4, 4, 1, false),
2398 INST(MOV
, 4, F
, 0, 2, DF
, 1, 4, 4, 1, false),
2399 INST(MOV
, 4, D
, 0, 2, Q
, 1, 4, 4, 1, false),
2400 INST(MOV
, 4, UD
, 0, 2, UQ
, 1, 4, 4, 1, false),
2402 INST(MUL
, 8, D
, 1, 2, D
, 0, 8, 4, 2, false),
2403 INST(MUL
, 8, UD
, 1, 2, UD
, 0, 8, 4, 2, false),
2405 INST(MUL
, 8, D
, 0, 2, D
, 1, 8, 4, 2, false),
2406 INST(MUL
, 8, UD
, 0, 2, UD
, 1, 8, 4, 2, false),
2411 /* These restrictions only apply to Gen8+ */
2412 if (devinfo
.gen
< 8)
2415 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
2416 if (!devinfo
.has_64bit_float
&&
2417 (inst
[i
].dst_type
== BRW_REGISTER_TYPE_DF
||
2418 inst
[i
].src_type
== BRW_REGISTER_TYPE_DF
))
2421 if (!devinfo
.has_64bit_int
&&
2422 (inst
[i
].dst_type
== BRW_REGISTER_TYPE_Q
||
2423 inst
[i
].dst_type
== BRW_REGISTER_TYPE_UQ
||
2424 inst
[i
].src_type
== BRW_REGISTER_TYPE_Q
||
2425 inst
[i
].src_type
== BRW_REGISTER_TYPE_UQ
))
2428 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
2429 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
2430 retype(g0
, inst
[i
].src_type
));
2432 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
2433 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
2434 retype(g0
, inst
[i
].src_type
),
2435 retype(zero
, inst
[i
].src_type
));
2437 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
2439 brw_inst_set_dst_address_mode(&devinfo
, last_inst
, inst
[i
].dst_is_indirect
);
2440 brw_inst_set_src0_address_mode(&devinfo
, last_inst
, inst
[i
].src_is_indirect
);
2442 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
2444 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
2445 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
2446 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
2448 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
2449 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
2451 EXPECT_TRUE(validate(p
));
2454 clear_instructions(p
);
2458 TEST_P(validation_test
, qword_low_power_no_64bit_arf
)
2460 static const struct {
2465 enum brw_reg_type dst_type
;
2466 unsigned dst_stride
;
2469 enum brw_reg_type src_type
;
2470 unsigned src_vstride
;
2472 unsigned src_hstride
;
2475 bool expected_result
;
2477 #define INST(opcode, exec_size, dst, dst_type, dst_stride, \
2478 src, src_type, src_vstride, src_width, src_hstride, \
2479 acc_wr, expected_result) \
2481 BRW_OPCODE_##opcode, \
2482 BRW_EXECUTE_##exec_size, \
2484 BRW_REGISTER_TYPE_##dst_type, \
2485 BRW_HORIZONTAL_STRIDE_##dst_stride, \
2487 BRW_REGISTER_TYPE_##src_type, \
2488 BRW_VERTICAL_STRIDE_##src_vstride, \
2489 BRW_WIDTH_##src_width, \
2490 BRW_HORIZONTAL_STRIDE_##src_hstride, \
2495 /* Some instruction that violate no restrictions, as a control */
2496 INST(MOV
, 4, g0
, DF
, 1, g0
, F
, 4, 2, 2, 0, true ),
2497 INST(MOV
, 4, g0
, F
, 2, g0
, DF
, 4, 4, 1, 0, true ),
2499 INST(MOV
, 4, g0
, Q
, 1, g0
, D
, 4, 2, 2, 0, true ),
2500 INST(MOV
, 4, g0
, D
, 2, g0
, Q
, 4, 4, 1, 0, true ),
2502 INST(MOV
, 4, g0
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, true ),
2503 INST(MOV
, 4, g0
, UD
, 2, g0
, UQ
, 4, 4, 1, 0, true ),
2505 INST(MOV
, 4, null
, F
, 1, g0
, F
, 4, 4, 1, 0, true ),
2506 INST(MOV
, 4, acc0
, F
, 1, g0
, F
, 4, 4, 1, 0, true ),
2507 INST(MOV
, 4, g0
, F
, 1, acc0
, F
, 4, 4, 1, 0, true ),
2509 INST(MOV
, 4, null
, D
, 1, g0
, D
, 4, 4, 1, 0, true ),
2510 INST(MOV
, 4, acc0
, D
, 1, g0
, D
, 4, 4, 1, 0, true ),
2511 INST(MOV
, 4, g0
, D
, 1, acc0
, D
, 4, 4, 1, 0, true ),
2513 INST(MOV
, 4, null
, UD
, 1, g0
, UD
, 4, 4, 1, 0, true ),
2514 INST(MOV
, 4, acc0
, UD
, 1, g0
, UD
, 4, 4, 1, 0, true ),
2515 INST(MOV
, 4, g0
, UD
, 1, acc0
, UD
, 4, 4, 1, 0, true ),
2517 INST(MUL
, 4, g0
, D
, 2, g0
, D
, 4, 2, 2, 0, true ),
2518 INST(MUL
, 4, g0
, UD
, 2, g0
, UD
, 4, 2, 2, 0, true ),
2520 /* The PRMs say that for CHV, BXT:
2522 * ARF registers must never be used with 64b datatype or when
2523 * operation is integer DWord multiply.
2525 INST(MOV
, 4, acc0
, DF
, 1, g0
, F
, 4, 2, 2, 0, false),
2526 INST(MOV
, 4, g0
, DF
, 1, acc0
, F
, 4, 2, 2, 0, false),
2528 INST(MOV
, 4, acc0
, Q
, 1, g0
, D
, 4, 2, 2, 0, false),
2529 INST(MOV
, 4, g0
, Q
, 1, acc0
, D
, 4, 2, 2, 0, false),
2531 INST(MOV
, 4, acc0
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, false),
2532 INST(MOV
, 4, g0
, UQ
, 1, acc0
, UD
, 4, 2, 2, 0, false),
2534 INST(MOV
, 4, acc0
, F
, 2, g0
, DF
, 4, 4, 1, 0, false),
2535 INST(MOV
, 4, g0
, F
, 2, acc0
, DF
, 4, 4, 1, 0, false),
2537 INST(MOV
, 4, acc0
, D
, 2, g0
, Q
, 4, 4, 1, 0, false),
2538 INST(MOV
, 4, g0
, D
, 2, acc0
, Q
, 4, 4, 1, 0, false),
2540 INST(MOV
, 4, acc0
, UD
, 2, g0
, UQ
, 4, 4, 1, 0, false),
2541 INST(MOV
, 4, g0
, UD
, 2, acc0
, UQ
, 4, 4, 1, 0, false),
2543 INST(MUL
, 4, acc0
, D
, 2, g0
, D
, 4, 2, 2, 0, false),
2544 INST(MUL
, 4, acc0
, UD
, 2, g0
, UD
, 4, 2, 2, 0, false),
2545 /* MUL cannot have integer accumulator sources, so don't test that */
2547 /* We assume that the restriction does not apply to the null register */
2548 INST(MOV
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 0, true ),
2549 INST(MOV
, 4, null
, Q
, 1, g0
, D
, 4, 2, 2, 0, true ),
2550 INST(MOV
, 4, null
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, true ),
2552 /* Check implicit accumulator write control */
2553 INST(MOV
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 1, false),
2554 INST(MUL
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 1, false),
2559 /* These restrictions only apply to Gen8+ */
2560 if (devinfo
.gen
< 8)
2563 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
2564 if (!devinfo
.has_64bit_float
&&
2565 (inst
[i
].dst_type
== BRW_REGISTER_TYPE_DF
||
2566 inst
[i
].src_type
== BRW_REGISTER_TYPE_DF
))
2569 if (!devinfo
.has_64bit_int
&&
2570 (inst
[i
].dst_type
== BRW_REGISTER_TYPE_Q
||
2571 inst
[i
].dst_type
== BRW_REGISTER_TYPE_UQ
||
2572 inst
[i
].src_type
== BRW_REGISTER_TYPE_Q
||
2573 inst
[i
].src_type
== BRW_REGISTER_TYPE_UQ
))
2576 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
2577 brw_MOV(p
, retype(inst
[i
].dst
, inst
[i
].dst_type
),
2578 retype(inst
[i
].src
, inst
[i
].src_type
));
2580 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
2581 brw_MUL(p
, retype(inst
[i
].dst
, inst
[i
].dst_type
),
2582 retype(inst
[i
].src
, inst
[i
].src_type
),
2583 retype(zero
, inst
[i
].src_type
));
2584 brw_inst_set_opcode(&devinfo
, last_inst
, inst
[i
].opcode
);
2586 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
2587 brw_inst_set_acc_wr_control(&devinfo
, last_inst
, inst
[i
].acc_wr
);
2589 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
2591 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
2592 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
2593 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
2595 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
2596 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
2598 EXPECT_TRUE(validate(p
));
2601 clear_instructions(p
);
2604 if (!devinfo
.has_64bit_float
)
2607 /* MAC implicitly reads the accumulator */
2608 brw_MAC(p
, retype(g0
, BRW_REGISTER_TYPE_DF
),
2609 retype(stride(g0
, 4, 4, 1), BRW_REGISTER_TYPE_DF
),
2610 retype(stride(g0
, 4, 4, 1), BRW_REGISTER_TYPE_DF
));
2611 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
2612 EXPECT_FALSE(validate(p
));
2614 EXPECT_TRUE(validate(p
));
2618 TEST_P(validation_test
, align16_64_bit_integer
)
2620 static const struct {
2624 enum brw_reg_type dst_type
;
2625 enum brw_reg_type src_type
;
2627 bool expected_result
;
2629 #define INST(opcode, exec_size, dst_type, src_type, expected_result) \
2631 BRW_OPCODE_##opcode, \
2632 BRW_EXECUTE_##exec_size, \
2633 BRW_REGISTER_TYPE_##dst_type, \
2634 BRW_REGISTER_TYPE_##src_type, \
2638 /* Some instruction that violate no restrictions, as a control */
2639 INST(MOV
, 2, Q
, D
, true ),
2640 INST(MOV
, 2, UQ
, UD
, true ),
2641 INST(MOV
, 2, DF
, F
, true ),
2643 INST(ADD
, 2, Q
, D
, true ),
2644 INST(ADD
, 2, UQ
, UD
, true ),
2645 INST(ADD
, 2, DF
, F
, true ),
2647 /* The PRMs say that for BDW, SKL:
2649 * If Align16 is required for an operation with QW destination and non-QW
2650 * source datatypes, the execution size cannot exceed 2.
2653 INST(MOV
, 4, Q
, D
, false),
2654 INST(MOV
, 4, UQ
, UD
, false),
2655 INST(MOV
, 4, DF
, F
, false),
2657 INST(ADD
, 4, Q
, D
, false),
2658 INST(ADD
, 4, UQ
, UD
, false),
2659 INST(ADD
, 4, DF
, F
, false),
2664 /* 64-bit integer types exist on Gen8+ */
2665 if (devinfo
.gen
< 8)
2668 /* Align16 does not exist on Gen11+ */
2669 if (devinfo
.gen
>= 11)
2672 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
2674 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
2675 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
2676 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
2677 retype(g0
, inst
[i
].src_type
));
2679 assert(inst
[i
].opcode
== BRW_OPCODE_ADD
);
2680 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
2681 retype(g0
, inst
[i
].src_type
),
2682 retype(g0
, inst
[i
].src_type
));
2684 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
2686 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
2688 clear_instructions(p
);
2692 TEST_P(validation_test
, qword_low_power_no_depctrl
)
2694 static const struct {
2698 enum brw_reg_type dst_type
;
2699 unsigned dst_stride
;
2701 enum brw_reg_type src_type
;
2702 unsigned src_vstride
;
2704 unsigned src_hstride
;
2709 bool expected_result
;
2711 #define INST(opcode, exec_size, dst_type, dst_stride, \
2712 src_type, src_vstride, src_width, src_hstride, \
2713 no_dd_check, no_dd_clear, expected_result) \
2715 BRW_OPCODE_##opcode, \
2716 BRW_EXECUTE_##exec_size, \
2717 BRW_REGISTER_TYPE_##dst_type, \
2718 BRW_HORIZONTAL_STRIDE_##dst_stride, \
2719 BRW_REGISTER_TYPE_##src_type, \
2720 BRW_VERTICAL_STRIDE_##src_vstride, \
2721 BRW_WIDTH_##src_width, \
2722 BRW_HORIZONTAL_STRIDE_##src_hstride, \
2728 /* Some instruction that violate no restrictions, as a control */
2729 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 0, 0, true ),
2730 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 0, 0, true ),
2731 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 0, 0, true ),
2733 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 0, 0, true ),
2734 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 0, 0, true ),
2735 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 0, 0, true ),
2737 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 0, 0, true ),
2738 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 0, 0, true ),
2740 INST(MOV
, 4, F
, 1, F
, 4, 4, 1, 1, 1, true ),
2742 /* The PRMs say that for CHV, BXT:
2744 * When source or destination datatype is 64b or operation is integer
2745 * DWord multiply, DepCtrl must not be used.
2747 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 1, 0, false),
2748 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 1, 0, false),
2749 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 1, 0, false),
2751 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 1, 0, false),
2752 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 1, 0, false),
2753 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 1, 0, false),
2755 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 0, 1, false),
2756 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 0, 1, false),
2757 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 0, 1, false),
2759 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 0, 1, false),
2760 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 0, 1, false),
2761 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 0, 1, false),
2763 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 1, 0, false),
2764 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 1, 0, false),
2766 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 0, 1, false),
2767 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 0, 1, false),
2772 /* These restrictions only apply to Gen8+ */
2773 if (devinfo
.gen
< 8)
2776 /* NoDDChk/NoDDClr does not exist on Gen12+ */
2777 if (devinfo
.gen
>= 12)
2780 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
2781 if (!devinfo
.has_64bit_float
&&
2782 (inst
[i
].dst_type
== BRW_REGISTER_TYPE_DF
||
2783 inst
[i
].src_type
== BRW_REGISTER_TYPE_DF
))
2786 if (!devinfo
.has_64bit_int
&&
2787 (inst
[i
].dst_type
== BRW_REGISTER_TYPE_Q
||
2788 inst
[i
].dst_type
== BRW_REGISTER_TYPE_UQ
||
2789 inst
[i
].src_type
== BRW_REGISTER_TYPE_Q
||
2790 inst
[i
].src_type
== BRW_REGISTER_TYPE_UQ
))
2793 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
2794 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
2795 retype(g0
, inst
[i
].src_type
));
2797 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
2798 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
2799 retype(g0
, inst
[i
].src_type
),
2800 retype(zero
, inst
[i
].src_type
));
2802 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
2804 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
2806 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
2807 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
2808 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
2810 brw_inst_set_no_dd_check(&devinfo
, last_inst
, inst
[i
].no_dd_check
);
2811 brw_inst_set_no_dd_clear(&devinfo
, last_inst
, inst
[i
].no_dd_clear
);
2813 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
2814 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
2816 EXPECT_TRUE(validate(p
));
2819 clear_instructions(p
);
2823 TEST_P(validation_test
, gen11_no_byte_src_1_2
)
2825 static const struct {
2827 unsigned access_mode
;
2829 enum brw_reg_type dst_type
;
2831 enum brw_reg_type type
;
2838 bool expected_result
;
2840 #define INST(opcode, access_mode, dst_type, \
2841 src0_type, src0_vstride, src0_width, src0_hstride, \
2842 src1_type, src1_vstride, src1_width, src1_hstride, \
2844 gen, expected_result) \
2846 BRW_OPCODE_##opcode, \
2847 BRW_ALIGN_##access_mode, \
2848 BRW_REGISTER_TYPE_##dst_type, \
2851 BRW_REGISTER_TYPE_##src0_type, \
2852 BRW_VERTICAL_STRIDE_##src0_vstride, \
2853 BRW_WIDTH_##src0_width, \
2854 BRW_HORIZONTAL_STRIDE_##src0_hstride, \
2857 BRW_REGISTER_TYPE_##src1_type, \
2858 BRW_VERTICAL_STRIDE_##src1_vstride, \
2859 BRW_WIDTH_##src1_width, \
2860 BRW_HORIZONTAL_STRIDE_##src1_hstride, \
2863 BRW_REGISTER_TYPE_##src2_type, \
2870 /* Passes on < 11 */
2871 INST(MOV
, 16, F
, B
, 2, 4, 0, UD
, 0, 4, 0, D
, 8, true ),
2872 INST(ADD
, 16, UD
, F
, 0, 4, 0, UB
, 0, 1, 0, D
, 7, true ),
2873 INST(MAD
, 16, D
, B
, 0, 4, 0, UB
, 0, 1, 0, B
, 10, true ),
2876 INST(MAD
, 1, UB
, W
, 1, 1, 0, D
, 0, 4, 0, B
, 11, false ),
2877 INST(MAD
, 1, UB
, W
, 1, 1, 1, UB
, 1, 1, 0, W
, 11, false ),
2878 INST(ADD
, 1, W
, W
, 1, 4, 1, B
, 1, 1, 0, D
, 11, false ),
2881 INST(MOV
, 1, W
, B
, 8, 8, 1, D
, 8, 8, 1, D
, 11, true ),
2882 INST(ADD
, 1, UD
, B
, 8, 8, 1, W
, 8, 8, 1, D
, 11, true ),
2883 INST(MAD
, 1, B
, B
, 0, 1, 0, D
, 0, 4, 0, W
, 11, true ),
2889 for (unsigned i
= 0; i
< ARRAY_SIZE(inst
); i
++) {
2890 /* Skip instruction not meant for this gen. */
2891 if (devinfo
.gen
!= inst
[i
].gen
)
2894 brw_push_insn_state(p
);
2896 brw_set_default_exec_size(p
, BRW_EXECUTE_8
);
2897 brw_set_default_access_mode(p
, inst
[i
].access_mode
);
2899 switch (inst
[i
].opcode
) {
2900 case BRW_OPCODE_MOV
:
2901 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
2902 retype(g0
, inst
[i
].srcs
[0].type
));
2903 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].vstride
);
2904 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].hstride
);
2906 case BRW_OPCODE_ADD
:
2907 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
2908 retype(g0
, inst
[i
].srcs
[0].type
),
2909 retype(g0
, inst
[i
].srcs
[1].type
));
2910 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].vstride
);
2911 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].srcs
[0].width
);
2912 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].hstride
);
2913 brw_inst_set_src1_vstride(&devinfo
, last_inst
, inst
[i
].srcs
[1].vstride
);
2914 brw_inst_set_src1_width(&devinfo
, last_inst
, inst
[i
].srcs
[1].width
);
2915 brw_inst_set_src1_hstride(&devinfo
, last_inst
, inst
[i
].srcs
[1].hstride
);
2917 case BRW_OPCODE_MAD
:
2918 brw_MAD(p
, retype(g0
, inst
[i
].dst_type
),
2919 retype(g0
, inst
[i
].srcs
[0].type
),
2920 retype(g0
, inst
[i
].srcs
[1].type
),
2921 retype(g0
, inst
[i
].srcs
[2].type
));
2922 brw_inst_set_3src_a1_src0_vstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].vstride
);
2923 brw_inst_set_3src_a1_src0_hstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].hstride
);
2924 brw_inst_set_3src_a1_src1_vstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].vstride
);
2925 brw_inst_set_3src_a1_src1_hstride(&devinfo
, last_inst
, inst
[i
].srcs
[0].hstride
);
2928 unreachable("invalid opcode");
2931 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
2933 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].srcs
[0].width
);
2934 brw_inst_set_src1_width(&devinfo
, last_inst
, inst
[i
].srcs
[1].width
);
2936 brw_pop_insn_state(p
);
2938 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
2940 clear_instructions(p
);