i965: Fix test_eu_validate.cpp
[mesa.git] / src / intel / compiler / test_eu_validate.cpp
1 /*
2 * Copyright © 2016 Intel Corporation
3 *
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:
10 *
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
13 * Software.
14 *
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
21 * IN THE SOFTWARE.
22 */
23
24 #include <gtest/gtest.h>
25 #include "brw_eu.h"
26 #include "util/ralloc.h"
27
28 enum subgen {
29 IS_G45 = 1,
30 IS_BYT,
31 IS_HSW,
32 IS_CHV,
33 IS_BXT,
34 IS_KBL,
35 };
36
37 static const struct gen_info {
38 const char *name;
39 int gen;
40 enum subgen subgen;
41 } gens[] = {
42 { "brw", 4 },
43 { "g45", 4, IS_G45 },
44 { "ilk", 5 },
45 { "snb", 6 },
46 { "ivb", 7 },
47 { "byt", 7, IS_BYT },
48 { "hsw", 7, IS_HSW },
49 { "bdw", 8 },
50 { "chv", 8, IS_CHV },
51 { "skl", 9 },
52 { "bxt", 9, IS_BXT },
53 { "kbl", 9, IS_KBL },
54 };
55
56 class validation_test: public ::testing::TestWithParam<struct gen_info> {
57 virtual void SetUp();
58
59 public:
60 validation_test();
61 virtual ~validation_test();
62
63 struct brw_codegen *p;
64 struct gen_device_info devinfo;
65 };
66
67 validation_test::validation_test()
68 {
69 p = rzalloc(NULL, struct brw_codegen);
70 memset(&devinfo, 0, sizeof(devinfo));
71 }
72
73 validation_test::~validation_test()
74 {
75 ralloc_free(p);
76 }
77
78 void validation_test::SetUp()
79 {
80 struct gen_info info = GetParam();
81
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;
89
90 brw_init_codegen(&devinfo, p, p);
91 }
92
93 struct gen_name {
94 template <class ParamType>
95 std::string
96 operator()(const ::testing::TestParamInfo<ParamType>& info) const {
97 return info.param.name;
98 }
99 };
100
101 INSTANTIATE_TEST_CASE_P(eu_assembly, validation_test,
102 ::testing::ValuesIn(gens),
103 gen_name());
104
105 static bool
106 validate(struct brw_codegen *p)
107 {
108 const bool print = getenv("TEST_DEBUG");
109 struct annotation_info annotation;
110 memset(&annotation, 0, sizeof(annotation));
111
112 if (print) {
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;
119 }
120
121 bool ret = brw_validate_instructions(p->devinfo, p->store, 0,
122 p->next_insn_offset, &annotation);
123
124 if (print) {
125 dump_assembly(p->store, annotation.ann_count, annotation.ann, p->devinfo);
126 ralloc_free(annotation.mem_ctx);
127 }
128
129 return ret;
130 }
131
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
136 static void
137 clear_instructions(struct brw_codegen *p)
138 {
139 p->next_insn_offset = 0;
140 p->nr_insn = 0;
141 }
142
143 TEST_P(validation_test, sanity)
144 {
145 brw_ADD(p, g0, g0, g0);
146
147 EXPECT_TRUE(validate(p));
148 }
149
150 TEST_P(validation_test, src0_null_reg)
151 {
152 brw_MOV(p, g0, null);
153
154 EXPECT_FALSE(validate(p));
155 }
156
157 TEST_P(validation_test, src1_null_reg)
158 {
159 brw_ADD(p, g0, g0, null);
160
161 EXPECT_FALSE(validate(p));
162 }
163
164 TEST_P(validation_test, math_src0_null_reg)
165 {
166 if (devinfo.gen >= 6) {
167 gen6_math(p, g0, BRW_MATH_FUNCTION_SIN, null, null);
168 } else {
169 gen4_math(p, g0, BRW_MATH_FUNCTION_SIN, 0, null, BRW_MATH_PRECISION_FULL);
170 }
171
172 EXPECT_FALSE(validate(p));
173 }
174
175 TEST_P(validation_test, math_src1_null_reg)
176 {
177 if (devinfo.gen >= 6) {
178 gen6_math(p, g0, BRW_MATH_FUNCTION_POW, g0, null);
179 EXPECT_FALSE(validate(p));
180 } else {
181 /* Math instructions on Gen4/5 are actually SEND messages with payloads.
182 * src1 is an immediate message descriptor set by gen4_math.
183 */
184 }
185 }
186
187 TEST_P(validation_test, opcode46)
188 {
189 /* opcode 46 is "push" on Gen 4 and 5
190 * "fork" on Gen 6
191 * reserved on Gen 7
192 * "goto" on Gen8+
193 */
194 brw_next_insn(p, 46);
195
196 if (devinfo.gen == 7) {
197 EXPECT_FALSE(validate(p));
198 } else {
199 EXPECT_TRUE(validate(p));
200 }
201 }
202
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.
206 */
207 TEST_P(validation_test, dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size)
208 {
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);
213
214 EXPECT_FALSE(validate(p));
215
216 clear_instructions(p);
217
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);
223
224 EXPECT_TRUE(validate(p));
225 }
226
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
229 * [...]
230 */
231 TEST_P(validation_test, dst_subreg_must_be_aligned_to_exec_type_size)
232 {
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);
239
240 EXPECT_FALSE(validate(p));
241
242 clear_instructions(p);
243
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);
257
258 EXPECT_TRUE(validate(p));
259 }
260
261 /* ExecSize must be greater than or equal to Width. */
262 TEST_P(validation_test, exec_size_less_than_width)
263 {
264 brw_ADD(p, g0, g0, g0);
265 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_16);
266
267 EXPECT_FALSE(validate(p));
268
269 clear_instructions(p);
270
271 brw_ADD(p, g0, g0, g0);
272 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_16);
273
274 EXPECT_FALSE(validate(p));
275 }
276
277 /* If ExecSize = Width and HorzStride ≠ 0,
278 * VertStride must be set to Width * HorzStride.
279 */
280 TEST_P(validation_test, vertical_stride_is_width_by_horizontal_stride)
281 {
282 brw_ADD(p, g0, g0, g0);
283 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
284
285 EXPECT_FALSE(validate(p));
286
287 clear_instructions(p);
288
289 brw_ADD(p, g0, g0, g0);
290 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
291
292 EXPECT_FALSE(validate(p));
293 }
294
295 /* If Width = 1, HorzStride must be 0 regardless of the values
296 * of ExecSize and VertStride.
297 */
298 TEST_P(validation_test, horizontal_stride_must_be_0_if_width_is_1)
299 {
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);
304
305 EXPECT_FALSE(validate(p));
306
307 clear_instructions(p);
308
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);
313
314 EXPECT_FALSE(validate(p));
315 }
316
317 /* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */
318 TEST_P(validation_test, scalar_region_must_be_0_1_0)
319 {
320 struct brw_reg g0_0 = brw_vec1_grf(0, 0);
321
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);
327
328 EXPECT_FALSE(validate(p));
329
330 clear_instructions(p);
331
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);
337
338 EXPECT_FALSE(validate(p));
339 }
340
341 /* If VertStride = HorzStride = 0, Width must be 1 regardless of the value
342 * of ExecSize.
343 */
344 TEST_P(validation_test, zero_stride_implies_0_1_0)
345 {
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);
350
351 EXPECT_FALSE(validate(p));
352
353 clear_instructions(p);
354
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);
359
360 EXPECT_FALSE(validate(p));
361 }
362
363 /* Dst.HorzStride must not be 0. */
364 TEST_P(validation_test, dst_horizontal_stride_0)
365 {
366 brw_ADD(p, g0, g0, g0);
367 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
368
369 EXPECT_FALSE(validate(p));
370
371 clear_instructions(p);
372
373 brw_set_default_access_mode(p, BRW_ALIGN_16);
374
375 brw_ADD(p, g0, g0, g0);
376 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
377
378 EXPECT_FALSE(validate(p));
379 }
380
381 /* VertStride must be used to cross GRF register boundaries. This rule implies
382 * that elements within a 'Width' cannot cross GRF boundaries.
383 */
384 TEST_P(validation_test, must_not_cross_grf_boundary_in_a_width)
385 {
386 brw_ADD(p, g0, g0, g0);
387 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 4);
388
389 EXPECT_FALSE(validate(p));
390
391 clear_instructions(p);
392
393 brw_ADD(p, g0, g0, g0);
394 brw_inst_set_src1_da1_subreg_nr(&devinfo, last_inst, 4);
395
396 EXPECT_FALSE(validate(p));
397
398 clear_instructions(p);
399
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);
404
405 EXPECT_FALSE(validate(p));
406
407 clear_instructions(p);
408
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);
413
414 EXPECT_FALSE(validate(p));
415 }
416
417 /* Destination Horizontal must be 1 in Align16 */
418 TEST_P(validation_test, dst_hstride_on_align16_must_be_1)
419 {
420 brw_set_default_access_mode(p, BRW_ALIGN_16);
421
422 brw_ADD(p, g0, g0, g0);
423 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
424
425 EXPECT_FALSE(validate(p));
426
427 clear_instructions(p);
428
429 brw_ADD(p, g0, g0, g0);
430 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
431
432 EXPECT_TRUE(validate(p));
433 }
434
435 /* VertStride must be 0 or 4 in Align16 */
436 TEST_P(validation_test, vstride_on_align16_must_be_0_or_4)
437 {
438 const struct {
439 enum brw_vertical_stride vstride;
440 bool expected_result;
441 } vstride[] = {
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 },
450 };
451
452 brw_set_default_access_mode(p, BRW_ALIGN_16);
453
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);
457
458 EXPECT_EQ(vstride[i].expected_result, validate(p));
459
460 clear_instructions(p);
461 }
462
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);
466
467 EXPECT_EQ(vstride[i].expected_result, validate(p));
468
469 clear_instructions(p);
470 }
471 }
472
473 /* In Direct Addressing mode, a source cannot span more than 2 adjacent GRF
474 * registers.
475 */
476 TEST_P(validation_test, source_cannot_span_more_than_2_registers)
477 {
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);
486
487 EXPECT_FALSE(validate(p));
488
489 clear_instructions(p);
490
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);
500
501 EXPECT_TRUE(validate(p));
502
503 clear_instructions(p);
504
505 brw_ADD(p, g0, g0, g0);
506 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
507
508 EXPECT_TRUE(validate(p));
509 }
510
511 /* A destination cannot span more than 2 adjacent GRF registers. */
512 TEST_P(validation_test, destination_cannot_span_more_than_2_registers)
513 {
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);
520
521 EXPECT_FALSE(validate(p));
522
523 clear_instructions(p);
524
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);
538
539 EXPECT_TRUE(validate(p));
540 }
541
542 TEST_P(validation_test, src_region_spans_two_regs_dst_region_spans_one)
543 {
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);
552
553 EXPECT_TRUE(validate(p));
554
555 clear_instructions(p);
556
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);
566
567 EXPECT_TRUE(validate(p));
568
569 clear_instructions(p);
570
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);
580
581 EXPECT_TRUE(validate(p));
582
583 clear_instructions(p);
584
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);
598
599 if (devinfo.gen >= 9) {
600 EXPECT_TRUE(validate(p));
601 } else {
602 EXPECT_FALSE(validate(p));
603 }
604 }
605
606 TEST_P(validation_test, dst_elements_must_be_evenly_split_between_registers)
607 {
608 brw_ADD(p, g0, g0, g0);
609 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 4);
610
611 if (devinfo.gen >= 9) {
612 EXPECT_TRUE(validate(p));
613 } else {
614 EXPECT_FALSE(validate(p));
615 }
616
617 clear_instructions(p);
618
619 brw_ADD(p, g0, g0, g0);
620 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
621
622 EXPECT_TRUE(validate(p));
623
624 clear_instructions(p);
625
626 if (devinfo.gen >= 6) {
627 gen6_math(p, g0, BRW_MATH_FUNCTION_SIN, g0, null);
628
629 EXPECT_TRUE(validate(p));
630
631 clear_instructions(p);
632
633 gen6_math(p, g0, BRW_MATH_FUNCTION_SIN, g0, null);
634 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 4);
635
636 EXPECT_FALSE(validate(p));
637 }
638 }
639
640 TEST_P(validation_test, two_src_two_dst_source_offsets_must_be_same)
641 {
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);
652
653 if (devinfo.gen <= 7) {
654 EXPECT_FALSE(validate(p));
655 } else {
656 EXPECT_TRUE(validate(p));
657 }
658
659 clear_instructions(p);
660
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);
670
671 EXPECT_TRUE(validate(p));
672 }
673
674 #if 0
675 TEST_P(validation_test, two_src_two_dst_each_dst_must_be_derived_from_one_src)
676 {
677 // mov (16) r10.0<2>:w r12.4<4;4,1>:w
678
679 brw_MOV(p, g0, g0);
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);
688
689 EXPECT_FALSE(validate(p));
690
691 clear_instructions(p);
692
693 #if 0
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);
699
700 EXPECT_FALSE(validate(p));
701 #endif
702 }
703 #endif
704
705 TEST_P(validation_test, one_src_two_dst)
706 {
707 struct brw_reg g0_0 = brw_vec1_grf(0, 0);
708
709 brw_ADD(p, g0, g0_0, g0_0);
710 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
711
712 EXPECT_TRUE(validate(p));
713
714 clear_instructions(p);
715
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);
721
722 EXPECT_TRUE(validate(p));
723
724 clear_instructions(p);
725
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);
735
736 if (devinfo.gen >= 8) {
737 EXPECT_TRUE(validate(p));
738 } else {
739 EXPECT_FALSE(validate(p));
740 }
741
742 clear_instructions(p);
743
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);
753
754 if (devinfo.gen >= 8) {
755 EXPECT_TRUE(validate(p));
756 } else {
757 EXPECT_FALSE(validate(p));
758 }
759 }
760
761 TEST_P(validation_test, packed_byte_destination)
762 {
763 static const struct {
764 enum brw_reg_type dst_type;
765 enum brw_reg_type src_type;
766 bool neg, abs, sat;
767 bool expected_result;
768 } move[] = {
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 },
773
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 },
778
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 },
783
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 },
788
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 },
793 };
794
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);
800
801 EXPECT_EQ(move[i].expected_result, validate(p));
802
803 clear_instructions(p);
804 }
805
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);
810
811 EXPECT_FALSE(validate(p));
812
813 clear_instructions(p);
814
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);
819
820 EXPECT_FALSE(validate(p));
821 }
822
823 TEST_P(validation_test, byte_destination_relaxed_alignment)
824 {
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);
830
831 EXPECT_TRUE(validate(p));
832
833 clear_instructions(p);
834
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);
841
842 if (devinfo.gen > 4 || devinfo.is_g4x) {
843 EXPECT_TRUE(validate(p));
844 } else {
845 EXPECT_FALSE(validate(p));
846 }
847
848 }