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(p
, 0, &annotation
);
124 dump_assembly(p
->store
, annotation
.ann_count
, annotation
.ann
, p
->devinfo
);
125 ralloc_free(annotation
.mem_ctx
);
131 #define last_inst (&p->store[p->nr_insn - 1])
132 #define g0 brw_vec8_grf(0, 0)
133 #define null brw_null_reg()
136 clear_instructions(struct brw_codegen
*p
)
138 p
->next_insn_offset
= 0;
142 TEST_P(validation_test
, sanity
)
144 brw_ADD(p
, g0
, g0
, g0
);
146 EXPECT_TRUE(validate(p
));
149 TEST_P(validation_test
, src0_null_reg
)
151 brw_MOV(p
, g0
, null
);
153 EXPECT_FALSE(validate(p
));
156 TEST_P(validation_test
, src1_null_reg
)
158 brw_ADD(p
, g0
, g0
, null
);
160 EXPECT_FALSE(validate(p
));
163 TEST_P(validation_test
, math_src0_null_reg
)
165 if (devinfo
.gen
>= 6) {
166 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, null
, null
);
168 gen4_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, 0, null
, BRW_MATH_PRECISION_FULL
);
171 EXPECT_FALSE(validate(p
));
174 TEST_P(validation_test
, math_src1_null_reg
)
176 if (devinfo
.gen
>= 6) {
177 gen6_math(p
, g0
, BRW_MATH_FUNCTION_POW
, g0
, null
);
178 EXPECT_FALSE(validate(p
));
180 /* Math instructions on Gen4/5 are actually SEND messages with payloads.
181 * src1 is an immediate message descriptor set by gen4_math.
186 TEST_P(validation_test
, opcode46
)
188 /* opcode 46 is "push" on Gen 4 and 5
193 brw_next_insn(p
, 46);
195 if (devinfo
.gen
== 7) {
196 EXPECT_FALSE(validate(p
));
198 EXPECT_TRUE(validate(p
));
202 /* When the Execution Data Type is wider than the destination data type, the
203 * destination must [...] specify a HorzStride equal to the ratio in sizes of
204 * the two data types.
206 TEST_P(validation_test
, dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size
)
208 brw_ADD(p
, g0
, g0
, g0
);
209 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
210 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
211 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
213 EXPECT_FALSE(validate(p
));
215 clear_instructions(p
);
217 brw_ADD(p
, g0
, g0
, g0
);
218 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
219 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
220 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
221 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
223 EXPECT_TRUE(validate(p
));
226 /* When the Execution Data Type is wider than the destination data type, the
227 * destination must be aligned as required by the wider execution data type
230 TEST_P(validation_test
, dst_subreg_must_be_aligned_to_exec_type_size
)
232 brw_ADD(p
, g0
, g0
, g0
);
233 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 2);
234 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
235 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
236 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
237 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
239 EXPECT_FALSE(validate(p
));
241 clear_instructions(p
);
243 brw_ADD(p
, g0
, g0
, g0
);
244 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
245 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 8);
246 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
247 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
248 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
249 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
250 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
251 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
252 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
253 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
254 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
255 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
257 EXPECT_TRUE(validate(p
));
260 /* ExecSize must be greater than or equal to Width. */
261 TEST_P(validation_test
, exec_size_less_than_width
)
263 brw_ADD(p
, g0
, g0
, g0
);
264 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
266 EXPECT_FALSE(validate(p
));
268 clear_instructions(p
);
270 brw_ADD(p
, g0
, g0
, g0
);
271 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
273 EXPECT_FALSE(validate(p
));
276 /* If ExecSize = Width and HorzStride ≠ 0,
277 * VertStride must be set to Width * HorzStride.
279 TEST_P(validation_test
, vertical_stride_is_width_by_horizontal_stride
)
281 brw_ADD(p
, g0
, g0
, g0
);
282 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
284 EXPECT_FALSE(validate(p
));
286 clear_instructions(p
);
288 brw_ADD(p
, g0
, g0
, g0
);
289 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
291 EXPECT_FALSE(validate(p
));
294 /* If Width = 1, HorzStride must be 0 regardless of the values
295 * of ExecSize and VertStride.
297 TEST_P(validation_test
, horizontal_stride_must_be_0_if_width_is_1
)
299 brw_ADD(p
, g0
, g0
, g0
);
300 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
301 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
302 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
304 EXPECT_FALSE(validate(p
));
306 clear_instructions(p
);
308 brw_ADD(p
, g0
, g0
, g0
);
309 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
310 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
311 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
313 EXPECT_FALSE(validate(p
));
316 /* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */
317 TEST_P(validation_test
, scalar_region_must_be_0_1_0
)
319 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
321 brw_ADD(p
, g0
, g0
, g0_0
);
322 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
323 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
324 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
325 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
327 EXPECT_FALSE(validate(p
));
329 clear_instructions(p
);
331 brw_ADD(p
, g0
, g0_0
, g0
);
332 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
333 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
334 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
335 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
337 EXPECT_FALSE(validate(p
));
340 /* If VertStride = HorzStride = 0, Width must be 1 regardless of the value
343 TEST_P(validation_test
, zero_stride_implies_0_1_0
)
345 brw_ADD(p
, g0
, g0
, g0
);
346 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
347 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
348 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
350 EXPECT_FALSE(validate(p
));
352 clear_instructions(p
);
354 brw_ADD(p
, g0
, g0
, g0
);
355 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
356 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
357 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
359 EXPECT_FALSE(validate(p
));
362 /* Dst.HorzStride must not be 0. */
363 TEST_P(validation_test
, dst_horizontal_stride_0
)
365 brw_ADD(p
, g0
, g0
, g0
);
366 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
368 EXPECT_FALSE(validate(p
));
370 clear_instructions(p
);
372 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
374 brw_ADD(p
, g0
, g0
, g0
);
375 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
377 EXPECT_FALSE(validate(p
));
380 /* VertStride must be used to cross GRF register boundaries. This rule implies
381 * that elements within a 'Width' cannot cross GRF boundaries.
383 TEST_P(validation_test
, must_not_cross_grf_boundary_in_a_width
)
385 brw_ADD(p
, g0
, g0
, g0
);
386 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 4);
388 EXPECT_FALSE(validate(p
));
390 clear_instructions(p
);
392 brw_ADD(p
, g0
, g0
, g0
);
393 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 4);
395 EXPECT_FALSE(validate(p
));
397 clear_instructions(p
);
399 brw_ADD(p
, g0
, g0
, g0
);
400 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
401 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
402 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
404 EXPECT_FALSE(validate(p
));
406 clear_instructions(p
);
408 brw_ADD(p
, g0
, g0
, g0
);
409 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
410 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
411 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
413 EXPECT_FALSE(validate(p
));
416 /* Destination Horizontal must be 1 in Align16 */
417 TEST_P(validation_test
, dst_hstride_on_align16_must_be_1
)
419 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
421 brw_ADD(p
, g0
, g0
, g0
);
422 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
424 EXPECT_FALSE(validate(p
));
426 clear_instructions(p
);
428 brw_ADD(p
, g0
, g0
, g0
);
429 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
431 EXPECT_TRUE(validate(p
));
434 /* VertStride must be 0 or 4 in Align16 */
435 TEST_P(validation_test
, vstride_on_align16_must_be_0_or_4
)
438 enum brw_vertical_stride vstride
;
439 bool expected_result
;
441 { BRW_VERTICAL_STRIDE_0
, true },
442 { BRW_VERTICAL_STRIDE_1
, false },
443 { BRW_VERTICAL_STRIDE_2
, devinfo
.is_haswell
|| devinfo
.gen
>= 8 },
444 { BRW_VERTICAL_STRIDE_4
, true },
445 { BRW_VERTICAL_STRIDE_8
, false },
446 { BRW_VERTICAL_STRIDE_16
, false },
447 { BRW_VERTICAL_STRIDE_32
, false },
448 { BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL
, false },
451 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
453 for (unsigned i
= 0; i
< sizeof(vstride
) / sizeof(vstride
[0]); i
++) {
454 brw_ADD(p
, g0
, g0
, g0
);
455 brw_inst_set_src0_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
457 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
459 clear_instructions(p
);
462 for (unsigned i
= 0; i
< sizeof(vstride
) / sizeof(vstride
[0]); i
++) {
463 brw_ADD(p
, g0
, g0
, g0
);
464 brw_inst_set_src1_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
466 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
468 clear_instructions(p
);
472 /* In Direct Addressing mode, a source cannot span more than 2 adjacent GRF
475 TEST_P(validation_test
, source_cannot_span_more_than_2_registers
)
477 brw_ADD(p
, g0
, g0
, g0
);
478 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
479 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
480 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
481 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
482 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
483 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
484 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
486 EXPECT_FALSE(validate(p
));
488 clear_instructions(p
);
490 brw_ADD(p
, g0
, g0
, g0
);
491 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
492 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
493 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
494 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
495 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
496 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
497 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
498 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 2);
500 EXPECT_TRUE(validate(p
));
502 clear_instructions(p
);
504 brw_ADD(p
, g0
, g0
, g0
);
505 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
507 EXPECT_TRUE(validate(p
));
510 /* A destination cannot span more than 2 adjacent GRF registers. */
511 TEST_P(validation_test
, destination_cannot_span_more_than_2_registers
)
513 brw_ADD(p
, g0
, g0
, g0
);
514 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
515 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
516 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
517 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
518 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
520 EXPECT_FALSE(validate(p
));
522 clear_instructions(p
);
524 brw_ADD(p
, g0
, g0
, g0
);
525 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_8
);
526 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 6);
527 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
528 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
529 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
530 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
531 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
532 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
533 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
534 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
535 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
536 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
538 EXPECT_TRUE(validate(p
));
541 TEST_P(validation_test
, src_region_spans_two_regs_dst_region_spans_one
)
543 /* Writes to dest are to the lower OWord */
544 brw_ADD(p
, g0
, g0
, g0
);
545 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
546 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
547 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
548 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
549 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
550 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
552 EXPECT_TRUE(validate(p
));
554 clear_instructions(p
);
556 /* Writes to dest are to the upper OWord */
557 brw_ADD(p
, g0
, g0
, g0
);
558 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 16);
559 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
560 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
561 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
562 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
563 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
564 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
566 EXPECT_TRUE(validate(p
));
568 clear_instructions(p
);
570 /* Writes to dest are evenly split between OWords */
571 brw_ADD(p
, g0
, g0
, g0
);
572 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
573 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
574 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
575 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
576 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
577 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
578 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
580 EXPECT_TRUE(validate(p
));
582 clear_instructions(p
);
584 /* Writes to dest are uneven between OWords */
585 brw_ADD(p
, g0
, g0
, g0
);
586 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
587 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 10);
588 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
589 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
590 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
591 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
592 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
593 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
594 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
595 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
596 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
598 if (devinfo
.gen
>= 9) {
599 EXPECT_TRUE(validate(p
));
601 EXPECT_FALSE(validate(p
));
605 TEST_P(validation_test
, dst_elements_must_be_evenly_split_between_registers
)
607 brw_ADD(p
, g0
, g0
, g0
);
608 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
610 if (devinfo
.gen
>= 9) {
611 EXPECT_TRUE(validate(p
));
613 EXPECT_FALSE(validate(p
));
616 clear_instructions(p
);
618 brw_ADD(p
, g0
, g0
, g0
);
619 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
621 EXPECT_TRUE(validate(p
));
623 clear_instructions(p
);
625 if (devinfo
.gen
>= 6) {
626 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
628 EXPECT_TRUE(validate(p
));
630 clear_instructions(p
);
632 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
633 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
635 EXPECT_FALSE(validate(p
));
639 TEST_P(validation_test
, two_src_two_dst_source_offsets_must_be_same
)
641 brw_ADD(p
, g0
, g0
, g0
);
642 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
643 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
644 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 16);
645 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_2
);
646 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
647 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
648 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
649 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
650 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
652 if (devinfo
.gen
<= 7) {
653 EXPECT_FALSE(validate(p
));
655 EXPECT_TRUE(validate(p
));
658 clear_instructions(p
);
660 brw_ADD(p
, g0
, g0
, g0
);
661 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
662 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
663 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
664 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
665 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
666 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_8
);
667 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
668 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
670 EXPECT_TRUE(validate(p
));
674 TEST_P(validation_test
, two_src_two_dst_each_dst_must_be_derived_from_one_src
)
676 // mov (16) r10.0<2>:w r12.4<4;4,1>:w
679 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
680 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
681 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
682 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
683 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 8);
684 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
685 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
686 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
688 EXPECT_FALSE(validate(p
));
690 clear_instructions(p
);
693 brw_ADD(p
, g0
, g0
, g0
);
694 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 16);
695 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
696 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
697 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
699 EXPECT_FALSE(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_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
718 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
719 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_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_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
729 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
730 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_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_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
747 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_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_reg_type(&devinfo
, last_inst
, BRW_HW_REG_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
));