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