intel/compiler: Readd ICL to 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 static const struct gen_info {
29 const char *name;
30 } gens[] = {
31 { "brw", },
32 { "g4x", },
33 { "ilk", },
34 { "snb", },
35 { "ivb", },
36 { "byt", },
37 { "hsw", },
38 { "bdw", },
39 { "chv", },
40 { "skl", },
41 { "bxt", },
42 { "kbl", },
43 { "glk", },
44 { "cfl", },
45 { "cnl", },
46 { "icl", },
47 };
48
49 class validation_test: public ::testing::TestWithParam<struct gen_info> {
50 virtual void SetUp();
51
52 public:
53 validation_test();
54 virtual ~validation_test();
55
56 struct brw_codegen *p;
57 struct gen_device_info devinfo;
58 };
59
60 validation_test::validation_test()
61 {
62 p = rzalloc(NULL, struct brw_codegen);
63 memset(&devinfo, 0, sizeof(devinfo));
64 }
65
66 validation_test::~validation_test()
67 {
68 ralloc_free(p);
69 }
70
71 void validation_test::SetUp()
72 {
73 struct gen_info info = GetParam();
74 int devid = gen_device_name_to_pci_device_id(info.name);
75
76 gen_get_device_info(devid, &devinfo);
77
78 brw_init_codegen(&devinfo, p, p);
79 }
80
81 struct gen_name {
82 template <class ParamType>
83 std::string
84 operator()(const ::testing::TestParamInfo<ParamType>& info) const {
85 return info.param.name;
86 }
87 };
88
89 INSTANTIATE_TEST_CASE_P(eu_assembly, validation_test,
90 ::testing::ValuesIn(gens),
91 gen_name());
92
93 static bool
94 validate(struct brw_codegen *p)
95 {
96 const bool print = getenv("TEST_DEBUG");
97 struct disasm_info *disasm = disasm_initialize(p->devinfo, NULL);
98
99 if (print) {
100 disasm_new_inst_group(disasm, 0);
101 disasm_new_inst_group(disasm, p->next_insn_offset);
102 }
103
104 bool ret = brw_validate_instructions(p->devinfo, p->store, 0,
105 p->next_insn_offset, disasm);
106
107 if (print) {
108 dump_assembly(p->store, disasm);
109 }
110 ralloc_free(disasm);
111
112 return ret;
113 }
114
115 #define last_inst (&p->store[p->nr_insn - 1])
116 #define g0 brw_vec8_grf(0, 0)
117 #define acc0 brw_acc_reg(8)
118 #define null brw_null_reg()
119 #define zero brw_imm_f(0.0f)
120
121 static void
122 clear_instructions(struct brw_codegen *p)
123 {
124 p->next_insn_offset = 0;
125 p->nr_insn = 0;
126 }
127
128 TEST_P(validation_test, sanity)
129 {
130 brw_ADD(p, g0, g0, g0);
131
132 EXPECT_TRUE(validate(p));
133 }
134
135 TEST_P(validation_test, src0_null_reg)
136 {
137 brw_MOV(p, g0, null);
138
139 EXPECT_FALSE(validate(p));
140 }
141
142 TEST_P(validation_test, src1_null_reg)
143 {
144 brw_ADD(p, g0, g0, null);
145
146 EXPECT_FALSE(validate(p));
147 }
148
149 TEST_P(validation_test, math_src0_null_reg)
150 {
151 if (devinfo.gen >= 6) {
152 gen6_math(p, g0, BRW_MATH_FUNCTION_SIN, null, null);
153 } else {
154 gen4_math(p, g0, BRW_MATH_FUNCTION_SIN, 0, null, BRW_MATH_PRECISION_FULL);
155 }
156
157 EXPECT_FALSE(validate(p));
158 }
159
160 TEST_P(validation_test, math_src1_null_reg)
161 {
162 if (devinfo.gen >= 6) {
163 gen6_math(p, g0, BRW_MATH_FUNCTION_POW, g0, null);
164 EXPECT_FALSE(validate(p));
165 } else {
166 /* Math instructions on Gen4/5 are actually SEND messages with payloads.
167 * src1 is an immediate message descriptor set by gen4_math.
168 */
169 }
170 }
171
172 TEST_P(validation_test, opcode46)
173 {
174 /* opcode 46 is "push" on Gen 4 and 5
175 * "fork" on Gen 6
176 * reserved on Gen 7
177 * "goto" on Gen8+
178 */
179 brw_next_insn(p, 46);
180
181 if (devinfo.gen == 7) {
182 EXPECT_FALSE(validate(p));
183 } else {
184 EXPECT_TRUE(validate(p));
185 }
186 }
187
188 /* When the Execution Data Type is wider than the destination data type, the
189 * destination must [...] specify a HorzStride equal to the ratio in sizes of
190 * the two data types.
191 */
192 TEST_P(validation_test, dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size)
193 {
194 brw_ADD(p, g0, g0, g0);
195 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
196 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
197 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
198
199 EXPECT_FALSE(validate(p));
200
201 clear_instructions(p);
202
203 brw_ADD(p, g0, g0, g0);
204 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
205 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
206 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
207 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
208
209 EXPECT_TRUE(validate(p));
210 }
211
212 /* When the Execution Data Type is wider than the destination data type, the
213 * destination must be aligned as required by the wider execution data type
214 * [...]
215 */
216 TEST_P(validation_test, dst_subreg_must_be_aligned_to_exec_type_size)
217 {
218 brw_ADD(p, g0, g0, g0);
219 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 2);
220 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
221 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
222 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
223 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
224
225 EXPECT_FALSE(validate(p));
226
227 clear_instructions(p);
228
229 brw_ADD(p, g0, g0, g0);
230 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
231 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 8);
232 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
233 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
234 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
235 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
236 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
237 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
238 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
239 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
240 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
241 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
242
243 EXPECT_TRUE(validate(p));
244 }
245
246 /* ExecSize must be greater than or equal to Width. */
247 TEST_P(validation_test, exec_size_less_than_width)
248 {
249 brw_ADD(p, g0, g0, g0);
250 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_16);
251
252 EXPECT_FALSE(validate(p));
253
254 clear_instructions(p);
255
256 brw_ADD(p, g0, g0, g0);
257 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_16);
258
259 EXPECT_FALSE(validate(p));
260 }
261
262 /* If ExecSize = Width and HorzStride ≠ 0,
263 * VertStride must be set to Width * HorzStride.
264 */
265 TEST_P(validation_test, vertical_stride_is_width_by_horizontal_stride)
266 {
267 brw_ADD(p, g0, g0, g0);
268 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
269
270 EXPECT_FALSE(validate(p));
271
272 clear_instructions(p);
273
274 brw_ADD(p, g0, g0, g0);
275 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
276
277 EXPECT_FALSE(validate(p));
278 }
279
280 /* If Width = 1, HorzStride must be 0 regardless of the values
281 * of ExecSize and VertStride.
282 */
283 TEST_P(validation_test, horizontal_stride_must_be_0_if_width_is_1)
284 {
285 brw_ADD(p, g0, g0, g0);
286 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
287 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
288 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
289
290 EXPECT_FALSE(validate(p));
291
292 clear_instructions(p);
293
294 brw_ADD(p, g0, g0, g0);
295 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
296 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_1);
297 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
298
299 EXPECT_FALSE(validate(p));
300 }
301
302 /* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */
303 TEST_P(validation_test, scalar_region_must_be_0_1_0)
304 {
305 struct brw_reg g0_0 = brw_vec1_grf(0, 0);
306
307 brw_ADD(p, g0, g0, g0_0);
308 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_1);
309 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_1);
310 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
311 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
312
313 EXPECT_FALSE(validate(p));
314
315 clear_instructions(p);
316
317 brw_ADD(p, g0, g0_0, g0);
318 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_1);
319 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_1);
320 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_1);
321 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
322
323 EXPECT_FALSE(validate(p));
324 }
325
326 /* If VertStride = HorzStride = 0, Width must be 1 regardless of the value
327 * of ExecSize.
328 */
329 TEST_P(validation_test, zero_stride_implies_0_1_0)
330 {
331 brw_ADD(p, g0, g0, g0);
332 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
333 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_2);
334 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
335
336 EXPECT_FALSE(validate(p));
337
338 clear_instructions(p);
339
340 brw_ADD(p, g0, g0, g0);
341 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
342 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2);
343 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
344
345 EXPECT_FALSE(validate(p));
346 }
347
348 /* Dst.HorzStride must not be 0. */
349 TEST_P(validation_test, dst_horizontal_stride_0)
350 {
351 brw_ADD(p, g0, g0, g0);
352 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
353
354 EXPECT_FALSE(validate(p));
355
356 clear_instructions(p);
357
358 /* Align16 does not exist on Gen11+ */
359 if (devinfo.gen >= 11)
360 return;
361
362 brw_set_default_access_mode(p, BRW_ALIGN_16);
363
364 brw_ADD(p, g0, g0, g0);
365 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
366
367 EXPECT_FALSE(validate(p));
368 }
369
370 /* VertStride must be used to cross BRW_GENERAL_REGISTER_FILE register boundaries. This rule implies
371 * that elements within a 'Width' cannot cross BRW_GENERAL_REGISTER_FILE boundaries.
372 */
373 TEST_P(validation_test, must_not_cross_grf_boundary_in_a_width)
374 {
375 brw_ADD(p, g0, g0, g0);
376 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 4);
377
378 EXPECT_FALSE(validate(p));
379
380 clear_instructions(p);
381
382 brw_ADD(p, g0, g0, g0);
383 brw_inst_set_src1_da1_subreg_nr(&devinfo, last_inst, 4);
384
385 EXPECT_FALSE(validate(p));
386
387 clear_instructions(p);
388
389 brw_ADD(p, g0, g0, g0);
390 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
391 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
392 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
393
394 EXPECT_FALSE(validate(p));
395
396 clear_instructions(p);
397
398 brw_ADD(p, g0, g0, g0);
399 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
400 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
401 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
402
403 EXPECT_FALSE(validate(p));
404 }
405
406 /* Destination Horizontal must be 1 in Align16 */
407 TEST_P(validation_test, dst_hstride_on_align16_must_be_1)
408 {
409 /* Align16 does not exist on Gen11+ */
410 if (devinfo.gen >= 11)
411 return;
412
413 brw_set_default_access_mode(p, BRW_ALIGN_16);
414
415 brw_ADD(p, g0, g0, g0);
416 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
417
418 EXPECT_FALSE(validate(p));
419
420 clear_instructions(p);
421
422 brw_ADD(p, g0, g0, g0);
423 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
424
425 EXPECT_TRUE(validate(p));
426 }
427
428 /* VertStride must be 0 or 4 in Align16 */
429 TEST_P(validation_test, vstride_on_align16_must_be_0_or_4)
430 {
431 /* Align16 does not exist on Gen11+ */
432 if (devinfo.gen >= 11)
433 return;
434
435 const struct {
436 enum brw_vertical_stride vstride;
437 bool expected_result;
438 } vstride[] = {
439 { BRW_VERTICAL_STRIDE_0, true },
440 { BRW_VERTICAL_STRIDE_1, false },
441 { BRW_VERTICAL_STRIDE_2, devinfo.is_haswell || devinfo.gen >= 8 },
442 { BRW_VERTICAL_STRIDE_4, true },
443 { BRW_VERTICAL_STRIDE_8, false },
444 { BRW_VERTICAL_STRIDE_16, false },
445 { BRW_VERTICAL_STRIDE_32, false },
446 { BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL, false },
447 };
448
449 brw_set_default_access_mode(p, BRW_ALIGN_16);
450
451 for (unsigned i = 0; i < sizeof(vstride) / sizeof(vstride[0]); i++) {
452 brw_ADD(p, g0, g0, g0);
453 brw_inst_set_src0_vstride(&devinfo, last_inst, vstride[i].vstride);
454
455 EXPECT_EQ(vstride[i].expected_result, validate(p));
456
457 clear_instructions(p);
458 }
459
460 for (unsigned i = 0; i < sizeof(vstride) / sizeof(vstride[0]); i++) {
461 brw_ADD(p, g0, g0, g0);
462 brw_inst_set_src1_vstride(&devinfo, last_inst, vstride[i].vstride);
463
464 EXPECT_EQ(vstride[i].expected_result, validate(p));
465
466 clear_instructions(p);
467 }
468 }
469
470 /* In Direct Addressing mode, a source cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE
471 * registers.
472 */
473 TEST_P(validation_test, source_cannot_span_more_than_2_registers)
474 {
475 brw_ADD(p, g0, g0, g0);
476 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_32);
477 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
478 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
479 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
480 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
481 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8);
482 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
483
484 EXPECT_FALSE(validate(p));
485
486 clear_instructions(p);
487
488 brw_ADD(p, g0, g0, g0);
489 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
490 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
491 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
492 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
493 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
494 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8);
495 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
496 brw_inst_set_src1_da1_subreg_nr(&devinfo, last_inst, 2);
497
498 EXPECT_TRUE(validate(p));
499
500 clear_instructions(p);
501
502 brw_ADD(p, g0, g0, g0);
503 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
504
505 EXPECT_TRUE(validate(p));
506 }
507
508 /* A destination cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE registers. */
509 TEST_P(validation_test, destination_cannot_span_more_than_2_registers)
510 {
511 brw_ADD(p, g0, g0, g0);
512 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_32);
513 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
514 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
515 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
516 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
517
518 EXPECT_FALSE(validate(p));
519
520 clear_instructions(p);
521
522 brw_ADD(p, g0, g0, g0);
523 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_8);
524 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 6);
525 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4);
526 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
527 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
528 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
529 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
530 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
531 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
532 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
533 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
534 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
535
536 EXPECT_TRUE(validate(p));
537 }
538
539 TEST_P(validation_test, src_region_spans_two_regs_dst_region_spans_one)
540 {
541 /* Writes to dest are to the lower OWord */
542 brw_ADD(p, g0, g0, g0);
543 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
544 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
545 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
546 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
547 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
548 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
549
550 EXPECT_TRUE(validate(p));
551
552 clear_instructions(p);
553
554 /* Writes to dest are to the upper OWord */
555 brw_ADD(p, g0, g0, g0);
556 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 16);
557 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
558 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
559 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
560 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
561 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
562 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
563
564 EXPECT_TRUE(validate(p));
565
566 clear_instructions(p);
567
568 /* Writes to dest are evenly split between OWords */
569 brw_ADD(p, g0, g0, g0);
570 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
571 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
572 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
573 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
574 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
575 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8);
576 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
577
578 EXPECT_TRUE(validate(p));
579
580 clear_instructions(p);
581
582 /* Writes to dest are uneven between OWords */
583 brw_ADD(p, g0, g0, g0);
584 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
585 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 10);
586 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
587 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
588 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
589 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
590 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
591 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
592 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
593 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2);
594 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
595
596 if (devinfo.gen >= 9) {
597 EXPECT_TRUE(validate(p));
598 } else {
599 EXPECT_FALSE(validate(p));
600 }
601 }
602
603 TEST_P(validation_test, dst_elements_must_be_evenly_split_between_registers)
604 {
605 brw_ADD(p, g0, g0, g0);
606 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 4);
607
608 if (devinfo.gen >= 9) {
609 EXPECT_TRUE(validate(p));
610 } else {
611 EXPECT_FALSE(validate(p));
612 }
613
614 clear_instructions(p);
615
616 brw_ADD(p, g0, g0, g0);
617 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
618
619 EXPECT_TRUE(validate(p));
620
621 clear_instructions(p);
622
623 if (devinfo.gen >= 6) {
624 gen6_math(p, g0, BRW_MATH_FUNCTION_SIN, g0, null);
625
626 EXPECT_TRUE(validate(p));
627
628 clear_instructions(p);
629
630 gen6_math(p, g0, BRW_MATH_FUNCTION_SIN, g0, null);
631 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 4);
632
633 EXPECT_FALSE(validate(p));
634 }
635 }
636
637 TEST_P(validation_test, two_src_two_dst_source_offsets_must_be_same)
638 {
639 brw_ADD(p, g0, g0, g0);
640 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
641 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4);
642 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 16);
643 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_2);
644 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
645 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
646 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
647 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
648 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
649
650 if (devinfo.gen <= 7) {
651 EXPECT_FALSE(validate(p));
652 } else {
653 EXPECT_TRUE(validate(p));
654 }
655
656 clear_instructions(p);
657
658 brw_ADD(p, g0, g0, g0);
659 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
660 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4);
661 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
662 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
663 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
664 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_8);
665 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2);
666 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
667
668 EXPECT_TRUE(validate(p));
669 }
670
671 TEST_P(validation_test, two_src_two_dst_each_dst_must_be_derived_from_one_src)
672 {
673 brw_MOV(p, g0, g0);
674 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
675 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
676 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
677 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
678 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 8);
679 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
680 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
681 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
682
683 if (devinfo.gen <= 7) {
684 EXPECT_FALSE(validate(p));
685 } else {
686 EXPECT_TRUE(validate(p));
687 }
688
689 clear_instructions(p);
690
691 brw_MOV(p, g0, g0);
692 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 16);
693 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 8);
694 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_2);
695 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_2);
696 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
697
698 if (devinfo.gen <= 7) {
699 EXPECT_FALSE(validate(p));
700 } else {
701 EXPECT_TRUE(validate(p));
702 }
703 }
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_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
719 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
720 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_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_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
730 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
731 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_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_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
748 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_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_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_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
849 TEST_P(validation_test, vector_immediate_destination_alignment)
850 {
851 static const struct {
852 enum brw_reg_type dst_type;
853 enum brw_reg_type src_type;
854 unsigned subnr;
855 unsigned exec_size;
856 bool expected_result;
857 } move[] = {
858 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, 0, BRW_EXECUTE_4, true },
859 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, 16, BRW_EXECUTE_4, true },
860 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, 1, BRW_EXECUTE_4, false },
861
862 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, 0, BRW_EXECUTE_8, true },
863 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, 16, BRW_EXECUTE_8, true },
864 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, 1, BRW_EXECUTE_8, false },
865
866 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, 0, BRW_EXECUTE_8, true },
867 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, 16, BRW_EXECUTE_8, true },
868 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, 1, BRW_EXECUTE_8, false },
869 };
870
871 for (unsigned i = 0; i < sizeof(move) / sizeof(move[0]); i++) {
872 /* UV type is Gen6+ */
873 if (devinfo.gen < 6 &&
874 move[i].src_type == BRW_REGISTER_TYPE_UV)
875 continue;
876
877 brw_MOV(p, retype(g0, move[i].dst_type), retype(zero, move[i].src_type));
878 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, move[i].subnr);
879 brw_inst_set_exec_size(&devinfo, last_inst, move[i].exec_size);
880
881 EXPECT_EQ(move[i].expected_result, validate(p));
882
883 clear_instructions(p);
884 }
885 }
886
887 TEST_P(validation_test, vector_immediate_destination_stride)
888 {
889 static const struct {
890 enum brw_reg_type dst_type;
891 enum brw_reg_type src_type;
892 unsigned stride;
893 bool expected_result;
894 } move[] = {
895 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_1, true },
896 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, false },
897 { BRW_REGISTER_TYPE_D, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_1, true },
898 { BRW_REGISTER_TYPE_D, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, false },
899 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, true },
900 { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_4, true },
901
902 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_1, true },
903 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_2, false },
904 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_4, false },
905 { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_2, true },
906
907 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_1, true },
908 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_2, false },
909 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_4, false },
910 { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_2, true },
911 };
912
913 for (unsigned i = 0; i < sizeof(move) / sizeof(move[0]); i++) {
914 /* UV type is Gen6+ */
915 if (devinfo.gen < 6 &&
916 move[i].src_type == BRW_REGISTER_TYPE_UV)
917 continue;
918
919 brw_MOV(p, retype(g0, move[i].dst_type), retype(zero, move[i].src_type));
920 brw_inst_set_dst_hstride(&devinfo, last_inst, move[i].stride);
921
922 EXPECT_EQ(move[i].expected_result, validate(p));
923
924 clear_instructions(p);
925 }
926 }
927
928 TEST_P(validation_test, qword_low_power_align1_regioning_restrictions)
929 {
930 static const struct {
931 enum opcode opcode;
932 unsigned exec_size;
933
934 enum brw_reg_type dst_type;
935 unsigned dst_subreg;
936 unsigned dst_stride;
937
938 enum brw_reg_type src_type;
939 unsigned src_subreg;
940 unsigned src_vstride;
941 unsigned src_width;
942 unsigned src_hstride;
943
944 bool expected_result;
945 } inst[] = {
946 #define INST(opcode, exec_size, dst_type, dst_subreg, dst_stride, src_type, \
947 src_subreg, src_vstride, src_width, src_hstride, expected_result) \
948 { \
949 BRW_OPCODE_##opcode, \
950 BRW_EXECUTE_##exec_size, \
951 BRW_REGISTER_TYPE_##dst_type, \
952 dst_subreg, \
953 BRW_HORIZONTAL_STRIDE_##dst_stride, \
954 BRW_REGISTER_TYPE_##src_type, \
955 src_subreg, \
956 BRW_VERTICAL_STRIDE_##src_vstride, \
957 BRW_WIDTH_##src_width, \
958 BRW_HORIZONTAL_STRIDE_##src_hstride, \
959 expected_result, \
960 }
961
962 /* Some instruction that violate no restrictions, as a control */
963 INST(MOV, 4, DF, 0, 1, DF, 0, 4, 4, 1, true ),
964 INST(MOV, 4, Q, 0, 1, Q, 0, 4, 4, 1, true ),
965 INST(MOV, 4, UQ, 0, 1, UQ, 0, 4, 4, 1, true ),
966
967 INST(MOV, 4, DF, 0, 1, F, 0, 8, 4, 2, true ),
968 INST(MOV, 4, Q, 0, 1, D, 0, 8, 4, 2, true ),
969 INST(MOV, 4, UQ, 0, 1, UD, 0, 8, 4, 2, true ),
970
971 INST(MOV, 4, F, 0, 2, DF, 0, 4, 4, 1, true ),
972 INST(MOV, 4, D, 0, 2, Q, 0, 4, 4, 1, true ),
973 INST(MOV, 4, UD, 0, 2, UQ, 0, 4, 4, 1, true ),
974
975 INST(MUL, 8, D, 0, 2, D, 0, 8, 4, 2, true ),
976 INST(MUL, 8, UD, 0, 2, UD, 0, 8, 4, 2, true ),
977
978 /* Something with subreg nrs */
979 INST(MOV, 2, DF, 8, 1, DF, 8, 2, 2, 1, true ),
980 INST(MOV, 2, Q, 8, 1, Q, 8, 2, 2, 1, true ),
981 INST(MOV, 2, UQ, 8, 1, UQ, 8, 2, 2, 1, true ),
982
983 INST(MUL, 2, D, 4, 2, D, 4, 4, 2, 2, true ),
984 INST(MUL, 2, UD, 4, 2, UD, 4, 4, 2, 2, true ),
985
986 /* The PRMs say that for CHV, BXT:
987 *
988 * When source or destination datatype is 64b or operation is integer
989 * DWord multiply, regioning in Align1 must follow these rules:
990 *
991 * 1. Source and Destination horizontal stride must be aligned to the
992 * same qword.
993 */
994 INST(MOV, 4, DF, 0, 2, DF, 0, 4, 4, 1, false),
995 INST(MOV, 4, Q, 0, 2, Q, 0, 4, 4, 1, false),
996 INST(MOV, 4, UQ, 0, 2, UQ, 0, 4, 4, 1, false),
997
998 INST(MOV, 4, DF, 0, 2, F, 0, 8, 4, 2, false),
999 INST(MOV, 4, Q, 0, 2, D, 0, 8, 4, 2, false),
1000 INST(MOV, 4, UQ, 0, 2, UD, 0, 8, 4, 2, false),
1001
1002 INST(MOV, 4, DF, 0, 2, F, 0, 4, 4, 1, false),
1003 INST(MOV, 4, Q, 0, 2, D, 0, 4, 4, 1, false),
1004 INST(MOV, 4, UQ, 0, 2, UD, 0, 4, 4, 1, false),
1005
1006 INST(MUL, 4, D, 0, 2, D, 0, 4, 4, 1, false),
1007 INST(MUL, 4, UD, 0, 2, UD, 0, 4, 4, 1, false),
1008
1009 INST(MUL, 4, D, 0, 1, D, 0, 8, 4, 2, false),
1010 INST(MUL, 4, UD, 0, 1, UD, 0, 8, 4, 2, false),
1011
1012 /* 2. Regioning must ensure Src.Vstride = Src.Width * Src.Hstride. */
1013 INST(MOV, 4, DF, 0, 1, DF, 0, 0, 2, 1, false),
1014 INST(MOV, 4, Q, 0, 1, Q, 0, 0, 2, 1, false),
1015 INST(MOV, 4, UQ, 0, 1, UQ, 0, 0, 2, 1, false),
1016
1017 INST(MOV, 4, DF, 0, 1, F, 0, 0, 2, 2, false),
1018 INST(MOV, 4, Q, 0, 1, D, 0, 0, 2, 2, false),
1019 INST(MOV, 4, UQ, 0, 1, UD, 0, 0, 2, 2, false),
1020
1021 INST(MOV, 8, F, 0, 2, DF, 0, 0, 2, 1, false),
1022 INST(MOV, 8, D, 0, 2, Q, 0, 0, 2, 1, false),
1023 INST(MOV, 8, UD, 0, 2, UQ, 0, 0, 2, 1, false),
1024
1025 INST(MUL, 8, D, 0, 2, D, 0, 0, 4, 2, false),
1026 INST(MUL, 8, UD, 0, 2, UD, 0, 0, 4, 2, false),
1027
1028 INST(MUL, 8, D, 0, 2, D, 0, 0, 4, 2, false),
1029 INST(MUL, 8, UD, 0, 2, UD, 0, 0, 4, 2, false),
1030
1031 /* 3. Source and Destination offset must be the same, except the case
1032 * of scalar source.
1033 */
1034 INST(MOV, 2, DF, 8, 1, DF, 0, 2, 2, 1, false),
1035 INST(MOV, 2, Q, 8, 1, Q, 0, 2, 2, 1, false),
1036 INST(MOV, 2, UQ, 8, 1, UQ, 0, 2, 2, 1, false),
1037
1038 INST(MOV, 2, DF, 0, 1, DF, 8, 2, 2, 1, false),
1039 INST(MOV, 2, Q, 0, 1, Q, 8, 2, 2, 1, false),
1040 INST(MOV, 2, UQ, 0, 1, UQ, 8, 2, 2, 1, false),
1041
1042 INST(MUL, 4, D, 4, 2, D, 0, 4, 2, 2, false),
1043 INST(MUL, 4, UD, 4, 2, UD, 0, 4, 2, 2, false),
1044
1045 INST(MUL, 4, D, 0, 2, D, 4, 4, 2, 2, false),
1046 INST(MUL, 4, UD, 0, 2, UD, 4, 4, 2, 2, false),
1047
1048 INST(MOV, 2, DF, 8, 1, DF, 0, 0, 1, 0, true ),
1049 INST(MOV, 2, Q, 8, 1, Q, 0, 0, 1, 0, true ),
1050 INST(MOV, 2, UQ, 8, 1, UQ, 0, 0, 1, 0, true ),
1051
1052 INST(MOV, 2, DF, 8, 1, F, 4, 0, 1, 0, true ),
1053 INST(MOV, 2, Q, 8, 1, D, 4, 0, 1, 0, true ),
1054 INST(MOV, 2, UQ, 8, 1, UD, 4, 0, 1, 0, true ),
1055
1056 INST(MUL, 4, D, 4, 1, D, 0, 0, 1, 0, true ),
1057 INST(MUL, 4, UD, 4, 1, UD, 0, 0, 1, 0, true ),
1058
1059 INST(MUL, 4, D, 0, 1, D, 4, 0, 1, 0, true ),
1060 INST(MUL, 4, UD, 0, 1, UD, 4, 0, 1, 0, true ),
1061
1062 #undef INST
1063 };
1064
1065 /* These restrictions only apply to Gen8+ */
1066 if (devinfo.gen < 8)
1067 return;
1068
1069 for (unsigned i = 0; i < sizeof(inst) / sizeof(inst[0]); i++) {
1070 if (!devinfo.has_64bit_types &&
1071 (type_sz(inst[i].dst_type) == 8 || type_sz(inst[i].src_type) == 8))
1072 continue;
1073
1074 if (inst[i].opcode == BRW_OPCODE_MOV) {
1075 brw_MOV(p, retype(g0, inst[i].dst_type),
1076 retype(g0, inst[i].src_type));
1077 } else {
1078 assert(inst[i].opcode == BRW_OPCODE_MUL);
1079 brw_MUL(p, retype(g0, inst[i].dst_type),
1080 retype(g0, inst[i].src_type),
1081 retype(zero, inst[i].src_type));
1082 }
1083 brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
1084
1085 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, inst[i].dst_subreg);
1086 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, inst[i].src_subreg);
1087
1088 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1089
1090 brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride);
1091 brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width);
1092 brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride);
1093
1094 if (devinfo.is_cherryview || gen_device_info_is_9lp(&devinfo)) {
1095 EXPECT_EQ(inst[i].expected_result, validate(p));
1096 } else {
1097 EXPECT_TRUE(validate(p));
1098 }
1099
1100 clear_instructions(p);
1101 }
1102 }
1103
1104 TEST_P(validation_test, qword_low_power_no_indirect_addressing)
1105 {
1106 static const struct {
1107 enum opcode opcode;
1108 unsigned exec_size;
1109
1110 enum brw_reg_type dst_type;
1111 bool dst_is_indirect;
1112 unsigned dst_stride;
1113
1114 enum brw_reg_type src_type;
1115 bool src_is_indirect;
1116 unsigned src_vstride;
1117 unsigned src_width;
1118 unsigned src_hstride;
1119
1120 bool expected_result;
1121 } inst[] = {
1122 #define INST(opcode, exec_size, dst_type, dst_is_indirect, dst_stride, \
1123 src_type, src_is_indirect, src_vstride, src_width, src_hstride, \
1124 expected_result) \
1125 { \
1126 BRW_OPCODE_##opcode, \
1127 BRW_EXECUTE_##exec_size, \
1128 BRW_REGISTER_TYPE_##dst_type, \
1129 dst_is_indirect, \
1130 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1131 BRW_REGISTER_TYPE_##src_type, \
1132 src_is_indirect, \
1133 BRW_VERTICAL_STRIDE_##src_vstride, \
1134 BRW_WIDTH_##src_width, \
1135 BRW_HORIZONTAL_STRIDE_##src_hstride, \
1136 expected_result, \
1137 }
1138
1139 /* Some instruction that violate no restrictions, as a control */
1140 INST(MOV, 4, DF, 0, 1, DF, 0, 4, 4, 1, true ),
1141 INST(MOV, 4, Q, 0, 1, Q, 0, 4, 4, 1, true ),
1142 INST(MOV, 4, UQ, 0, 1, UQ, 0, 4, 4, 1, true ),
1143
1144 INST(MUL, 8, D, 0, 2, D, 0, 8, 4, 2, true ),
1145 INST(MUL, 8, UD, 0, 2, UD, 0, 8, 4, 2, true ),
1146
1147 INST(MOV, 4, F, 1, 1, F, 0, 4, 4, 1, true ),
1148 INST(MOV, 4, F, 0, 1, F, 1, 4, 4, 1, true ),
1149 INST(MOV, 4, F, 1, 1, F, 1, 4, 4, 1, true ),
1150
1151 /* The PRMs say that for CHV, BXT:
1152 *
1153 * When source or destination datatype is 64b or operation is integer
1154 * DWord multiply, indirect addressing must not be used.
1155 */
1156 INST(MOV, 4, DF, 1, 1, DF, 0, 4, 4, 1, false),
1157 INST(MOV, 4, Q, 1, 1, Q, 0, 4, 4, 1, false),
1158 INST(MOV, 4, UQ, 1, 1, UQ, 0, 4, 4, 1, false),
1159
1160 INST(MOV, 4, DF, 0, 1, DF, 1, 4, 4, 1, false),
1161 INST(MOV, 4, Q, 0, 1, Q, 1, 4, 4, 1, false),
1162 INST(MOV, 4, UQ, 0, 1, UQ, 1, 4, 4, 1, false),
1163
1164 INST(MOV, 4, DF, 1, 1, F, 0, 8, 4, 2, false),
1165 INST(MOV, 4, Q, 1, 1, D, 0, 8, 4, 2, false),
1166 INST(MOV, 4, UQ, 1, 1, UD, 0, 8, 4, 2, false),
1167
1168 INST(MOV, 4, DF, 0, 1, F, 1, 8, 4, 2, false),
1169 INST(MOV, 4, Q, 0, 1, D, 1, 8, 4, 2, false),
1170 INST(MOV, 4, UQ, 0, 1, UD, 1, 8, 4, 2, false),
1171
1172 INST(MOV, 4, F, 1, 2, DF, 0, 4, 4, 1, false),
1173 INST(MOV, 4, D, 1, 2, Q, 0, 4, 4, 1, false),
1174 INST(MOV, 4, UD, 1, 2, UQ, 0, 4, 4, 1, false),
1175
1176 INST(MOV, 4, F, 0, 2, DF, 1, 4, 4, 1, false),
1177 INST(MOV, 4, D, 0, 2, Q, 1, 4, 4, 1, false),
1178 INST(MOV, 4, UD, 0, 2, UQ, 1, 4, 4, 1, false),
1179
1180 INST(MUL, 8, D, 1, 2, D, 0, 8, 4, 2, false),
1181 INST(MUL, 8, UD, 1, 2, UD, 0, 8, 4, 2, false),
1182
1183 INST(MUL, 8, D, 0, 2, D, 1, 8, 4, 2, false),
1184 INST(MUL, 8, UD, 0, 2, UD, 1, 8, 4, 2, false),
1185
1186 #undef INST
1187 };
1188
1189 /* These restrictions only apply to Gen8+ */
1190 if (devinfo.gen < 8)
1191 return;
1192
1193 for (unsigned i = 0; i < sizeof(inst) / sizeof(inst[0]); i++) {
1194 if (!devinfo.has_64bit_types &&
1195 (type_sz(inst[i].dst_type) == 8 || type_sz(inst[i].src_type) == 8))
1196 continue;
1197
1198 if (inst[i].opcode == BRW_OPCODE_MOV) {
1199 brw_MOV(p, retype(g0, inst[i].dst_type),
1200 retype(g0, inst[i].src_type));
1201 } else {
1202 assert(inst[i].opcode == BRW_OPCODE_MUL);
1203 brw_MUL(p, retype(g0, inst[i].dst_type),
1204 retype(g0, inst[i].src_type),
1205 retype(zero, inst[i].src_type));
1206 }
1207 brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
1208
1209 brw_inst_set_dst_address_mode(&devinfo, last_inst, inst[i].dst_is_indirect);
1210 brw_inst_set_src0_address_mode(&devinfo, last_inst, inst[i].src_is_indirect);
1211
1212 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1213
1214 brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride);
1215 brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width);
1216 brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride);
1217
1218 if (devinfo.is_cherryview || gen_device_info_is_9lp(&devinfo)) {
1219 EXPECT_EQ(inst[i].expected_result, validate(p));
1220 } else {
1221 EXPECT_TRUE(validate(p));
1222 }
1223
1224 clear_instructions(p);
1225 }
1226 }
1227
1228 TEST_P(validation_test, qword_low_power_no_64bit_arf)
1229 {
1230 static const struct {
1231 enum opcode opcode;
1232 unsigned exec_size;
1233
1234 struct brw_reg dst;
1235 enum brw_reg_type dst_type;
1236 unsigned dst_stride;
1237
1238 struct brw_reg src;
1239 enum brw_reg_type src_type;
1240 unsigned src_vstride;
1241 unsigned src_width;
1242 unsigned src_hstride;
1243
1244 bool acc_wr;
1245 bool expected_result;
1246 } inst[] = {
1247 #define INST(opcode, exec_size, dst, dst_type, dst_stride, \
1248 src, src_type, src_vstride, src_width, src_hstride, \
1249 acc_wr, expected_result) \
1250 { \
1251 BRW_OPCODE_##opcode, \
1252 BRW_EXECUTE_##exec_size, \
1253 dst, \
1254 BRW_REGISTER_TYPE_##dst_type, \
1255 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1256 src, \
1257 BRW_REGISTER_TYPE_##src_type, \
1258 BRW_VERTICAL_STRIDE_##src_vstride, \
1259 BRW_WIDTH_##src_width, \
1260 BRW_HORIZONTAL_STRIDE_##src_hstride, \
1261 acc_wr, \
1262 expected_result, \
1263 }
1264
1265 /* Some instruction that violate no restrictions, as a control */
1266 INST(MOV, 4, g0, DF, 1, g0, F, 4, 2, 2, 0, true ),
1267 INST(MOV, 4, g0, F, 2, g0, DF, 4, 4, 1, 0, true ),
1268
1269 INST(MOV, 4, g0, Q, 1, g0, D, 4, 2, 2, 0, true ),
1270 INST(MOV, 4, g0, D, 2, g0, Q, 4, 4, 1, 0, true ),
1271
1272 INST(MOV, 4, g0, UQ, 1, g0, UD, 4, 2, 2, 0, true ),
1273 INST(MOV, 4, g0, UD, 2, g0, UQ, 4, 4, 1, 0, true ),
1274
1275 INST(MOV, 4, null, F, 1, g0, F, 4, 4, 1, 0, true ),
1276 INST(MOV, 4, acc0, F, 1, g0, F, 4, 4, 1, 0, true ),
1277 INST(MOV, 4, g0, F, 1, acc0, F, 4, 4, 1, 0, true ),
1278
1279 INST(MOV, 4, null, D, 1, g0, D, 4, 4, 1, 0, true ),
1280 INST(MOV, 4, acc0, D, 1, g0, D, 4, 4, 1, 0, true ),
1281 INST(MOV, 4, g0, D, 1, acc0, D, 4, 4, 1, 0, true ),
1282
1283 INST(MOV, 4, null, UD, 1, g0, UD, 4, 4, 1, 0, true ),
1284 INST(MOV, 4, acc0, UD, 1, g0, UD, 4, 4, 1, 0, true ),
1285 INST(MOV, 4, g0, UD, 1, acc0, UD, 4, 4, 1, 0, true ),
1286
1287 INST(MUL, 4, g0, D, 2, g0, D, 4, 2, 2, 0, true ),
1288 INST(MUL, 4, g0, UD, 2, g0, UD, 4, 2, 2, 0, true ),
1289
1290 /* The PRMs say that for CHV, BXT:
1291 *
1292 * ARF registers must never be used with 64b datatype or when
1293 * operation is integer DWord multiply.
1294 */
1295 INST(MOV, 4, acc0, DF, 1, g0, F, 4, 2, 2, 0, false),
1296 INST(MOV, 4, g0, DF, 1, acc0, F, 4, 2, 2, 0, false),
1297
1298 INST(MOV, 4, acc0, Q, 1, g0, D, 4, 2, 2, 0, false),
1299 INST(MOV, 4, g0, Q, 1, acc0, D, 4, 2, 2, 0, false),
1300
1301 INST(MOV, 4, acc0, UQ, 1, g0, UD, 4, 2, 2, 0, false),
1302 INST(MOV, 4, g0, UQ, 1, acc0, UD, 4, 2, 2, 0, false),
1303
1304 INST(MOV, 4, acc0, F, 2, g0, DF, 4, 4, 1, 0, false),
1305 INST(MOV, 4, g0, F, 2, acc0, DF, 4, 4, 1, 0, false),
1306
1307 INST(MOV, 4, acc0, D, 2, g0, Q, 4, 4, 1, 0, false),
1308 INST(MOV, 4, g0, D, 2, acc0, Q, 4, 4, 1, 0, false),
1309
1310 INST(MOV, 4, acc0, UD, 2, g0, UQ, 4, 4, 1, 0, false),
1311 INST(MOV, 4, g0, UD, 2, acc0, UQ, 4, 4, 1, 0, false),
1312
1313 INST(MUL, 4, acc0, D, 2, g0, D, 4, 2, 2, 0, false),
1314 INST(MUL, 4, acc0, UD, 2, g0, UD, 4, 2, 2, 0, false),
1315 /* MUL cannot have integer accumulator sources, so don't test that */
1316
1317 /* We assume that the restriction does not apply to the null register */
1318 INST(MOV, 4, null, DF, 1, g0, F, 4, 2, 2, 0, true ),
1319 INST(MOV, 4, null, Q, 1, g0, D, 4, 2, 2, 0, true ),
1320 INST(MOV, 4, null, UQ, 1, g0, UD, 4, 2, 2, 0, true ),
1321
1322 /* Check implicit accumulator write control */
1323 INST(MOV, 4, null, DF, 1, g0, F, 4, 2, 2, 1, false),
1324 INST(MUL, 4, null, DF, 1, g0, F, 4, 2, 2, 1, false),
1325
1326 #undef INST
1327 };
1328
1329 /* These restrictions only apply to Gen8+ */
1330 if (devinfo.gen < 8)
1331 return;
1332
1333 for (unsigned i = 0; i < sizeof(inst) / sizeof(inst[0]); i++) {
1334 if (!devinfo.has_64bit_types &&
1335 (type_sz(inst[i].dst_type) == 8 || type_sz(inst[i].src_type) == 8))
1336 continue;
1337
1338 if (inst[i].opcode == BRW_OPCODE_MOV) {
1339 brw_MOV(p, retype(inst[i].dst, inst[i].dst_type),
1340 retype(inst[i].src, inst[i].src_type));
1341 } else {
1342 assert(inst[i].opcode == BRW_OPCODE_MUL);
1343 brw_MUL(p, retype(inst[i].dst, inst[i].dst_type),
1344 retype(inst[i].src, inst[i].src_type),
1345 retype(zero, inst[i].src_type));
1346 brw_inst_set_opcode(&devinfo, last_inst, inst[i].opcode);
1347 }
1348 brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
1349 brw_inst_set_acc_wr_control(&devinfo, last_inst, inst[i].acc_wr);
1350
1351 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1352
1353 brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride);
1354 brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width);
1355 brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride);
1356
1357 if (devinfo.is_cherryview || gen_device_info_is_9lp(&devinfo)) {
1358 EXPECT_EQ(inst[i].expected_result, validate(p));
1359 } else {
1360 EXPECT_TRUE(validate(p));
1361 }
1362
1363 clear_instructions(p);
1364 }
1365
1366 if (!devinfo.has_64bit_types)
1367 return;
1368
1369 /* MAC implicitly reads the accumulator */
1370 brw_MAC(p, retype(g0, BRW_REGISTER_TYPE_DF),
1371 retype(stride(g0, 4, 4, 1), BRW_REGISTER_TYPE_DF),
1372 retype(stride(g0, 4, 4, 1), BRW_REGISTER_TYPE_DF));
1373 if (devinfo.is_cherryview || gen_device_info_is_9lp(&devinfo)) {
1374 EXPECT_FALSE(validate(p));
1375 } else {
1376 EXPECT_TRUE(validate(p));
1377 }
1378 }
1379
1380 TEST_P(validation_test, align16_64_bit_integer)
1381 {
1382 static const struct {
1383 enum opcode opcode;
1384 unsigned exec_size;
1385
1386 enum brw_reg_type dst_type;
1387 enum brw_reg_type src_type;
1388
1389 bool expected_result;
1390 } inst[] = {
1391 #define INST(opcode, exec_size, dst_type, src_type, expected_result) \
1392 { \
1393 BRW_OPCODE_##opcode, \
1394 BRW_EXECUTE_##exec_size, \
1395 BRW_REGISTER_TYPE_##dst_type, \
1396 BRW_REGISTER_TYPE_##src_type, \
1397 expected_result, \
1398 }
1399
1400 /* Some instruction that violate no restrictions, as a control */
1401 INST(MOV, 2, Q, D, true ),
1402 INST(MOV, 2, UQ, UD, true ),
1403 INST(MOV, 2, DF, F, true ),
1404
1405 INST(ADD, 2, Q, D, true ),
1406 INST(ADD, 2, UQ, UD, true ),
1407 INST(ADD, 2, DF, F, true ),
1408
1409 /* The PRMs say that for BDW, SKL:
1410 *
1411 * If Align16 is required for an operation with QW destination and non-QW
1412 * source datatypes, the execution size cannot exceed 2.
1413 */
1414
1415 INST(MOV, 4, Q, D, false),
1416 INST(MOV, 4, UQ, UD, false),
1417 INST(MOV, 4, DF, F, false),
1418
1419 INST(ADD, 4, Q, D, false),
1420 INST(ADD, 4, UQ, UD, false),
1421 INST(ADD, 4, DF, F, false),
1422
1423 #undef INST
1424 };
1425
1426 /* 64-bit integer types exist on Gen8+ */
1427 if (devinfo.gen < 8)
1428 return;
1429
1430 /* Align16 does not exist on Gen11+ */
1431 if (devinfo.gen >= 11)
1432 return;
1433
1434 brw_set_default_access_mode(p, BRW_ALIGN_16);
1435
1436 for (unsigned i = 0; i < sizeof(inst) / sizeof(inst[0]); i++) {
1437 if (inst[i].opcode == BRW_OPCODE_MOV) {
1438 brw_MOV(p, retype(g0, inst[i].dst_type),
1439 retype(g0, inst[i].src_type));
1440 } else {
1441 assert(inst[i].opcode == BRW_OPCODE_ADD);
1442 brw_ADD(p, retype(g0, inst[i].dst_type),
1443 retype(g0, inst[i].src_type),
1444 retype(g0, inst[i].src_type));
1445 }
1446 brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
1447
1448 EXPECT_EQ(inst[i].expected_result, validate(p));
1449
1450 clear_instructions(p);
1451 }
1452 }
1453
1454 TEST_P(validation_test, qword_low_power_no_depctrl)
1455 {
1456 static const struct {
1457 enum opcode opcode;
1458 unsigned exec_size;
1459
1460 enum brw_reg_type dst_type;
1461 unsigned dst_stride;
1462
1463 enum brw_reg_type src_type;
1464 unsigned src_vstride;
1465 unsigned src_width;
1466 unsigned src_hstride;
1467
1468 bool no_dd_check;
1469 bool no_dd_clear;
1470
1471 bool expected_result;
1472 } inst[] = {
1473 #define INST(opcode, exec_size, dst_type, dst_stride, \
1474 src_type, src_vstride, src_width, src_hstride, \
1475 no_dd_check, no_dd_clear, expected_result) \
1476 { \
1477 BRW_OPCODE_##opcode, \
1478 BRW_EXECUTE_##exec_size, \
1479 BRW_REGISTER_TYPE_##dst_type, \
1480 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1481 BRW_REGISTER_TYPE_##src_type, \
1482 BRW_VERTICAL_STRIDE_##src_vstride, \
1483 BRW_WIDTH_##src_width, \
1484 BRW_HORIZONTAL_STRIDE_##src_hstride, \
1485 no_dd_check, \
1486 no_dd_clear, \
1487 expected_result, \
1488 }
1489
1490 /* Some instruction that violate no restrictions, as a control */
1491 INST(MOV, 4, DF, 1, F, 8, 4, 2, 0, 0, true ),
1492 INST(MOV, 4, Q, 1, D, 8, 4, 2, 0, 0, true ),
1493 INST(MOV, 4, UQ, 1, UD, 8, 4, 2, 0, 0, true ),
1494
1495 INST(MOV, 4, F, 2, DF, 4, 4, 1, 0, 0, true ),
1496 INST(MOV, 4, D, 2, Q, 4, 4, 1, 0, 0, true ),
1497 INST(MOV, 4, UD, 2, UQ, 4, 4, 1, 0, 0, true ),
1498
1499 INST(MUL, 8, D, 2, D, 8, 4, 2, 0, 0, true ),
1500 INST(MUL, 8, UD, 2, UD, 8, 4, 2, 0, 0, true ),
1501
1502 INST(MOV, 4, F, 1, F, 4, 4, 1, 1, 1, true ),
1503
1504 /* The PRMs say that for CHV, BXT:
1505 *
1506 * When source or destination datatype is 64b or operation is integer
1507 * DWord multiply, DepCtrl must not be used.
1508 */
1509 INST(MOV, 4, DF, 1, F, 8, 4, 2, 1, 0, false),
1510 INST(MOV, 4, Q, 1, D, 8, 4, 2, 1, 0, false),
1511 INST(MOV, 4, UQ, 1, UD, 8, 4, 2, 1, 0, false),
1512
1513 INST(MOV, 4, F, 2, DF, 4, 4, 1, 1, 0, false),
1514 INST(MOV, 4, D, 2, Q, 4, 4, 1, 1, 0, false),
1515 INST(MOV, 4, UD, 2, UQ, 4, 4, 1, 1, 0, false),
1516
1517 INST(MOV, 4, DF, 1, F, 8, 4, 2, 0, 1, false),
1518 INST(MOV, 4, Q, 1, D, 8, 4, 2, 0, 1, false),
1519 INST(MOV, 4, UQ, 1, UD, 8, 4, 2, 0, 1, false),
1520
1521 INST(MOV, 4, F, 2, DF, 4, 4, 1, 0, 1, false),
1522 INST(MOV, 4, D, 2, Q, 4, 4, 1, 0, 1, false),
1523 INST(MOV, 4, UD, 2, UQ, 4, 4, 1, 0, 1, false),
1524
1525 INST(MUL, 8, D, 2, D, 8, 4, 2, 1, 0, false),
1526 INST(MUL, 8, UD, 2, UD, 8, 4, 2, 1, 0, false),
1527
1528 INST(MUL, 8, D, 2, D, 8, 4, 2, 0, 1, false),
1529 INST(MUL, 8, UD, 2, UD, 8, 4, 2, 0, 1, false),
1530
1531 #undef INST
1532 };
1533
1534 /* These restrictions only apply to Gen8+ */
1535 if (devinfo.gen < 8)
1536 return;
1537
1538 for (unsigned i = 0; i < sizeof(inst) / sizeof(inst[0]); i++) {
1539 if (!devinfo.has_64bit_types &&
1540 (type_sz(inst[i].dst_type) == 8 || type_sz(inst[i].src_type) == 8))
1541 continue;
1542
1543 if (inst[i].opcode == BRW_OPCODE_MOV) {
1544 brw_MOV(p, retype(g0, inst[i].dst_type),
1545 retype(g0, inst[i].src_type));
1546 } else {
1547 assert(inst[i].opcode == BRW_OPCODE_MUL);
1548 brw_MUL(p, retype(g0, inst[i].dst_type),
1549 retype(g0, inst[i].src_type),
1550 retype(zero, inst[i].src_type));
1551 }
1552 brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
1553
1554 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1555
1556 brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride);
1557 brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width);
1558 brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride);
1559
1560 brw_inst_set_no_dd_check(&devinfo, last_inst, inst[i].no_dd_check);
1561 brw_inst_set_no_dd_clear(&devinfo, last_inst, inst[i].no_dd_clear);
1562
1563 if (devinfo.is_cherryview || gen_device_info_is_9lp(&devinfo)) {
1564 EXPECT_EQ(inst[i].expected_result, validate(p));
1565 } else {
1566 EXPECT_TRUE(validate(p));
1567 }
1568
1569 clear_instructions(p);
1570 }
1571 }