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