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
->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()
135 #define zero brw_imm_f(0.0f)
138 clear_instructions(struct brw_codegen
*p
)
140 p
->next_insn_offset
= 0;
144 TEST_P(validation_test
, sanity
)
146 brw_ADD(p
, g0
, g0
, g0
);
148 EXPECT_TRUE(validate(p
));
151 TEST_P(validation_test
, src0_null_reg
)
153 brw_MOV(p
, g0
, null
);
155 EXPECT_FALSE(validate(p
));
158 TEST_P(validation_test
, src1_null_reg
)
160 brw_ADD(p
, g0
, g0
, null
);
162 EXPECT_FALSE(validate(p
));
165 TEST_P(validation_test
, math_src0_null_reg
)
167 if (devinfo
.gen
>= 6) {
168 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, null
, null
);
170 gen4_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, 0, null
, BRW_MATH_PRECISION_FULL
);
173 EXPECT_FALSE(validate(p
));
176 TEST_P(validation_test
, math_src1_null_reg
)
178 if (devinfo
.gen
>= 6) {
179 gen6_math(p
, g0
, BRW_MATH_FUNCTION_POW
, g0
, null
);
180 EXPECT_FALSE(validate(p
));
182 /* Math instructions on Gen4/5 are actually SEND messages with payloads.
183 * src1 is an immediate message descriptor set by gen4_math.
188 TEST_P(validation_test
, opcode46
)
190 /* opcode 46 is "push" on Gen 4 and 5
195 brw_next_insn(p
, 46);
197 if (devinfo
.gen
== 7) {
198 EXPECT_FALSE(validate(p
));
200 EXPECT_TRUE(validate(p
));
204 /* When the Execution Data Type is wider than the destination data type, the
205 * destination must [...] specify a HorzStride equal to the ratio in sizes of
206 * the two data types.
208 TEST_P(validation_test
, dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size
)
210 brw_ADD(p
, g0
, g0
, g0
);
211 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
212 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
213 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
215 EXPECT_FALSE(validate(p
));
217 clear_instructions(p
);
219 brw_ADD(p
, g0
, g0
, g0
);
220 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
221 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
222 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
223 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
225 EXPECT_TRUE(validate(p
));
228 /* When the Execution Data Type is wider than the destination data type, the
229 * destination must be aligned as required by the wider execution data type
232 TEST_P(validation_test
, dst_subreg_must_be_aligned_to_exec_type_size
)
234 brw_ADD(p
, g0
, g0
, g0
);
235 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 2);
236 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
237 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
238 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
239 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
241 EXPECT_FALSE(validate(p
));
243 clear_instructions(p
);
245 brw_ADD(p
, g0
, g0
, g0
);
246 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
247 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 8);
248 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
249 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
250 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
251 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
252 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
253 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
254 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
255 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
256 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
257 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
259 EXPECT_TRUE(validate(p
));
262 /* ExecSize must be greater than or equal to Width. */
263 TEST_P(validation_test
, exec_size_less_than_width
)
265 brw_ADD(p
, g0
, g0
, g0
);
266 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
268 EXPECT_FALSE(validate(p
));
270 clear_instructions(p
);
272 brw_ADD(p
, g0
, g0
, g0
);
273 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_16
);
275 EXPECT_FALSE(validate(p
));
278 /* If ExecSize = Width and HorzStride ≠ 0,
279 * VertStride must be set to Width * HorzStride.
281 TEST_P(validation_test
, vertical_stride_is_width_by_horizontal_stride
)
283 brw_ADD(p
, g0
, g0
, g0
);
284 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
286 EXPECT_FALSE(validate(p
));
288 clear_instructions(p
);
290 brw_ADD(p
, g0
, g0
, g0
);
291 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
293 EXPECT_FALSE(validate(p
));
296 /* If Width = 1, HorzStride must be 0 regardless of the values
297 * of ExecSize and VertStride.
299 TEST_P(validation_test
, horizontal_stride_must_be_0_if_width_is_1
)
301 brw_ADD(p
, g0
, g0
, g0
);
302 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
303 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
304 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
306 EXPECT_FALSE(validate(p
));
308 clear_instructions(p
);
310 brw_ADD(p
, g0
, g0
, g0
);
311 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
312 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
313 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
315 EXPECT_FALSE(validate(p
));
318 /* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */
319 TEST_P(validation_test
, scalar_region_must_be_0_1_0
)
321 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
323 brw_ADD(p
, g0
, g0
, g0_0
);
324 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
325 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
326 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
327 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
329 EXPECT_FALSE(validate(p
));
331 clear_instructions(p
);
333 brw_ADD(p
, g0
, g0_0
, g0
);
334 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_1
);
335 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_1
);
336 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
337 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
339 EXPECT_FALSE(validate(p
));
342 /* If VertStride = HorzStride = 0, Width must be 1 regardless of the value
345 TEST_P(validation_test
, zero_stride_implies_0_1_0
)
347 brw_ADD(p
, g0
, g0
, g0
);
348 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
349 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
350 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
352 EXPECT_FALSE(validate(p
));
354 clear_instructions(p
);
356 brw_ADD(p
, g0
, g0
, g0
);
357 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
358 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
359 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
361 EXPECT_FALSE(validate(p
));
364 /* Dst.HorzStride must not be 0. */
365 TEST_P(validation_test
, dst_horizontal_stride_0
)
367 brw_ADD(p
, g0
, g0
, g0
);
368 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
370 EXPECT_FALSE(validate(p
));
372 clear_instructions(p
);
374 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
376 brw_ADD(p
, g0
, g0
, g0
);
377 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
379 EXPECT_FALSE(validate(p
));
382 /* VertStride must be used to cross GRF register boundaries. This rule implies
383 * that elements within a 'Width' cannot cross GRF boundaries.
385 TEST_P(validation_test
, must_not_cross_grf_boundary_in_a_width
)
387 brw_ADD(p
, g0
, g0
, g0
);
388 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 4);
390 EXPECT_FALSE(validate(p
));
392 clear_instructions(p
);
394 brw_ADD(p
, g0
, g0
, g0
);
395 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 4);
397 EXPECT_FALSE(validate(p
));
399 clear_instructions(p
);
401 brw_ADD(p
, g0
, g0
, g0
);
402 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
403 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
404 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
406 EXPECT_FALSE(validate(p
));
408 clear_instructions(p
);
410 brw_ADD(p
, g0
, g0
, g0
);
411 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
412 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
413 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
415 EXPECT_FALSE(validate(p
));
418 /* Destination Horizontal must be 1 in Align16 */
419 TEST_P(validation_test
, dst_hstride_on_align16_must_be_1
)
421 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
423 brw_ADD(p
, g0
, g0
, g0
);
424 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
426 EXPECT_FALSE(validate(p
));
428 clear_instructions(p
);
430 brw_ADD(p
, g0
, g0
, g0
);
431 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
433 EXPECT_TRUE(validate(p
));
436 /* VertStride must be 0 or 4 in Align16 */
437 TEST_P(validation_test
, vstride_on_align16_must_be_0_or_4
)
440 enum brw_vertical_stride vstride
;
441 bool expected_result
;
443 { BRW_VERTICAL_STRIDE_0
, true },
444 { BRW_VERTICAL_STRIDE_1
, false },
445 { BRW_VERTICAL_STRIDE_2
, devinfo
.is_haswell
|| devinfo
.gen
>= 8 },
446 { BRW_VERTICAL_STRIDE_4
, true },
447 { BRW_VERTICAL_STRIDE_8
, false },
448 { BRW_VERTICAL_STRIDE_16
, false },
449 { BRW_VERTICAL_STRIDE_32
, false },
450 { BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL
, false },
453 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
455 for (unsigned i
= 0; i
< sizeof(vstride
) / sizeof(vstride
[0]); i
++) {
456 brw_ADD(p
, g0
, g0
, g0
);
457 brw_inst_set_src0_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
459 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
461 clear_instructions(p
);
464 for (unsigned i
= 0; i
< sizeof(vstride
) / sizeof(vstride
[0]); i
++) {
465 brw_ADD(p
, g0
, g0
, g0
);
466 brw_inst_set_src1_vstride(&devinfo
, last_inst
, vstride
[i
].vstride
);
468 EXPECT_EQ(vstride
[i
].expected_result
, validate(p
));
470 clear_instructions(p
);
474 /* In Direct Addressing mode, a source cannot span more than 2 adjacent GRF
477 TEST_P(validation_test
, source_cannot_span_more_than_2_registers
)
479 brw_ADD(p
, g0
, g0
, g0
);
480 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
481 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
482 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
483 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
484 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
485 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
486 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
488 EXPECT_FALSE(validate(p
));
490 clear_instructions(p
);
492 brw_ADD(p
, g0
, g0
, g0
);
493 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
494 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
495 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
496 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
497 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
498 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
499 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
500 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 2);
502 EXPECT_TRUE(validate(p
));
504 clear_instructions(p
);
506 brw_ADD(p
, g0
, g0
, g0
);
507 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
509 EXPECT_TRUE(validate(p
));
512 /* A destination cannot span more than 2 adjacent GRF registers. */
513 TEST_P(validation_test
, destination_cannot_span_more_than_2_registers
)
515 brw_ADD(p
, g0
, g0
, g0
);
516 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_32
);
517 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
518 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
519 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
520 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
522 EXPECT_FALSE(validate(p
));
524 clear_instructions(p
);
526 brw_ADD(p
, g0
, g0
, g0
);
527 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_8
);
528 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 6);
529 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
530 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
531 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
532 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
533 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
534 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
535 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
536 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
537 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
538 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
540 EXPECT_TRUE(validate(p
));
543 TEST_P(validation_test
, src_region_spans_two_regs_dst_region_spans_one
)
545 /* Writes to dest are to the lower OWord */
546 brw_ADD(p
, g0
, g0
, g0
);
547 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
548 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
549 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
550 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
551 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
552 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
554 EXPECT_TRUE(validate(p
));
556 clear_instructions(p
);
558 /* Writes to dest are to the upper OWord */
559 brw_ADD(p
, g0
, g0
, g0
);
560 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 16);
561 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
562 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
563 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
564 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
565 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
566 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
568 EXPECT_TRUE(validate(p
));
570 clear_instructions(p
);
572 /* Writes to dest are evenly split between OWords */
573 brw_ADD(p
, g0
, g0
, g0
);
574 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
575 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
576 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
577 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
578 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
579 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_8
);
580 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
582 EXPECT_TRUE(validate(p
));
584 clear_instructions(p
);
586 /* Writes to dest are uneven between OWords */
587 brw_ADD(p
, g0
, g0
, g0
);
588 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
589 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 10);
590 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
591 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
592 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
593 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
594 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
595 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
596 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_16
);
597 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
598 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
600 if (devinfo
.gen
>= 9) {
601 EXPECT_TRUE(validate(p
));
603 EXPECT_FALSE(validate(p
));
607 TEST_P(validation_test
, dst_elements_must_be_evenly_split_between_registers
)
609 brw_ADD(p
, g0
, g0
, g0
);
610 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
612 if (devinfo
.gen
>= 9) {
613 EXPECT_TRUE(validate(p
));
615 EXPECT_FALSE(validate(p
));
618 clear_instructions(p
);
620 brw_ADD(p
, g0
, g0
, g0
);
621 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
623 EXPECT_TRUE(validate(p
));
625 clear_instructions(p
);
627 if (devinfo
.gen
>= 6) {
628 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
630 EXPECT_TRUE(validate(p
));
632 clear_instructions(p
);
634 gen6_math(p
, g0
, BRW_MATH_FUNCTION_SIN
, g0
, null
);
635 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 4);
637 EXPECT_FALSE(validate(p
));
641 TEST_P(validation_test
, two_src_two_dst_source_offsets_must_be_same
)
643 brw_ADD(p
, g0
, g0
, g0
);
644 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
645 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
646 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 16);
647 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_2
);
648 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
649 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
650 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
651 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
652 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
654 if (devinfo
.gen
<= 7) {
655 EXPECT_FALSE(validate(p
));
657 EXPECT_TRUE(validate(p
));
660 clear_instructions(p
);
662 brw_ADD(p
, g0
, g0
, g0
);
663 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_4
);
664 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
665 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
666 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
667 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
668 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_8
);
669 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_2
);
670 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
672 EXPECT_TRUE(validate(p
));
676 TEST_P(validation_test
, two_src_two_dst_each_dst_must_be_derived_from_one_src
)
678 // mov (16) r10.0<2>:w r12.4<4;4,1>:w
681 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
682 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
683 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
684 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
685 brw_inst_set_src0_da1_subreg_nr(&devinfo
, last_inst
, 8);
686 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
687 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
688 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_4
);
690 EXPECT_FALSE(validate(p
));
692 clear_instructions(p
);
695 brw_ADD(p
, g0
, g0
, g0
);
696 brw_inst_set_src1_da1_subreg_nr(&devinfo
, last_inst
, 16);
697 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_4
);
698 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_4
);
699 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_1
);
701 EXPECT_FALSE(validate(p
));
706 TEST_P(validation_test
, one_src_two_dst
)
708 struct brw_reg g0_0
= brw_vec1_grf(0, 0);
710 brw_ADD(p
, g0
, g0_0
, g0_0
);
711 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
713 EXPECT_TRUE(validate(p
));
715 clear_instructions(p
);
717 brw_ADD(p
, g0
, g0
, g0
);
718 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
719 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_D
);
720 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
721 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
723 EXPECT_TRUE(validate(p
));
725 clear_instructions(p
);
727 brw_ADD(p
, g0
, g0
, g0
);
728 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
729 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
730 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
731 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
732 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
733 brw_inst_set_src1_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
734 brw_inst_set_src1_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
735 brw_inst_set_src1_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
737 if (devinfo
.gen
>= 8) {
738 EXPECT_TRUE(validate(p
));
740 EXPECT_FALSE(validate(p
));
743 clear_instructions(p
);
745 brw_ADD(p
, g0
, g0
, g0
);
746 brw_inst_set_exec_size(&devinfo
, last_inst
, BRW_EXECUTE_16
);
747 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
748 brw_inst_set_dst_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
749 brw_inst_set_src0_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
750 brw_inst_set_src0_vstride(&devinfo
, last_inst
, BRW_VERTICAL_STRIDE_0
);
751 brw_inst_set_src0_width(&devinfo
, last_inst
, BRW_WIDTH_1
);
752 brw_inst_set_src0_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_0
);
753 brw_inst_set_src1_reg_type(&devinfo
, last_inst
, BRW_HW_REG_TYPE_W
);
755 if (devinfo
.gen
>= 8) {
756 EXPECT_TRUE(validate(p
));
758 EXPECT_FALSE(validate(p
));
762 TEST_P(validation_test
, packed_byte_destination
)
764 static const struct {
765 enum brw_reg_type dst_type
;
766 enum brw_reg_type src_type
;
768 bool expected_result
;
770 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 0, 0, true },
771 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 0, 0, true },
772 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 0, 0, true },
773 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 0, 0, true },
775 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 1, 0, 0, false },
776 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 1, 0, 0, false },
777 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 1, 0, 0, false },
778 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 1, 0, 0, false },
780 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 1, 0, false },
781 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 1, 0, false },
782 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 1, 0, false },
783 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 1, 0, false },
785 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UB
, 0, 0, 1, false },
786 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_B
, 0, 0, 1, false },
787 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_B
, 0, 0, 1, false },
788 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UB
, 0, 0, 1, false },
790 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UW
, 0, 0, 0, false },
791 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_W
, 0, 0, 0, false },
792 { BRW_REGISTER_TYPE_UB
, BRW_REGISTER_TYPE_UD
, 0, 0, 0, false },
793 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_D
, 0, 0, 0, false },
796 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
797 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(g0
, move
[i
].src_type
));
798 brw_inst_set_src0_negate(&devinfo
, last_inst
, move
[i
].neg
);
799 brw_inst_set_src0_abs(&devinfo
, last_inst
, move
[i
].abs
);
800 brw_inst_set_saturate(&devinfo
, last_inst
, move
[i
].sat
);
802 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
804 clear_instructions(p
);
807 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_UB
),
808 retype(g0
, BRW_REGISTER_TYPE_UB
),
809 retype(g0
, BRW_REGISTER_TYPE_UB
));
810 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
812 EXPECT_FALSE(validate(p
));
814 clear_instructions(p
);
816 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
817 retype(g0
, BRW_REGISTER_TYPE_B
),
818 retype(g0
, BRW_REGISTER_TYPE_B
));
819 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
821 EXPECT_FALSE(validate(p
));
824 TEST_P(validation_test
, byte_destination_relaxed_alignment
)
826 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
827 retype(g0
, BRW_REGISTER_TYPE_W
),
828 retype(g0
, BRW_REGISTER_TYPE_W
));
829 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
830 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
832 EXPECT_TRUE(validate(p
));
834 clear_instructions(p
);
836 brw_SEL(p
, retype(g0
, BRW_REGISTER_TYPE_B
),
837 retype(g0
, BRW_REGISTER_TYPE_W
),
838 retype(g0
, BRW_REGISTER_TYPE_W
));
839 brw_inst_set_pred_control(&devinfo
, last_inst
, BRW_PREDICATE_NORMAL
);
840 brw_inst_set_dst_hstride(&devinfo
, last_inst
, BRW_HORIZONTAL_STRIDE_2
);
841 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, 1);
843 if (devinfo
.gen
> 4 || devinfo
.is_g4x
) {
844 EXPECT_TRUE(validate(p
));
846 EXPECT_FALSE(validate(p
));
850 TEST_P(validation_test
, vector_immediate_destination_alignment
)
852 static const struct {
853 enum brw_reg_type dst_type
;
854 enum brw_reg_type src_type
;
857 bool expected_result
;
859 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 0, BRW_EXECUTE_4
, true },
860 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 16, BRW_EXECUTE_4
, true },
861 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, 1, BRW_EXECUTE_4
, false },
863 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 0, BRW_EXECUTE_8
, true },
864 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 16, BRW_EXECUTE_8
, true },
865 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, 1, BRW_EXECUTE_8
, false },
867 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 0, BRW_EXECUTE_8
, true },
868 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 16, BRW_EXECUTE_8
, true },
869 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, 1, BRW_EXECUTE_8
, false },
872 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
873 /* UV type is Gen6+ */
874 if (devinfo
.gen
< 6 &&
875 move
[i
].src_type
== BRW_REGISTER_TYPE_UV
)
878 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(zero
, move
[i
].src_type
));
879 brw_inst_set_dst_da1_subreg_nr(&devinfo
, last_inst
, move
[i
].subnr
);
880 brw_inst_set_exec_size(&devinfo
, last_inst
, move
[i
].exec_size
);
882 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
884 clear_instructions(p
);
888 TEST_P(validation_test
, vector_immediate_destination_stride
)
890 static const struct {
891 enum brw_reg_type dst_type
;
892 enum brw_reg_type src_type
;
894 bool expected_result
;
896 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_1
, true },
897 { BRW_REGISTER_TYPE_F
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, false },
898 { BRW_REGISTER_TYPE_D
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_1
, true },
899 { BRW_REGISTER_TYPE_D
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, false },
900 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_2
, true },
901 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_VF
, BRW_HORIZONTAL_STRIDE_4
, true },
903 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_1
, true },
904 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_2
, false },
905 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_4
, false },
906 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_V
, BRW_HORIZONTAL_STRIDE_2
, true },
908 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_1
, true },
909 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_2
, false },
910 { BRW_REGISTER_TYPE_W
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_4
, false },
911 { BRW_REGISTER_TYPE_B
, BRW_REGISTER_TYPE_UV
, BRW_HORIZONTAL_STRIDE_2
, true },
914 for (unsigned i
= 0; i
< sizeof(move
) / sizeof(move
[0]); i
++) {
915 /* UV type is Gen6+ */
916 if (devinfo
.gen
< 6 &&
917 move
[i
].src_type
== BRW_REGISTER_TYPE_UV
)
920 brw_MOV(p
, retype(g0
, move
[i
].dst_type
), retype(zero
, move
[i
].src_type
));
921 brw_inst_set_dst_hstride(&devinfo
, last_inst
, move
[i
].stride
);
923 EXPECT_EQ(move
[i
].expected_result
, validate(p
));
925 clear_instructions(p
);