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"
37 static const struct gen_info
{
56 class validation_test
: public ::testing::TestWithParam
<struct gen_info
> {
61 virtual ~validation_test();
63 struct brw_codegen
*p
;
64 struct gen_device_info devinfo
;
67 validation_test::validation_test()
69 p
= rzalloc(NULL
, struct brw_codegen
);
70 memset(&devinfo
, 0, sizeof(devinfo
));
73 validation_test::~validation_test()
78 void validation_test::SetUp()
80 struct gen_info info
= GetParam();
82 devinfo
.gen
= info
.gen
;
83 devinfo
.is_g4x
= info
.subgen
== IS_G45
;
84 devinfo
.is_baytrail
= info
.subgen
== IS_BYT
;
85 devinfo
.is_haswell
= info
.subgen
== IS_HSW
;
86 devinfo
.is_cherryview
= info
.subgen
== IS_CHV
;
87 devinfo
.is_broxton
= info
.subgen
== IS_BXT
;
88 devinfo
.is_kabylake
= info
.subgen
== IS_KBL
;
90 brw_init_codegen(&devinfo
, p
, p
);
94 template <class ParamType
>
96 operator()(const ::testing::TestParamInfo
<ParamType
>& info
) const {
97 return info
.param
.name
;
101 INSTANTIATE_TEST_CASE_P(eu_assembly
, validation_test
,
102 ::testing::ValuesIn(gens
),
106 validate(struct brw_codegen
*p
)
108 const bool print
= getenv("TEST_DEBUG");
109 struct annotation_info annotation
;
110 memset(&annotation
, 0, sizeof(annotation
));
113 annotation
.mem_ctx
= ralloc_context(NULL
);
114 annotation
.ann_count
= 1;
115 annotation
.ann_size
= 2;
116 annotation
.ann
= rzalloc_array(annotation
.mem_ctx
, struct annotation
,
117 annotation
.ann_size
);
118 annotation
.ann
[annotation
.ann_count
].offset
= p
->next_insn_offset
;
121 bool ret
= brw_validate_instructions(devinfo
, p
->store
, 0,
122 p
->next_insn_offset
, &annotation
);
125 dump_assembly(p
->store
, annotation
.ann_count
, annotation
.ann
, p
->devinfo
);
126 ralloc_free(annotation
.mem_ctx
);
132 #define last_inst (&p->store[p->nr_insn - 1])
133 #define g0 brw_vec8_grf(0, 0)
134 #define null brw_null_reg()
137 clear_instructions(struct brw_codegen
*p
)
139 p
->next_insn_offset
= 0;
143 TEST_P(validation_test
, sanity
)
145 brw_ADD(p
, g0
, g0
, g0
);
147 EXPECT_TRUE(validate(p
));
150 TEST_P(validation_test
, src0_null_reg
)
152 brw_MOV(p
, g0
, null
);
154 EXPECT_FALSE(validate(p
));
157 TEST_P(validation_test
, src1_null_reg
)
159 brw_ADD(p
, g0
, g0
, null
);
161 EXPECT_FALSE(validate(p
));
164 TEST_P(validation_test
, math_src0_null_reg
)
166 if (devinfo
.gen
>= 6) {
167 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, null
, null
);
169 gen4_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, 0, null
, BRW_MATH_PRECISION_FULL
);
172 EXPECT_FALSE(validate(p
));
175 TEST_P(validation_test
, math_src1_null_reg
)
177 if (devinfo
.gen
>= 6) {
178 gen6_math(p
, g0
, BRW_MATH_FUNCTION_POW
, g0
, null
);
179 EXPECT_FALSE(validate(p
));
181 /* Math instructions on Gen4/5 are actually SEND messages with payloads.
182 * src1 is an immediate message descriptor set by gen4_math.
187 TEST_P(validation_test
, opcode46
)
189 /* opcode 46 is "push" on Gen 4 and 5
194 brw_next_insn(p
, 46);
196 if (devinfo
.gen
== 7) {
197 EXPECT_FALSE(validate(p
));
199 EXPECT_TRUE(validate(p
));
203 /* When the Execution Data Type is wider than the destination data type, the
204 * destination must [...] specify a HorzStride equal to the ratio in sizes of
205 * the two data types.
207 TEST_P(validation_test
, dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size
)
209 brw_ADD(p
, g0
, g0
, g0
);
210 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
211 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
212 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
214 EXPECT_FALSE(validate(p
));
216 clear_instructions(p
);
218 brw_ADD(p
, g0
, g0
, g0
);
219 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
220 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
221 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
222 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
224 EXPECT_TRUE(validate(p
));
227 /* When the Execution Data Type is wider than the destination data type, the
228 * destination must be aligned as required by the wider execution data type
231 TEST_P(validation_test
, dst_subreg_must_be_aligned_to_exec_type_size
)
233 brw_ADD(p
, g0
, g0
, g0
);
234 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 2);
235 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
236 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
237 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
238 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
240 EXPECT_FALSE(validate(p
));
242 clear_instructions(p
);
244 brw_ADD(p
, g0
, g0
, g0
);
245 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
246 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 8);
247 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
248 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
249 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
250 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
251 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
252 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
253 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
254 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
255 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
256 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
258 EXPECT_TRUE(validate(p
));
261 /* ExecSize must be greater than or equal to Width. */
262 TEST_P(validation_test
, exec_size_less_than_width
)
264 brw_ADD(p
, g0
, g0
, g0
);
265 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
267 EXPECT_FALSE(validate(p
));
269 clear_instructions(p
);
271 brw_ADD(p
, g0
, g0
, g0
);
272 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
274 EXPECT_FALSE(validate(p
));
277 /* If ExecSize = Width and HorzStride ≠ 0,
278 * VertStride must be set to Width * HorzStride.
280 TEST_P(validation_test
, vertical_stride_is_width_by_horizontal_stride
)
282 brw_ADD(p
, g0
, g0
, g0
);
283 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
285 EXPECT_FALSE(validate(p
));
287 clear_instructions(p
);
289 brw_ADD(p
, g0
, g0
, g0
);
290 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
292 EXPECT_FALSE(validate(p
));
295 /* If Width = 1, HorzStride must be 0 regardless of the values
296 * of ExecSize and VertStride.
298 TEST_P(validation_test
, horizontal_stride_must_be_0_if_width_is_1
)
300 brw_ADD(p
, g0
, g0
, g0
);
301 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
302 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
303 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
305 EXPECT_FALSE(validate(p
));
307 clear_instructions(p
);
309 brw_ADD(p
, g0
, g0
, g0
);
310 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
311 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
312 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
314 EXPECT_FALSE(validate(p
));
317 /* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */
318 TEST_P(validation_test
, scalar_region_must_be_0_1_0
)
320 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
322 brw_ADD(p
, g0
, g0
, g0_0
);
323 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
324 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
325 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
326 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
328 EXPECT_FALSE(validate(p
));
330 clear_instructions(p
);
332 brw_ADD(p
, g0
, g0_0
, g0
);
333 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
334 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
335 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
336 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
338 EXPECT_FALSE(validate(p
));
341 /* If VertStride = HorzStride = 0, Width must be 1 regardless of the value
344 TEST_P(validation_test
, zero_stride_implies_0_1_0
)
346 brw_ADD(p
, g0
, g0
, g0
);
347 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
348 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
349 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
351 EXPECT_FALSE(validate(p
));
353 clear_instructions(p
);
355 brw_ADD(p
, g0
, g0
, g0
);
356 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
357 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
358 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
360 EXPECT_FALSE(validate(p
));
363 /* Dst.HorzStride must not be 0. */
364 TEST_P(validation_test
, dst_horizontal_stride_0
)
366 brw_ADD(p
, g0
, g0
, g0
);
367 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
369 EXPECT_FALSE(validate(p
));
371 clear_instructions(p
);
373 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
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
));
381 /* VertStride must be used to cross GRF register boundaries. This rule implies
382 * that elements within a 'Width' cannot cross GRF boundaries.
384 TEST_P(validation_test
, must_not_cross_grf_boundary_in_a_width
)
386 brw_ADD(p
, g0
, g0
, g0
);
387 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 4);
389 EXPECT_FALSE(validate(p
));
391 clear_instructions(p
);
393 brw_ADD(p
, g0
, g0
, g0
);
394 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 4);
396 EXPECT_FALSE(validate(p
));
398 clear_instructions(p
);
400 brw_ADD(p
, g0
, g0
, g0
);
401 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
402 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
403 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
405 EXPECT_FALSE(validate(p
));
407 clear_instructions(p
);
409 brw_ADD(p
, g0
, g0
, g0
);
410 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
411 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
412 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
414 EXPECT_FALSE(validate(p
));
417 /* Destination Horizontal must be 1 in Align16 */
418 TEST_P(validation_test
, dst_hstride_on_align16_must_be_1
)
420 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
422 brw_ADD(p
, g0
, g0
, g0
);
423 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
425 EXPECT_FALSE(validate(p
));
427 clear_instructions(p
);
429 brw_ADD(p
, g0
, g0
, g0
);
430 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
432 EXPECT_TRUE(validate(p
));
435 /* VertStride must be 0 or 4 in Align16 */
436 TEST_P(validation_test
, vstride_on_align16_must_be_0_or_4
)
439 enum brw_vertical_stride vstride
;
440 bool expected_result
;
442 { BRW_VERTICAL_STRIDE_0
, true },
443 { BRW_VERTICAL_STRIDE_1
, false },
444 { BRW_VERTICAL_STRIDE_2
, devinfo
.is_haswell
|| devinfo
.gen
>= 8 },
445 { BRW_VERTICAL_STRIDE_4
, true },
446 { BRW_VERTICAL_STRIDE_8
, false },
447 { BRW_VERTICAL_STRIDE_16
, false },
448 { BRW_VERTICAL_STRIDE_32
, false },
449 { BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL
, false },
452 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
454 for (unsigned i
= 0; i
< sizeof(vstride
) / sizeof(vstride
[0]); i
++) {
455 brw_ADD(p
, g0
, g0
, g0
);
456 brw_inst_set_src0_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
458 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
460 clear_instructions(p
);
463 for (unsigned i
= 0; i
< sizeof(vstride
) / sizeof(vstride
[0]); i
++) {
464 brw_ADD(p
, g0
, g0
, g0
);
465 brw_inst_set_src1_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
467 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
469 clear_instructions(p
);
473 /* In Direct Addressing mode, a source cannot span more than 2 adjacent GRF
476 TEST_P(validation_test
, source_cannot_span_more_than_2_registers
)
478 brw_ADD(p
, g0
, g0
, g0
);
479 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
480 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
481 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
482 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
483 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
484 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
485 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
487 EXPECT_FALSE(validate(p
));
489 clear_instructions(p
);
491 brw_ADD(p
, g0
, g0
, g0
);
492 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
493 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
494 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
495 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
496 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
497 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
498 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
499 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 2);
501 EXPECT_TRUE(validate(p
));
503 clear_instructions(p
);
505 brw_ADD(p
, g0
, g0
, g0
);
506 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
508 EXPECT_TRUE(validate(p
));
511 /* A destination cannot span more than 2 adjacent GRF registers. */
512 TEST_P(validation_test
, destination_cannot_span_more_than_2_registers
)
514 brw_ADD(p
, g0
, g0
, g0
);
515 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
516 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
517 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
518 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
519 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
521 EXPECT_FALSE(validate(p
));
523 clear_instructions(p
);
525 brw_ADD(p
, g0
, g0
, g0
);
526 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_8
);
527 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 6);
528 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
529 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
530 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
531 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
532 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
533 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
534 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
535 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
536 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
537 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
539 EXPECT_TRUE(validate(p
));
542 TEST_P(validation_test
, src_region_spans_two_regs_dst_region_spans_one
)
544 /* Writes to dest are to the lower OWord */
545 brw_ADD(p
, g0
, g0
, g0
);
546 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
547 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
548 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
549 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
550 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
551 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
553 EXPECT_TRUE(validate(p
));
555 clear_instructions(p
);
557 /* Writes to dest are to the upper OWord */
558 brw_ADD(p
, g0
, g0
, g0
);
559 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 16);
560 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
561 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
562 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
563 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
564 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
565 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
567 EXPECT_TRUE(validate(p
));
569 clear_instructions(p
);
571 /* Writes to dest are evenly split between OWords */
572 brw_ADD(p
, g0
, g0
, g0
);
573 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
574 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
575 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
576 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
577 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
578 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
579 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
581 EXPECT_TRUE(validate(p
));
583 clear_instructions(p
);
585 /* Writes to dest are uneven between OWords */
586 brw_ADD(p
, g0
, g0
, g0
);
587 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
588 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 10);
589 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
590 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
591 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
592 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
593 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
594 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
595 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
596 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
597 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
599 if (devinfo
.gen
>= 9) {
600 EXPECT_TRUE(validate(p
));
602 EXPECT_FALSE(validate(p
));
606 TEST_P(validation_test
, dst_elements_must_be_evenly_split_between_registers
)
608 brw_ADD(p
, g0
, g0
, g0
);
609 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
611 if (devinfo
.gen
>= 9) {
612 EXPECT_TRUE(validate(p
));
614 EXPECT_FALSE(validate(p
));
617 clear_instructions(p
);
619 brw_ADD(p
, g0
, g0
, g0
);
620 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
622 EXPECT_TRUE(validate(p
));
624 clear_instructions(p
);
626 if (devinfo
.gen
>= 6) {
627 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
629 EXPECT_TRUE(validate(p
));
631 clear_instructions(p
);
633 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
634 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
636 EXPECT_FALSE(validate(p
));
640 TEST_P(validation_test
, two_src_two_dst_source_offsets_must_be_same
)
642 brw_ADD(p
, g0
, g0
, g0
);
643 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
644 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
645 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 16);
646 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_2
);
647 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
648 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
649 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
650 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
651 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
653 if (devinfo
.gen
<= 7) {
654 EXPECT_FALSE(validate(p
));
656 EXPECT_TRUE(validate(p
));
659 clear_instructions(p
);
661 brw_ADD(p
, g0
, g0
, g0
);
662 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
663 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
664 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
665 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
666 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
667 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_8
);
668 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
669 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
671 EXPECT_TRUE(validate(p
));
675 TEST_P(validation_test
, two_src_two_dst_each_dst_must_be_derived_from_one_src
)
677 // mov (16) r10.0<2>:w r12.4<4;4,1>:w
680 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
681 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
682 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
683 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
684 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 8);
685 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
686 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
687 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
689 EXPECT_FALSE(validate(p
));
691 clear_instructions(p
);
694 brw_ADD(p
, g0
, g0
, g0
);
695 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 16);
696 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
697 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
698 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
700 EXPECT_FALSE(validate(p
));
705 TEST_P(validation_test
, one_src_two_dst
)
707 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
709 brw_ADD(p
, g0
, g0_0
, g0_0
);
710 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
712 EXPECT_TRUE(validate(p
));
714 clear_instructions(p
);
716 brw_ADD(p
, g0
, g0
, g0
);
717 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
718 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
719 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
720 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
722 EXPECT_TRUE(validate(p
));
724 clear_instructions(p
);
726 brw_ADD(p
, g0
, g0
, g0
);
727 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
728 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
729 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
730 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
731 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
732 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
733 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
734 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
736 if (devinfo
.gen
>= 8) {
737 EXPECT_TRUE(validate(p
));
739 EXPECT_FALSE(validate(p
));
742 clear_instructions(p
);
744 brw_ADD(p
, g0
, g0
, g0
);
745 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
746 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
747 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
748 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
749 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
750 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
751 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
752 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
754 if (devinfo
.gen
>= 8) {
755 EXPECT_TRUE(validate(p
));
757 EXPECT_FALSE(validate(p
));
761 TEST_P(validation_test
, packed_byte_destination
)
763 static const struct {
764 enum brw_reg_type dst_type
;
765 enum brw_reg_type src_type
;
767 bool expected_result
;
769 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 0, 0, true },
770 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 0, 0, true },
771 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 0, 0, true },
772 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 0, 0, true },
774 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 1, 0, 0, false },
775 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 1, 0, 0, false },
776 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 1, 0, 0, false },
777 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 1, 0, 0, false },
779 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 1, 0, false },
780 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 1, 0, false },
781 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 1, 0, false },
782 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 1, 0, false },
784 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 0, 1, false },
785 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 0, 1, false },
786 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 0, 1, false },
787 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 0, 1, false },
789 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UW
, 0, 0, 0, false },
790 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_W
, 0, 0, 0, false },
791 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UD
, 0, 0, 0, false },
792 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_D
, 0, 0, 0, false },
795 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
796 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(g0
, move
[i
].src_type
));
797 brw_inst_set_src0_negate(&devinfo
, last_inst
, move
[i
].neg
);
798 brw_inst_set_src0_abs(&devinfo
, last_inst
, move
[i
].abs
);
799 brw_inst_set_saturate(&devinfo
, last_inst
, move
[i
].sat
);
801 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
803 clear_instructions(p
);
806 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_UB
),
807 retype(g0
, BRW_REGISTER_TYPE_UB
),
808 retype(g0
, BRW_REGISTER_TYPE_UB
));
809 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
811 EXPECT_FALSE(validate(p
));
813 clear_instructions(p
);
815 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
816 retype(g0
, BRW_REGISTER_TYPE_B
),
817 retype(g0
, BRW_REGISTER_TYPE_B
));
818 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
820 EXPECT_FALSE(validate(p
));
823 TEST_P(validation_test
, byte_destination_relaxed_alignment
)
825 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
826 retype(g0
, BRW_REGISTER_TYPE_W
),
827 retype(g0
, BRW_REGISTER_TYPE_W
));
828 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
829 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
831 EXPECT_TRUE(validate(p
));
833 clear_instructions(p
);
835 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
836 retype(g0
, BRW_REGISTER_TYPE_W
),
837 retype(g0
, BRW_REGISTER_TYPE_W
));
838 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
839 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
840 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 1);
842 if (devinfo
.gen
> 4 || devinfo
.is_g4x
) {
843 EXPECT_TRUE(validate(p
));
845 EXPECT_FALSE(validate(p
));