2 * Copyright © 2016 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 #include <gtest/gtest.h>
26 #include "util/ralloc.h"
28 static const struct gen_info
{
51 class validation_test
: public ::testing::TestWithParam
<struct gen_info
> {
56 virtual ~validation_test();
58 struct brw_codegen
*p
;
59 struct gen_device_info devinfo
;
62 validation_test::validation_test()
64 p
= rzalloc(NULL
, struct brw_codegen
);
65 memset(&devinfo
, 0, sizeof(devinfo
));
68 validation_test::~validation_test()
73 void validation_test::SetUp()
75 struct gen_info info
= GetParam();
76 int devid
= gen_device_name_to_pci_device_id(info
.name
);
78 gen_get_device_info(devid
, &devinfo
);
80 brw_init_codegen(&devinfo
, p
, p
);
84 template <class ParamType
>
86 operator()(const ::testing::TestParamInfo
<ParamType
>& info
) const {
87 return info
.param
.name
;
91 INSTANTIATE_TEST_CASE_P(eu_assembly
, validation_test
,
92 ::testing::ValuesIn(gens
),
96 validate(struct brw_codegen
*p
)
98 const bool print
= getenv("TEST_DEBUG");
99 struct disasm_info
*disasm
= disasm_initialize(p
->devinfo
, NULL
);
102 disasm_new_inst_group(disasm
, 0);
103 disasm_new_inst_group(disasm
, p
->next_insn_offset
);
106 bool ret
= brw_validate_instructions(p
->devinfo
, p
->store
, 0,
107 p
->next_insn_offset
, disasm
);
110 dump_assembly(p
->store
, disasm
);
117 #define last_inst (&p->store[p->nr_insn - 1])
118 #define g0 brw_vec8_grf(0, 0)
119 #define acc0 brw_acc_reg(8)
120 #define null brw_null_reg()
121 #define zero brw_imm_f(0.0f)
124 clear_instructions(struct brw_codegen
*p
)
126 p
->next_insn_offset
= 0;
130 TEST_P(validation_test
, sanity
)
132 brw_ADD(p
, g0
, g0
, g0
);
134 EXPECT_TRUE(validate(p
));
137 TEST_P(validation_test
, src0_null_reg
)
139 brw_MOV(p
, g0
, null
);
141 EXPECT_FALSE(validate(p
));
144 TEST_P(validation_test
, src1_null_reg
)
146 brw_ADD(p
, g0
, g0
, null
);
148 EXPECT_FALSE(validate(p
));
151 TEST_P(validation_test
, math_src0_null_reg
)
153 if (devinfo
.gen
>= 6) {
154 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, null
, null
);
156 gen4_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, 0, null
, BRW_MATH_PRECISION_FULL
);
159 EXPECT_FALSE(validate(p
));
162 TEST_P(validation_test
, math_src1_null_reg
)
164 if (devinfo
.gen
>= 6) {
165 gen6_math(p
, g0
, BRW_MATH_FUNCTION_POW
, g0
, null
);
166 EXPECT_FALSE(validate(p
));
168 /* Math instructions on Gen4/5 are actually SEND messages with payloads.
169 * src1 is an immediate message descriptor set by gen4_math.
174 TEST_P(validation_test
, opcode46
)
176 /* opcode 46 is "push" on Gen 4 and 5
181 brw_next_insn(p
, 46);
183 if (devinfo
.gen
== 7) {
184 EXPECT_FALSE(validate(p
));
186 EXPECT_TRUE(validate(p
));
190 /* When the Execution Data Type is wider than the destination data type, the
191 * destination must [...] specify a HorzStride equal to the ratio in sizes of
192 * the two data types.
194 TEST_P(validation_test
, dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size
)
196 brw_ADD(p
, g0
, g0
, g0
);
197 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
198 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
199 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
201 EXPECT_FALSE(validate(p
));
203 clear_instructions(p
);
205 brw_ADD(p
, g0
, g0
, g0
);
206 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
207 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
208 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
209 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
211 EXPECT_TRUE(validate(p
));
214 /* When the Execution Data Type is wider than the destination data type, the
215 * destination must be aligned as required by the wider execution data type
218 TEST_P(validation_test
, dst_subreg_must_be_aligned_to_exec_type_size
)
220 brw_ADD(p
, g0
, g0
, g0
);
221 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 2);
222 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
223 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
224 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
225 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
227 EXPECT_FALSE(validate(p
));
229 clear_instructions(p
);
231 brw_ADD(p
, g0
, g0
, g0
);
232 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
233 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 8);
234 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
235 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
236 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
237 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
238 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
239 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
240 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
241 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
242 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
243 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
245 EXPECT_TRUE(validate(p
));
248 /* ExecSize must be greater than or equal to Width. */
249 TEST_P(validation_test
, exec_size_less_than_width
)
251 brw_ADD(p
, g0
, g0
, g0
);
252 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
254 EXPECT_FALSE(validate(p
));
256 clear_instructions(p
);
258 brw_ADD(p
, g0
, g0
, g0
);
259 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
261 EXPECT_FALSE(validate(p
));
264 /* If ExecSize = Width and HorzStride ≠ 0,
265 * VertStride must be set to Width * HorzStride.
267 TEST_P(validation_test
, vertical_stride_is_width_by_horizontal_stride
)
269 brw_ADD(p
, g0
, g0
, g0
);
270 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
272 EXPECT_FALSE(validate(p
));
274 clear_instructions(p
);
276 brw_ADD(p
, g0
, g0
, g0
);
277 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
279 EXPECT_FALSE(validate(p
));
282 /* If Width = 1, HorzStride must be 0 regardless of the values
283 * of ExecSize and VertStride.
285 TEST_P(validation_test
, horizontal_stride_must_be_0_if_width_is_1
)
287 brw_ADD(p
, g0
, g0
, g0
);
288 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
289 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
290 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
292 EXPECT_FALSE(validate(p
));
294 clear_instructions(p
);
296 brw_ADD(p
, g0
, g0
, g0
);
297 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
298 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
299 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
301 EXPECT_FALSE(validate(p
));
304 /* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */
305 TEST_P(validation_test
, scalar_region_must_be_0_1_0
)
307 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
309 brw_ADD(p
, g0
, g0
, g0_0
);
310 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
311 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
312 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
313 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
315 EXPECT_FALSE(validate(p
));
317 clear_instructions(p
);
319 brw_ADD(p
, g0
, g0_0
, g0
);
320 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
321 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
322 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
323 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
325 EXPECT_FALSE(validate(p
));
328 /* If VertStride = HorzStride = 0, Width must be 1 regardless of the value
331 TEST_P(validation_test
, zero_stride_implies_0_1_0
)
333 brw_ADD(p
, g0
, g0
, g0
);
334 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
335 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
336 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
338 EXPECT_FALSE(validate(p
));
340 clear_instructions(p
);
342 brw_ADD(p
, g0
, g0
, g0
);
343 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
344 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
345 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
347 EXPECT_FALSE(validate(p
));
350 /* Dst.HorzStride must not be 0. */
351 TEST_P(validation_test
, dst_horizontal_stride_0
)
353 brw_ADD(p
, g0
, g0
, g0
);
354 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
356 EXPECT_FALSE(validate(p
));
358 clear_instructions(p
);
360 /* Align16 does not exist on Gen11+ */
361 if (devinfo
.gen
>= 11)
364 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
366 brw_ADD(p
, g0
, g0
, g0
);
367 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
369 EXPECT_FALSE(validate(p
));
372 /* VertStride must be used to cross BRW_GENERAL_REGISTER_FILE register boundaries. This rule implies
373 * that elements within a 'Width' cannot cross BRW_GENERAL_REGISTER_FILE boundaries.
375 TEST_P(validation_test
, must_not_cross_grf_boundary_in_a_width
)
377 brw_ADD(p
, g0
, g0
, g0
);
378 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 4);
380 EXPECT_FALSE(validate(p
));
382 clear_instructions(p
);
384 brw_ADD(p
, g0
, g0
, g0
);
385 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 4);
387 EXPECT_FALSE(validate(p
));
389 clear_instructions(p
);
391 brw_ADD(p
, g0
, g0
, g0
);
392 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
393 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
394 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
396 EXPECT_FALSE(validate(p
));
398 clear_instructions(p
);
400 brw_ADD(p
, g0
, g0
, g0
);
401 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
402 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
403 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
405 EXPECT_FALSE(validate(p
));
408 /* Destination Horizontal must be 1 in Align16 */
409 TEST_P(validation_test
, dst_hstride_on_align16_must_be_1
)
411 /* Align16 does not exist on Gen11+ */
412 if (devinfo
.gen
>= 11)
415 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
417 brw_ADD(p
, g0
, g0
, g0
);
418 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
420 EXPECT_FALSE(validate(p
));
422 clear_instructions(p
);
424 brw_ADD(p
, g0
, g0
, g0
);
425 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
427 EXPECT_TRUE(validate(p
));
430 /* VertStride must be 0 or 4 in Align16 */
431 TEST_P(validation_test
, vstride_on_align16_must_be_0_or_4
)
433 /* Align16 does not exist on Gen11+ */
434 if (devinfo
.gen
>= 11)
438 enum brw_vertical_stride vstride
;
439 bool expected_result
;
441 { BRW_VERTICAL_STRIDE_0
, true },
442 { BRW_VERTICAL_STRIDE_1
, false },
443 { BRW_VERTICAL_STRIDE_2
, devinfo
.is_haswell
|| devinfo
.gen
>= 8 },
444 { BRW_VERTICAL_STRIDE_4
, true },
445 { BRW_VERTICAL_STRIDE_8
, false },
446 { BRW_VERTICAL_STRIDE_16
, false },
447 { BRW_VERTICAL_STRIDE_32
, false },
448 { BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL
, false },
451 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
453 for (unsigned i
= 0; i
< sizeof(vstride
) / sizeof(vstride
[0]); i
++) {
454 brw_ADD(p
, g0
, g0
, g0
);
455 brw_inst_set_src0_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
457 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
459 clear_instructions(p
);
462 for (unsigned i
= 0; i
< sizeof(vstride
) / sizeof(vstride
[0]); i
++) {
463 brw_ADD(p
, g0
, g0
, g0
);
464 brw_inst_set_src1_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
466 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
468 clear_instructions(p
);
472 /* In Direct Addressing mode, a source cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE
475 TEST_P(validation_test
, source_cannot_span_more_than_2_registers
)
477 brw_ADD(p
, g0
, g0
, g0
);
478 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
479 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
480 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
481 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
482 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
483 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
484 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
486 EXPECT_FALSE(validate(p
));
488 clear_instructions(p
);
490 brw_ADD(p
, g0
, g0
, g0
);
491 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
492 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
493 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
494 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
495 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
496 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
497 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
498 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 2);
500 EXPECT_TRUE(validate(p
));
502 clear_instructions(p
);
504 brw_ADD(p
, g0
, g0
, g0
);
505 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
507 EXPECT_TRUE(validate(p
));
510 /* A destination cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE registers. */
511 TEST_P(validation_test
, destination_cannot_span_more_than_2_registers
)
513 brw_ADD(p
, g0
, g0
, g0
);
514 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
515 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
516 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
517 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
518 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
520 EXPECT_FALSE(validate(p
));
522 clear_instructions(p
);
524 brw_ADD(p
, g0
, g0
, g0
);
525 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_8
);
526 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 6);
527 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
528 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
529 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
530 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
531 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
532 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
533 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
534 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
535 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
536 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
538 EXPECT_TRUE(validate(p
));
541 TEST_P(validation_test
, src_region_spans_two_regs_dst_region_spans_one
)
543 /* Writes to dest are to the lower OWord */
544 brw_ADD(p
, g0
, g0
, g0
);
545 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
546 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
547 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
548 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
549 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
550 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
552 EXPECT_TRUE(validate(p
));
554 clear_instructions(p
);
556 /* Writes to dest are to the upper OWord */
557 brw_ADD(p
, g0
, g0
, g0
);
558 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 16);
559 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
560 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
561 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
562 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
563 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
564 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
566 EXPECT_TRUE(validate(p
));
568 clear_instructions(p
);
570 /* Writes to dest are evenly split between OWords */
571 brw_ADD(p
, g0
, g0
, g0
);
572 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
573 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
574 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
575 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
576 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
577 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
578 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
580 EXPECT_TRUE(validate(p
));
582 clear_instructions(p
);
584 /* Writes to dest are uneven between OWords */
585 brw_ADD(p
, g0
, g0
, g0
);
586 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
587 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 10);
588 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
589 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
590 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
591 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
592 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
593 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
594 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
595 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
596 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
598 if (devinfo
.gen
>= 9) {
599 EXPECT_TRUE(validate(p
));
601 EXPECT_FALSE(validate(p
));
605 TEST_P(validation_test
, dst_elements_must_be_evenly_split_between_registers
)
607 brw_ADD(p
, g0
, g0
, g0
);
608 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
610 if (devinfo
.gen
>= 9) {
611 EXPECT_TRUE(validate(p
));
613 EXPECT_FALSE(validate(p
));
616 clear_instructions(p
);
618 brw_ADD(p
, g0
, g0
, g0
);
619 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
621 EXPECT_TRUE(validate(p
));
623 clear_instructions(p
);
625 if (devinfo
.gen
>= 6) {
626 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
628 EXPECT_TRUE(validate(p
));
630 clear_instructions(p
);
632 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
633 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
635 EXPECT_FALSE(validate(p
));
639 TEST_P(validation_test
, two_src_two_dst_source_offsets_must_be_same
)
641 brw_ADD(p
, g0
, g0
, g0
);
642 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
643 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
644 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 16);
645 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_2
);
646 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
647 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
648 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
649 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
650 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
652 if (devinfo
.gen
<= 7) {
653 EXPECT_FALSE(validate(p
));
655 EXPECT_TRUE(validate(p
));
658 clear_instructions(p
);
660 brw_ADD(p
, g0
, g0
, g0
);
661 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
662 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
663 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
664 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
665 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
666 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_8
);
667 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
668 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
670 EXPECT_TRUE(validate(p
));
673 TEST_P(validation_test
, two_src_two_dst_each_dst_must_be_derived_from_one_src
)
676 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
677 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
678 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
679 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
680 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 8);
681 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
682 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
683 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
685 if (devinfo
.gen
<= 7) {
686 EXPECT_FALSE(validate(p
));
688 EXPECT_TRUE(validate(p
));
691 clear_instructions(p
);
694 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 16);
695 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 8);
696 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_2
);
697 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
698 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
700 if (devinfo
.gen
<= 7) {
701 EXPECT_FALSE(validate(p
));
703 EXPECT_TRUE(validate(p
));
707 TEST_P(validation_test
, one_src_two_dst
)
709 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
711 brw_ADD(p
, g0
, g0_0
, g0_0
);
712 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
714 EXPECT_TRUE(validate(p
));
716 clear_instructions(p
);
718 brw_ADD(p
, g0
, g0
, g0
);
719 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
720 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
721 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
722 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
724 EXPECT_TRUE(validate(p
));
726 clear_instructions(p
);
728 brw_ADD(p
, g0
, g0
, g0
);
729 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
730 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
731 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
732 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
733 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
734 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
735 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
736 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
738 if (devinfo
.gen
>= 8) {
739 EXPECT_TRUE(validate(p
));
741 EXPECT_FALSE(validate(p
));
744 clear_instructions(p
);
746 brw_ADD(p
, g0
, g0
, g0
);
747 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
748 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
749 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
750 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
751 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
752 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
753 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
754 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
756 if (devinfo
.gen
>= 8) {
757 EXPECT_TRUE(validate(p
));
759 EXPECT_FALSE(validate(p
));
763 TEST_P(validation_test
, packed_byte_destination
)
765 static const struct {
766 enum brw_reg_type dst_type
;
767 enum brw_reg_type src_type
;
769 bool expected_result
;
771 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 0, 0, true },
772 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 0, 0, true },
773 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 0, 0, true },
774 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 0, 0, true },
776 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 1, 0, 0, false },
777 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 1, 0, 0, false },
778 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 1, 0, 0, false },
779 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 1, 0, 0, false },
781 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 1, 0, false },
782 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 1, 0, false },
783 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 1, 0, false },
784 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 1, 0, false },
786 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 0, 1, false },
787 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 0, 1, false },
788 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 0, 1, false },
789 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 0, 1, false },
791 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UW
, 0, 0, 0, false },
792 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_W
, 0, 0, 0, false },
793 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UD
, 0, 0, 0, false },
794 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_D
, 0, 0, 0, false },
797 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
798 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(g0
, move
[i
].src_type
));
799 brw_inst_set_src0_negate(&devinfo
, last_inst
, move
[i
].neg
);
800 brw_inst_set_src0_abs(&devinfo
, last_inst
, move
[i
].abs
);
801 brw_inst_set_saturate(&devinfo
, last_inst
, move
[i
].sat
);
803 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
805 clear_instructions(p
);
808 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_UB
),
809 retype(g0
, BRW_REGISTER_TYPE_UB
),
810 retype(g0
, BRW_REGISTER_TYPE_UB
));
811 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
813 EXPECT_FALSE(validate(p
));
815 clear_instructions(p
);
817 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
818 retype(g0
, BRW_REGISTER_TYPE_B
),
819 retype(g0
, BRW_REGISTER_TYPE_B
));
820 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
822 EXPECT_FALSE(validate(p
));
825 TEST_P(validation_test
, byte_destination_relaxed_alignment
)
827 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
828 retype(g0
, BRW_REGISTER_TYPE_W
),
829 retype(g0
, BRW_REGISTER_TYPE_W
));
830 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
831 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
833 EXPECT_TRUE(validate(p
));
835 clear_instructions(p
);
837 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
838 retype(g0
, BRW_REGISTER_TYPE_W
),
839 retype(g0
, BRW_REGISTER_TYPE_W
));
840 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
841 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
842 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 1);
844 if (devinfo
.gen
> 4 || devinfo
.is_g4x
) {
845 EXPECT_TRUE(validate(p
));
847 EXPECT_FALSE(validate(p
));
851 TEST_P(validation_test
, vector_immediate_destination_alignment
)
853 static const struct {
854 enum brw_reg_type dst_type
;
855 enum brw_reg_type src_type
;
858 bool expected_result
;
860 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 0, BRW_EXECUTE_4
, true },
861 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 16, BRW_EXECUTE_4
, true },
862 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 1, BRW_EXECUTE_4
, false },
864 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 0, BRW_EXECUTE_8
, true },
865 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 16, BRW_EXECUTE_8
, true },
866 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 1, BRW_EXECUTE_8
, false },
868 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 0, BRW_EXECUTE_8
, true },
869 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 16, BRW_EXECUTE_8
, true },
870 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 1, BRW_EXECUTE_8
, false },
873 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
874 /* UV type is Gen6+ */
875 if (devinfo
.gen
< 6 &&
876 move
[i
].src_type
== BRW_REGISTER_TYPE_UV
)
879 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(zero
, move
[i
].src_type
));
880 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, move
[i
].subnr
);
881 brw_inst_set_exec_size(&devinfo
, last_inst
, move
[i
].exec_size
);
883 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
885 clear_instructions(p
);
889 TEST_P(validation_test
, vector_immediate_destination_stride
)
891 static const struct {
892 enum brw_reg_type dst_type
;
893 enum brw_reg_type src_type
;
895 bool expected_result
;
897 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_1
, true },
898 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, false },
899 { BRW_REGISTER_TYPE_D
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_1
, true },
900 { BRW_REGISTER_TYPE_D
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, false },
901 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, true },
902 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_4
, true },
904 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_1
, true },
905 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_2
, false },
906 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_4
, false },
907 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_2
, true },
909 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_1
, true },
910 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_2
, false },
911 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_4
, false },
912 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_2
, true },
915 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
916 /* UV type is Gen6+ */
917 if (devinfo
.gen
< 6 &&
918 move
[i
].src_type
== BRW_REGISTER_TYPE_UV
)
921 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(zero
, move
[i
].src_type
));
922 brw_inst_set_dst_hstride(&devinfo
, last_inst
, move
[i
].stride
);
924 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
926 clear_instructions(p
);
930 TEST_P(validation_test
, qword_low_power_align1_regioning_restrictions
)
932 static const struct {
936 enum brw_reg_type dst_type
;
940 enum brw_reg_type src_type
;
942 unsigned src_vstride
;
944 unsigned src_hstride
;
946 bool expected_result
;
948 #define INST(opcode, exec_size, dst_type, dst_subreg, dst_stride, src_type, \
949 src_subreg, src_vstride, src_width, src_hstride, expected_result) \
951 BRW_OPCODE_##opcode, \
952 BRW_EXECUTE_##exec_size, \
953 BRW_REGISTER_TYPE_##dst_type, \
955 BRW_HORIZONTAL_STRIDE_##dst_stride, \
956 BRW_REGISTER_TYPE_##src_type, \
958 BRW_VERTICAL_STRIDE_##src_vstride, \
959 BRW_WIDTH_##src_width, \
960 BRW_HORIZONTAL_STRIDE_##src_hstride, \
964 /* Some instruction that violate no restrictions, as a control */
965 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 4, 4, 1, true ),
966 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 4, 4, 1, true ),
967 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 4, 4, 1, true ),
969 INST(MOV
, 4, DF
, 0, 1, F
, 0, 8, 4, 2, true ),
970 INST(MOV
, 4, Q
, 0, 1, D
, 0, 8, 4, 2, true ),
971 INST(MOV
, 4, UQ
, 0, 1, UD
, 0, 8, 4, 2, true ),
973 INST(MOV
, 4, F
, 0, 2, DF
, 0, 4, 4, 1, true ),
974 INST(MOV
, 4, D
, 0, 2, Q
, 0, 4, 4, 1, true ),
975 INST(MOV
, 4, UD
, 0, 2, UQ
, 0, 4, 4, 1, true ),
977 INST(MUL
, 8, D
, 0, 2, D
, 0, 8, 4, 2, true ),
978 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 8, 4, 2, true ),
980 /* Something with subreg nrs */
981 INST(MOV
, 2, DF
, 8, 1, DF
, 8, 2, 2, 1, true ),
982 INST(MOV
, 2, Q
, 8, 1, Q
, 8, 2, 2, 1, true ),
983 INST(MOV
, 2, UQ
, 8, 1, UQ
, 8, 2, 2, 1, true ),
985 INST(MUL
, 2, D
, 4, 2, D
, 4, 4, 2, 2, true ),
986 INST(MUL
, 2, UD
, 4, 2, UD
, 4, 4, 2, 2, true ),
988 /* The PRMs say that for CHV, BXT:
990 * When source or destination datatype is 64b or operation is integer
991 * DWord multiply, regioning in Align1 must follow these rules:
993 * 1. Source and Destination horizontal stride must be aligned to the
996 INST(MOV
, 4, DF
, 0, 2, DF
, 0, 4, 4, 1, false),
997 INST(MOV
, 4, Q
, 0, 2, Q
, 0, 4, 4, 1, false),
998 INST(MOV
, 4, UQ
, 0, 2, UQ
, 0, 4, 4, 1, false),
1000 INST(MOV
, 4, DF
, 0, 2, F
, 0, 8, 4, 2, false),
1001 INST(MOV
, 4, Q
, 0, 2, D
, 0, 8, 4, 2, false),
1002 INST(MOV
, 4, UQ
, 0, 2, UD
, 0, 8, 4, 2, false),
1004 INST(MOV
, 4, DF
, 0, 2, F
, 0, 4, 4, 1, false),
1005 INST(MOV
, 4, Q
, 0, 2, D
, 0, 4, 4, 1, false),
1006 INST(MOV
, 4, UQ
, 0, 2, UD
, 0, 4, 4, 1, false),
1008 INST(MUL
, 4, D
, 0, 2, D
, 0, 4, 4, 1, false),
1009 INST(MUL
, 4, UD
, 0, 2, UD
, 0, 4, 4, 1, false),
1011 INST(MUL
, 4, D
, 0, 1, D
, 0, 8, 4, 2, false),
1012 INST(MUL
, 4, UD
, 0, 1, UD
, 0, 8, 4, 2, false),
1014 /* 2. Regioning must ensure Src.Vstride = Src.Width * Src.Hstride. */
1015 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 0, 2, 1, false),
1016 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 0, 2, 1, false),
1017 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 0, 2, 1, false),
1019 INST(MOV
, 4, DF
, 0, 1, F
, 0, 0, 2, 2, false),
1020 INST(MOV
, 4, Q
, 0, 1, D
, 0, 0, 2, 2, false),
1021 INST(MOV
, 4, UQ
, 0, 1, UD
, 0, 0, 2, 2, false),
1023 INST(MOV
, 8, F
, 0, 2, DF
, 0, 0, 2, 1, false),
1024 INST(MOV
, 8, D
, 0, 2, Q
, 0, 0, 2, 1, false),
1025 INST(MOV
, 8, UD
, 0, 2, UQ
, 0, 0, 2, 1, false),
1027 INST(MUL
, 8, D
, 0, 2, D
, 0, 0, 4, 2, false),
1028 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 0, 4, 2, false),
1030 INST(MUL
, 8, D
, 0, 2, D
, 0, 0, 4, 2, false),
1031 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 0, 4, 2, false),
1033 /* 3. Source and Destination offset must be the same, except the case
1036 INST(MOV
, 2, DF
, 8, 1, DF
, 0, 2, 2, 1, false),
1037 INST(MOV
, 2, Q
, 8, 1, Q
, 0, 2, 2, 1, false),
1038 INST(MOV
, 2, UQ
, 8, 1, UQ
, 0, 2, 2, 1, false),
1040 INST(MOV
, 2, DF
, 0, 1, DF
, 8, 2, 2, 1, false),
1041 INST(MOV
, 2, Q
, 0, 1, Q
, 8, 2, 2, 1, false),
1042 INST(MOV
, 2, UQ
, 0, 1, UQ
, 8, 2, 2, 1, false),
1044 INST(MUL
, 4, D
, 4, 2, D
, 0, 4, 2, 2, false),
1045 INST(MUL
, 4, UD
, 4, 2, UD
, 0, 4, 2, 2, false),
1047 INST(MUL
, 4, D
, 0, 2, D
, 4, 4, 2, 2, false),
1048 INST(MUL
, 4, UD
, 0, 2, UD
, 4, 4, 2, 2, false),
1050 INST(MOV
, 2, DF
, 8, 1, DF
, 0, 0, 1, 0, true ),
1051 INST(MOV
, 2, Q
, 8, 1, Q
, 0, 0, 1, 0, true ),
1052 INST(MOV
, 2, UQ
, 8, 1, UQ
, 0, 0, 1, 0, true ),
1054 INST(MOV
, 2, DF
, 8, 1, F
, 4, 0, 1, 0, true ),
1055 INST(MOV
, 2, Q
, 8, 1, D
, 4, 0, 1, 0, true ),
1056 INST(MOV
, 2, UQ
, 8, 1, UD
, 4, 0, 1, 0, true ),
1058 INST(MUL
, 4, D
, 4, 1, D
, 0, 0, 1, 0, true ),
1059 INST(MUL
, 4, UD
, 4, 1, UD
, 0, 0, 1, 0, true ),
1061 INST(MUL
, 4, D
, 0, 1, D
, 4, 0, 1, 0, true ),
1062 INST(MUL
, 4, UD
, 0, 1, UD
, 4, 0, 1, 0, true ),
1067 /* These restrictions only apply to Gen8+ */
1068 if (devinfo
.gen
< 8)
1071 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1072 if (!devinfo
.has_64bit_types
&&
1073 (type_sz(inst
[i
].dst_type
) == 8 || type_sz(inst
[i
].src_type
) == 8))
1076 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1077 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
1078 retype(g0
, inst
[i
].src_type
));
1080 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
1081 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
1082 retype(g0
, inst
[i
].src_type
),
1083 retype(zero
, inst
[i
].src_type
));
1085 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1087 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].dst_subreg
);
1088 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].src_subreg
);
1090 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1092 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
1093 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
1094 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
1096 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1097 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1099 EXPECT_TRUE(validate(p
));
1102 clear_instructions(p
);
1106 TEST_P(validation_test
, qword_low_power_no_indirect_addressing
)
1108 static const struct {
1112 enum brw_reg_type dst_type
;
1113 bool dst_is_indirect
;
1114 unsigned dst_stride
;
1116 enum brw_reg_type src_type
;
1117 bool src_is_indirect
;
1118 unsigned src_vstride
;
1120 unsigned src_hstride
;
1122 bool expected_result
;
1124 #define INST(opcode, exec_size, dst_type, dst_is_indirect, dst_stride, \
1125 src_type, src_is_indirect, src_vstride, src_width, src_hstride, \
1128 BRW_OPCODE_##opcode, \
1129 BRW_EXECUTE_##exec_size, \
1130 BRW_REGISTER_TYPE_##dst_type, \
1132 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1133 BRW_REGISTER_TYPE_##src_type, \
1135 BRW_VERTICAL_STRIDE_##src_vstride, \
1136 BRW_WIDTH_##src_width, \
1137 BRW_HORIZONTAL_STRIDE_##src_hstride, \
1141 /* Some instruction that violate no restrictions, as a control */
1142 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 4, 4, 1, true ),
1143 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 4, 4, 1, true ),
1144 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 4, 4, 1, true ),
1146 INST(MUL
, 8, D
, 0, 2, D
, 0, 8, 4, 2, true ),
1147 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 8, 4, 2, true ),
1149 INST(MOV
, 4, F
, 1, 1, F
, 0, 4, 4, 1, true ),
1150 INST(MOV
, 4, F
, 0, 1, F
, 1, 4, 4, 1, true ),
1151 INST(MOV
, 4, F
, 1, 1, F
, 1, 4, 4, 1, true ),
1153 /* The PRMs say that for CHV, BXT:
1155 * When source or destination datatype is 64b or operation is integer
1156 * DWord multiply, indirect addressing must not be used.
1158 INST(MOV
, 4, DF
, 1, 1, DF
, 0, 4, 4, 1, false),
1159 INST(MOV
, 4, Q
, 1, 1, Q
, 0, 4, 4, 1, false),
1160 INST(MOV
, 4, UQ
, 1, 1, UQ
, 0, 4, 4, 1, false),
1162 INST(MOV
, 4, DF
, 0, 1, DF
, 1, 4, 4, 1, false),
1163 INST(MOV
, 4, Q
, 0, 1, Q
, 1, 4, 4, 1, false),
1164 INST(MOV
, 4, UQ
, 0, 1, UQ
, 1, 4, 4, 1, false),
1166 INST(MOV
, 4, DF
, 1, 1, F
, 0, 8, 4, 2, false),
1167 INST(MOV
, 4, Q
, 1, 1, D
, 0, 8, 4, 2, false),
1168 INST(MOV
, 4, UQ
, 1, 1, UD
, 0, 8, 4, 2, false),
1170 INST(MOV
, 4, DF
, 0, 1, F
, 1, 8, 4, 2, false),
1171 INST(MOV
, 4, Q
, 0, 1, D
, 1, 8, 4, 2, false),
1172 INST(MOV
, 4, UQ
, 0, 1, UD
, 1, 8, 4, 2, false),
1174 INST(MOV
, 4, F
, 1, 2, DF
, 0, 4, 4, 1, false),
1175 INST(MOV
, 4, D
, 1, 2, Q
, 0, 4, 4, 1, false),
1176 INST(MOV
, 4, UD
, 1, 2, UQ
, 0, 4, 4, 1, false),
1178 INST(MOV
, 4, F
, 0, 2, DF
, 1, 4, 4, 1, false),
1179 INST(MOV
, 4, D
, 0, 2, Q
, 1, 4, 4, 1, false),
1180 INST(MOV
, 4, UD
, 0, 2, UQ
, 1, 4, 4, 1, false),
1182 INST(MUL
, 8, D
, 1, 2, D
, 0, 8, 4, 2, false),
1183 INST(MUL
, 8, UD
, 1, 2, UD
, 0, 8, 4, 2, false),
1185 INST(MUL
, 8, D
, 0, 2, D
, 1, 8, 4, 2, false),
1186 INST(MUL
, 8, UD
, 0, 2, UD
, 1, 8, 4, 2, false),
1191 /* These restrictions only apply to Gen8+ */
1192 if (devinfo
.gen
< 8)
1195 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1196 if (!devinfo
.has_64bit_types
&&
1197 (type_sz(inst
[i
].dst_type
) == 8 || type_sz(inst
[i
].src_type
) == 8))
1200 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1201 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
1202 retype(g0
, inst
[i
].src_type
));
1204 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
1205 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
1206 retype(g0
, inst
[i
].src_type
),
1207 retype(zero
, inst
[i
].src_type
));
1209 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1211 brw_inst_set_dst_address_mode(&devinfo
, last_inst
, inst
[i
].dst_is_indirect
);
1212 brw_inst_set_src0_address_mode(&devinfo
, last_inst
, inst
[i
].src_is_indirect
);
1214 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1216 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
1217 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
1218 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
1220 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1221 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1223 EXPECT_TRUE(validate(p
));
1226 clear_instructions(p
);
1230 TEST_P(validation_test
, qword_low_power_no_64bit_arf
)
1232 static const struct {
1237 enum brw_reg_type dst_type
;
1238 unsigned dst_stride
;
1241 enum brw_reg_type src_type
;
1242 unsigned src_vstride
;
1244 unsigned src_hstride
;
1247 bool expected_result
;
1249 #define INST(opcode, exec_size, dst, dst_type, dst_stride, \
1250 src, src_type, src_vstride, src_width, src_hstride, \
1251 acc_wr, expected_result) \
1253 BRW_OPCODE_##opcode, \
1254 BRW_EXECUTE_##exec_size, \
1256 BRW_REGISTER_TYPE_##dst_type, \
1257 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1259 BRW_REGISTER_TYPE_##src_type, \
1260 BRW_VERTICAL_STRIDE_##src_vstride, \
1261 BRW_WIDTH_##src_width, \
1262 BRW_HORIZONTAL_STRIDE_##src_hstride, \
1267 /* Some instruction that violate no restrictions, as a control */
1268 INST(MOV
, 4, g0
, DF
, 1, g0
, F
, 4, 2, 2, 0, true ),
1269 INST(MOV
, 4, g0
, F
, 2, g0
, DF
, 4, 4, 1, 0, true ),
1271 INST(MOV
, 4, g0
, Q
, 1, g0
, D
, 4, 2, 2, 0, true ),
1272 INST(MOV
, 4, g0
, D
, 2, g0
, Q
, 4, 4, 1, 0, true ),
1274 INST(MOV
, 4, g0
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, true ),
1275 INST(MOV
, 4, g0
, UD
, 2, g0
, UQ
, 4, 4, 1, 0, true ),
1277 INST(MOV
, 4, null
, F
, 1, g0
, F
, 4, 4, 1, 0, true ),
1278 INST(MOV
, 4, acc0
, F
, 1, g0
, F
, 4, 4, 1, 0, true ),
1279 INST(MOV
, 4, g0
, F
, 1, acc0
, F
, 4, 4, 1, 0, true ),
1281 INST(MOV
, 4, null
, D
, 1, g0
, D
, 4, 4, 1, 0, true ),
1282 INST(MOV
, 4, acc0
, D
, 1, g0
, D
, 4, 4, 1, 0, true ),
1283 INST(MOV
, 4, g0
, D
, 1, acc0
, D
, 4, 4, 1, 0, true ),
1285 INST(MOV
, 4, null
, UD
, 1, g0
, UD
, 4, 4, 1, 0, true ),
1286 INST(MOV
, 4, acc0
, UD
, 1, g0
, UD
, 4, 4, 1, 0, true ),
1287 INST(MOV
, 4, g0
, UD
, 1, acc0
, UD
, 4, 4, 1, 0, true ),
1289 INST(MUL
, 4, g0
, D
, 2, g0
, D
, 4, 2, 2, 0, true ),
1290 INST(MUL
, 4, g0
, UD
, 2, g0
, UD
, 4, 2, 2, 0, true ),
1292 /* The PRMs say that for CHV, BXT:
1294 * ARF registers must never be used with 64b datatype or when
1295 * operation is integer DWord multiply.
1297 INST(MOV
, 4, acc0
, DF
, 1, g0
, F
, 4, 2, 2, 0, false),
1298 INST(MOV
, 4, g0
, DF
, 1, acc0
, F
, 4, 2, 2, 0, false),
1300 INST(MOV
, 4, acc0
, Q
, 1, g0
, D
, 4, 2, 2, 0, false),
1301 INST(MOV
, 4, g0
, Q
, 1, acc0
, D
, 4, 2, 2, 0, false),
1303 INST(MOV
, 4, acc0
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, false),
1304 INST(MOV
, 4, g0
, UQ
, 1, acc0
, UD
, 4, 2, 2, 0, false),
1306 INST(MOV
, 4, acc0
, F
, 2, g0
, DF
, 4, 4, 1, 0, false),
1307 INST(MOV
, 4, g0
, F
, 2, acc0
, DF
, 4, 4, 1, 0, false),
1309 INST(MOV
, 4, acc0
, D
, 2, g0
, Q
, 4, 4, 1, 0, false),
1310 INST(MOV
, 4, g0
, D
, 2, acc0
, Q
, 4, 4, 1, 0, false),
1312 INST(MOV
, 4, acc0
, UD
, 2, g0
, UQ
, 4, 4, 1, 0, false),
1313 INST(MOV
, 4, g0
, UD
, 2, acc0
, UQ
, 4, 4, 1, 0, false),
1315 INST(MUL
, 4, acc0
, D
, 2, g0
, D
, 4, 2, 2, 0, false),
1316 INST(MUL
, 4, acc0
, UD
, 2, g0
, UD
, 4, 2, 2, 0, false),
1317 /* MUL cannot have integer accumulator sources, so don't test that */
1319 /* We assume that the restriction does not apply to the null register */
1320 INST(MOV
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 0, true ),
1321 INST(MOV
, 4, null
, Q
, 1, g0
, D
, 4, 2, 2, 0, true ),
1322 INST(MOV
, 4, null
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, true ),
1324 /* Check implicit accumulator write control */
1325 INST(MOV
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 1, false),
1326 INST(MUL
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 1, false),
1331 /* These restrictions only apply to Gen8+ */
1332 if (devinfo
.gen
< 8)
1335 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1336 if (!devinfo
.has_64bit_types
&&
1337 (type_sz(inst
[i
].dst_type
) == 8 || type_sz(inst
[i
].src_type
) == 8))
1340 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1341 brw_MOV(p
, retype(inst
[i
].dst
, inst
[i
].dst_type
),
1342 retype(inst
[i
].src
, inst
[i
].src_type
));
1344 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
1345 brw_MUL(p
, retype(inst
[i
].dst
, inst
[i
].dst_type
),
1346 retype(inst
[i
].src
, inst
[i
].src_type
),
1347 retype(zero
, inst
[i
].src_type
));
1348 brw_inst_set_opcode(&devinfo
, last_inst
, inst
[i
].opcode
);
1350 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1351 brw_inst_set_acc_wr_control(&devinfo
, last_inst
, inst
[i
].acc_wr
);
1353 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1355 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
1356 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
1357 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
1359 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1360 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1362 EXPECT_TRUE(validate(p
));
1365 clear_instructions(p
);
1368 if (!devinfo
.has_64bit_types
)
1371 /* MAC implicitly reads the accumulator */
1372 brw_MAC(p
, retype(g0
, BRW_REGISTER_TYPE_DF
),
1373 retype(stride(g0
, 4, 4, 1), BRW_REGISTER_TYPE_DF
),
1374 retype(stride(g0
, 4, 4, 1), BRW_REGISTER_TYPE_DF
));
1375 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1376 EXPECT_FALSE(validate(p
));
1378 EXPECT_TRUE(validate(p
));
1382 TEST_P(validation_test
, align16_64_bit_integer
)
1384 static const struct {
1388 enum brw_reg_type dst_type
;
1389 enum brw_reg_type src_type
;
1391 bool expected_result
;
1393 #define INST(opcode, exec_size, dst_type, src_type, expected_result) \
1395 BRW_OPCODE_##opcode, \
1396 BRW_EXECUTE_##exec_size, \
1397 BRW_REGISTER_TYPE_##dst_type, \
1398 BRW_REGISTER_TYPE_##src_type, \
1402 /* Some instruction that violate no restrictions, as a control */
1403 INST(MOV
, 2, Q
, D
, true ),
1404 INST(MOV
, 2, UQ
, UD
, true ),
1405 INST(MOV
, 2, DF
, F
, true ),
1407 INST(ADD
, 2, Q
, D
, true ),
1408 INST(ADD
, 2, UQ
, UD
, true ),
1409 INST(ADD
, 2, DF
, F
, true ),
1411 /* The PRMs say that for BDW, SKL:
1413 * If Align16 is required for an operation with QW destination and non-QW
1414 * source datatypes, the execution size cannot exceed 2.
1417 INST(MOV
, 4, Q
, D
, false),
1418 INST(MOV
, 4, UQ
, UD
, false),
1419 INST(MOV
, 4, DF
, F
, false),
1421 INST(ADD
, 4, Q
, D
, false),
1422 INST(ADD
, 4, UQ
, UD
, false),
1423 INST(ADD
, 4, DF
, F
, false),
1428 /* 64-bit integer types exist on Gen8+ */
1429 if (devinfo
.gen
< 8)
1432 /* Align16 does not exist on Gen11+ */
1433 if (devinfo
.gen
>= 11)
1436 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
1438 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1439 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1440 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
1441 retype(g0
, inst
[i
].src_type
));
1443 assert(inst
[i
].opcode
== BRW_OPCODE_ADD
);
1444 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1445 retype(g0
, inst
[i
].src_type
),
1446 retype(g0
, inst
[i
].src_type
));
1448 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1450 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1452 clear_instructions(p
);
1456 TEST_P(validation_test
, qword_low_power_no_depctrl
)
1458 static const struct {
1462 enum brw_reg_type dst_type
;
1463 unsigned dst_stride
;
1465 enum brw_reg_type src_type
;
1466 unsigned src_vstride
;
1468 unsigned src_hstride
;
1473 bool expected_result
;
1475 #define INST(opcode, exec_size, dst_type, dst_stride, \
1476 src_type, src_vstride, src_width, src_hstride, \
1477 no_dd_check, no_dd_clear, expected_result) \
1479 BRW_OPCODE_##opcode, \
1480 BRW_EXECUTE_##exec_size, \
1481 BRW_REGISTER_TYPE_##dst_type, \
1482 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1483 BRW_REGISTER_TYPE_##src_type, \
1484 BRW_VERTICAL_STRIDE_##src_vstride, \
1485 BRW_WIDTH_##src_width, \
1486 BRW_HORIZONTAL_STRIDE_##src_hstride, \
1492 /* Some instruction that violate no restrictions, as a control */
1493 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 0, 0, true ),
1494 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 0, 0, true ),
1495 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 0, 0, true ),
1497 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 0, 0, true ),
1498 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 0, 0, true ),
1499 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 0, 0, true ),
1501 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 0, 0, true ),
1502 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 0, 0, true ),
1504 INST(MOV
, 4, F
, 1, F
, 4, 4, 1, 1, 1, true ),
1506 /* The PRMs say that for CHV, BXT:
1508 * When source or destination datatype is 64b or operation is integer
1509 * DWord multiply, DepCtrl must not be used.
1511 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 1, 0, false),
1512 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 1, 0, false),
1513 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 1, 0, false),
1515 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 1, 0, false),
1516 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 1, 0, false),
1517 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 1, 0, false),
1519 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 0, 1, false),
1520 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 0, 1, false),
1521 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 0, 1, false),
1523 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 0, 1, false),
1524 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 0, 1, false),
1525 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 0, 1, false),
1527 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 1, 0, false),
1528 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 1, 0, false),
1530 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 0, 1, false),
1531 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 0, 1, false),
1536 /* These restrictions only apply to Gen8+ */
1537 if (devinfo
.gen
< 8)
1540 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1541 if (!devinfo
.has_64bit_types
&&
1542 (type_sz(inst
[i
].dst_type
) == 8 || type_sz(inst
[i
].src_type
) == 8))
1545 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1546 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
1547 retype(g0
, inst
[i
].src_type
));
1549 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
1550 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
1551 retype(g0
, inst
[i
].src_type
),
1552 retype(zero
, inst
[i
].src_type
));
1554 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1556 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1558 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
1559 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
1560 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
1562 brw_inst_set_no_dd_check(&devinfo
, last_inst
, inst
[i
].no_dd_check
);
1563 brw_inst_set_no_dd_clear(&devinfo
, last_inst
, inst
[i
].no_dd_clear
);
1565 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1566 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1568 EXPECT_TRUE(validate(p
));
1571 clear_instructions(p
);