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