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"
39 static const struct gen_info
{
61 class validation_test
: public ::testing::TestWithParam
<struct gen_info
> {
66 virtual ~validation_test();
68 struct brw_codegen
*p
;
69 struct gen_device_info devinfo
;
72 validation_test::validation_test()
74 p
= rzalloc(NULL
, struct brw_codegen
);
75 memset(&devinfo
, 0, sizeof(devinfo
));
78 validation_test::~validation_test()
83 void validation_test::SetUp()
85 struct gen_info info
= GetParam();
87 devinfo
.gen
= info
.gen
;
88 devinfo
.is_g4x
= info
.subgen
== IS_G45
;
89 devinfo
.is_baytrail
= info
.subgen
== IS_BYT
;
90 devinfo
.is_haswell
= info
.subgen
== IS_HSW
;
91 devinfo
.is_cherryview
= info
.subgen
== IS_CHV
;
92 devinfo
.is_broxton
= info
.subgen
== IS_BXT
;
93 devinfo
.is_kabylake
= info
.subgen
== IS_KBL
;
94 devinfo
.is_geminilake
= info
.subgen
== IS_GLK
;
95 devinfo
.is_coffeelake
= info
.subgen
== IS_CFL
;
97 brw_init_codegen(&devinfo
, p
, p
);
101 template <class ParamType
>
103 operator()(const ::testing::TestParamInfo
<ParamType
>& info
) const {
104 return info
.param
.name
;
108 INSTANTIATE_TEST_CASE_P(eu_assembly
, validation_test
,
109 ::testing::ValuesIn(gens
),
113 validate(struct brw_codegen
*p
)
115 const bool print
= getenv("TEST_DEBUG");
116 struct annotation_info annotation
;
117 memset(&annotation
, 0, sizeof(annotation
));
120 annotation
.mem_ctx
= ralloc_context(NULL
);
121 annotation
.ann_count
= 1;
122 annotation
.ann_size
= 2;
123 annotation
.ann
= rzalloc_array(annotation
.mem_ctx
, struct annotation
,
124 annotation
.ann_size
);
125 annotation
.ann
[annotation
.ann_count
].offset
= p
->next_insn_offset
;
128 bool ret
= brw_validate_instructions(p
->devinfo
, p
->store
, 0,
129 p
->next_insn_offset
, &annotation
);
132 dump_assembly(p
->store
, annotation
.ann_count
, annotation
.ann
, p
->devinfo
);
133 ralloc_free(annotation
.mem_ctx
);
139 #define last_inst (&p->store[p->nr_insn - 1])
140 #define g0 brw_vec8_grf(0, 0)
141 #define acc0 brw_acc_reg(8)
142 #define null brw_null_reg()
143 #define zero brw_imm_f(0.0f)
146 clear_instructions(struct brw_codegen
*p
)
148 p
->next_insn_offset
= 0;
152 TEST_P(validation_test
, sanity
)
154 brw_ADD(p
, g0
, g0
, g0
);
156 EXPECT_TRUE(validate(p
));
159 TEST_P(validation_test
, src0_null_reg
)
161 brw_MOV(p
, g0
, null
);
163 EXPECT_FALSE(validate(p
));
166 TEST_P(validation_test
, src1_null_reg
)
168 brw_ADD(p
, g0
, g0
, null
);
170 EXPECT_FALSE(validate(p
));
173 TEST_P(validation_test
, math_src0_null_reg
)
175 if (devinfo
.gen
>= 6) {
176 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, null
, null
);
178 gen4_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, 0, null
, BRW_MATH_PRECISION_FULL
);
181 EXPECT_FALSE(validate(p
));
184 TEST_P(validation_test
, math_src1_null_reg
)
186 if (devinfo
.gen
>= 6) {
187 gen6_math(p
, g0
, BRW_MATH_FUNCTION_POW
, g0
, null
);
188 EXPECT_FALSE(validate(p
));
190 /* Math instructions on Gen4/5 are actually SEND messages with payloads.
191 * src1 is an immediate message descriptor set by gen4_math.
196 TEST_P(validation_test
, opcode46
)
198 /* opcode 46 is "push" on Gen 4 and 5
203 brw_next_insn(p
, 46);
205 if (devinfo
.gen
== 7) {
206 EXPECT_FALSE(validate(p
));
208 EXPECT_TRUE(validate(p
));
212 /* When the Execution Data Type is wider than the destination data type, the
213 * destination must [...] specify a HorzStride equal to the ratio in sizes of
214 * the two data types.
216 TEST_P(validation_test
, dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size
)
218 brw_ADD(p
, g0
, g0
, g0
);
219 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
220 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
221 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
223 EXPECT_FALSE(validate(p
));
225 clear_instructions(p
);
227 brw_ADD(p
, g0
, g0
, g0
);
228 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
229 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
230 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
231 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
233 EXPECT_TRUE(validate(p
));
236 /* When the Execution Data Type is wider than the destination data type, the
237 * destination must be aligned as required by the wider execution data type
240 TEST_P(validation_test
, dst_subreg_must_be_aligned_to_exec_type_size
)
242 brw_ADD(p
, g0
, g0
, g0
);
243 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 2);
244 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
245 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
246 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
247 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
249 EXPECT_FALSE(validate(p
));
251 clear_instructions(p
);
253 brw_ADD(p
, g0
, g0
, g0
);
254 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
255 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 8);
256 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
257 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
258 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
259 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
260 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
261 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
262 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
263 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
264 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
265 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
267 EXPECT_TRUE(validate(p
));
270 /* ExecSize must be greater than or equal to Width. */
271 TEST_P(validation_test
, exec_size_less_than_width
)
273 brw_ADD(p
, g0
, g0
, g0
);
274 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
276 EXPECT_FALSE(validate(p
));
278 clear_instructions(p
);
280 brw_ADD(p
, g0
, g0
, g0
);
281 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
283 EXPECT_FALSE(validate(p
));
286 /* If ExecSize = Width and HorzStride ≠ 0,
287 * VertStride must be set to Width * HorzStride.
289 TEST_P(validation_test
, vertical_stride_is_width_by_horizontal_stride
)
291 brw_ADD(p
, g0
, g0
, g0
);
292 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
294 EXPECT_FALSE(validate(p
));
296 clear_instructions(p
);
298 brw_ADD(p
, g0
, g0
, g0
);
299 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
301 EXPECT_FALSE(validate(p
));
304 /* If Width = 1, HorzStride must be 0 regardless of the values
305 * of ExecSize and VertStride.
307 TEST_P(validation_test
, horizontal_stride_must_be_0_if_width_is_1
)
309 brw_ADD(p
, g0
, g0
, g0
);
310 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
311 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
312 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
314 EXPECT_FALSE(validate(p
));
316 clear_instructions(p
);
318 brw_ADD(p
, g0
, g0
, g0
);
319 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
320 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
321 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
323 EXPECT_FALSE(validate(p
));
326 /* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */
327 TEST_P(validation_test
, scalar_region_must_be_0_1_0
)
329 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
331 brw_ADD(p
, g0
, g0
, g0_0
);
332 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
333 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
334 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
335 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
337 EXPECT_FALSE(validate(p
));
339 clear_instructions(p
);
341 brw_ADD(p
, g0
, g0_0
, g0
);
342 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
343 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
344 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
345 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
347 EXPECT_FALSE(validate(p
));
350 /* If VertStride = HorzStride = 0, Width must be 1 regardless of the value
353 TEST_P(validation_test
, zero_stride_implies_0_1_0
)
355 brw_ADD(p
, g0
, g0
, g0
);
356 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
357 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
358 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
360 EXPECT_FALSE(validate(p
));
362 clear_instructions(p
);
364 brw_ADD(p
, g0
, g0
, g0
);
365 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
366 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
367 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
369 EXPECT_FALSE(validate(p
));
372 /* Dst.HorzStride must not be 0. */
373 TEST_P(validation_test
, dst_horizontal_stride_0
)
375 brw_ADD(p
, g0
, g0
, g0
);
376 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
378 EXPECT_FALSE(validate(p
));
380 clear_instructions(p
);
382 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
384 brw_ADD(p
, g0
, g0
, g0
);
385 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
387 EXPECT_FALSE(validate(p
));
390 /* VertStride must be used to cross BRW_GENERAL_REGISTER_FILE register boundaries. This rule implies
391 * that elements within a 'Width' cannot cross BRW_GENERAL_REGISTER_FILE boundaries.
393 TEST_P(validation_test
, must_not_cross_grf_boundary_in_a_width
)
395 brw_ADD(p
, g0
, g0
, g0
);
396 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 4);
398 EXPECT_FALSE(validate(p
));
400 clear_instructions(p
);
402 brw_ADD(p
, g0
, g0
, g0
);
403 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 4);
405 EXPECT_FALSE(validate(p
));
407 clear_instructions(p
);
409 brw_ADD(p
, g0
, g0
, g0
);
410 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
411 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
412 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
414 EXPECT_FALSE(validate(p
));
416 clear_instructions(p
);
418 brw_ADD(p
, g0
, g0
, g0
);
419 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
420 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
421 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
423 EXPECT_FALSE(validate(p
));
426 /* Destination Horizontal must be 1 in Align16 */
427 TEST_P(validation_test
, dst_hstride_on_align16_must_be_1
)
429 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
431 brw_ADD(p
, g0
, g0
, g0
);
432 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
434 EXPECT_FALSE(validate(p
));
436 clear_instructions(p
);
438 brw_ADD(p
, g0
, g0
, g0
);
439 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
441 EXPECT_TRUE(validate(p
));
444 /* VertStride must be 0 or 4 in Align16 */
445 TEST_P(validation_test
, vstride_on_align16_must_be_0_or_4
)
448 enum brw_vertical_stride vstride
;
449 bool expected_result
;
451 { BRW_VERTICAL_STRIDE_0
, true },
452 { BRW_VERTICAL_STRIDE_1
, false },
453 { BRW_VERTICAL_STRIDE_2
, devinfo
.is_haswell
|| devinfo
.gen
>= 8 },
454 { BRW_VERTICAL_STRIDE_4
, true },
455 { BRW_VERTICAL_STRIDE_8
, false },
456 { BRW_VERTICAL_STRIDE_16
, false },
457 { BRW_VERTICAL_STRIDE_32
, false },
458 { BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL
, false },
461 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
463 for (unsigned i
= 0; i
< sizeof(vstride
) / sizeof(vstride
[0]); i
++) {
464 brw_ADD(p
, g0
, g0
, g0
);
465 brw_inst_set_src0_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
467 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
469 clear_instructions(p
);
472 for (unsigned i
= 0; i
< sizeof(vstride
) / sizeof(vstride
[0]); i
++) {
473 brw_ADD(p
, g0
, g0
, g0
);
474 brw_inst_set_src1_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
476 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
478 clear_instructions(p
);
482 /* In Direct Addressing mode, a source cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE
485 TEST_P(validation_test
, source_cannot_span_more_than_2_registers
)
487 brw_ADD(p
, g0
, g0
, g0
);
488 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
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
);
496 EXPECT_FALSE(validate(p
));
498 clear_instructions(p
);
500 brw_ADD(p
, g0
, g0
, g0
);
501 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
502 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
503 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
504 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
505 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
506 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
507 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
508 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 2);
510 EXPECT_TRUE(validate(p
));
512 clear_instructions(p
);
514 brw_ADD(p
, g0
, g0
, g0
);
515 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
517 EXPECT_TRUE(validate(p
));
520 /* A destination cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE registers. */
521 TEST_P(validation_test
, destination_cannot_span_more_than_2_registers
)
523 brw_ADD(p
, g0
, g0
, g0
);
524 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
525 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
526 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
527 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
528 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
530 EXPECT_FALSE(validate(p
));
532 clear_instructions(p
);
534 brw_ADD(p
, g0
, g0
, g0
);
535 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_8
);
536 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 6);
537 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
538 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
539 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
540 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
541 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
542 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
543 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
544 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
545 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
546 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
548 EXPECT_TRUE(validate(p
));
551 TEST_P(validation_test
, src_region_spans_two_regs_dst_region_spans_one
)
553 /* Writes to dest are to the lower OWord */
554 brw_ADD(p
, g0
, g0
, g0
);
555 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
556 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
557 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
558 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
559 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
560 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
562 EXPECT_TRUE(validate(p
));
564 clear_instructions(p
);
566 /* Writes to dest are to the upper OWord */
567 brw_ADD(p
, g0
, g0
, g0
);
568 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 16);
569 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
570 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
571 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
572 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
573 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
574 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
576 EXPECT_TRUE(validate(p
));
578 clear_instructions(p
);
580 /* Writes to dest are evenly split between OWords */
581 brw_ADD(p
, g0
, g0
, g0
);
582 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
583 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
584 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
585 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
586 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
587 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
588 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
590 EXPECT_TRUE(validate(p
));
592 clear_instructions(p
);
594 /* Writes to dest are uneven between OWords */
595 brw_ADD(p
, g0
, g0
, g0
);
596 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
597 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 10);
598 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
599 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
600 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
601 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
602 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
603 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
604 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
605 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
606 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
608 if (devinfo
.gen
>= 9) {
609 EXPECT_TRUE(validate(p
));
611 EXPECT_FALSE(validate(p
));
615 TEST_P(validation_test
, dst_elements_must_be_evenly_split_between_registers
)
617 brw_ADD(p
, g0
, g0
, g0
);
618 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
620 if (devinfo
.gen
>= 9) {
621 EXPECT_TRUE(validate(p
));
623 EXPECT_FALSE(validate(p
));
626 clear_instructions(p
);
628 brw_ADD(p
, g0
, g0
, g0
);
629 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
631 EXPECT_TRUE(validate(p
));
633 clear_instructions(p
);
635 if (devinfo
.gen
>= 6) {
636 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
638 EXPECT_TRUE(validate(p
));
640 clear_instructions(p
);
642 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
643 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
645 EXPECT_FALSE(validate(p
));
649 TEST_P(validation_test
, two_src_two_dst_source_offsets_must_be_same
)
651 brw_ADD(p
, g0
, g0
, g0
);
652 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
653 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
654 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 16);
655 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_2
);
656 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
657 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
658 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
659 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
660 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
662 if (devinfo
.gen
<= 7) {
663 EXPECT_FALSE(validate(p
));
665 EXPECT_TRUE(validate(p
));
668 clear_instructions(p
);
670 brw_ADD(p
, g0
, g0
, g0
);
671 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
672 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
673 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
674 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
675 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
676 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_8
);
677 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
678 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
680 EXPECT_TRUE(validate(p
));
683 TEST_P(validation_test
, two_src_two_dst_each_dst_must_be_derived_from_one_src
)
686 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
687 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
688 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
689 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
690 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 8);
691 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
692 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
693 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
695 if (devinfo
.gen
<= 7) {
696 EXPECT_FALSE(validate(p
));
698 EXPECT_TRUE(validate(p
));
701 clear_instructions(p
);
704 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 16);
705 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 8);
706 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_2
);
707 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
708 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
710 if (devinfo
.gen
<= 7) {
711 EXPECT_FALSE(validate(p
));
713 EXPECT_TRUE(validate(p
));
717 TEST_P(validation_test
, one_src_two_dst
)
719 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
721 brw_ADD(p
, g0
, g0_0
, g0_0
);
722 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
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_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_D
);
731 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
732 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
734 EXPECT_TRUE(validate(p
));
736 clear_instructions(p
);
738 brw_ADD(p
, g0
, g0
, g0
);
739 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
740 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
741 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
742 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
743 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
744 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
745 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
746 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
748 if (devinfo
.gen
>= 8) {
749 EXPECT_TRUE(validate(p
));
751 EXPECT_FALSE(validate(p
));
754 clear_instructions(p
);
756 brw_ADD(p
, g0
, g0
, g0
);
757 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
758 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
759 brw_inst_set_dst_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
760 brw_inst_set_src0_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
761 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
762 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
763 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
764 brw_inst_set_src1_file_type(&devinfo
, last_inst
, BRW_GENERAL_REGISTER_FILE
, BRW_REGISTER_TYPE_W
);
766 if (devinfo
.gen
>= 8) {
767 EXPECT_TRUE(validate(p
));
769 EXPECT_FALSE(validate(p
));
773 TEST_P(validation_test
, packed_byte_destination
)
775 static const struct {
776 enum brw_reg_type dst_type
;
777 enum brw_reg_type src_type
;
779 bool expected_result
;
781 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 0, 0, true },
782 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 0, 0, true },
783 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 0, 0, true },
784 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 0, 0, true },
786 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 1, 0, 0, false },
787 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 1, 0, 0, false },
788 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 1, 0, 0, false },
789 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 1, 0, 0, false },
791 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 1, 0, false },
792 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 1, 0, false },
793 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 1, 0, false },
794 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 1, 0, false },
796 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 0, 1, false },
797 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 0, 1, false },
798 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 0, 1, false },
799 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 0, 1, false },
801 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UW
, 0, 0, 0, false },
802 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_W
, 0, 0, 0, false },
803 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UD
, 0, 0, 0, false },
804 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_D
, 0, 0, 0, false },
807 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
808 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(g0
, move
[i
].src_type
));
809 brw_inst_set_src0_negate(&devinfo
, last_inst
, move
[i
].neg
);
810 brw_inst_set_src0_abs(&devinfo
, last_inst
, move
[i
].abs
);
811 brw_inst_set_saturate(&devinfo
, last_inst
, move
[i
].sat
);
813 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
815 clear_instructions(p
);
818 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_UB
),
819 retype(g0
, BRW_REGISTER_TYPE_UB
),
820 retype(g0
, BRW_REGISTER_TYPE_UB
));
821 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
823 EXPECT_FALSE(validate(p
));
825 clear_instructions(p
);
827 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
828 retype(g0
, BRW_REGISTER_TYPE_B
),
829 retype(g0
, BRW_REGISTER_TYPE_B
));
830 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
832 EXPECT_FALSE(validate(p
));
835 TEST_P(validation_test
, byte_destination_relaxed_alignment
)
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
);
843 EXPECT_TRUE(validate(p
));
845 clear_instructions(p
);
847 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
848 retype(g0
, BRW_REGISTER_TYPE_W
),
849 retype(g0
, BRW_REGISTER_TYPE_W
));
850 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
851 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
852 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 1);
854 if (devinfo
.gen
> 4 || devinfo
.is_g4x
) {
855 EXPECT_TRUE(validate(p
));
857 EXPECT_FALSE(validate(p
));
861 TEST_P(validation_test
, vector_immediate_destination_alignment
)
863 static const struct {
864 enum brw_reg_type dst_type
;
865 enum brw_reg_type src_type
;
868 bool expected_result
;
870 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 0, BRW_EXECUTE_4
, true },
871 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 16, BRW_EXECUTE_4
, true },
872 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 1, BRW_EXECUTE_4
, false },
874 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 0, BRW_EXECUTE_8
, true },
875 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 16, BRW_EXECUTE_8
, true },
876 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 1, BRW_EXECUTE_8
, false },
878 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 0, BRW_EXECUTE_8
, true },
879 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 16, BRW_EXECUTE_8
, true },
880 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 1, BRW_EXECUTE_8
, false },
883 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
884 /* UV type is Gen6+ */
885 if (devinfo
.gen
< 6 &&
886 move
[i
].src_type
== BRW_REGISTER_TYPE_UV
)
889 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(zero
, move
[i
].src_type
));
890 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, move
[i
].subnr
);
891 brw_inst_set_exec_size(&devinfo
, last_inst
, move
[i
].exec_size
);
893 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
895 clear_instructions(p
);
899 TEST_P(validation_test
, vector_immediate_destination_stride
)
901 static const struct {
902 enum brw_reg_type dst_type
;
903 enum brw_reg_type src_type
;
905 bool expected_result
;
907 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_1
, true },
908 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, false },
909 { BRW_REGISTER_TYPE_D
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_1
, true },
910 { BRW_REGISTER_TYPE_D
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, false },
911 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, true },
912 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_4
, true },
914 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_1
, true },
915 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_2
, false },
916 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_4
, false },
917 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_2
, true },
919 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_1
, true },
920 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_2
, false },
921 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_4
, false },
922 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_2
, true },
925 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
926 /* UV type is Gen6+ */
927 if (devinfo
.gen
< 6 &&
928 move
[i
].src_type
== BRW_REGISTER_TYPE_UV
)
931 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(zero
, move
[i
].src_type
));
932 brw_inst_set_dst_hstride(&devinfo
, last_inst
, move
[i
].stride
);
934 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
936 clear_instructions(p
);
940 TEST_P(validation_test
, qword_low_power_align1_regioning_restrictions
)
942 static const struct {
946 enum brw_reg_type dst_type
;
950 enum brw_reg_type src_type
;
952 unsigned src_vstride
;
954 unsigned src_hstride
;
956 bool expected_result
;
958 #define INST(opcode, exec_size, dst_type, dst_subreg, dst_stride, src_type, \
959 src_subreg, src_vstride, src_width, src_hstride, expected_result) \
961 BRW_OPCODE_##opcode, \
962 BRW_EXECUTE_##exec_size, \
963 BRW_REGISTER_TYPE_##dst_type, \
965 BRW_HORIZONTAL_STRIDE_##dst_stride, \
966 BRW_REGISTER_TYPE_##src_type, \
968 BRW_VERTICAL_STRIDE_##src_vstride, \
969 BRW_WIDTH_##src_width, \
970 BRW_HORIZONTAL_STRIDE_##src_hstride, \
974 /* Some instruction that violate no restrictions, as a control */
975 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 4, 4, 1, true ),
976 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 4, 4, 1, true ),
977 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 4, 4, 1, true ),
979 INST(MOV
, 4, DF
, 0, 1, F
, 0, 8, 4, 2, true ),
980 INST(MOV
, 4, Q
, 0, 1, D
, 0, 8, 4, 2, true ),
981 INST(MOV
, 4, UQ
, 0, 1, UD
, 0, 8, 4, 2, true ),
983 INST(MOV
, 4, F
, 0, 2, DF
, 0, 4, 4, 1, true ),
984 INST(MOV
, 4, D
, 0, 2, Q
, 0, 4, 4, 1, true ),
985 INST(MOV
, 4, UD
, 0, 2, UQ
, 0, 4, 4, 1, true ),
987 INST(MUL
, 8, D
, 0, 2, D
, 0, 8, 4, 2, true ),
988 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 8, 4, 2, true ),
990 /* Something with subreg nrs */
991 INST(MOV
, 2, DF
, 8, 1, DF
, 8, 2, 2, 1, true ),
992 INST(MOV
, 2, Q
, 8, 1, Q
, 8, 2, 2, 1, true ),
993 INST(MOV
, 2, UQ
, 8, 1, UQ
, 8, 2, 2, 1, true ),
995 INST(MUL
, 2, D
, 4, 2, D
, 4, 4, 2, 2, true ),
996 INST(MUL
, 2, UD
, 4, 2, UD
, 4, 4, 2, 2, true ),
998 /* The PRMs say that for CHV, BXT:
1000 * When source or destination datatype is 64b or operation is integer
1001 * DWord multiply, regioning in Align1 must follow these rules:
1003 * 1. Source and Destination horizontal stride must be aligned to the
1006 INST(MOV
, 4, DF
, 0, 2, DF
, 0, 4, 4, 1, false),
1007 INST(MOV
, 4, Q
, 0, 2, Q
, 0, 4, 4, 1, false),
1008 INST(MOV
, 4, UQ
, 0, 2, UQ
, 0, 4, 4, 1, false),
1010 INST(MOV
, 4, DF
, 0, 2, F
, 0, 8, 4, 2, false),
1011 INST(MOV
, 4, Q
, 0, 2, D
, 0, 8, 4, 2, false),
1012 INST(MOV
, 4, UQ
, 0, 2, UD
, 0, 8, 4, 2, false),
1014 INST(MOV
, 4, DF
, 0, 2, F
, 0, 4, 4, 1, false),
1015 INST(MOV
, 4, Q
, 0, 2, D
, 0, 4, 4, 1, false),
1016 INST(MOV
, 4, UQ
, 0, 2, UD
, 0, 4, 4, 1, false),
1018 INST(MUL
, 4, D
, 0, 2, D
, 0, 4, 4, 1, false),
1019 INST(MUL
, 4, UD
, 0, 2, UD
, 0, 4, 4, 1, false),
1021 INST(MUL
, 4, D
, 0, 1, D
, 0, 8, 4, 2, false),
1022 INST(MUL
, 4, UD
, 0, 1, UD
, 0, 8, 4, 2, false),
1024 /* 2. Regioning must ensure Src.Vstride = Src.Width * Src.Hstride. */
1025 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 0, 2, 1, false),
1026 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 0, 2, 1, false),
1027 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 0, 2, 1, false),
1029 INST(MOV
, 4, DF
, 0, 1, F
, 0, 0, 2, 2, false),
1030 INST(MOV
, 4, Q
, 0, 1, D
, 0, 0, 2, 2, false),
1031 INST(MOV
, 4, UQ
, 0, 1, UD
, 0, 0, 2, 2, false),
1033 INST(MOV
, 8, F
, 0, 2, DF
, 0, 0, 2, 1, false),
1034 INST(MOV
, 8, D
, 0, 2, Q
, 0, 0, 2, 1, false),
1035 INST(MOV
, 8, UD
, 0, 2, UQ
, 0, 0, 2, 1, false),
1037 INST(MUL
, 8, D
, 0, 2, D
, 0, 0, 4, 2, false),
1038 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 0, 4, 2, false),
1040 INST(MUL
, 8, D
, 0, 2, D
, 0, 0, 4, 2, false),
1041 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 0, 4, 2, false),
1043 /* 3. Source and Destination offset must be the same, except the case
1046 INST(MOV
, 2, DF
, 8, 1, DF
, 0, 2, 2, 1, false),
1047 INST(MOV
, 2, Q
, 8, 1, Q
, 0, 2, 2, 1, false),
1048 INST(MOV
, 2, UQ
, 8, 1, UQ
, 0, 2, 2, 1, false),
1050 INST(MOV
, 2, DF
, 0, 1, DF
, 8, 2, 2, 1, false),
1051 INST(MOV
, 2, Q
, 0, 1, Q
, 8, 2, 2, 1, false),
1052 INST(MOV
, 2, UQ
, 0, 1, UQ
, 8, 2, 2, 1, false),
1054 INST(MUL
, 4, D
, 4, 2, D
, 0, 4, 2, 2, false),
1055 INST(MUL
, 4, UD
, 4, 2, UD
, 0, 4, 2, 2, false),
1057 INST(MUL
, 4, D
, 0, 2, D
, 4, 4, 2, 2, false),
1058 INST(MUL
, 4, UD
, 0, 2, UD
, 4, 4, 2, 2, false),
1060 INST(MOV
, 2, DF
, 8, 1, DF
, 0, 0, 1, 0, true ),
1061 INST(MOV
, 2, Q
, 8, 1, Q
, 0, 0, 1, 0, true ),
1062 INST(MOV
, 2, UQ
, 8, 1, UQ
, 0, 0, 1, 0, true ),
1064 INST(MOV
, 2, DF
, 8, 1, F
, 4, 0, 1, 0, true ),
1065 INST(MOV
, 2, Q
, 8, 1, D
, 4, 0, 1, 0, true ),
1066 INST(MOV
, 2, UQ
, 8, 1, UD
, 4, 0, 1, 0, true ),
1068 INST(MUL
, 4, D
, 4, 1, D
, 0, 0, 1, 0, true ),
1069 INST(MUL
, 4, UD
, 4, 1, UD
, 0, 0, 1, 0, true ),
1071 INST(MUL
, 4, D
, 0, 1, D
, 4, 0, 1, 0, true ),
1072 INST(MUL
, 4, UD
, 0, 1, UD
, 4, 0, 1, 0, true ),
1077 /* These restrictions only apply to Gen8+ */
1078 if (devinfo
.gen
< 8)
1081 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1082 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1083 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
1084 retype(g0
, inst
[i
].src_type
));
1086 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
1087 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
1088 retype(g0
, inst
[i
].src_type
),
1089 retype(zero
, inst
[i
].src_type
));
1091 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1093 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].dst_subreg
);
1094 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, inst
[i
].src_subreg
);
1096 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1098 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
1099 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
1100 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
1102 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1103 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1105 EXPECT_TRUE(validate(p
));
1108 clear_instructions(p
);
1112 TEST_P(validation_test
, qword_low_power_no_indirect_addressing
)
1114 static const struct {
1118 enum brw_reg_type dst_type
;
1119 bool dst_is_indirect
;
1120 unsigned dst_stride
;
1122 enum brw_reg_type src_type
;
1123 bool src_is_indirect
;
1124 unsigned src_vstride
;
1126 unsigned src_hstride
;
1128 bool expected_result
;
1130 #define INST(opcode, exec_size, dst_type, dst_is_indirect, dst_stride, \
1131 src_type, src_is_indirect, src_vstride, src_width, src_hstride, \
1134 BRW_OPCODE_##opcode, \
1135 BRW_EXECUTE_##exec_size, \
1136 BRW_REGISTER_TYPE_##dst_type, \
1138 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1139 BRW_REGISTER_TYPE_##src_type, \
1141 BRW_VERTICAL_STRIDE_##src_vstride, \
1142 BRW_WIDTH_##src_width, \
1143 BRW_HORIZONTAL_STRIDE_##src_hstride, \
1147 /* Some instruction that violate no restrictions, as a control */
1148 INST(MOV
, 4, DF
, 0, 1, DF
, 0, 4, 4, 1, true ),
1149 INST(MOV
, 4, Q
, 0, 1, Q
, 0, 4, 4, 1, true ),
1150 INST(MOV
, 4, UQ
, 0, 1, UQ
, 0, 4, 4, 1, true ),
1152 INST(MUL
, 8, D
, 0, 2, D
, 0, 8, 4, 2, true ),
1153 INST(MUL
, 8, UD
, 0, 2, UD
, 0, 8, 4, 2, true ),
1155 INST(MOV
, 4, F
, 1, 1, F
, 0, 4, 4, 1, true ),
1156 INST(MOV
, 4, F
, 0, 1, F
, 1, 4, 4, 1, true ),
1157 INST(MOV
, 4, F
, 1, 1, F
, 1, 4, 4, 1, true ),
1159 /* The PRMs say that for CHV, BXT:
1161 * When source or destination datatype is 64b or operation is integer
1162 * DWord multiply, indirect addressing must not be used.
1164 INST(MOV
, 4, DF
, 1, 1, DF
, 0, 4, 4, 1, false),
1165 INST(MOV
, 4, Q
, 1, 1, Q
, 0, 4, 4, 1, false),
1166 INST(MOV
, 4, UQ
, 1, 1, UQ
, 0, 4, 4, 1, false),
1168 INST(MOV
, 4, DF
, 0, 1, DF
, 1, 4, 4, 1, false),
1169 INST(MOV
, 4, Q
, 0, 1, Q
, 1, 4, 4, 1, false),
1170 INST(MOV
, 4, UQ
, 0, 1, UQ
, 1, 4, 4, 1, false),
1172 INST(MOV
, 4, DF
, 1, 1, F
, 0, 8, 4, 2, false),
1173 INST(MOV
, 4, Q
, 1, 1, D
, 0, 8, 4, 2, false),
1174 INST(MOV
, 4, UQ
, 1, 1, UD
, 0, 8, 4, 2, false),
1176 INST(MOV
, 4, DF
, 0, 1, F
, 1, 8, 4, 2, false),
1177 INST(MOV
, 4, Q
, 0, 1, D
, 1, 8, 4, 2, false),
1178 INST(MOV
, 4, UQ
, 0, 1, UD
, 1, 8, 4, 2, false),
1180 INST(MOV
, 4, F
, 1, 2, DF
, 0, 4, 4, 1, false),
1181 INST(MOV
, 4, D
, 1, 2, Q
, 0, 4, 4, 1, false),
1182 INST(MOV
, 4, UD
, 1, 2, UQ
, 0, 4, 4, 1, false),
1184 INST(MOV
, 4, F
, 0, 2, DF
, 1, 4, 4, 1, false),
1185 INST(MOV
, 4, D
, 0, 2, Q
, 1, 4, 4, 1, false),
1186 INST(MOV
, 4, UD
, 0, 2, UQ
, 1, 4, 4, 1, false),
1188 INST(MUL
, 8, D
, 1, 2, D
, 0, 8, 4, 2, false),
1189 INST(MUL
, 8, UD
, 1, 2, UD
, 0, 8, 4, 2, false),
1191 INST(MUL
, 8, D
, 0, 2, D
, 1, 8, 4, 2, false),
1192 INST(MUL
, 8, UD
, 0, 2, UD
, 1, 8, 4, 2, false),
1197 /* These restrictions only apply to Gen8+ */
1198 if (devinfo
.gen
< 8)
1201 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1202 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1203 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
1204 retype(g0
, inst
[i
].src_type
));
1206 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
1207 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
1208 retype(g0
, inst
[i
].src_type
),
1209 retype(zero
, inst
[i
].src_type
));
1211 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1213 brw_inst_set_dst_address_mode(&devinfo
, last_inst
, inst
[i
].dst_is_indirect
);
1214 brw_inst_set_src0_address_mode(&devinfo
, last_inst
, inst
[i
].src_is_indirect
);
1216 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1218 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
1219 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
1220 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
1222 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1223 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1225 EXPECT_TRUE(validate(p
));
1228 clear_instructions(p
);
1232 TEST_P(validation_test
, qword_low_power_no_64bit_arf
)
1234 static const struct {
1239 enum brw_reg_type dst_type
;
1240 unsigned dst_stride
;
1243 enum brw_reg_type src_type
;
1244 unsigned src_vstride
;
1246 unsigned src_hstride
;
1249 bool expected_result
;
1251 #define INST(opcode, exec_size, dst, dst_type, dst_stride, \
1252 src, src_type, src_vstride, src_width, src_hstride, \
1253 acc_wr, expected_result) \
1255 BRW_OPCODE_##opcode, \
1256 BRW_EXECUTE_##exec_size, \
1258 BRW_REGISTER_TYPE_##dst_type, \
1259 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1261 BRW_REGISTER_TYPE_##src_type, \
1262 BRW_VERTICAL_STRIDE_##src_vstride, \
1263 BRW_WIDTH_##src_width, \
1264 BRW_HORIZONTAL_STRIDE_##src_hstride, \
1269 /* Some instruction that violate no restrictions, as a control */
1270 INST(MOV
, 4, g0
, DF
, 1, g0
, F
, 4, 2, 2, 0, true ),
1271 INST(MOV
, 4, g0
, F
, 2, g0
, DF
, 4, 4, 1, 0, true ),
1273 INST(MOV
, 4, g0
, Q
, 1, g0
, D
, 4, 2, 2, 0, true ),
1274 INST(MOV
, 4, g0
, D
, 2, g0
, Q
, 4, 4, 1, 0, true ),
1276 INST(MOV
, 4, g0
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, true ),
1277 INST(MOV
, 4, g0
, UD
, 2, g0
, UQ
, 4, 4, 1, 0, true ),
1279 INST(MOV
, 4, null
, F
, 1, g0
, F
, 4, 4, 1, 0, true ),
1280 INST(MOV
, 4, acc0
, F
, 1, g0
, F
, 4, 4, 1, 0, true ),
1281 INST(MOV
, 4, g0
, F
, 1, acc0
, F
, 4, 4, 1, 0, true ),
1283 INST(MOV
, 4, null
, D
, 1, g0
, D
, 4, 4, 1, 0, true ),
1284 INST(MOV
, 4, acc0
, D
, 1, g0
, D
, 4, 4, 1, 0, true ),
1285 INST(MOV
, 4, g0
, D
, 1, acc0
, D
, 4, 4, 1, 0, true ),
1287 INST(MOV
, 4, null
, UD
, 1, g0
, UD
, 4, 4, 1, 0, true ),
1288 INST(MOV
, 4, acc0
, UD
, 1, g0
, UD
, 4, 4, 1, 0, true ),
1289 INST(MOV
, 4, g0
, UD
, 1, acc0
, UD
, 4, 4, 1, 0, true ),
1291 INST(MUL
, 4, g0
, D
, 2, g0
, D
, 4, 2, 2, 0, true ),
1292 INST(MUL
, 4, g0
, UD
, 2, g0
, UD
, 4, 2, 2, 0, true ),
1294 /* The PRMs say that for CHV, BXT:
1296 * ARF registers must never be used with 64b datatype or when
1297 * operation is integer DWord multiply.
1299 INST(MOV
, 4, acc0
, DF
, 1, g0
, F
, 4, 2, 2, 0, false),
1300 INST(MOV
, 4, g0
, DF
, 1, acc0
, F
, 4, 2, 2, 0, false),
1302 INST(MOV
, 4, acc0
, Q
, 1, g0
, D
, 4, 2, 2, 0, false),
1303 INST(MOV
, 4, g0
, Q
, 1, acc0
, D
, 4, 2, 2, 0, false),
1305 INST(MOV
, 4, acc0
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, false),
1306 INST(MOV
, 4, g0
, UQ
, 1, acc0
, UD
, 4, 2, 2, 0, false),
1308 INST(MOV
, 4, acc0
, F
, 2, g0
, DF
, 4, 4, 1, 0, false),
1309 INST(MOV
, 4, g0
, F
, 2, acc0
, DF
, 4, 4, 1, 0, false),
1311 INST(MOV
, 4, acc0
, D
, 2, g0
, Q
, 4, 4, 1, 0, false),
1312 INST(MOV
, 4, g0
, D
, 2, acc0
, Q
, 4, 4, 1, 0, false),
1314 INST(MOV
, 4, acc0
, UD
, 2, g0
, UQ
, 4, 4, 1, 0, false),
1315 INST(MOV
, 4, g0
, UD
, 2, acc0
, UQ
, 4, 4, 1, 0, false),
1317 INST(MUL
, 4, acc0
, D
, 2, g0
, D
, 4, 2, 2, 0, false),
1318 INST(MUL
, 4, acc0
, UD
, 2, g0
, UD
, 4, 2, 2, 0, false),
1319 /* MUL cannot have integer accumulator sources, so don't test that */
1321 /* We assume that the restriction does not apply to the null register */
1322 INST(MOV
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 0, true ),
1323 INST(MOV
, 4, null
, Q
, 1, g0
, D
, 4, 2, 2, 0, true ),
1324 INST(MOV
, 4, null
, UQ
, 1, g0
, UD
, 4, 2, 2, 0, true ),
1326 /* Check implicit accumulator write control */
1327 INST(MOV
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 1, false),
1328 INST(MUL
, 4, null
, DF
, 1, g0
, F
, 4, 2, 2, 1, false),
1333 /* These restrictions only apply to Gen8+ */
1334 if (devinfo
.gen
< 8)
1337 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1338 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1339 brw_MOV(p
, retype(inst
[i
].dst
, inst
[i
].dst_type
),
1340 retype(inst
[i
].src
, inst
[i
].src_type
));
1342 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
1343 brw_MUL(p
, retype(inst
[i
].dst
, inst
[i
].dst_type
),
1344 retype(inst
[i
].src
, inst
[i
].src_type
),
1345 retype(zero
, inst
[i
].src_type
));
1346 brw_inst_set_opcode(&devinfo
, last_inst
, inst
[i
].opcode
);
1348 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1349 brw_inst_set_acc_wr_control(&devinfo
, last_inst
, inst
[i
].acc_wr
);
1351 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1353 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
1354 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
1355 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
1357 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1358 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1360 EXPECT_TRUE(validate(p
));
1363 clear_instructions(p
);
1366 /* MAC implicitly reads the accumulator */
1367 brw_MAC(p
, retype(g0
, BRW_REGISTER_TYPE_DF
),
1368 retype(stride(g0
, 4, 4, 1), BRW_REGISTER_TYPE_DF
),
1369 retype(stride(g0
, 4, 4, 1), BRW_REGISTER_TYPE_DF
));
1370 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1371 EXPECT_FALSE(validate(p
));
1373 EXPECT_TRUE(validate(p
));
1377 TEST_P(validation_test
, align16_64_bit_integer
)
1379 static const struct {
1383 enum brw_reg_type dst_type
;
1384 enum brw_reg_type src_type
;
1386 bool expected_result
;
1388 #define INST(opcode, exec_size, dst_type, src_type, expected_result) \
1390 BRW_OPCODE_##opcode, \
1391 BRW_EXECUTE_##exec_size, \
1392 BRW_REGISTER_TYPE_##dst_type, \
1393 BRW_REGISTER_TYPE_##src_type, \
1397 /* Some instruction that violate no restrictions, as a control */
1398 INST(MOV
, 2, Q
, D
, true ),
1399 INST(MOV
, 2, UQ
, UD
, true ),
1400 INST(MOV
, 2, DF
, F
, true ),
1402 INST(ADD
, 2, Q
, D
, true ),
1403 INST(ADD
, 2, UQ
, UD
, true ),
1404 INST(ADD
, 2, DF
, F
, true ),
1406 /* The PRMs say that for BDW, SKL:
1408 * If Align16 is required for an operation with QW destination and non-QW
1409 * source datatypes, the execution size cannot exceed 2.
1412 INST(MOV
, 4, Q
, D
, false),
1413 INST(MOV
, 4, UQ
, UD
, false),
1414 INST(MOV
, 4, DF
, F
, false),
1416 INST(ADD
, 4, Q
, D
, false),
1417 INST(ADD
, 4, UQ
, UD
, false),
1418 INST(ADD
, 4, DF
, F
, false),
1423 /* 64-bit integer types exist on Gen8+ */
1424 if (devinfo
.gen
< 8)
1427 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
1429 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1430 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1431 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
1432 retype(g0
, inst
[i
].src_type
));
1434 assert(inst
[i
].opcode
== BRW_OPCODE_ADD
);
1435 brw_ADD(p
, retype(g0
, inst
[i
].dst_type
),
1436 retype(g0
, inst
[i
].src_type
),
1437 retype(g0
, inst
[i
].src_type
));
1439 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1441 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1443 clear_instructions(p
);
1447 TEST_P(validation_test
, qword_low_power_no_depctrl
)
1449 static const struct {
1453 enum brw_reg_type dst_type
;
1454 unsigned dst_stride
;
1456 enum brw_reg_type src_type
;
1457 unsigned src_vstride
;
1459 unsigned src_hstride
;
1464 bool expected_result
;
1466 #define INST(opcode, exec_size, dst_type, dst_stride, \
1467 src_type, src_vstride, src_width, src_hstride, \
1468 no_dd_check, no_dd_clear, expected_result) \
1470 BRW_OPCODE_##opcode, \
1471 BRW_EXECUTE_##exec_size, \
1472 BRW_REGISTER_TYPE_##dst_type, \
1473 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1474 BRW_REGISTER_TYPE_##src_type, \
1475 BRW_VERTICAL_STRIDE_##src_vstride, \
1476 BRW_WIDTH_##src_width, \
1477 BRW_HORIZONTAL_STRIDE_##src_hstride, \
1483 /* Some instruction that violate no restrictions, as a control */
1484 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 0, 0, true ),
1485 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 0, 0, true ),
1486 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 0, 0, true ),
1488 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 0, 0, true ),
1489 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 0, 0, true ),
1490 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 0, 0, true ),
1492 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 0, 0, true ),
1493 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 0, 0, true ),
1495 INST(MOV
, 4, F
, 1, F
, 4, 4, 1, 1, 1, true ),
1497 /* The PRMs say that for CHV, BXT:
1499 * When source or destination datatype is 64b or operation is integer
1500 * DWord multiply, DepCtrl must not be used.
1502 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 1, 0, false),
1503 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 1, 0, false),
1504 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 1, 0, false),
1506 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 1, 0, false),
1507 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 1, 0, false),
1508 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 1, 0, false),
1510 INST(MOV
, 4, DF
, 1, F
, 8, 4, 2, 0, 1, false),
1511 INST(MOV
, 4, Q
, 1, D
, 8, 4, 2, 0, 1, false),
1512 INST(MOV
, 4, UQ
, 1, UD
, 8, 4, 2, 0, 1, false),
1514 INST(MOV
, 4, F
, 2, DF
, 4, 4, 1, 0, 1, false),
1515 INST(MOV
, 4, D
, 2, Q
, 4, 4, 1, 0, 1, false),
1516 INST(MOV
, 4, UD
, 2, UQ
, 4, 4, 1, 0, 1, false),
1518 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 1, 0, false),
1519 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 1, 0, false),
1521 INST(MUL
, 8, D
, 2, D
, 8, 4, 2, 0, 1, false),
1522 INST(MUL
, 8, UD
, 2, UD
, 8, 4, 2, 0, 1, false),
1527 /* These restrictions only apply to Gen8+ */
1528 if (devinfo
.gen
< 8)
1531 for (unsigned i
= 0; i
< sizeof(inst
) / sizeof(inst
[0]); i
++) {
1532 if (inst
[i
].opcode
== BRW_OPCODE_MOV
) {
1533 brw_MOV(p
, retype(g0
, inst
[i
].dst_type
),
1534 retype(g0
, inst
[i
].src_type
));
1536 assert(inst
[i
].opcode
== BRW_OPCODE_MUL
);
1537 brw_MUL(p
, retype(g0
, inst
[i
].dst_type
),
1538 retype(g0
, inst
[i
].src_type
),
1539 retype(zero
, inst
[i
].src_type
));
1541 brw_inst_set_exec_size(&devinfo
, last_inst
, inst
[i
].exec_size
);
1543 brw_inst_set_dst_hstride(&devinfo
, last_inst
, inst
[i
].dst_stride
);
1545 brw_inst_set_src0_vstride(&devinfo
, last_inst
, inst
[i
].src_vstride
);
1546 brw_inst_set_src0_width(&devinfo
, last_inst
, inst
[i
].src_width
);
1547 brw_inst_set_src0_hstride(&devinfo
, last_inst
, inst
[i
].src_hstride
);
1549 brw_inst_set_no_dd_check(&devinfo
, last_inst
, inst
[i
].no_dd_check
);
1550 brw_inst_set_no_dd_clear(&devinfo
, last_inst
, inst
[i
].no_dd_clear
);
1552 if (devinfo
.is_cherryview
|| gen_device_info_is_9lp(&devinfo
)) {
1553 EXPECT_EQ(inst
[i
].expected_result
, validate(p
));
1555 EXPECT_TRUE(validate(p
));
1558 clear_instructions(p
);