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
{
48 class validation_test
: public ::testing::TestWithParam
<struct gen_info
> {
53 virtual ~validation_test();
55 struct brw_codegen
*p
;
56 struct gen_device_info devinfo
;
59 validation_test::validation_test()
61 p
= rzalloc(NULL
, struct brw_codegen
);
62 memset(&devinfo
, 0, sizeof(devinfo
));
65 validation_test::~validation_test()
70 void validation_test::SetUp()
72 struct gen_info info
= GetParam();
73 int devid
= gen_device_name_to_pci_device_id(info
.name
);
75 gen_get_device_info(devid
, &devinfo
);
77 brw_init_codegen(&devinfo
, p
, p
);
81 template <class ParamType
>
83 operator()(const ::testing::TestParamInfo
<ParamType
>& info
) const {
84 return info
.param
.name
;
88 INSTANTIATE_TEST_CASE_P(eu_assembly
, validation_test
,
89 ::testing::ValuesIn(gens
),
93 validate(struct brw_codegen
*p
)
95 const bool print
= getenv("TEST_DEBUG");
96 struct disasm_info
*disasm
= disasm_initialize(p
->devinfo
, NULL
);
99 disasm_new_inst_group(disasm
, 0);
100 disasm_new_inst_group(disasm
, p
->next_insn_offset
);
103 bool ret
= brw_validate_instructions(p
->devinfo
, p
->store
, 0,
104 p
->next_insn_offset
, disasm
);
107 dump_assembly(p
->store
, disasm
);
114 #define last_inst (&p->store[p->nr_insn - 1])
115 #define g0 brw_vec8_grf(0, 0)
116 #define acc0 brw_acc_reg(8)
117 #define null brw_null_reg()
118 #define zero brw_imm_f(0.0f)
121 clear_instructions(struct brw_codegen
*p
)
123 p
->next_insn_offset
= 0;
127 TEST_P(validation_test
, sanity
)
129 brw_ADD(p
, g0
, g0
, g0
);
131 EXPECT_TRUE(validate(p
));
134 TEST_P(validation_test
, src0_null_reg
)
136 brw_MOV(p
, g0
, null
);
138 EXPECT_FALSE(validate(p
));
141 TEST_P(validation_test
, src1_null_reg
)
143 brw_ADD(p
, g0
, g0
, null
);
145 EXPECT_FALSE(validate(p
));
148 TEST_P(validation_test
, math_src0_null_reg
)
150 if (devinfo
.gen
>= 6) {
151 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, null
, null
);
153 gen4_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, 0, null
, BRW_MATH_PRECISION_FULL
);
156 EXPECT_FALSE(validate(p
));
159 TEST_P(validation_test
, math_src1_null_reg
)
161 if (devinfo
.gen
>= 6) {
162 gen6_math(p
, g0
, BRW_MATH_FUNCTION_POW
, g0
, null
);
163 EXPECT_FALSE(validate(p
));
165 /* Math instructions on Gen4/5 are actually SEND messages with payloads.
166 * src1 is an immediate message descriptor set by gen4_math.
171 TEST_P(validation_test
, opcode46
)
173 /* opcode 46 is "push" on Gen 4 and 5
178 brw_next_insn(p
, 46);
180 if (devinfo
.gen
== 7) {
181 EXPECT_FALSE(validate(p
));
183 EXPECT_TRUE(validate(p
));
187 /* When the Execution Data Type is wider than the destination data type, the
188 * destination must [...] specify a HorzStride equal to the ratio in sizes of
189 * the two data types.
191 TEST_P(validation_test
, dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size
)
193 brw_ADD(p
, g0
, g0
, g0
);
194 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
195 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
196 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
198 EXPECT_FALSE(validate(p
));
200 clear_instructions(p
);
202 brw_ADD(p
, g0
, g0
, g0
);
203 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
204 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
205 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
206 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
208 EXPECT_TRUE(validate(p
));
211 /* When the Execution Data Type is wider than the destination data type, the
212 * destination must be aligned as required by the wider execution data type
215 TEST_P(validation_test
, dst_subreg_must_be_aligned_to_exec_type_size
)
217 brw_ADD(p
, g0
, g0
, g0
);
218 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 2);
219 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
220 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
221 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
222 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
224 EXPECT_FALSE(validate(p
));
226 clear_instructions(p
);
228 brw_ADD(p
, g0
, g0
, g0
);
229 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
230 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 8);
231 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
232 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
233 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
234 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
235 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
236 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
237 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
238 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
239 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
240 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
242 EXPECT_TRUE(validate(p
));
245 /* ExecSize must be greater than or equal to Width. */
246 TEST_P(validation_test
, exec_size_less_than_width
)
248 brw_ADD(p
, g0
, g0
, g0
);
249 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
251 EXPECT_FALSE(validate(p
));
253 clear_instructions(p
);
255 brw_ADD(p
, g0
, g0
, g0
);
256 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
258 EXPECT_FALSE(validate(p
));
261 /* If ExecSize = Width and HorzStride ≠ 0,
262 * VertStride must be set to Width * HorzStride.
264 TEST_P(validation_test
, vertical_stride_is_width_by_horizontal_stride
)
266 brw_ADD(p
, g0
, g0
, g0
);
267 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
269 EXPECT_FALSE(validate(p
));
271 clear_instructions(p
);
273 brw_ADD(p
, g0
, g0
, g0
);
274 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
276 EXPECT_FALSE(validate(p
));
279 /* If Width = 1, HorzStride must be 0 regardless of the values
280 * of ExecSize and VertStride.
282 TEST_P(validation_test
, horizontal_stride_must_be_0_if_width_is_1
)
284 brw_ADD(p
, g0
, g0
, g0
);
285 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
286 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
287 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
289 EXPECT_FALSE(validate(p
));
291 clear_instructions(p
);
293 brw_ADD(p
, g0
, g0
, g0
);
294 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
295 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
296 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
298 EXPECT_FALSE(validate(p
));
301 /* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */
302 TEST_P(validation_test
, scalar_region_must_be_0_1_0
)
304 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
306 brw_ADD(p
, g0
, g0
, g0_0
);
307 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
308 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
309 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
310 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
312 EXPECT_FALSE(validate(p
));
314 clear_instructions(p
);
316 brw_ADD(p
, g0
, g0_0
, g0
);
317 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
318 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
319 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
320 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
322 EXPECT_FALSE(validate(p
));
325 /* If VertStride = HorzStride = 0, Width must be 1 regardless of the value
328 TEST_P(validation_test
, zero_stride_implies_0_1_0
)
330 brw_ADD(p
, g0
, g0
, g0
);
331 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
332 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
333 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
335 EXPECT_FALSE(validate(p
));
337 clear_instructions(p
);
339 brw_ADD(p
, g0
, g0
, g0
);
340 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
341 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
342 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
344 EXPECT_FALSE(validate(p
));
347 /* Dst.HorzStride must not be 0. */
348 TEST_P(validation_test
, dst_horizontal_stride_0
)
350 brw_ADD(p
, g0
, g0
, g0
);
351 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
353 EXPECT_FALSE(validate(p
));
355 clear_instructions(p
);
357 /* Align16 does not exist on Gen11+ */
358 if (devinfo
.gen
>= 11)
361 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
363 brw_ADD(p
, g0
, g0
, g0
);
364 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
366 EXPECT_FALSE(validate(p
));
369 /* VertStride must be used to cross BRW_GENERAL_REGISTER_FILE register boundaries. This rule implies
370 * that elements within a 'Width' cannot cross BRW_GENERAL_REGISTER_FILE boundaries.
372 TEST_P(validation_test
, must_not_cross_grf_boundary_in_a_width
)
374 brw_ADD(p
, g0
, g0
, g0
);
375 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 4);
377 EXPECT_FALSE(validate(p
));
379 clear_instructions(p
);
381 brw_ADD(p
, g0
, g0
, g0
);
382 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 4);
384 EXPECT_FALSE(validate(p
));
386 clear_instructions(p
);
388 brw_ADD(p
, g0
, g0
, g0
);
389 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
390 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
391 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
393 EXPECT_FALSE(validate(p
));
395 clear_instructions(p
);
397 brw_ADD(p
, g0
, g0
, g0
);
398 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
399 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
400 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
402 EXPECT_FALSE(validate(p
));
405 /* Destination Horizontal must be 1 in Align16 */
406 TEST_P(validation_test
, dst_hstride_on_align16_must_be_1
)
408 /* Align16 does not exist on Gen11+ */
409 if (devinfo
.gen
>= 11)
412 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
414 brw_ADD(p
, g0
, g0
, g0
);
415 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
417 EXPECT_FALSE(validate(p
));
419 clear_instructions(p
);
421 brw_ADD(p
, g0
, g0
, g0
);
422 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
424 EXPECT_TRUE(validate(p
));
427 /* VertStride must be 0 or 4 in Align16 */
428 TEST_P(validation_test
, vstride_on_align16_must_be_0_or_4
)
430 /* Align16 does not exist on Gen11+ */
431 if (devinfo
.gen
>= 11)
435 enum brw_vertical_stride vstride
;
436 bool expected_result
;
438 { BRW_VERTICAL_STRIDE_0
, true },
439 { BRW_VERTICAL_STRIDE_1
, false },
440 { BRW_VERTICAL_STRIDE_2
, devinfo
.is_haswell
|| devinfo
.gen
>= 8 },
441 { BRW_VERTICAL_STRIDE_4
, true },
442 { BRW_VERTICAL_STRIDE_8
, false },
443 { BRW_VERTICAL_STRIDE_16
, false },
444 { BRW_VERTICAL_STRIDE_32
, false },
445 { BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL
, false },
448 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
450 for (unsigned i
= 0; i
< sizeof(vstride
) / sizeof(vstride
[0]); i
++) {
451 brw_ADD(p
, g0
, g0
, g0
);
452 brw_inst_set_src0_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
454 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
456 clear_instructions(p
);
459 for (unsigned i
= 0; i
< sizeof(vstride
) / sizeof(vstride
[0]); i
++) {
460 brw_ADD(p
, g0
, g0
, g0
);
461 brw_inst_set_src1_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
463 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
465 clear_instructions(p
);
469 /* In Direct Addressing mode, a source cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE
472 TEST_P(validation_test
, source_cannot_span_more_than_2_registers
)
474 brw_ADD(p
, g0
, g0
, g0
);
475 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
476 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
477 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
478 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
479 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
480 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
481 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
483 EXPECT_FALSE(validate(p
));
485 clear_instructions(p
);
487 brw_ADD(p
, g0
, g0
, g0
);
488 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
489 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
490 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
491 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
492 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
493 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
494 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
495 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 2);
497 EXPECT_TRUE(validate(p
));
499 clear_instructions(p
);
501 brw_ADD(p
, g0
, g0
, g0
);
502 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
504 EXPECT_TRUE(validate(p
));
507 /* A destination cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE registers. */
508 TEST_P(validation_test
, destination_cannot_span_more_than_2_registers
)
510 brw_ADD(p
, g0
, g0
, g0
);
511 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
512 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
513 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
514 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
515 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
517 EXPECT_FALSE(validate(p
));
519 clear_instructions(p
);
521 brw_ADD(p
, g0
, g0
, g0
);
522 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_8
);
523 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 6);
524 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
525 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
526 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
527 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
528 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
529 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
530 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
531 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
532 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
533 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
535 EXPECT_TRUE(validate(p
));
538 TEST_P(validation_test
, src_region_spans_two_regs_dst_region_spans_one
)
540 /* Writes to dest are to the lower OWord */
541 brw_ADD(p
, g0
, g0
, g0
);
542 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
543 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
544 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
545 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
546 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
547 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
549 EXPECT_TRUE(validate(p
));
551 clear_instructions(p
);
553 /* Writes to dest are to the upper OWord */
554 brw_ADD(p
, g0
, g0
, g0
);
555 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 16);
556 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
557 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
558 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
559 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
560 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
561 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
563 EXPECT_TRUE(validate(p
));
565 clear_instructions(p
);
567 /* Writes to dest are evenly split between OWords */
568 brw_ADD(p
, g0
, g0
, g0
);
569 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
570 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
571 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
572 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
573 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
574 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
575 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
577 EXPECT_TRUE(validate(p
));
579 clear_instructions(p
);
581 /* Writes to dest are uneven between OWords */
582 brw_ADD(p
, g0
, g0
, g0
);
583 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
584 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 10);
585 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
586 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
587 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
588 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
589 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
590 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
591 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
592 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
593 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
595 if (devinfo
.gen
>= 9) {
596 EXPECT_TRUE(validate(p
));
598 EXPECT_FALSE(validate(p
));
602 TEST_P(validation_test
, dst_elements_must_be_evenly_split_between_registers
)
604 brw_ADD(p
, g0
, g0
, g0
);
605 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
607 if (devinfo
.gen
>= 9) {
608 EXPECT_TRUE(validate(p
));
610 EXPECT_FALSE(validate(p
));
613 clear_instructions(p
);
615 brw_ADD(p
, g0
, g0
, g0
);
616 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
618 EXPECT_TRUE(validate(p
));
620 clear_instructions(p
);
622 if (devinfo
.gen
>= 6) {
623 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
625 EXPECT_TRUE(validate(p
));
627 clear_instructions(p
);
629 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
630 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
632 EXPECT_FALSE(validate(p
));
636 TEST_P(validation_test
, two_src_two_dst_source_offsets_must_be_same
)
638 brw_ADD(p
, g0
, g0
, g0
);
639 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
640 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
641 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 16);
642 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_2
);
643 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
644 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
645 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
646 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
647 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
649 if (devinfo
.gen
<= 7) {
650 EXPECT_FALSE(validate(p
));
652 EXPECT_TRUE(validate(p
));
655 clear_instructions(p
);
657 brw_ADD(p
, g0
, g0
, g0
);
658 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
659 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
660 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
661 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
662 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
663 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_8
);
664 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
665 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
667 EXPECT_TRUE(validate(p
));
670 TEST_P(validation_test
, two_src_two_dst_each_dst_must_be_derived_from_one_src
)
673 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
674 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
675 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
676 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
677 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 8);
678 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
679 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
680 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
682 if (devinfo
.gen
<= 7) {
683 EXPECT_FALSE(validate(p
));
685 EXPECT_TRUE(validate(p
));
688 clear_instructions(p
);
691 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 16);
692 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 8);
693 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_2
);
694 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
695 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
697 if (devinfo
.gen
<= 7) {
698 EXPECT_FALSE(validate(p
));
700 EXPECT_TRUE(validate(p
));
704 TEST_P(validation_test
, one_src_two_dst
)
706 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
708 brw_ADD(p
, g0
, g0_0
, g0_0
);
709 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
711 EXPECT_TRUE(validate(p
));
713 clear_instructions(p
);
715 brw_ADD(p
, g0
, g0
, g0
);
716 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
717 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
718 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
719 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
721 EXPECT_TRUE(validate(p
));
723 clear_instructions(p
);
725 brw_ADD(p
, g0
, g0
, g0
);
726 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
727 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
728 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
729 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
730 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
731 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
732 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
733 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
735 if (devinfo
.gen
>= 8) {
736 EXPECT_TRUE(validate(p
));
738 EXPECT_FALSE(validate(p
));
741 clear_instructions(p
);
743 brw_ADD(p
, g0
, g0
, g0
);
744 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
745 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
746 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
747 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
748 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
749 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
750 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
751 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
753 if (devinfo
.gen
>= 8) {
754 EXPECT_TRUE(validate(p
));
756 EXPECT_FALSE(validate(p
));
760 TEST_P(validation_test
, packed_byte_destination
)
762 static const struct {
763 enum brw_reg_type dst_type
;
764 enum brw_reg_type src_type
;
766 bool expected_result
;
768 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 0, 0, true },
769 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 0, 0, true },
770 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 0, 0, true },
771 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 0, 0, true },
773 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 1, 0, 0, false },
774 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 1, 0, 0, false },
775 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 1, 0, 0, false },
776 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 1, 0, 0, false },
778 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 1, 0, false },
779 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 1, 0, false },
780 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 1, 0, false },
781 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 1, 0, false },
783 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 0, 1, false },
784 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 0, 1, false },
785 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 0, 1, false },
786 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 0, 1, false },
788 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UW
, 0, 0, 0, false },
789 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_W
, 0, 0, 0, false },
790 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UD
, 0, 0, 0, false },
791 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_D
, 0, 0, 0, false },
794 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
795 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(g0
, move
[i
].src_type
));
796 brw_inst_set_src0_negate(&devinfo
, last_inst
, move
[i
].neg
);
797 brw_inst_set_src0_abs(&devinfo
, last_inst
, move
[i
].abs
);
798 brw_inst_set_saturate(&devinfo
, last_inst
, move
[i
].sat
);
800 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
802 clear_instructions(p
);
805 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_UB
),
806 retype(g0
, BRW_REGISTER_TYPE_UB
),
807 retype(g0
, BRW_REGISTER_TYPE_UB
));
808 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
810 EXPECT_FALSE(validate(p
));
812 clear_instructions(p
);
814 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
815 retype(g0
, BRW_REGISTER_TYPE_B
),
816 retype(g0
, BRW_REGISTER_TYPE_B
));
817 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
819 EXPECT_FALSE(validate(p
));
822 TEST_P(validation_test
, byte_destination_relaxed_alignment
)
824 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
825 retype(g0
, BRW_REGISTER_TYPE_W
),
826 retype(g0
, BRW_REGISTER_TYPE_W
));
827 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
828 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
830 EXPECT_TRUE(validate(p
));
832 clear_instructions(p
);
834 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
835 retype(g0
, BRW_REGISTER_TYPE_W
),
836 retype(g0
, BRW_REGISTER_TYPE_W
));
837 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
838 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
839 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 1);
841 if (devinfo
.gen
> 4 || devinfo
.is_g4x
) {
842 EXPECT_TRUE(validate(p
));
844 EXPECT_FALSE(validate(p
));
848 TEST_P(validation_test
, vector_immediate_destination_alignment
)
850 static const struct {
851 enum brw_reg_type dst_type
;
852 enum brw_reg_type src_type
;
855 bool expected_result
;
857 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 0, BRW_EXECUTE_4
, true },
858 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 16, BRW_EXECUTE_4
, true },
859 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 1, BRW_EXECUTE_4
, false },
861 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 0, BRW_EXECUTE_8
, true },
862 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 16, BRW_EXECUTE_8
, true },
863 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 1, BRW_EXECUTE_8
, false },
865 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 0, BRW_EXECUTE_8
, true },
866 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 16, BRW_EXECUTE_8
, true },
867 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 1, BRW_EXECUTE_8
, false },
870 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
871 /* UV type is Gen6+ */
872 if (devinfo
.gen
< 6 &&
873 move
[i
].src_type
== BRW_REGISTER_TYPE_UV
)
876 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(zero
, move
[i
].src_type
));
877 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, move
[i
].subnr
);
878 brw_inst_set_exec_size(&devinfo
, last_inst
, move
[i
].exec_size
);
880 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
882 clear_instructions(p
);
886 TEST_P(validation_test
, vector_immediate_destination_stride
)
888 static const struct {
889 enum brw_reg_type dst_type
;
890 enum brw_reg_type src_type
;
892 bool expected_result
;
894 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_1
, true },
895 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, false },
896 { BRW_REGISTER_TYPE_D
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_1
, true },
897 { BRW_REGISTER_TYPE_D
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, false },
898 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, true },
899 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_4
, true },
901 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_1
, true },
902 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_2
, false },
903 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_4
, false },
904 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_2
, true },
906 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_1
, true },
907 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_2
, false },
908 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_4
, false },
909 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_2
, true },
912 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
913 /* UV type is Gen6+ */
914 if (devinfo
.gen
< 6 &&
915 move
[i
].src_type
== BRW_REGISTER_TYPE_UV
)
918 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(zero
, move
[i
].src_type
));
919 brw_inst_set_dst_hstride(&devinfo
, last_inst
, move
[i
].stride
);
921 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
923 clear_instructions(p
);
927 TEST_P(validation_test
, qword_low_power_align1_regioning_restrictions
)
929 static const struct {
933 enum brw_reg_type dst_type
;
937 enum brw_reg_type src_type
;
939 unsigned src_vstride
;
941 unsigned src_hstride
;
943 bool expected_result
;
945 #define INST(opcode, exec_size, dst_type, dst_subreg, dst_stride, src_type, \
946 src_subreg, src_vstride, src_width, src_hstride, expected_result) \
948 BRW_OPCODE_##opcode, \
949 BRW_EXECUTE_##exec_size, \
950 BRW_REGISTER_TYPE_##dst_type, \
952 BRW_HORIZONTAL_STRIDE_##dst_stride, \
953 BRW_REGISTER_TYPE_##src_type, \
955 BRW_VERTICAL_STRIDE_##src_vstride, \
956 BRW_WIDTH_##src_width, \
957 BRW_HORIZONTAL_STRIDE_##src_hstride, \
961 /* Some instruction that violate no restrictions, as a control */
962 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 4, 4, 1, true ),
963 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 4, 4, 1, true ),
964 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 4, 4, 1, true ),
966 INST(MOV
, 4, DF
, 0, 1, F
, 0, 8, 4, 2, true ),
967 INST(MOV
, 4, Q
, 0, 1, D
, 0, 8, 4, 2, true ),
968 INST(MOV
, 4, UQ
, 0, 1, UD
, 0, 8, 4, 2, true ),
970 INST(MOV
, 4, F
, 0, 2, DF
, 0, 4, 4, 1, true ),
971 INST(MOV
, 4, D
, 0, 2, Q
, 0, 4, 4, 1, true ),
972 INST(MOV
, 4, UD
, 0, 2, UQ
, 0, 4, 4, 1, true ),
974 INST(MUL
, 8, D
, 0, 2, D
, 0, 8, 4, 2, true ),
975 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 8, 4, 2, true ),
977 /* Something with subreg nrs */
978 INST(MOV
, 2, DF
, 8, 1, DF
, 8, 2, 2, 1, true ),
979 INST(MOV
, 2, Q
, 8, 1, Q
, 8, 2, 2, 1, true ),
980 INST(MOV
, 2, UQ
, 8, 1, UQ
, 8, 2, 2, 1, true ),
982 INST(MUL
, 2, D
, 4, 2, D
, 4, 4, 2, 2, true ),
983 INST(MUL
, 2, UD
, 4, 2, UD
, 4, 4, 2, 2, true ),
985 /* The PRMs say that for CHV, BXT:
987 * When source or destination datatype is 64b or operation is integer
988 * DWord multiply, regioning in Align1 must follow these rules:
990 * 1. Source and Destination horizontal stride must be aligned to the
993 INST(MOV
, 4, DF
, 0, 2, DF
, 0, 4, 4, 1, false),
994 INST(MOV
, 4, Q
, 0, 2, Q
, 0, 4, 4, 1, false),
995 INST(MOV
, 4, UQ
, 0, 2, UQ
, 0, 4, 4, 1, false),
997 INST(MOV
, 4, DF
, 0, 2, F
, 0, 8, 4, 2, false),
998 INST(MOV
, 4, Q
, 0, 2, D
, 0, 8, 4, 2, false),
999 INST(MOV
, 4, UQ
, 0, 2, UD
, 0, 8, 4, 2, false),
1001 INST(MOV
, 4, DF
, 0, 2, F
, 0, 4, 4, 1, false),
1002 INST(MOV
, 4, Q
, 0, 2, D
, 0, 4, 4, 1, false),
1003 INST(MOV
, 4, UQ
, 0, 2, UD
, 0, 4, 4, 1, false),
1005 INST(MUL
, 4, D
, 0, 2, D
, 0, 4, 4, 1, false),
1006 INST(MUL
, 4, UD
, 0, 2, UD
, 0, 4, 4, 1, false),
1008 INST(MUL
, 4, D
, 0, 1, D
, 0, 8, 4, 2, false),
1009 INST(MUL
, 4, UD
, 0, 1, UD
, 0, 8, 4, 2, false),
1011 /* 2. Regioning must ensure Src.Vstride = Src.Width * Src.Hstride. */
1012 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 0, 2, 1, false),
1013 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 0, 2, 1, false),
1014 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 0, 2, 1, false),
1016 INST(MOV
, 4, DF
, 0, 1, F
, 0, 0, 2, 2, false),
1017 INST(MOV
, 4, Q
, 0, 1, D
, 0, 0, 2, 2, false),
1018 INST(MOV
, 4, UQ
, 0, 1, UD
, 0, 0, 2, 2, false),
1020 INST(MOV
, 8, F
, 0, 2, DF
, 0, 0, 2, 1, false),
1021 INST(MOV
, 8, D
, 0, 2, Q
, 0, 0, 2, 1, false),
1022 INST(MOV
, 8, UD
, 0, 2, UQ
, 0, 0, 2, 1, false),
1024 INST(MUL
, 8, D
, 0, 2, D
, 0, 0, 4, 2, false),
1025 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 0, 4, 2, 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 /* 3. Source and Destination offset must be the same, except the case
1033 INST(MOV
, 2, DF
, 8, 1, DF
, 0, 2, 2, 1, false),
1034 INST(MOV
, 2, Q
, 8, 1, Q
, 0, 2, 2, 1, false),
1035 INST(MOV
, 2, UQ
, 8, 1, UQ
, 0, 2, 2, 1, false),
1037 INST(MOV
, 2, DF
, 0, 1, DF
, 8, 2, 2, 1, false),
1038 INST(MOV
, 2, Q
, 0, 1, Q
, 8, 2, 2, 1, false),
1039 INST(MOV
, 2, UQ
, 0, 1, UQ
, 8, 2, 2, 1, false),
1041 INST(MUL
, 4, D
, 4, 2, D
, 0, 4, 2, 2, false),
1042 INST(MUL
, 4, UD
, 4, 2, UD
, 0, 4, 2, 2, false),
1044 INST(MUL
, 4, D
, 0, 2, D
, 4, 4, 2, 2, false),
1045 INST(MUL
, 4, UD
, 0, 2, UD
, 4, 4, 2, 2, false),
1047 INST(MOV
, 2, DF
, 8, 1, DF
, 0, 0, 1, 0, true ),
1048 INST(MOV
, 2, Q
, 8, 1, Q
, 0, 0, 1, 0, true ),
1049 INST(MOV
, 2, UQ
, 8, 1, UQ
, 0, 0, 1, 0, true ),
1051 INST(MOV
, 2, DF
, 8, 1, F
, 4, 0, 1, 0, true ),
1052 INST(MOV
, 2, Q
, 8, 1, D
, 4, 0, 1, 0, true ),
1053 INST(MOV
, 2, UQ
, 8, 1, UD
, 4, 0, 1, 0, true ),
1055 INST(MUL
, 4, D
, 4, 1, D
, 0, 0, 1, 0, true ),
1056 INST(MUL
, 4, UD
, 4, 1, UD
, 0, 0, 1, 0, true ),
1058 INST(MUL
, 4, D
, 0, 1, D
, 4, 0, 1, 0, true ),
1059 INST(MUL
, 4, UD
, 0, 1, UD
, 4, 0, 1, 0, true ),
1064 /* These restrictions only apply to Gen8+ */
1065 if (devinfo
.gen
< 8)
1068 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1069 if (!devinfo
.has_64bit_types
&&
1070 (type_sz(inst
[i
].dst_type
) == 8 || type_sz(inst
[i
].src_type
) == 8))
1073 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1074 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
1075 retype(g0
, inst
[i
].src_type
));
1077 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
1078 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
1079 retype(g0
, inst
[i
].src_type
),
1080 retype(zero
, inst
[i
].src_type
));
1082 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1084 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].dst_subreg
);
1085 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].src_subreg
);
1087 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1089 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
1090 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
1091 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
1093 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1094 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1096 EXPECT_TRUE(validate(p
));
1099 clear_instructions(p
);
1103 TEST_P(validation_test
, qword_low_power_no_indirect_addressing
)
1105 static const struct {
1109 enum brw_reg_type dst_type
;
1110 bool dst_is_indirect
;
1111 unsigned dst_stride
;
1113 enum brw_reg_type src_type
;
1114 bool src_is_indirect
;
1115 unsigned src_vstride
;
1117 unsigned src_hstride
;
1119 bool expected_result
;
1121 #define INST(opcode, exec_size, dst_type, dst_is_indirect, dst_stride, \
1122 src_type, src_is_indirect, src_vstride, src_width, src_hstride, \
1125 BRW_OPCODE_##opcode, \
1126 BRW_EXECUTE_##exec_size, \
1127 BRW_REGISTER_TYPE_##dst_type, \
1129 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1130 BRW_REGISTER_TYPE_##src_type, \
1132 BRW_VERTICAL_STRIDE_##src_vstride, \
1133 BRW_WIDTH_##src_width, \
1134 BRW_HORIZONTAL_STRIDE_##src_hstride, \
1138 /* Some instruction that violate no restrictions, as a control */
1139 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 4, 4, 1, true ),
1140 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 4, 4, 1, true ),
1141 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 4, 4, 1, true ),
1143 INST(MUL
, 8, D
, 0, 2, D
, 0, 8, 4, 2, true ),
1144 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 8, 4, 2, true ),
1146 INST(MOV
, 4, F
, 1, 1, F
, 0, 4, 4, 1, true ),
1147 INST(MOV
, 4, F
, 0, 1, F
, 1, 4, 4, 1, true ),
1148 INST(MOV
, 4, F
, 1, 1, F
, 1, 4, 4, 1, true ),
1150 /* The PRMs say that for CHV, BXT:
1152 * When source or destination datatype is 64b or operation is integer
1153 * DWord multiply, indirect addressing must not be used.
1155 INST(MOV
, 4, DF
, 1, 1, DF
, 0, 4, 4, 1, false),
1156 INST(MOV
, 4, Q
, 1, 1, Q
, 0, 4, 4, 1, false),
1157 INST(MOV
, 4, UQ
, 1, 1, UQ
, 0, 4, 4, 1, false),
1159 INST(MOV
, 4, DF
, 0, 1, DF
, 1, 4, 4, 1, false),
1160 INST(MOV
, 4, Q
, 0, 1, Q
, 1, 4, 4, 1, false),
1161 INST(MOV
, 4, UQ
, 0, 1, UQ
, 1, 4, 4, 1, false),
1163 INST(MOV
, 4, DF
, 1, 1, F
, 0, 8, 4, 2, false),
1164 INST(MOV
, 4, Q
, 1, 1, D
, 0, 8, 4, 2, false),
1165 INST(MOV
, 4, UQ
, 1, 1, UD
, 0, 8, 4, 2, false),
1167 INST(MOV
, 4, DF
, 0, 1, F
, 1, 8, 4, 2, false),
1168 INST(MOV
, 4, Q
, 0, 1, D
, 1, 8, 4, 2, false),
1169 INST(MOV
, 4, UQ
, 0, 1, UD
, 1, 8, 4, 2, false),
1171 INST(MOV
, 4, F
, 1, 2, DF
, 0, 4, 4, 1, false),
1172 INST(MOV
, 4, D
, 1, 2, Q
, 0, 4, 4, 1, false),
1173 INST(MOV
, 4, UD
, 1, 2, UQ
, 0, 4, 4, 1, false),
1175 INST(MOV
, 4, F
, 0, 2, DF
, 1, 4, 4, 1, false),
1176 INST(MOV
, 4, D
, 0, 2, Q
, 1, 4, 4, 1, false),
1177 INST(MOV
, 4, UD
, 0, 2, UQ
, 1, 4, 4, 1, false),
1179 INST(MUL
, 8, D
, 1, 2, D
, 0, 8, 4, 2, false),
1180 INST(MUL
, 8, UD
, 1, 2, UD
, 0, 8, 4, 2, false),
1182 INST(MUL
, 8, D
, 0, 2, D
, 1, 8, 4, 2, false),
1183 INST(MUL
, 8, UD
, 0, 2, UD
, 1, 8, 4, 2, false),
1188 /* These restrictions only apply to Gen8+ */
1189 if (devinfo
.gen
< 8)
1192 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1193 if (!devinfo
.has_64bit_types
&&
1194 (type_sz(inst
[i
].dst_type
) == 8 || type_sz(inst
[i
].src_type
) == 8))
1197 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1198 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
1199 retype(g0
, inst
[i
].src_type
));
1201 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
1202 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
1203 retype(g0
, inst
[i
].src_type
),
1204 retype(zero
, inst
[i
].src_type
));
1206 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1208 brw_inst_set_dst_address_mode(&devinfo
, last_inst
, inst
[i
].dst_is_indirect
);
1209 brw_inst_set_src0_address_mode(&devinfo
, last_inst
, inst
[i
].src_is_indirect
);
1211 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1213 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
1214 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
1215 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
1217 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1218 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1220 EXPECT_TRUE(validate(p
));
1223 clear_instructions(p
);
1227 TEST_P(validation_test
, qword_low_power_no_64bit_arf
)
1229 static const struct {
1234 enum brw_reg_type dst_type
;
1235 unsigned dst_stride
;
1238 enum brw_reg_type src_type
;
1239 unsigned src_vstride
;
1241 unsigned src_hstride
;
1244 bool expected_result
;
1246 #define INST(opcode, exec_size, dst, dst_type, dst_stride, \
1247 src, src_type, src_vstride, src_width, src_hstride, \
1248 acc_wr, expected_result) \
1250 BRW_OPCODE_##opcode, \
1251 BRW_EXECUTE_##exec_size, \
1253 BRW_REGISTER_TYPE_##dst_type, \
1254 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1256 BRW_REGISTER_TYPE_##src_type, \
1257 BRW_VERTICAL_STRIDE_##src_vstride, \
1258 BRW_WIDTH_##src_width, \
1259 BRW_HORIZONTAL_STRIDE_##src_hstride, \
1264 /* Some instruction that violate no restrictions, as a control */
1265 INST(MOV
, 4, g0
, DF
, 1, g0
, F
, 4, 2, 2, 0, true ),
1266 INST(MOV
, 4, g0
, F
, 2, g0
, DF
, 4, 4, 1, 0, true ),
1268 INST(MOV
, 4, g0
, Q
, 1, g0
, D
, 4, 2, 2, 0, true ),
1269 INST(MOV
, 4, g0
, D
, 2, g0
, Q
, 4, 4, 1, 0, true ),
1271 INST(MOV
, 4, g0
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, true ),
1272 INST(MOV
, 4, g0
, UD
, 2, g0
, UQ
, 4, 4, 1, 0, true ),
1274 INST(MOV
, 4, null
, F
, 1, g0
, F
, 4, 4, 1, 0, true ),
1275 INST(MOV
, 4, acc0
, F
, 1, g0
, F
, 4, 4, 1, 0, true ),
1276 INST(MOV
, 4, g0
, F
, 1, acc0
, F
, 4, 4, 1, 0, true ),
1278 INST(MOV
, 4, null
, D
, 1, g0
, D
, 4, 4, 1, 0, true ),
1279 INST(MOV
, 4, acc0
, D
, 1, g0
, D
, 4, 4, 1, 0, true ),
1280 INST(MOV
, 4, g0
, D
, 1, acc0
, D
, 4, 4, 1, 0, true ),
1282 INST(MOV
, 4, null
, UD
, 1, g0
, UD
, 4, 4, 1, 0, true ),
1283 INST(MOV
, 4, acc0
, UD
, 1, g0
, UD
, 4, 4, 1, 0, true ),
1284 INST(MOV
, 4, g0
, UD
, 1, acc0
, UD
, 4, 4, 1, 0, true ),
1286 INST(MUL
, 4, g0
, D
, 2, g0
, D
, 4, 2, 2, 0, true ),
1287 INST(MUL
, 4, g0
, UD
, 2, g0
, UD
, 4, 2, 2, 0, true ),
1289 /* The PRMs say that for CHV, BXT:
1291 * ARF registers must never be used with 64b datatype or when
1292 * operation is integer DWord multiply.
1294 INST(MOV
, 4, acc0
, DF
, 1, g0
, F
, 4, 2, 2, 0, false),
1295 INST(MOV
, 4, g0
, DF
, 1, acc0
, F
, 4, 2, 2, 0, false),
1297 INST(MOV
, 4, acc0
, Q
, 1, g0
, D
, 4, 2, 2, 0, false),
1298 INST(MOV
, 4, g0
, Q
, 1, acc0
, D
, 4, 2, 2, 0, false),
1300 INST(MOV
, 4, acc0
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, false),
1301 INST(MOV
, 4, g0
, UQ
, 1, acc0
, UD
, 4, 2, 2, 0, false),
1303 INST(MOV
, 4, acc0
, F
, 2, g0
, DF
, 4, 4, 1, 0, false),
1304 INST(MOV
, 4, g0
, F
, 2, acc0
, DF
, 4, 4, 1, 0, false),
1306 INST(MOV
, 4, acc0
, D
, 2, g0
, Q
, 4, 4, 1, 0, false),
1307 INST(MOV
, 4, g0
, D
, 2, acc0
, Q
, 4, 4, 1, 0, false),
1309 INST(MOV
, 4, acc0
, UD
, 2, g0
, UQ
, 4, 4, 1, 0, false),
1310 INST(MOV
, 4, g0
, UD
, 2, acc0
, UQ
, 4, 4, 1, 0, false),
1312 INST(MUL
, 4, acc0
, D
, 2, g0
, D
, 4, 2, 2, 0, false),
1313 INST(MUL
, 4, acc0
, UD
, 2, g0
, UD
, 4, 2, 2, 0, false),
1314 /* MUL cannot have integer accumulator sources, so don't test that */
1316 /* We assume that the restriction does not apply to the null register */
1317 INST(MOV
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 0, true ),
1318 INST(MOV
, 4, null
, Q
, 1, g0
, D
, 4, 2, 2, 0, true ),
1319 INST(MOV
, 4, null
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, true ),
1321 /* Check implicit accumulator write control */
1322 INST(MOV
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 1, false),
1323 INST(MUL
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 1, false),
1328 /* These restrictions only apply to Gen8+ */
1329 if (devinfo
.gen
< 8)
1332 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1333 if (!devinfo
.has_64bit_types
&&
1334 (type_sz(inst
[i
].dst_type
) == 8 || type_sz(inst
[i
].src_type
) == 8))
1337 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1338 brw_MOV(p
, retype(inst
[i
].dst
, inst
[i
].dst_type
),
1339 retype(inst
[i
].src
, inst
[i
].src_type
));
1341 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
1342 brw_MUL(p
, retype(inst
[i
].dst
, inst
[i
].dst_type
),
1343 retype(inst
[i
].src
, inst
[i
].src_type
),
1344 retype(zero
, inst
[i
].src_type
));
1345 brw_inst_set_opcode(&devinfo
, last_inst
, inst
[i
].opcode
);
1347 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1348 brw_inst_set_acc_wr_control(&devinfo
, last_inst
, inst
[i
].acc_wr
);
1350 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1352 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
1353 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
1354 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
1356 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1357 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1359 EXPECT_TRUE(validate(p
));
1362 clear_instructions(p
);
1365 if (!devinfo
.has_64bit_types
)
1368 /* MAC implicitly reads the accumulator */
1369 brw_MAC(p
, retype(g0
, BRW_REGISTER_TYPE_DF
),
1370 retype(stride(g0
, 4, 4, 1), BRW_REGISTER_TYPE_DF
),
1371 retype(stride(g0
, 4, 4, 1), BRW_REGISTER_TYPE_DF
));
1372 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1373 EXPECT_FALSE(validate(p
));
1375 EXPECT_TRUE(validate(p
));
1379 TEST_P(validation_test
, align16_64_bit_integer
)
1381 static const struct {
1385 enum brw_reg_type dst_type
;
1386 enum brw_reg_type src_type
;
1388 bool expected_result
;
1390 #define INST(opcode, exec_size, dst_type, src_type, expected_result) \
1392 BRW_OPCODE_##opcode, \
1393 BRW_EXECUTE_##exec_size, \
1394 BRW_REGISTER_TYPE_##dst_type, \
1395 BRW_REGISTER_TYPE_##src_type, \
1399 /* Some instruction that violate no restrictions, as a control */
1400 INST(MOV
, 2, Q
, D
, true ),
1401 INST(MOV
, 2, UQ
, UD
, true ),
1402 INST(MOV
, 2, DF
, F
, true ),
1404 INST(ADD
, 2, Q
, D
, true ),
1405 INST(ADD
, 2, UQ
, UD
, true ),
1406 INST(ADD
, 2, DF
, F
, true ),
1408 /* The PRMs say that for BDW, SKL:
1410 * If Align16 is required for an operation with QW destination and non-QW
1411 * source datatypes, the execution size cannot exceed 2.
1414 INST(MOV
, 4, Q
, D
, false),
1415 INST(MOV
, 4, UQ
, UD
, false),
1416 INST(MOV
, 4, DF
, F
, false),
1418 INST(ADD
, 4, Q
, D
, false),
1419 INST(ADD
, 4, UQ
, UD
, false),
1420 INST(ADD
, 4, DF
, F
, false),
1425 /* 64-bit integer types exist on Gen8+ */
1426 if (devinfo
.gen
< 8)
1429 /* Align16 does not exist on Gen11+ */
1430 if (devinfo
.gen
>= 11)
1433 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
1435 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1436 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1437 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
1438 retype(g0
, inst
[i
].src_type
));
1440 assert(inst
[i
].opcode
== BRW_OPCODE_ADD
);
1441 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1442 retype(g0
, inst
[i
].src_type
),
1443 retype(g0
, inst
[i
].src_type
));
1445 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1447 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1449 clear_instructions(p
);
1453 TEST_P(validation_test
, qword_low_power_no_depctrl
)
1455 static const struct {
1459 enum brw_reg_type dst_type
;
1460 unsigned dst_stride
;
1462 enum brw_reg_type src_type
;
1463 unsigned src_vstride
;
1465 unsigned src_hstride
;
1470 bool expected_result
;
1472 #define INST(opcode, exec_size, dst_type, dst_stride, \
1473 src_type, src_vstride, src_width, src_hstride, \
1474 no_dd_check, no_dd_clear, expected_result) \
1476 BRW_OPCODE_##opcode, \
1477 BRW_EXECUTE_##exec_size, \
1478 BRW_REGISTER_TYPE_##dst_type, \
1479 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1480 BRW_REGISTER_TYPE_##src_type, \
1481 BRW_VERTICAL_STRIDE_##src_vstride, \
1482 BRW_WIDTH_##src_width, \
1483 BRW_HORIZONTAL_STRIDE_##src_hstride, \
1489 /* Some instruction that violate no restrictions, as a control */
1490 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 0, 0, true ),
1491 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 0, 0, true ),
1492 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 0, 0, true ),
1494 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 0, 0, true ),
1495 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 0, 0, true ),
1496 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 0, 0, true ),
1498 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 0, 0, true ),
1499 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 0, 0, true ),
1501 INST(MOV
, 4, F
, 1, F
, 4, 4, 1, 1, 1, true ),
1503 /* The PRMs say that for CHV, BXT:
1505 * When source or destination datatype is 64b or operation is integer
1506 * DWord multiply, DepCtrl must not be used.
1508 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 1, 0, false),
1509 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 1, 0, false),
1510 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 1, 0, false),
1512 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 1, 0, false),
1513 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 1, 0, false),
1514 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 1, 0, false),
1516 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 0, 1, false),
1517 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 0, 1, false),
1518 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 0, 1, false),
1520 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 0, 1, false),
1521 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 0, 1, false),
1522 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 0, 1, false),
1524 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 1, 0, false),
1525 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 1, 0, false),
1527 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 0, 1, false),
1528 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 0, 1, false),
1533 /* These restrictions only apply to Gen8+ */
1534 if (devinfo
.gen
< 8)
1537 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1538 if (!devinfo
.has_64bit_types
&&
1539 (type_sz(inst
[i
].dst_type
) == 8 || type_sz(inst
[i
].src_type
) == 8))
1542 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1543 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
1544 retype(g0
, inst
[i
].src_type
));
1546 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
1547 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
1548 retype(g0
, inst
[i
].src_type
),
1549 retype(zero
, inst
[i
].src_type
));
1551 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1553 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1555 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
1556 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
1557 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
1559 brw_inst_set_no_dd_check(&devinfo
, last_inst
, inst
[i
].no_dd_check
);
1560 brw_inst_set_no_dd_clear(&devinfo
, last_inst
, inst
[i
].no_dd_clear
);
1562 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1563 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1565 EXPECT_TRUE(validate(p
));
1568 clear_instructions(p
);