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