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