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 "brw_eu_defines.h"
27 #include "util/bitset.h"
28 #include "util/ralloc.h"
29
30 static const struct intel_gfx_info {
31 const char *name;
32 } gfx_names[] = {
33 { "brw", },
34 { "g4x", },
35 { "ilk", },
36 { "snb", },
37 { "ivb", },
38 { "byt", },
39 { "hsw", },
40 { "bdw", },
41 { "chv", },
42 { "skl", },
43 { "bxt", },
44 { "kbl", },
45 { "aml", },
46 { "glk", },
47 { "cfl", },
48 { "whl", },
49 { "icl", },
50 { "tgl", },
51 };
52
53 class validation_test: public ::testing::TestWithParam<struct intel_gfx_info> {
54 virtual void SetUp();
55
56 public:
57 validation_test();
58 virtual ~validation_test();
59
60 struct brw_codegen *p;
61 struct intel_device_info devinfo;
62 };
63
validation_test()64 validation_test::validation_test()
65 {
66 p = rzalloc(NULL, struct brw_codegen);
67 memset(&devinfo, 0, sizeof(devinfo));
68 }
69
~validation_test()70 validation_test::~validation_test()
71 {
72 ralloc_free(p);
73 }
74
SetUp()75 void validation_test::SetUp()
76 {
77 struct intel_gfx_info info = GetParam();
78 int devid = intel_device_name_to_pci_device_id(info.name);
79
80 intel_get_device_info_from_pci_id(devid, &devinfo);
81
82 brw_init_codegen(&devinfo, p, p);
83 }
84
85 struct gfx_name {
86 template <class ParamType>
87 std::string
operator ()gfx_name88 operator()(const ::testing::TestParamInfo<ParamType>& info) const {
89 return info.param.name;
90 }
91 };
92
93 INSTANTIATE_TEST_CASE_P(eu_assembly, validation_test,
94 ::testing::ValuesIn(gfx_names),
95 gfx_name());
96
97 static bool
validate(struct brw_codegen * p)98 validate(struct brw_codegen *p)
99 {
100 const bool print = getenv("TEST_DEBUG");
101 struct disasm_info *disasm = disasm_initialize(p->devinfo, NULL);
102
103 if (print) {
104 disasm_new_inst_group(disasm, 0);
105 disasm_new_inst_group(disasm, p->next_insn_offset);
106 }
107
108 bool ret = brw_validate_instructions(p->devinfo, p->store, 0,
109 p->next_insn_offset, disasm);
110
111 if (print) {
112 dump_assembly(p->store, 0, p->next_insn_offset, disasm, NULL);
113 }
114 ralloc_free(disasm);
115
116 return ret;
117 }
118
119 #define last_inst (&p->store[p->nr_insn - 1])
120 #define g0 brw_vec8_grf(0, 0)
121 #define acc0 brw_acc_reg(8)
122 #define null brw_null_reg()
123 #define zero brw_imm_f(0.0f)
124
125 static void
clear_instructions(struct brw_codegen * p)126 clear_instructions(struct brw_codegen *p)
127 {
128 p->next_insn_offset = 0;
129 p->nr_insn = 0;
130 }
131
TEST_P(validation_test,sanity)132 TEST_P(validation_test, sanity)
133 {
134 brw_ADD(p, g0, g0, g0);
135
136 EXPECT_TRUE(validate(p));
137 }
138
TEST_P(validation_test,src0_null_reg)139 TEST_P(validation_test, src0_null_reg)
140 {
141 brw_MOV(p, g0, null);
142
143 EXPECT_FALSE(validate(p));
144 }
145
TEST_P(validation_test,src1_null_reg)146 TEST_P(validation_test, src1_null_reg)
147 {
148 brw_ADD(p, g0, g0, null);
149
150 EXPECT_FALSE(validate(p));
151 }
152
TEST_P(validation_test,math_src0_null_reg)153 TEST_P(validation_test, math_src0_null_reg)
154 {
155 if (devinfo.ver >= 6) {
156 gfx6_math(p, g0, BRW_MATH_FUNCTION_SIN, null, null);
157 } else {
158 gfx4_math(p, g0, BRW_MATH_FUNCTION_SIN, 0, null, BRW_MATH_PRECISION_FULL);
159 }
160
161 EXPECT_FALSE(validate(p));
162 }
163
TEST_P(validation_test,math_src1_null_reg)164 TEST_P(validation_test, math_src1_null_reg)
165 {
166 if (devinfo.ver >= 6) {
167 gfx6_math(p, g0, BRW_MATH_FUNCTION_POW, g0, null);
168 EXPECT_FALSE(validate(p));
169 } else {
170 /* Math instructions on Gfx4/5 are actually SEND messages with payloads.
171 * src1 is an immediate message descriptor set by gfx4_math.
172 */
173 }
174 }
175
TEST_P(validation_test,opcode46)176 TEST_P(validation_test, opcode46)
177 {
178 /* opcode 46 is "push" on Gen 4 and 5
179 * "fork" on Gen 6
180 * reserved on Gen 7
181 * "goto" on Gfx8+
182 */
183 brw_next_insn(p, brw_opcode_decode(&devinfo, 46));
184
185 if (devinfo.ver == 7) {
186 EXPECT_FALSE(validate(p));
187 } else {
188 EXPECT_TRUE(validate(p));
189 }
190 }
191
TEST_P(validation_test,invalid_exec_size_encoding)192 TEST_P(validation_test, invalid_exec_size_encoding)
193 {
194 const struct {
195 enum brw_execution_size exec_size;
196 bool expected_result;
197 } test_case[] = {
198 { BRW_EXECUTE_1, true },
199 { BRW_EXECUTE_2, true },
200 { BRW_EXECUTE_4, true },
201 { BRW_EXECUTE_8, true },
202 { BRW_EXECUTE_16, true },
203 { BRW_EXECUTE_32, true },
204
205 { (enum brw_execution_size)((int)BRW_EXECUTE_32 + 1), false },
206 { (enum brw_execution_size)((int)BRW_EXECUTE_32 + 2), false },
207 };
208
209 for (unsigned i = 0; i < ARRAY_SIZE(test_case); i++) {
210 brw_MOV(p, g0, g0);
211
212 brw_inst_set_exec_size(&devinfo, last_inst, test_case[i].exec_size);
213 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
214 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
215
216 if (test_case[i].exec_size == BRW_EXECUTE_1) {
217 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
218 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
219 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
220 } else {
221 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_2);
222 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_2);
223 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
224 }
225
226 EXPECT_EQ(test_case[i].expected_result, validate(p));
227
228 clear_instructions(p);
229 }
230 }
231
TEST_P(validation_test,invalid_file_encoding)232 TEST_P(validation_test, invalid_file_encoding)
233 {
234 /* Register file on Gfx12 is only one bit */
235 if (devinfo.ver >= 12)
236 return;
237
238 brw_MOV(p, g0, g0);
239 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_MESSAGE_REGISTER_FILE, BRW_REGISTER_TYPE_F);
240
241 if (devinfo.ver > 6) {
242 EXPECT_FALSE(validate(p));
243 } else {
244 EXPECT_TRUE(validate(p));
245 }
246
247 clear_instructions(p);
248
249 if (devinfo.ver < 6) {
250 gfx4_math(p, g0, BRW_MATH_FUNCTION_SIN, 0, g0, BRW_MATH_PRECISION_FULL);
251 } else {
252 gfx6_math(p, g0, BRW_MATH_FUNCTION_SIN, g0, null);
253 }
254 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_MESSAGE_REGISTER_FILE, BRW_REGISTER_TYPE_F);
255
256 if (devinfo.ver > 6) {
257 EXPECT_FALSE(validate(p));
258 } else {
259 EXPECT_TRUE(validate(p));
260 }
261 }
262
TEST_P(validation_test,invalid_type_encoding)263 TEST_P(validation_test, invalid_type_encoding)
264 {
265 enum brw_reg_file files[2] = {
266 BRW_GENERAL_REGISTER_FILE,
267 BRW_IMMEDIATE_VALUE,
268 };
269
270 for (unsigned i = 0; i < ARRAY_SIZE(files); i++) {
271 const enum brw_reg_file file = files[i];
272 const int num_bits = devinfo.ver >= 8 ? 4 : 3;
273 const int num_encodings = 1 << num_bits;
274
275 /* The data types are encoded into <num_bits> bits to be used in hardware
276 * instructions, so keep a record in a bitset the invalid patterns so
277 * they can be verified to be invalid when used.
278 */
279 BITSET_DECLARE(invalid_encodings, num_encodings);
280
281 const struct {
282 enum brw_reg_type type;
283 bool expected_result;
284 } test_case[] = {
285 { BRW_REGISTER_TYPE_NF, devinfo.ver == 11 && file != IMM },
286 { BRW_REGISTER_TYPE_DF, devinfo.has_64bit_float && (devinfo.ver >= 8 || file != IMM) },
287 { BRW_REGISTER_TYPE_F, true },
288 { BRW_REGISTER_TYPE_HF, devinfo.ver >= 8 },
289 { BRW_REGISTER_TYPE_VF, file == IMM },
290 { BRW_REGISTER_TYPE_Q, devinfo.has_64bit_int },
291 { BRW_REGISTER_TYPE_UQ, devinfo.has_64bit_int },
292 { BRW_REGISTER_TYPE_D, true },
293 { BRW_REGISTER_TYPE_UD, true },
294 { BRW_REGISTER_TYPE_W, true },
295 { BRW_REGISTER_TYPE_UW, true },
296 { BRW_REGISTER_TYPE_B, file == FIXED_GRF },
297 { BRW_REGISTER_TYPE_UB, file == FIXED_GRF },
298 { BRW_REGISTER_TYPE_V, file == IMM },
299 { BRW_REGISTER_TYPE_UV, devinfo.ver >= 6 && file == IMM },
300 };
301
302 /* Initially assume all hardware encodings are invalid */
303 BITSET_ONES(invalid_encodings);
304
305 brw_set_default_exec_size(p, BRW_EXECUTE_4);
306
307 for (unsigned i = 0; i < ARRAY_SIZE(test_case); i++) {
308 if (test_case[i].expected_result) {
309 unsigned hw_type = brw_reg_type_to_hw_type(&devinfo, file, test_case[i].type);
310 if (hw_type != INVALID_REG_TYPE) {
311 /* ... and remove valid encodings from the set */
312 assert(BITSET_TEST(invalid_encodings, hw_type));
313 BITSET_CLEAR(invalid_encodings, hw_type);
314 }
315
316 if (file == FIXED_GRF) {
317 struct brw_reg g = retype(g0, test_case[i].type);
318 brw_MOV(p, g, g);
319 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
320 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
321 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
322 } else {
323 enum brw_reg_type t;
324
325 switch (test_case[i].type) {
326 case BRW_REGISTER_TYPE_V:
327 t = BRW_REGISTER_TYPE_W;
328 break;
329 case BRW_REGISTER_TYPE_UV:
330 t = BRW_REGISTER_TYPE_UW;
331 break;
332 case BRW_REGISTER_TYPE_VF:
333 t = BRW_REGISTER_TYPE_F;
334 break;
335 default:
336 t = test_case[i].type;
337 break;
338 }
339
340 struct brw_reg g = retype(g0, t);
341 brw_MOV(p, g, retype(brw_imm_w(0), test_case[i].type));
342 }
343
344 EXPECT_TRUE(validate(p));
345
346 clear_instructions(p);
347 }
348 }
349
350 /* The remaining encodings in invalid_encodings do not have a mapping
351 * from BRW_REGISTER_TYPE_* and must be invalid. Verify that invalid
352 * encodings are rejected by the validator.
353 */
354 int e;
355 BITSET_FOREACH_SET(e, invalid_encodings, num_encodings) {
356 if (file == FIXED_GRF) {
357 brw_MOV(p, g0, g0);
358 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
359 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
360 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
361 } else {
362 brw_MOV(p, g0, brw_imm_w(0));
363 }
364 brw_inst_set_dst_reg_hw_type(&devinfo, last_inst, e);
365 brw_inst_set_src0_reg_hw_type(&devinfo, last_inst, e);
366
367 EXPECT_FALSE(validate(p));
368
369 clear_instructions(p);
370 }
371 }
372 }
373
TEST_P(validation_test,invalid_type_encoding_3src_a16)374 TEST_P(validation_test, invalid_type_encoding_3src_a16)
375 {
376 /* 3-src instructions in align16 mode only supported on Gfx6-10 */
377 if (devinfo.ver < 6 || devinfo.ver > 10)
378 return;
379
380 const int num_bits = devinfo.ver >= 8 ? 3 : 2;
381 const int num_encodings = 1 << num_bits;
382
383 /* The data types are encoded into <num_bits> bits to be used in hardware
384 * instructions, so keep a record in a bitset the invalid patterns so
385 * they can be verified to be invalid when used.
386 */
387 BITSET_DECLARE(invalid_encodings, num_encodings);
388
389 const struct {
390 enum brw_reg_type type;
391 bool expected_result;
392 } test_case[] = {
393 { BRW_REGISTER_TYPE_DF, devinfo.ver >= 7 },
394 { BRW_REGISTER_TYPE_F, true },
395 { BRW_REGISTER_TYPE_HF, devinfo.ver >= 8 },
396 { BRW_REGISTER_TYPE_D, devinfo.ver >= 7 },
397 { BRW_REGISTER_TYPE_UD, devinfo.ver >= 7 },
398 };
399
400 /* Initially assume all hardware encodings are invalid */
401 BITSET_ONES(invalid_encodings);
402
403 brw_set_default_access_mode(p, BRW_ALIGN_16);
404 brw_set_default_exec_size(p, BRW_EXECUTE_4);
405
406 for (unsigned i = 0; i < ARRAY_SIZE(test_case); i++) {
407 if (test_case[i].expected_result) {
408 unsigned hw_type = brw_reg_type_to_a16_hw_3src_type(&devinfo, test_case[i].type);
409 if (hw_type != INVALID_HW_REG_TYPE) {
410 /* ... and remove valid encodings from the set */
411 assert(BITSET_TEST(invalid_encodings, hw_type));
412 BITSET_CLEAR(invalid_encodings, hw_type);
413 }
414
415 struct brw_reg g = retype(g0, test_case[i].type);
416 if (!brw_reg_type_is_integer(test_case[i].type)) {
417 brw_MAD(p, g, g, g, g);
418 } else {
419 brw_BFE(p, g, g, g, g);
420 }
421
422 EXPECT_TRUE(validate(p));
423
424 clear_instructions(p);
425 }
426 }
427
428 /* The remaining encodings in invalid_encodings do not have a mapping
429 * from BRW_REGISTER_TYPE_* and must be invalid. Verify that invalid
430 * encodings are rejected by the validator.
431 */
432 int e;
433 BITSET_FOREACH_SET(e, invalid_encodings, num_encodings) {
434 for (unsigned i = 0; i < 2; i++) {
435 if (i == 0) {
436 brw_MAD(p, g0, g0, g0, g0);
437 } else {
438 brw_BFE(p, g0, g0, g0, g0);
439 }
440
441 brw_inst_set_3src_a16_dst_hw_type(&devinfo, last_inst, e);
442 brw_inst_set_3src_a16_src_hw_type(&devinfo, last_inst, e);
443
444 EXPECT_FALSE(validate(p));
445
446 clear_instructions(p);
447
448 if (devinfo.ver == 6)
449 break;
450 }
451 }
452 }
453
TEST_P(validation_test,invalid_type_encoding_3src_a1)454 TEST_P(validation_test, invalid_type_encoding_3src_a1)
455 {
456 /* 3-src instructions in align1 mode only supported on Gfx10+ */
457 if (devinfo.ver < 10)
458 return;
459
460 const int num_bits = 3 + 1 /* for exec_type */;
461 const int num_encodings = 1 << num_bits;
462
463 /* The data types are encoded into <num_bits> bits to be used in hardware
464 * instructions, so keep a record in a bitset the invalid patterns so
465 * they can be verified to be invalid when used.
466 */
467 BITSET_DECLARE(invalid_encodings, num_encodings);
468
469 const struct {
470 enum brw_reg_type type;
471 unsigned exec_type;
472 bool expected_result;
473 } test_case[] = {
474 #define E(x) ((unsigned)BRW_ALIGN1_3SRC_EXEC_TYPE_##x)
475 { BRW_REGISTER_TYPE_NF, E(FLOAT), devinfo.ver == 11 },
476 { BRW_REGISTER_TYPE_DF, E(FLOAT), devinfo.has_64bit_float },
477 { BRW_REGISTER_TYPE_F, E(FLOAT), true },
478 { BRW_REGISTER_TYPE_HF, E(FLOAT), true },
479 { BRW_REGISTER_TYPE_D, E(INT), true },
480 { BRW_REGISTER_TYPE_UD, E(INT), true },
481 { BRW_REGISTER_TYPE_W, E(INT), true },
482 { BRW_REGISTER_TYPE_UW, E(INT), true },
483
484 /* There are no ternary instructions that can operate on B-type sources
485 * on Gfx11-12. Src1/Src2 cannot be B-typed either.
486 */
487 { BRW_REGISTER_TYPE_B, E(INT), false },
488 { BRW_REGISTER_TYPE_UB, E(INT), false },
489 };
490
491 /* Initially assume all hardware encodings are invalid */
492 BITSET_ONES(invalid_encodings);
493
494 brw_set_default_access_mode(p, BRW_ALIGN_1);
495 brw_set_default_exec_size(p, BRW_EXECUTE_4);
496
497 for (unsigned i = 0; i < ARRAY_SIZE(test_case); i++) {
498 if (test_case[i].expected_result) {
499 unsigned hw_type = brw_reg_type_to_a1_hw_3src_type(&devinfo, test_case[i].type);
500 unsigned hw_exec_type = hw_type | (test_case[i].exec_type << 3);
501 if (hw_type != INVALID_HW_REG_TYPE) {
502 /* ... and remove valid encodings from the set */
503 assert(BITSET_TEST(invalid_encodings, hw_exec_type));
504 BITSET_CLEAR(invalid_encodings, hw_exec_type);
505 }
506
507 struct brw_reg g = retype(g0, test_case[i].type);
508 if (!brw_reg_type_is_integer(test_case[i].type)) {
509 brw_MAD(p, g, g, g, g);
510 } else {
511 brw_BFE(p, g, g, g, g);
512 }
513
514 EXPECT_TRUE(validate(p));
515
516 clear_instructions(p);
517 }
518 }
519
520 /* The remaining encodings in invalid_encodings do not have a mapping
521 * from BRW_REGISTER_TYPE_* and must be invalid. Verify that invalid
522 * encodings are rejected by the validator.
523 */
524 int e;
525 BITSET_FOREACH_SET(e, invalid_encodings, num_encodings) {
526 const unsigned hw_type = e & 0x7;
527 const unsigned exec_type = e >> 3;
528
529 for (unsigned i = 0; i < 2; i++) {
530 if (i == 0) {
531 brw_MAD(p, g0, g0, g0, g0);
532 brw_inst_set_3src_a1_exec_type(&devinfo, last_inst, BRW_ALIGN1_3SRC_EXEC_TYPE_FLOAT);
533 } else {
534 brw_CSEL(p, g0, g0, g0, g0);
535 brw_inst_set_3src_cond_modifier(&devinfo, last_inst, BRW_CONDITIONAL_NZ);
536 brw_inst_set_3src_a1_exec_type(&devinfo, last_inst, BRW_ALIGN1_3SRC_EXEC_TYPE_INT);
537 }
538
539 brw_inst_set_3src_a1_exec_type(&devinfo, last_inst, exec_type);
540 brw_inst_set_3src_a1_dst_hw_type (&devinfo, last_inst, hw_type);
541 brw_inst_set_3src_a1_src0_hw_type(&devinfo, last_inst, hw_type);
542 brw_inst_set_3src_a1_src1_hw_type(&devinfo, last_inst, hw_type);
543 brw_inst_set_3src_a1_src2_hw_type(&devinfo, last_inst, hw_type);
544
545 EXPECT_FALSE(validate(p));
546
547 clear_instructions(p);
548 }
549 }
550 }
551
552 TEST_P(validation_test, 3src_inst_access_mode)
553 {
554 /* 3-src instructions only supported on Gfx6+ */
555 if (devinfo.ver < 6)
556 return;
557
558 /* No access mode bit on Gfx12+ */
559 if (devinfo.ver >= 12)
560 return;
561
562 const struct {
563 unsigned mode;
564 bool expected_result;
565 } test_case[] = {
566 { BRW_ALIGN_1, devinfo.ver >= 10 },
567 { BRW_ALIGN_16, devinfo.ver <= 10 },
568 };
569
570 for (unsigned i = 0; i < ARRAY_SIZE(test_case); i++) {
571 if (devinfo.ver < 10)
572 brw_set_default_access_mode(p, BRW_ALIGN_16);
573
574 brw_MAD(p, g0, g0, g0, g0);
575 brw_inst_set_access_mode(&devinfo, last_inst, test_case[i].mode);
576
577 EXPECT_EQ(test_case[i].expected_result, validate(p));
578
579 clear_instructions(p);
580 }
581 }
582
583 /* When the Execution Data Type is wider than the destination data type, the
584 * destination must [...] specify a HorzStride equal to the ratio in sizes of
585 * the two data types.
586 */
TEST_P(validation_test,dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size)587 TEST_P(validation_test, dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size)
588 {
589 brw_ADD(p, g0, g0, g0);
590 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
591 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
592 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
593
594 EXPECT_FALSE(validate(p));
595
596 clear_instructions(p);
597
598 brw_ADD(p, g0, g0, g0);
599 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
600 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
601 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
602 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
603
604 EXPECT_TRUE(validate(p));
605 }
606
607 /* When the Execution Data Type is wider than the destination data type, the
608 * destination must be aligned as required by the wider execution data type
609 * [...]
610 */
TEST_P(validation_test,dst_subreg_must_be_aligned_to_exec_type_size)611 TEST_P(validation_test, dst_subreg_must_be_aligned_to_exec_type_size)
612 {
613 brw_ADD(p, g0, g0, g0);
614 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 2);
615 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
616 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
617 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
618 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
619
620 EXPECT_FALSE(validate(p));
621
622 clear_instructions(p);
623
624 brw_ADD(p, g0, g0, g0);
625 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
626 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 8);
627 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
628 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
629 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
630 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
631 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
632 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
633 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
634 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
635 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
636 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
637
638 EXPECT_TRUE(validate(p));
639 }
640
641 /* ExecSize must be greater than or equal to Width. */
TEST_P(validation_test,exec_size_less_than_width)642 TEST_P(validation_test, exec_size_less_than_width)
643 {
644 brw_ADD(p, g0, g0, g0);
645 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_16);
646
647 EXPECT_FALSE(validate(p));
648
649 clear_instructions(p);
650
651 brw_ADD(p, g0, g0, g0);
652 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_16);
653
654 EXPECT_FALSE(validate(p));
655 }
656
657 /* If ExecSize = Width and HorzStride ≠ 0,
658 * VertStride must be set to Width * HorzStride.
659 */
TEST_P(validation_test,vertical_stride_is_width_by_horizontal_stride)660 TEST_P(validation_test, vertical_stride_is_width_by_horizontal_stride)
661 {
662 brw_ADD(p, g0, g0, g0);
663 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
664
665 EXPECT_FALSE(validate(p));
666
667 clear_instructions(p);
668
669 brw_ADD(p, g0, g0, g0);
670 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
671
672 EXPECT_FALSE(validate(p));
673 }
674
675 /* If Width = 1, HorzStride must be 0 regardless of the values
676 * of ExecSize and VertStride.
677 */
TEST_P(validation_test,horizontal_stride_must_be_0_if_width_is_1)678 TEST_P(validation_test, horizontal_stride_must_be_0_if_width_is_1)
679 {
680 brw_ADD(p, g0, g0, g0);
681 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
682 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
683 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
684
685 EXPECT_FALSE(validate(p));
686
687 clear_instructions(p);
688
689 brw_ADD(p, g0, g0, g0);
690 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
691 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_1);
692 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
693
694 EXPECT_FALSE(validate(p));
695 }
696
697 /* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */
TEST_P(validation_test,scalar_region_must_be_0_1_0)698 TEST_P(validation_test, scalar_region_must_be_0_1_0)
699 {
700 struct brw_reg g0_0 = brw_vec1_grf(0, 0);
701
702 brw_ADD(p, g0, g0, g0_0);
703 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_1);
704 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_1);
705 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
706 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
707
708 EXPECT_FALSE(validate(p));
709
710 clear_instructions(p);
711
712 brw_ADD(p, g0, g0_0, g0);
713 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_1);
714 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_1);
715 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_1);
716 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
717
718 EXPECT_FALSE(validate(p));
719 }
720
721 /* If VertStride = HorzStride = 0, Width must be 1 regardless of the value
722 * of ExecSize.
723 */
TEST_P(validation_test,zero_stride_implies_0_1_0)724 TEST_P(validation_test, zero_stride_implies_0_1_0)
725 {
726 brw_ADD(p, g0, g0, g0);
727 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
728 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_2);
729 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
730
731 EXPECT_FALSE(validate(p));
732
733 clear_instructions(p);
734
735 brw_ADD(p, g0, g0, g0);
736 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
737 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2);
738 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
739
740 EXPECT_FALSE(validate(p));
741 }
742
743 /* Dst.HorzStride must not be 0. */
TEST_P(validation_test,dst_horizontal_stride_0)744 TEST_P(validation_test, dst_horizontal_stride_0)
745 {
746 brw_ADD(p, g0, g0, g0);
747 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
748
749 EXPECT_FALSE(validate(p));
750
751 clear_instructions(p);
752
753 /* Align16 does not exist on Gfx11+ */
754 if (devinfo.ver >= 11)
755 return;
756
757 brw_set_default_access_mode(p, BRW_ALIGN_16);
758
759 brw_ADD(p, g0, g0, g0);
760 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
761
762 EXPECT_FALSE(validate(p));
763 }
764
765 /* VertStride must be used to cross BRW_GENERAL_REGISTER_FILE register boundaries. This rule implies
766 * that elements within a 'Width' cannot cross BRW_GENERAL_REGISTER_FILE boundaries.
767 */
TEST_P(validation_test,must_not_cross_grf_boundary_in_a_width)768 TEST_P(validation_test, must_not_cross_grf_boundary_in_a_width)
769 {
770 brw_ADD(p, g0, g0, g0);
771 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 4);
772
773 EXPECT_FALSE(validate(p));
774
775 clear_instructions(p);
776
777 brw_ADD(p, g0, g0, g0);
778 brw_inst_set_src1_da1_subreg_nr(&devinfo, last_inst, 4);
779
780 EXPECT_FALSE(validate(p));
781
782 clear_instructions(p);
783
784 brw_ADD(p, g0, g0, g0);
785 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
786 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
787 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
788
789 EXPECT_FALSE(validate(p));
790
791 clear_instructions(p);
792
793 brw_ADD(p, g0, g0, g0);
794 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
795 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
796 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
797
798 EXPECT_FALSE(validate(p));
799 }
800
801 /* Destination Horizontal must be 1 in Align16 */
TEST_P(validation_test,dst_hstride_on_align16_must_be_1)802 TEST_P(validation_test, dst_hstride_on_align16_must_be_1)
803 {
804 /* Align16 does not exist on Gfx11+ */
805 if (devinfo.ver >= 11)
806 return;
807
808 brw_set_default_access_mode(p, BRW_ALIGN_16);
809
810 brw_ADD(p, g0, g0, g0);
811 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
812
813 EXPECT_FALSE(validate(p));
814
815 clear_instructions(p);
816
817 brw_ADD(p, g0, g0, g0);
818 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
819
820 EXPECT_TRUE(validate(p));
821 }
822
823 /* VertStride must be 0 or 4 in Align16 */
TEST_P(validation_test,vstride_on_align16_must_be_0_or_4)824 TEST_P(validation_test, vstride_on_align16_must_be_0_or_4)
825 {
826 /* Align16 does not exist on Gfx11+ */
827 if (devinfo.ver >= 11)
828 return;
829
830 const struct {
831 enum brw_vertical_stride vstride;
832 bool expected_result;
833 } vstride[] = {
834 { BRW_VERTICAL_STRIDE_0, true },
835 { BRW_VERTICAL_STRIDE_1, false },
836 { BRW_VERTICAL_STRIDE_2, devinfo.verx10 >= 75 },
837 { BRW_VERTICAL_STRIDE_4, true },
838 { BRW_VERTICAL_STRIDE_8, false },
839 { BRW_VERTICAL_STRIDE_16, false },
840 { BRW_VERTICAL_STRIDE_32, false },
841 { BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL, false },
842 };
843
844 brw_set_default_access_mode(p, BRW_ALIGN_16);
845
846 for (unsigned i = 0; i < ARRAY_SIZE(vstride); i++) {
847 brw_ADD(p, g0, g0, g0);
848 brw_inst_set_src0_vstride(&devinfo, last_inst, vstride[i].vstride);
849
850 EXPECT_EQ(vstride[i].expected_result, validate(p));
851
852 clear_instructions(p);
853 }
854
855 for (unsigned i = 0; i < ARRAY_SIZE(vstride); i++) {
856 brw_ADD(p, g0, g0, g0);
857 brw_inst_set_src1_vstride(&devinfo, last_inst, vstride[i].vstride);
858
859 EXPECT_EQ(vstride[i].expected_result, validate(p));
860
861 clear_instructions(p);
862 }
863 }
864
865 /* In Direct Addressing mode, a source cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE
866 * registers.
867 */
TEST_P(validation_test,source_cannot_span_more_than_2_registers)868 TEST_P(validation_test, source_cannot_span_more_than_2_registers)
869 {
870 brw_ADD(p, g0, g0, g0);
871 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_32);
872 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
873 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
874 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
875 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
876 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8);
877 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
878
879 EXPECT_FALSE(validate(p));
880
881 clear_instructions(p);
882
883 brw_ADD(p, g0, g0, g0);
884 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
885 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
886 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
887 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
888 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
889 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8);
890 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
891 brw_inst_set_src1_da1_subreg_nr(&devinfo, last_inst, 2);
892
893 EXPECT_TRUE(validate(p));
894
895 clear_instructions(p);
896
897 brw_ADD(p, g0, g0, g0);
898 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
899
900 EXPECT_TRUE(validate(p));
901 }
902
903 /* A destination cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE registers. */
TEST_P(validation_test,destination_cannot_span_more_than_2_registers)904 TEST_P(validation_test, destination_cannot_span_more_than_2_registers)
905 {
906 brw_ADD(p, g0, g0, g0);
907 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_32);
908 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
909 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
910 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
911 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
912
913 EXPECT_FALSE(validate(p));
914
915 clear_instructions(p);
916
917 brw_ADD(p, g0, g0, g0);
918 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_8);
919 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 6);
920 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4);
921 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
922 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
923 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
924 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
925 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
926 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
927 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
928 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
929 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
930
931 EXPECT_TRUE(validate(p));
932 }
933
TEST_P(validation_test,src_region_spans_two_regs_dst_region_spans_one)934 TEST_P(validation_test, src_region_spans_two_regs_dst_region_spans_one)
935 {
936 /* Writes to dest are to the lower OWord */
937 brw_ADD(p, g0, g0, g0);
938 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
939 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
940 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
941 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
942 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
943 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
944
945 EXPECT_TRUE(validate(p));
946
947 clear_instructions(p);
948
949 /* Writes to dest are to the upper OWord */
950 brw_ADD(p, g0, g0, g0);
951 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 16);
952 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
953 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
954 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
955 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
956 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
957 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
958
959 EXPECT_TRUE(validate(p));
960
961 clear_instructions(p);
962
963 /* Writes to dest are evenly split between OWords */
964 brw_ADD(p, g0, g0, g0);
965 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
966 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
967 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
968 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
969 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
970 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8);
971 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
972
973 EXPECT_TRUE(validate(p));
974
975 clear_instructions(p);
976
977 /* Writes to dest are uneven between OWords */
978 brw_ADD(p, g0, g0, g0);
979 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
980 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 10);
981 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
982 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
983 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
984 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
985 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
986 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
987 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
988 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2);
989 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
990
991 if (devinfo.ver >= 9) {
992 EXPECT_TRUE(validate(p));
993 } else {
994 EXPECT_FALSE(validate(p));
995 }
996 }
997
TEST_P(validation_test,dst_elements_must_be_evenly_split_between_registers)998 TEST_P(validation_test, dst_elements_must_be_evenly_split_between_registers)
999 {
1000 brw_ADD(p, g0, g0, g0);
1001 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 4);
1002
1003 if (devinfo.ver >= 9) {
1004 EXPECT_TRUE(validate(p));
1005 } else {
1006 EXPECT_FALSE(validate(p));
1007 }
1008
1009 clear_instructions(p);
1010
1011 brw_ADD(p, g0, g0, g0);
1012 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
1013
1014 EXPECT_TRUE(validate(p));
1015
1016 clear_instructions(p);
1017
1018 if (devinfo.ver >= 6) {
1019 gfx6_math(p, g0, BRW_MATH_FUNCTION_SIN, g0, null);
1020
1021 EXPECT_TRUE(validate(p));
1022
1023 clear_instructions(p);
1024
1025 gfx6_math(p, g0, BRW_MATH_FUNCTION_SIN, g0, null);
1026 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 4);
1027
1028 EXPECT_FALSE(validate(p));
1029 }
1030 }
1031
TEST_P(validation_test,two_src_two_dst_source_offsets_must_be_same)1032 TEST_P(validation_test, two_src_two_dst_source_offsets_must_be_same)
1033 {
1034 brw_ADD(p, g0, g0, g0);
1035 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
1036 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4);
1037 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 16);
1038 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_2);
1039 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
1040 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
1041 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
1042 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
1043 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
1044
1045 if (devinfo.ver <= 7) {
1046 EXPECT_FALSE(validate(p));
1047 } else {
1048 EXPECT_TRUE(validate(p));
1049 }
1050
1051 clear_instructions(p);
1052
1053 brw_ADD(p, g0, g0, g0);
1054 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
1055 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4);
1056 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
1057 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
1058 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
1059 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_8);
1060 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2);
1061 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
1062
1063 EXPECT_TRUE(validate(p));
1064 }
1065
TEST_P(validation_test,two_src_two_dst_each_dst_must_be_derived_from_one_src)1066 TEST_P(validation_test, two_src_two_dst_each_dst_must_be_derived_from_one_src)
1067 {
1068 brw_MOV(p, g0, g0);
1069 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
1070 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
1071 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
1072 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
1073 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 8);
1074 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
1075 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
1076 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
1077
1078 if (devinfo.ver <= 7) {
1079 EXPECT_FALSE(validate(p));
1080 } else {
1081 EXPECT_TRUE(validate(p));
1082 }
1083
1084 clear_instructions(p);
1085
1086 brw_MOV(p, g0, g0);
1087 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 16);
1088 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 8);
1089 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_2);
1090 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_2);
1091 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
1092
1093 if (devinfo.ver <= 7) {
1094 EXPECT_FALSE(validate(p));
1095 } else {
1096 EXPECT_TRUE(validate(p));
1097 }
1098 }
1099
TEST_P(validation_test,one_src_two_dst)1100 TEST_P(validation_test, one_src_two_dst)
1101 {
1102 struct brw_reg g0_0 = brw_vec1_grf(0, 0);
1103
1104 brw_ADD(p, g0, g0_0, g0_0);
1105 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
1106
1107 EXPECT_TRUE(validate(p));
1108
1109 clear_instructions(p);
1110
1111 brw_ADD(p, g0, g0, g0);
1112 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
1113 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
1114 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
1115 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
1116
1117 EXPECT_TRUE(validate(p));
1118
1119 clear_instructions(p);
1120
1121 brw_ADD(p, g0, g0, g0);
1122 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
1123 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
1124 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
1125 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
1126 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
1127 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
1128 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_1);
1129 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
1130
1131 if (devinfo.ver >= 8) {
1132 EXPECT_TRUE(validate(p));
1133 } else {
1134 EXPECT_FALSE(validate(p));
1135 }
1136
1137 clear_instructions(p);
1138
1139 brw_ADD(p, g0, g0, g0);
1140 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
1141 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
1142 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
1143 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
1144 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
1145 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
1146 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
1147 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
1148
1149 if (devinfo.ver >= 8) {
1150 EXPECT_TRUE(validate(p));
1151 } else {
1152 EXPECT_FALSE(validate(p));
1153 }
1154 }
1155
TEST_P(validation_test,packed_byte_destination)1156 TEST_P(validation_test, packed_byte_destination)
1157 {
1158 static const struct {
1159 enum brw_reg_type dst_type;
1160 enum brw_reg_type src_type;
1161 bool neg, abs, sat;
1162 bool expected_result;
1163 } move[] = {
1164 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 0, 0, 0, true },
1165 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 0, 0, 0, true },
1166 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 0, 0, 0, true },
1167 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 0, 0, 0, true },
1168
1169 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 1, 0, 0, false },
1170 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 1, 0, 0, false },
1171 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 1, 0, 0, false },
1172 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 1, 0, 0, false },
1173
1174 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 0, 1, 0, false },
1175 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 0, 1, 0, false },
1176 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 0, 1, 0, false },
1177 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 0, 1, 0, false },
1178
1179 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 0, 0, 1, false },
1180 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 0, 0, 1, false },
1181 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 0, 0, 1, false },
1182 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 0, 0, 1, false },
1183
1184 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UW, 0, 0, 0, false },
1185 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_W , 0, 0, 0, false },
1186 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UD, 0, 0, 0, false },
1187 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_D , 0, 0, 0, false },
1188 };
1189
1190 for (unsigned i = 0; i < ARRAY_SIZE(move); i++) {
1191 brw_MOV(p, retype(g0, move[i].dst_type), retype(g0, move[i].src_type));
1192 brw_inst_set_src0_negate(&devinfo, last_inst, move[i].neg);
1193 brw_inst_set_src0_abs(&devinfo, last_inst, move[i].abs);
1194 brw_inst_set_saturate(&devinfo, last_inst, move[i].sat);
1195
1196 EXPECT_EQ(move[i].expected_result, validate(p));
1197
1198 clear_instructions(p);
1199 }
1200
1201 brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_UB),
1202 retype(g0, BRW_REGISTER_TYPE_UB),
1203 retype(g0, BRW_REGISTER_TYPE_UB));
1204 brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL);
1205
1206 EXPECT_FALSE(validate(p));
1207
1208 clear_instructions(p);
1209
1210 brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_B),
1211 retype(g0, BRW_REGISTER_TYPE_B),
1212 retype(g0, BRW_REGISTER_TYPE_B));
1213 brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL);
1214
1215 EXPECT_FALSE(validate(p));
1216 }
1217
TEST_P(validation_test,byte_destination_relaxed_alignment)1218 TEST_P(validation_test, byte_destination_relaxed_alignment)
1219 {
1220 brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_B),
1221 retype(g0, BRW_REGISTER_TYPE_W),
1222 retype(g0, BRW_REGISTER_TYPE_W));
1223 brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL);
1224 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
1225
1226 EXPECT_TRUE(validate(p));
1227
1228 clear_instructions(p);
1229
1230 brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_B),
1231 retype(g0, BRW_REGISTER_TYPE_W),
1232 retype(g0, BRW_REGISTER_TYPE_W));
1233 brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL);
1234 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
1235 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 1);
1236
1237 if (devinfo.ver > 4 || devinfo.is_g4x) {
1238 EXPECT_TRUE(validate(p));
1239 } else {
1240 EXPECT_FALSE(validate(p));
1241 }
1242 }
1243
TEST_P(validation_test,byte_64bit_conversion)1244 TEST_P(validation_test, byte_64bit_conversion)
1245 {
1246 static const struct {
1247 enum brw_reg_type dst_type;
1248 enum brw_reg_type src_type;
1249 unsigned dst_stride;
1250 bool expected_result;
1251 } inst[] = {
1252 #define INST(dst_type, src_type, dst_stride, expected_result) \
1253 { \
1254 BRW_REGISTER_TYPE_##dst_type, \
1255 BRW_REGISTER_TYPE_##src_type, \
1256 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1257 expected_result, \
1258 }
1259
1260 INST(B, Q, 1, false),
1261 INST(B, UQ, 1, false),
1262 INST(B, DF, 1, false),
1263 INST(UB, Q, 1, false),
1264 INST(UB, UQ, 1, false),
1265 INST(UB, DF, 1, false),
1266
1267 INST(B, Q, 2, false),
1268 INST(B, UQ, 2, false),
1269 INST(B , DF, 2, false),
1270 INST(UB, Q, 2, false),
1271 INST(UB, UQ, 2, false),
1272 INST(UB, DF, 2, false),
1273
1274 INST(B, Q, 4, false),
1275 INST(B, UQ, 4, false),
1276 INST(B, DF, 4, false),
1277 INST(UB, Q, 4, false),
1278 INST(UB, UQ, 4, false),
1279 INST(UB, DF, 4, false),
1280
1281 #undef INST
1282 };
1283
1284 if (devinfo.ver < 8)
1285 return;
1286
1287 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
1288 if (!devinfo.has_64bit_float &&
1289 inst[i].src_type == BRW_REGISTER_TYPE_DF)
1290 continue;
1291
1292 if (!devinfo.has_64bit_int &&
1293 (inst[i].src_type == BRW_REGISTER_TYPE_Q ||
1294 inst[i].src_type == BRW_REGISTER_TYPE_UQ))
1295 continue;
1296
1297 brw_MOV(p, retype(g0, inst[i].dst_type), retype(g0, inst[i].src_type));
1298 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1299 EXPECT_EQ(inst[i].expected_result, validate(p));
1300
1301 clear_instructions(p);
1302 }
1303 }
1304
TEST_P(validation_test,half_float_conversion)1305 TEST_P(validation_test, half_float_conversion)
1306 {
1307 static const struct {
1308 enum brw_reg_type dst_type;
1309 enum brw_reg_type src_type;
1310 unsigned dst_stride;
1311 unsigned dst_subnr;
1312 bool expected_result_bdw;
1313 bool expected_result_chv_gfx9;
1314 } inst[] = {
1315 #define INST_C(dst_type, src_type, dst_stride, dst_subnr, expected_result) \
1316 { \
1317 BRW_REGISTER_TYPE_##dst_type, \
1318 BRW_REGISTER_TYPE_##src_type, \
1319 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1320 dst_subnr, \
1321 expected_result, \
1322 expected_result, \
1323 }
1324 #define INST_S(dst_type, src_type, dst_stride, dst_subnr, \
1325 expected_result_bdw, expected_result_chv_gfx9) \
1326 { \
1327 BRW_REGISTER_TYPE_##dst_type, \
1328 BRW_REGISTER_TYPE_##src_type, \
1329 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1330 dst_subnr, \
1331 expected_result_bdw, \
1332 expected_result_chv_gfx9, \
1333 }
1334
1335 /* MOV to half-float destination */
1336 INST_C(HF, B, 1, 0, false),
1337 INST_C(HF, W, 1, 0, false),
1338 INST_C(HF, HF, 1, 0, true),
1339 INST_C(HF, HF, 1, 2, true),
1340 INST_C(HF, D, 1, 0, false),
1341 INST_S(HF, F, 1, 0, false, true),
1342 INST_C(HF, Q, 1, 0, false),
1343 INST_C(HF, B, 2, 0, true),
1344 INST_C(HF, B, 2, 2, false),
1345 INST_C(HF, W, 2, 0, true),
1346 INST_C(HF, W, 2, 2, false),
1347 INST_C(HF, HF, 2, 0, true),
1348 INST_C(HF, HF, 2, 2, true),
1349 INST_C(HF, D, 2, 0, true),
1350 INST_C(HF, D, 2, 2, false),
1351 INST_C(HF, F, 2, 0, true),
1352 INST_S(HF, F, 2, 2, false, true),
1353 INST_C(HF, Q, 2, 0, false),
1354 INST_C(HF, DF, 2, 0, false),
1355 INST_C(HF, B, 4, 0, false),
1356 INST_C(HF, W, 4, 0, false),
1357 INST_C(HF, HF, 4, 0, true),
1358 INST_C(HF, HF, 4, 2, true),
1359 INST_C(HF, D, 4, 0, false),
1360 INST_C(HF, F, 4, 0, false),
1361 INST_C(HF, Q, 4, 0, false),
1362 INST_C(HF, DF, 4, 0, false),
1363
1364 /* MOV from half-float source */
1365 INST_C( B, HF, 1, 0, false),
1366 INST_C( W, HF, 1, 0, false),
1367 INST_C( D, HF, 1, 0, true),
1368 INST_C( D, HF, 1, 4, true),
1369 INST_C( F, HF, 1, 0, true),
1370 INST_C( F, HF, 1, 4, true),
1371 INST_C( Q, HF, 1, 0, false),
1372 INST_C(DF, HF, 1, 0, false),
1373 INST_C( B, HF, 2, 0, false),
1374 INST_C( W, HF, 2, 0, true),
1375 INST_C( W, HF, 2, 2, false),
1376 INST_C( D, HF, 2, 0, false),
1377 INST_C( F, HF, 2, 0, true),
1378 INST_C( B, HF, 4, 0, true),
1379 INST_C( B, HF, 4, 1, false),
1380 INST_C( W, HF, 4, 0, false),
1381
1382 #undef INST_C
1383 #undef INST_S
1384 };
1385
1386 if (devinfo.ver < 8)
1387 return;
1388
1389 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
1390 if (!devinfo.has_64bit_float &&
1391 (inst[i].dst_type == BRW_REGISTER_TYPE_DF ||
1392 inst[i].src_type == BRW_REGISTER_TYPE_DF))
1393 continue;
1394
1395 if (!devinfo.has_64bit_int &&
1396 (inst[i].dst_type == BRW_REGISTER_TYPE_Q ||
1397 inst[i].dst_type == BRW_REGISTER_TYPE_UQ ||
1398 inst[i].src_type == BRW_REGISTER_TYPE_Q ||
1399 inst[i].src_type == BRW_REGISTER_TYPE_UQ))
1400 continue;
1401
1402 brw_MOV(p, retype(g0, inst[i].dst_type), retype(g0, inst[i].src_type));
1403
1404 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
1405
1406 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1407 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, inst[i].dst_subnr);
1408
1409 if (inst[i].src_type == BRW_REGISTER_TYPE_B) {
1410 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
1411 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_2);
1412 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
1413 } else {
1414 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
1415 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
1416 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
1417 }
1418
1419 if (devinfo.is_cherryview || devinfo.ver >= 9)
1420 EXPECT_EQ(inst[i].expected_result_chv_gfx9, validate(p));
1421 else
1422 EXPECT_EQ(inst[i].expected_result_bdw, validate(p));
1423
1424 clear_instructions(p);
1425 }
1426 }
1427
TEST_P(validation_test,mixed_float_source_indirect_addressing)1428 TEST_P(validation_test, mixed_float_source_indirect_addressing)
1429 {
1430 static const struct {
1431 enum brw_reg_type dst_type;
1432 enum brw_reg_type src0_type;
1433 enum brw_reg_type src1_type;
1434 unsigned dst_stride;
1435 bool dst_indirect;
1436 bool src0_indirect;
1437 bool expected_result;
1438 } inst[] = {
1439 #define INST(dst_type, src0_type, src1_type, \
1440 dst_stride, dst_indirect, src0_indirect, expected_result) \
1441 { \
1442 BRW_REGISTER_TYPE_##dst_type, \
1443 BRW_REGISTER_TYPE_##src0_type, \
1444 BRW_REGISTER_TYPE_##src1_type, \
1445 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1446 dst_indirect, \
1447 src0_indirect, \
1448 expected_result, \
1449 }
1450
1451 /* Source and dest are mixed float: indirect src addressing not allowed */
1452 INST(HF, F, F, 2, false, false, true),
1453 INST(HF, F, F, 2, true, false, true),
1454 INST(HF, F, F, 2, false, true, false),
1455 INST(HF, F, F, 2, true, true, false),
1456 INST( F, HF, F, 1, false, false, true),
1457 INST( F, HF, F, 1, true, false, true),
1458 INST( F, HF, F, 1, false, true, false),
1459 INST( F, HF, F, 1, true, true, false),
1460
1461 INST(HF, HF, F, 2, false, false, true),
1462 INST(HF, HF, F, 2, true, false, true),
1463 INST(HF, HF, F, 2, false, true, false),
1464 INST(HF, HF, F, 2, true, true, false),
1465 INST( F, F, HF, 1, false, false, true),
1466 INST( F, F, HF, 1, true, false, true),
1467 INST( F, F, HF, 1, false, true, false),
1468 INST( F, F, HF, 1, true, true, false),
1469
1470 #undef INST
1471 };
1472
1473 if (devinfo.ver < 8)
1474 return;
1475
1476 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
1477 brw_ADD(p, retype(g0, inst[i].dst_type),
1478 retype(g0, inst[i].src0_type),
1479 retype(g0, inst[i].src1_type));
1480
1481 brw_inst_set_dst_address_mode(&devinfo, last_inst, inst[i].dst_indirect);
1482 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1483 brw_inst_set_src0_address_mode(&devinfo, last_inst, inst[i].src0_indirect);
1484
1485 EXPECT_EQ(inst[i].expected_result, validate(p));
1486
1487 clear_instructions(p);
1488 }
1489 }
1490
TEST_P(validation_test,mixed_float_align1_simd16)1491 TEST_P(validation_test, mixed_float_align1_simd16)
1492 {
1493 static const struct {
1494 unsigned exec_size;
1495 enum brw_reg_type dst_type;
1496 enum brw_reg_type src0_type;
1497 enum brw_reg_type src1_type;
1498 unsigned dst_stride;
1499 bool expected_result;
1500 } inst[] = {
1501 #define INST(exec_size, dst_type, src0_type, src1_type, \
1502 dst_stride, expected_result) \
1503 { \
1504 BRW_EXECUTE_##exec_size, \
1505 BRW_REGISTER_TYPE_##dst_type, \
1506 BRW_REGISTER_TYPE_##src0_type, \
1507 BRW_REGISTER_TYPE_##src1_type, \
1508 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1509 expected_result, \
1510 }
1511
1512 /* No SIMD16 in mixed mode when destination is packed f16 */
1513 INST( 8, HF, F, HF, 2, true),
1514 INST(16, HF, HF, F, 2, true),
1515 INST(16, HF, HF, F, 1, false),
1516 INST(16, HF, F, HF, 1, false),
1517
1518 /* No SIMD16 in mixed mode when destination is f32 */
1519 INST( 8, F, HF, F, 1, true),
1520 INST( 8, F, F, HF, 1, true),
1521 INST(16, F, HF, F, 1, false),
1522 INST(16, F, F, HF, 1, false),
1523
1524 #undef INST
1525 };
1526
1527 if (devinfo.ver < 8)
1528 return;
1529
1530 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
1531 brw_ADD(p, retype(g0, inst[i].dst_type),
1532 retype(g0, inst[i].src0_type),
1533 retype(g0, inst[i].src1_type));
1534
1535 brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
1536
1537 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1538
1539 EXPECT_EQ(inst[i].expected_result, validate(p));
1540
1541 clear_instructions(p);
1542 }
1543 }
1544
TEST_P(validation_test,mixed_float_align1_packed_fp16_dst_acc_read_offset_0)1545 TEST_P(validation_test, mixed_float_align1_packed_fp16_dst_acc_read_offset_0)
1546 {
1547 static const struct {
1548 enum brw_reg_type dst_type;
1549 enum brw_reg_type src0_type;
1550 enum brw_reg_type src1_type;
1551 unsigned dst_stride;
1552 bool read_acc;
1553 unsigned subnr;
1554 bool expected_result_bdw;
1555 bool expected_result_chv_skl;
1556 } inst[] = {
1557 #define INST(dst_type, src0_type, src1_type, dst_stride, read_acc, subnr, \
1558 expected_result_bdw, expected_result_chv_skl) \
1559 { \
1560 BRW_REGISTER_TYPE_##dst_type, \
1561 BRW_REGISTER_TYPE_##src0_type, \
1562 BRW_REGISTER_TYPE_##src1_type, \
1563 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1564 read_acc, \
1565 subnr, \
1566 expected_result_bdw, \
1567 expected_result_chv_skl, \
1568 }
1569
1570 /* Destination is not packed */
1571 INST(HF, HF, F, 2, true, 0, true, true),
1572 INST(HF, HF, F, 2, true, 2, true, true),
1573 INST(HF, HF, F, 2, true, 4, true, true),
1574 INST(HF, HF, F, 2, true, 8, true, true),
1575 INST(HF, HF, F, 2, true, 16, true, true),
1576
1577 /* Destination is packed, we don't read acc */
1578 INST(HF, HF, F, 1, false, 0, false, true),
1579 INST(HF, HF, F, 1, false, 2, false, true),
1580 INST(HF, HF, F, 1, false, 4, false, true),
1581 INST(HF, HF, F, 1, false, 8, false, true),
1582 INST(HF, HF, F, 1, false, 16, false, true),
1583
1584 /* Destination is packed, we read acc */
1585 INST(HF, HF, F, 1, true, 0, false, false),
1586 INST(HF, HF, F, 1, true, 2, false, false),
1587 INST(HF, HF, F, 1, true, 4, false, false),
1588 INST(HF, HF, F, 1, true, 8, false, false),
1589 INST(HF, HF, F, 1, true, 16, false, false),
1590
1591 #undef INST
1592 };
1593
1594 if (devinfo.ver < 8)
1595 return;
1596
1597 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
1598 brw_ADD(p, retype(g0, inst[i].dst_type),
1599 retype(inst[i].read_acc ? acc0 : g0, inst[i].src0_type),
1600 retype(g0, inst[i].src1_type));
1601
1602 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1603
1604 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, inst[i].subnr);
1605
1606 if (devinfo.is_cherryview || devinfo.ver >= 9)
1607 EXPECT_EQ(inst[i].expected_result_chv_skl, validate(p));
1608 else
1609 EXPECT_EQ(inst[i].expected_result_bdw, validate(p));
1610
1611 clear_instructions(p);
1612 }
1613 }
1614
TEST_P(validation_test,mixed_float_fp16_dest_with_acc)1615 TEST_P(validation_test, mixed_float_fp16_dest_with_acc)
1616 {
1617 static const struct {
1618 unsigned exec_size;
1619 unsigned opcode;
1620 enum brw_reg_type dst_type;
1621 enum brw_reg_type src0_type;
1622 enum brw_reg_type src1_type;
1623 unsigned dst_stride;
1624 bool read_acc;
1625 bool expected_result_bdw;
1626 bool expected_result_chv_skl;
1627 } inst[] = {
1628 #define INST(exec_size, opcode, dst_type, src0_type, src1_type, \
1629 dst_stride, read_acc,expected_result_bdw, \
1630 expected_result_chv_skl) \
1631 { \
1632 BRW_EXECUTE_##exec_size, \
1633 BRW_OPCODE_##opcode, \
1634 BRW_REGISTER_TYPE_##dst_type, \
1635 BRW_REGISTER_TYPE_##src0_type, \
1636 BRW_REGISTER_TYPE_##src1_type, \
1637 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1638 read_acc, \
1639 expected_result_bdw, \
1640 expected_result_chv_skl, \
1641 }
1642
1643 /* Packed fp16 dest with implicit acc needs hstride=2 */
1644 INST(8, MAC, HF, HF, F, 1, false, false, false),
1645 INST(8, MAC, HF, HF, F, 2, false, true, true),
1646 INST(8, MAC, HF, F, HF, 1, false, false, false),
1647 INST(8, MAC, HF, F, HF, 2, false, true, true),
1648
1649 /* Packed fp16 dest with explicit acc needs hstride=2 */
1650 INST(8, ADD, HF, HF, F, 1, true, false, false),
1651 INST(8, ADD, HF, HF, F, 2, true, true, true),
1652 INST(8, ADD, HF, F, HF, 1, true, false, false),
1653 INST(8, ADD, HF, F, HF, 2, true, true, true),
1654
1655 /* If destination is not fp16, restriction doesn't apply */
1656 INST(8, MAC, F, HF, F, 1, false, true, true),
1657 INST(8, MAC, F, HF, F, 2, false, true, true),
1658
1659 /* If there is no implicit/explicit acc, restriction doesn't apply */
1660 INST(8, ADD, HF, HF, F, 1, false, false, true),
1661 INST(8, ADD, HF, HF, F, 2, false, true, true),
1662 INST(8, ADD, HF, F, HF, 1, false, false, true),
1663 INST(8, ADD, HF, F, HF, 2, false, true, true),
1664 INST(8, ADD, F, HF, F, 1, false, true, true),
1665 INST(8, ADD, F, HF, F, 2, false, true, true),
1666
1667 #undef INST
1668 };
1669
1670 if (devinfo.ver < 8)
1671 return;
1672
1673 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
1674 if (inst[i].opcode == BRW_OPCODE_MAC) {
1675 brw_MAC(p, retype(g0, inst[i].dst_type),
1676 retype(g0, inst[i].src0_type),
1677 retype(g0, inst[i].src1_type));
1678 } else {
1679 assert(inst[i].opcode == BRW_OPCODE_ADD);
1680 brw_ADD(p, retype(g0, inst[i].dst_type),
1681 retype(inst[i].read_acc ? acc0: g0, inst[i].src0_type),
1682 retype(g0, inst[i].src1_type));
1683 }
1684
1685 brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
1686
1687 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1688
1689 if (devinfo.is_cherryview || devinfo.ver >= 9)
1690 EXPECT_EQ(inst[i].expected_result_chv_skl, validate(p));
1691 else
1692 EXPECT_EQ(inst[i].expected_result_bdw, validate(p));
1693
1694 clear_instructions(p);
1695 }
1696 }
1697
TEST_P(validation_test,mixed_float_align1_math_strided_fp16_inputs)1698 TEST_P(validation_test, mixed_float_align1_math_strided_fp16_inputs)
1699 {
1700 static const struct {
1701 enum brw_reg_type dst_type;
1702 enum brw_reg_type src0_type;
1703 enum brw_reg_type src1_type;
1704 unsigned dst_stride;
1705 unsigned src0_stride;
1706 unsigned src1_stride;
1707 bool expected_result;
1708 } inst[] = {
1709 #define INST(dst_type, src0_type, src1_type, \
1710 dst_stride, src0_stride, src1_stride, expected_result) \
1711 { \
1712 BRW_REGISTER_TYPE_##dst_type, \
1713 BRW_REGISTER_TYPE_##src0_type, \
1714 BRW_REGISTER_TYPE_##src1_type, \
1715 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1716 BRW_HORIZONTAL_STRIDE_##src0_stride, \
1717 BRW_HORIZONTAL_STRIDE_##src1_stride, \
1718 expected_result, \
1719 }
1720
1721 INST(HF, HF, F, 2, 2, 1, true),
1722 INST(HF, F, HF, 2, 1, 2, true),
1723 INST(HF, F, HF, 1, 1, 2, true),
1724 INST(HF, F, HF, 2, 1, 1, false),
1725 INST(HF, HF, F, 2, 1, 1, false),
1726 INST(HF, HF, F, 1, 1, 1, false),
1727 INST(HF, HF, F, 2, 1, 1, false),
1728 INST( F, HF, F, 1, 1, 1, false),
1729 INST( F, F, HF, 1, 1, 2, true),
1730 INST( F, HF, HF, 1, 2, 1, false),
1731 INST( F, HF, HF, 1, 2, 2, true),
1732
1733 #undef INST
1734 };
1735
1736 /* No half-float math in gfx8 */
1737 if (devinfo.ver < 9)
1738 return;
1739
1740 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
1741 gfx6_math(p, retype(g0, inst[i].dst_type),
1742 BRW_MATH_FUNCTION_POW,
1743 retype(g0, inst[i].src0_type),
1744 retype(g0, inst[i].src1_type));
1745
1746 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1747
1748 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
1749 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
1750 brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src0_stride);
1751
1752 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
1753 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
1754 brw_inst_set_src1_hstride(&devinfo, last_inst, inst[i].src1_stride);
1755
1756 EXPECT_EQ(inst[i].expected_result, validate(p));
1757
1758 clear_instructions(p);
1759 }
1760 }
1761
TEST_P(validation_test,mixed_float_align1_packed_fp16_dst)1762 TEST_P(validation_test, mixed_float_align1_packed_fp16_dst)
1763 {
1764 static const struct {
1765 unsigned exec_size;
1766 enum brw_reg_type dst_type;
1767 enum brw_reg_type src0_type;
1768 enum brw_reg_type src1_type;
1769 unsigned dst_stride;
1770 unsigned dst_subnr;
1771 bool expected_result_bdw;
1772 bool expected_result_chv_skl;
1773 } inst[] = {
1774 #define INST(exec_size, dst_type, src0_type, src1_type, dst_stride, dst_subnr, \
1775 expected_result_bdw, expected_result_chv_skl) \
1776 { \
1777 BRW_EXECUTE_##exec_size, \
1778 BRW_REGISTER_TYPE_##dst_type, \
1779 BRW_REGISTER_TYPE_##src0_type, \
1780 BRW_REGISTER_TYPE_##src1_type, \
1781 BRW_HORIZONTAL_STRIDE_##dst_stride, \
1782 dst_subnr, \
1783 expected_result_bdw, \
1784 expected_result_chv_skl \
1785 }
1786
1787 /* SIMD8 packed fp16 dst won't cross oword boundaries if region is
1788 * oword-aligned
1789 */
1790 INST( 8, HF, HF, F, 1, 0, false, true),
1791 INST( 8, HF, HF, F, 1, 2, false, false),
1792 INST( 8, HF, HF, F, 1, 4, false, false),
1793 INST( 8, HF, HF, F, 1, 8, false, false),
1794 INST( 8, HF, HF, F, 1, 16, false, true),
1795
1796 /* SIMD16 packed fp16 always crosses oword boundaries */
1797 INST(16, HF, HF, F, 1, 0, false, false),
1798 INST(16, HF, HF, F, 1, 2, false, false),
1799 INST(16, HF, HF, F, 1, 4, false, false),
1800 INST(16, HF, HF, F, 1, 8, false, false),
1801 INST(16, HF, HF, F, 1, 16, false, false),
1802
1803 /* If destination is not packed (or not fp16) we can cross oword
1804 * boundaries
1805 */
1806 INST( 8, HF, HF, F, 2, 0, true, true),
1807 INST( 8, F, HF, F, 1, 0, true, true),
1808
1809 #undef INST
1810 };
1811
1812 if (devinfo.ver < 8)
1813 return;
1814
1815 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
1816 brw_ADD(p, retype(g0, inst[i].dst_type),
1817 retype(g0, inst[i].src0_type),
1818 retype(g0, inst[i].src1_type));
1819
1820 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1821 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, inst[i].dst_subnr);
1822
1823 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
1824 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
1825 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
1826
1827 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
1828 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
1829 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
1830
1831 brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
1832
1833 if (devinfo.is_cherryview || devinfo.ver >= 9)
1834 EXPECT_EQ(inst[i].expected_result_chv_skl, validate(p));
1835 else
1836 EXPECT_EQ(inst[i].expected_result_bdw, validate(p));
1837
1838 clear_instructions(p);
1839 }
1840 }
1841
TEST_P(validation_test,mixed_float_align16_packed_data)1842 TEST_P(validation_test, mixed_float_align16_packed_data)
1843 {
1844 static const struct {
1845 enum brw_reg_type dst_type;
1846 enum brw_reg_type src0_type;
1847 enum brw_reg_type src1_type;
1848 unsigned src0_vstride;
1849 unsigned src1_vstride;
1850 bool expected_result;
1851 } inst[] = {
1852 #define INST(dst_type, src0_type, src1_type, \
1853 src0_vstride, src1_vstride, expected_result) \
1854 { \
1855 BRW_REGISTER_TYPE_##dst_type, \
1856 BRW_REGISTER_TYPE_##src0_type, \
1857 BRW_REGISTER_TYPE_##src1_type, \
1858 BRW_VERTICAL_STRIDE_##src0_vstride, \
1859 BRW_VERTICAL_STRIDE_##src1_vstride, \
1860 expected_result, \
1861 }
1862
1863 /* We only test with F destination because there is a restriction
1864 * by which F->HF conversions need to be DWord aligned but Align16 also
1865 * requires that destination horizontal stride is 1.
1866 */
1867 INST(F, F, HF, 4, 4, true),
1868 INST(F, F, HF, 2, 4, false),
1869 INST(F, F, HF, 4, 2, false),
1870 INST(F, F, HF, 0, 4, false),
1871 INST(F, F, HF, 4, 0, false),
1872 INST(F, HF, F, 4, 4, true),
1873 INST(F, HF, F, 4, 2, false),
1874 INST(F, HF, F, 2, 4, false),
1875 INST(F, HF, F, 0, 4, false),
1876 INST(F, HF, F, 4, 0, false),
1877
1878 #undef INST
1879 };
1880
1881 if (devinfo.ver < 8 || devinfo.ver >= 11)
1882 return;
1883
1884 brw_set_default_access_mode(p, BRW_ALIGN_16);
1885
1886 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
1887 brw_ADD(p, retype(g0, inst[i].dst_type),
1888 retype(g0, inst[i].src0_type),
1889 retype(g0, inst[i].src1_type));
1890
1891 brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src0_vstride);
1892 brw_inst_set_src1_vstride(&devinfo, last_inst, inst[i].src1_vstride);
1893
1894 EXPECT_EQ(inst[i].expected_result, validate(p));
1895
1896 clear_instructions(p);
1897 }
1898 }
1899
TEST_P(validation_test,mixed_float_align16_no_simd16)1900 TEST_P(validation_test, mixed_float_align16_no_simd16)
1901 {
1902 static const struct {
1903 unsigned exec_size;
1904 enum brw_reg_type dst_type;
1905 enum brw_reg_type src0_type;
1906 enum brw_reg_type src1_type;
1907 bool expected_result;
1908 } inst[] = {
1909 #define INST(exec_size, dst_type, src0_type, src1_type, expected_result) \
1910 { \
1911 BRW_EXECUTE_##exec_size, \
1912 BRW_REGISTER_TYPE_##dst_type, \
1913 BRW_REGISTER_TYPE_##src0_type, \
1914 BRW_REGISTER_TYPE_##src1_type, \
1915 expected_result, \
1916 }
1917
1918 /* We only test with F destination because there is a restriction
1919 * by which F->HF conversions need to be DWord aligned but Align16 also
1920 * requires that destination horizontal stride is 1.
1921 */
1922 INST( 8, F, F, HF, true),
1923 INST( 8, F, HF, F, true),
1924 INST( 8, F, F, HF, true),
1925 INST(16, F, F, HF, false),
1926 INST(16, F, HF, F, false),
1927 INST(16, F, F, HF, false),
1928
1929 #undef INST
1930 };
1931
1932 if (devinfo.ver < 8 || devinfo.ver >= 11)
1933 return;
1934
1935 brw_set_default_access_mode(p, BRW_ALIGN_16);
1936
1937 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
1938 brw_ADD(p, retype(g0, inst[i].dst_type),
1939 retype(g0, inst[i].src0_type),
1940 retype(g0, inst[i].src1_type));
1941
1942 brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
1943
1944 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
1945 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
1946
1947 EXPECT_EQ(inst[i].expected_result, validate(p));
1948
1949 clear_instructions(p);
1950 }
1951 }
1952
TEST_P(validation_test,mixed_float_align16_no_acc_read)1953 TEST_P(validation_test, mixed_float_align16_no_acc_read)
1954 {
1955 static const struct {
1956 enum brw_reg_type dst_type;
1957 enum brw_reg_type src0_type;
1958 enum brw_reg_type src1_type;
1959 bool read_acc;
1960 bool expected_result;
1961 } inst[] = {
1962 #define INST(dst_type, src0_type, src1_type, read_acc, expected_result) \
1963 { \
1964 BRW_REGISTER_TYPE_##dst_type, \
1965 BRW_REGISTER_TYPE_##src0_type, \
1966 BRW_REGISTER_TYPE_##src1_type, \
1967 read_acc, \
1968 expected_result, \
1969 }
1970
1971 /* We only test with F destination because there is a restriction
1972 * by which F->HF conversions need to be DWord aligned but Align16 also
1973 * requires that destination horizontal stride is 1.
1974 */
1975 INST( F, F, HF, false, true),
1976 INST( F, F, HF, true, false),
1977 INST( F, HF, F, false, true),
1978 INST( F, HF, F, true, false),
1979
1980 #undef INST
1981 };
1982
1983 if (devinfo.ver < 8 || devinfo.ver >= 11)
1984 return;
1985
1986 brw_set_default_access_mode(p, BRW_ALIGN_16);
1987
1988 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
1989 brw_ADD(p, retype(g0, inst[i].dst_type),
1990 retype(inst[i].read_acc ? acc0 : g0, inst[i].src0_type),
1991 retype(g0, inst[i].src1_type));
1992
1993 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
1994 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
1995
1996 EXPECT_EQ(inst[i].expected_result, validate(p));
1997
1998 clear_instructions(p);
1999 }
2000 }
2001
TEST_P(validation_test,mixed_float_align16_math_packed_format)2002 TEST_P(validation_test, mixed_float_align16_math_packed_format)
2003 {
2004 static const struct {
2005 enum brw_reg_type dst_type;
2006 enum brw_reg_type src0_type;
2007 enum brw_reg_type src1_type;
2008 unsigned src0_vstride;
2009 unsigned src1_vstride;
2010 bool expected_result;
2011 } inst[] = {
2012 #define INST(dst_type, src0_type, src1_type, \
2013 src0_vstride, src1_vstride, expected_result) \
2014 { \
2015 BRW_REGISTER_TYPE_##dst_type, \
2016 BRW_REGISTER_TYPE_##src0_type, \
2017 BRW_REGISTER_TYPE_##src1_type, \
2018 BRW_VERTICAL_STRIDE_##src0_vstride, \
2019 BRW_VERTICAL_STRIDE_##src1_vstride, \
2020 expected_result, \
2021 }
2022
2023 /* We only test with F destination because there is a restriction
2024 * by which F->HF conversions need to be DWord aligned but Align16 also
2025 * requires that destination horizontal stride is 1.
2026 */
2027 INST( F, HF, F, 4, 0, false),
2028 INST( F, HF, HF, 4, 4, true),
2029 INST( F, F, HF, 4, 0, false),
2030 INST( F, F, HF, 2, 4, false),
2031 INST( F, F, HF, 4, 2, false),
2032 INST( F, HF, HF, 0, 4, false),
2033
2034 #undef INST
2035 };
2036
2037 /* Align16 Math for mixed float mode is not supported in gfx8 */
2038 if (devinfo.ver < 9 || devinfo.ver >= 11)
2039 return;
2040
2041 brw_set_default_access_mode(p, BRW_ALIGN_16);
2042
2043 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
2044 gfx6_math(p, retype(g0, inst[i].dst_type),
2045 BRW_MATH_FUNCTION_POW,
2046 retype(g0, inst[i].src0_type),
2047 retype(g0, inst[i].src1_type));
2048
2049 brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src0_vstride);
2050 brw_inst_set_src1_vstride(&devinfo, last_inst, inst[i].src1_vstride);
2051
2052 EXPECT_EQ(inst[i].expected_result, validate(p));
2053
2054 clear_instructions(p);
2055 }
2056 }
2057
TEST_P(validation_test,vector_immediate_destination_alignment)2058 TEST_P(validation_test, vector_immediate_destination_alignment)
2059 {
2060 static const struct {
2061 enum brw_reg_type dst_type;
2062 enum brw_reg_type src_type;
2063 unsigned subnr;
2064 unsigned exec_size;
2065 bool expected_result;
2066 } move[] = {
2067 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, 0, BRW_EXECUTE_4, true },
2068 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, 16, BRW_EXECUTE_4, true },
2069 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, 1, BRW_EXECUTE_4, false },
2070
2071 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, 0, BRW_EXECUTE_8, true },
2072 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, 16, BRW_EXECUTE_8, true },
2073 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, 1, BRW_EXECUTE_8, false },
2074
2075 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, 0, BRW_EXECUTE_8, true },
2076 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, 16, BRW_EXECUTE_8, true },
2077 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, 1, BRW_EXECUTE_8, false },
2078 };
2079
2080 for (unsigned i = 0; i < ARRAY_SIZE(move); i++) {
2081 /* UV type is Gfx6+ */
2082 if (devinfo.ver < 6 &&
2083 move[i].src_type == BRW_REGISTER_TYPE_UV)
2084 continue;
2085
2086 brw_MOV(p, retype(g0, move[i].dst_type), retype(zero, move[i].src_type));
2087 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, move[i].subnr);
2088 brw_inst_set_exec_size(&devinfo, last_inst, move[i].exec_size);
2089
2090 EXPECT_EQ(move[i].expected_result, validate(p));
2091
2092 clear_instructions(p);
2093 }
2094 }
2095
TEST_P(validation_test,vector_immediate_destination_stride)2096 TEST_P(validation_test, vector_immediate_destination_stride)
2097 {
2098 static const struct {
2099 enum brw_reg_type dst_type;
2100 enum brw_reg_type src_type;
2101 unsigned stride;
2102 bool expected_result;
2103 } move[] = {
2104 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_1, true },
2105 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, false },
2106 { BRW_REGISTER_TYPE_D, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_1, true },
2107 { BRW_REGISTER_TYPE_D, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, false },
2108 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, true },
2109 { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_4, true },
2110
2111 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_1, true },
2112 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_2, false },
2113 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_4, false },
2114 { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_2, true },
2115
2116 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_1, true },
2117 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_2, false },
2118 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_4, false },
2119 { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_2, true },
2120 };
2121
2122 for (unsigned i = 0; i < ARRAY_SIZE(move); i++) {
2123 /* UV type is Gfx6+ */
2124 if (devinfo.ver < 6 &&
2125 move[i].src_type == BRW_REGISTER_TYPE_UV)
2126 continue;
2127
2128 brw_MOV(p, retype(g0, move[i].dst_type), retype(zero, move[i].src_type));
2129 brw_inst_set_dst_hstride(&devinfo, last_inst, move[i].stride);
2130
2131 EXPECT_EQ(move[i].expected_result, validate(p));
2132
2133 clear_instructions(p);
2134 }
2135 }
2136
TEST_P(validation_test,qword_low_power_align1_regioning_restrictions)2137 TEST_P(validation_test, qword_low_power_align1_regioning_restrictions)
2138 {
2139 static const struct {
2140 enum opcode opcode;
2141 unsigned exec_size;
2142
2143 enum brw_reg_type dst_type;
2144 unsigned dst_subreg;
2145 unsigned dst_stride;
2146
2147 enum brw_reg_type src_type;
2148 unsigned src_subreg;
2149 unsigned src_vstride;
2150 unsigned src_width;
2151 unsigned src_hstride;
2152
2153 bool expected_result;
2154 } inst[] = {
2155 #define INST(opcode, exec_size, dst_type, dst_subreg, dst_stride, src_type, \
2156 src_subreg, src_vstride, src_width, src_hstride, expected_result) \
2157 { \
2158 BRW_OPCODE_##opcode, \
2159 BRW_EXECUTE_##exec_size, \
2160 BRW_REGISTER_TYPE_##dst_type, \
2161 dst_subreg, \
2162 BRW_HORIZONTAL_STRIDE_##dst_stride, \
2163 BRW_REGISTER_TYPE_##src_type, \
2164 src_subreg, \
2165 BRW_VERTICAL_STRIDE_##src_vstride, \
2166 BRW_WIDTH_##src_width, \
2167 BRW_HORIZONTAL_STRIDE_##src_hstride, \
2168 expected_result, \
2169 }
2170
2171 /* Some instruction that violate no restrictions, as a control */
2172 INST(MOV, 4, DF, 0, 1, DF, 0, 4, 4, 1, true ),
2173 INST(MOV, 4, Q, 0, 1, Q, 0, 4, 4, 1, true ),
2174 INST(MOV, 4, UQ, 0, 1, UQ, 0, 4, 4, 1, true ),
2175
2176 INST(MOV, 4, DF, 0, 1, F, 0, 8, 4, 2, true ),
2177 INST(MOV, 4, Q, 0, 1, D, 0, 8, 4, 2, true ),
2178 INST(MOV, 4, UQ, 0, 1, UD, 0, 8, 4, 2, true ),
2179
2180 INST(MOV, 4, F, 0, 2, DF, 0, 4, 4, 1, true ),
2181 INST(MOV, 4, D, 0, 2, Q, 0, 4, 4, 1, true ),
2182 INST(MOV, 4, UD, 0, 2, UQ, 0, 4, 4, 1, true ),
2183
2184 INST(MUL, 8, D, 0, 2, D, 0, 8, 4, 2, true ),
2185 INST(MUL, 8, UD, 0, 2, UD, 0, 8, 4, 2, true ),
2186
2187 /* Something with subreg nrs */
2188 INST(MOV, 2, DF, 8, 1, DF, 8, 2, 2, 1, true ),
2189 INST(MOV, 2, Q, 8, 1, Q, 8, 2, 2, 1, true ),
2190 INST(MOV, 2, UQ, 8, 1, UQ, 8, 2, 2, 1, true ),
2191
2192 INST(MUL, 2, D, 4, 2, D, 4, 4, 2, 2, true ),
2193 INST(MUL, 2, UD, 4, 2, UD, 4, 4, 2, 2, true ),
2194
2195 /* The PRMs say that for CHV, BXT:
2196 *
2197 * When source or destination datatype is 64b or operation is integer
2198 * DWord multiply, regioning in Align1 must follow these rules:
2199 *
2200 * 1. Source and Destination horizontal stride must be aligned to the
2201 * same qword.
2202 */
2203 INST(MOV, 4, DF, 0, 2, DF, 0, 4, 4, 1, false),
2204 INST(MOV, 4, Q, 0, 2, Q, 0, 4, 4, 1, false),
2205 INST(MOV, 4, UQ, 0, 2, UQ, 0, 4, 4, 1, false),
2206
2207 INST(MOV, 4, DF, 0, 2, F, 0, 8, 4, 2, false),
2208 INST(MOV, 4, Q, 0, 2, D, 0, 8, 4, 2, false),
2209 INST(MOV, 4, UQ, 0, 2, UD, 0, 8, 4, 2, false),
2210
2211 INST(MOV, 4, DF, 0, 2, F, 0, 4, 4, 1, false),
2212 INST(MOV, 4, Q, 0, 2, D, 0, 4, 4, 1, false),
2213 INST(MOV, 4, UQ, 0, 2, UD, 0, 4, 4, 1, false),
2214
2215 INST(MUL, 4, D, 0, 2, D, 0, 4, 4, 1, false),
2216 INST(MUL, 4, UD, 0, 2, UD, 0, 4, 4, 1, false),
2217
2218 INST(MUL, 4, D, 0, 1, D, 0, 8, 4, 2, false),
2219 INST(MUL, 4, UD, 0, 1, UD, 0, 8, 4, 2, false),
2220
2221 /* 2. Regioning must ensure Src.Vstride = Src.Width * Src.Hstride. */
2222 INST(MOV, 4, DF, 0, 1, DF, 0, 0, 2, 1, false),
2223 INST(MOV, 4, Q, 0, 1, Q, 0, 0, 2, 1, false),
2224 INST(MOV, 4, UQ, 0, 1, UQ, 0, 0, 2, 1, false),
2225
2226 INST(MOV, 4, DF, 0, 1, F, 0, 0, 2, 2, false),
2227 INST(MOV, 4, Q, 0, 1, D, 0, 0, 2, 2, false),
2228 INST(MOV, 4, UQ, 0, 1, UD, 0, 0, 2, 2, false),
2229
2230 INST(MOV, 8, F, 0, 2, DF, 0, 0, 2, 1, false),
2231 INST(MOV, 8, D, 0, 2, Q, 0, 0, 2, 1, false),
2232 INST(MOV, 8, UD, 0, 2, UQ, 0, 0, 2, 1, false),
2233
2234 INST(MUL, 8, D, 0, 2, D, 0, 0, 4, 2, false),
2235 INST(MUL, 8, UD, 0, 2, UD, 0, 0, 4, 2, false),
2236
2237 INST(MUL, 8, D, 0, 2, D, 0, 0, 4, 2, false),
2238 INST(MUL, 8, UD, 0, 2, UD, 0, 0, 4, 2, false),
2239
2240 /* 3. Source and Destination offset must be the same, except the case
2241 * of scalar source.
2242 */
2243 INST(MOV, 2, DF, 8, 1, DF, 0, 2, 2, 1, false),
2244 INST(MOV, 2, Q, 8, 1, Q, 0, 2, 2, 1, false),
2245 INST(MOV, 2, UQ, 8, 1, UQ, 0, 2, 2, 1, false),
2246
2247 INST(MOV, 2, DF, 0, 1, DF, 8, 2, 2, 1, false),
2248 INST(MOV, 2, Q, 0, 1, Q, 8, 2, 2, 1, false),
2249 INST(MOV, 2, UQ, 0, 1, UQ, 8, 2, 2, 1, false),
2250
2251 INST(MUL, 4, D, 4, 2, D, 0, 4, 2, 2, false),
2252 INST(MUL, 4, UD, 4, 2, UD, 0, 4, 2, 2, false),
2253
2254 INST(MUL, 4, D, 0, 2, D, 4, 4, 2, 2, false),
2255 INST(MUL, 4, UD, 0, 2, UD, 4, 4, 2, 2, false),
2256
2257 INST(MOV, 2, DF, 8, 1, DF, 0, 0, 1, 0, true ),
2258 INST(MOV, 2, Q, 8, 1, Q, 0, 0, 1, 0, true ),
2259 INST(MOV, 2, UQ, 8, 1, UQ, 0, 0, 1, 0, true ),
2260
2261 INST(MOV, 2, DF, 8, 1, F, 4, 0, 1, 0, true ),
2262 INST(MOV, 2, Q, 8, 1, D, 4, 0, 1, 0, true ),
2263 INST(MOV, 2, UQ, 8, 1, UD, 4, 0, 1, 0, true ),
2264
2265 INST(MUL, 4, D, 4, 1, D, 0, 0, 1, 0, true ),
2266 INST(MUL, 4, UD, 4, 1, UD, 0, 0, 1, 0, true ),
2267
2268 INST(MUL, 4, D, 0, 1, D, 4, 0, 1, 0, true ),
2269 INST(MUL, 4, UD, 0, 1, UD, 4, 0, 1, 0, true ),
2270
2271 #undef INST
2272 };
2273
2274 /* These restrictions only apply to Gfx8+ */
2275 if (devinfo.ver < 8)
2276 return;
2277
2278 /* NoDDChk/NoDDClr does not exist on Gfx12+ */
2279 if (devinfo.ver >= 12)
2280 return;
2281
2282 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
2283 if (!devinfo.has_64bit_float &&
2284 (inst[i].dst_type == BRW_REGISTER_TYPE_DF ||
2285 inst[i].src_type == BRW_REGISTER_TYPE_DF))
2286 continue;
2287
2288 if (!devinfo.has_64bit_int &&
2289 (inst[i].dst_type == BRW_REGISTER_TYPE_Q ||
2290 inst[i].dst_type == BRW_REGISTER_TYPE_UQ ||
2291 inst[i].src_type == BRW_REGISTER_TYPE_Q ||
2292 inst[i].src_type == BRW_REGISTER_TYPE_UQ))
2293 continue;
2294
2295 if (inst[i].opcode == BRW_OPCODE_MOV) {
2296 brw_MOV(p, retype(g0, inst[i].dst_type),
2297 retype(g0, inst[i].src_type));
2298 } else {
2299 assert(inst[i].opcode == BRW_OPCODE_MUL);
2300 brw_MUL(p, retype(g0, inst[i].dst_type),
2301 retype(g0, inst[i].src_type),
2302 retype(zero, inst[i].src_type));
2303 }
2304 brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
2305
2306 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, inst[i].dst_subreg);
2307 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, inst[i].src_subreg);
2308
2309 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
2310
2311 brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride);
2312 brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width);
2313 brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride);
2314
2315 if (devinfo.is_cherryview || intel_device_info_is_9lp(&devinfo)) {
2316 EXPECT_EQ(inst[i].expected_result, validate(p));
2317 } else {
2318 EXPECT_TRUE(validate(p));
2319 }
2320
2321 clear_instructions(p);
2322 }
2323 }
2324
TEST_P(validation_test,qword_low_power_no_indirect_addressing)2325 TEST_P(validation_test, qword_low_power_no_indirect_addressing)
2326 {
2327 static const struct {
2328 enum opcode opcode;
2329 unsigned exec_size;
2330
2331 enum brw_reg_type dst_type;
2332 bool dst_is_indirect;
2333 unsigned dst_stride;
2334
2335 enum brw_reg_type src_type;
2336 bool src_is_indirect;
2337 unsigned src_vstride;
2338 unsigned src_width;
2339 unsigned src_hstride;
2340
2341 bool expected_result;
2342 } inst[] = {
2343 #define INST(opcode, exec_size, dst_type, dst_is_indirect, dst_stride, \
2344 src_type, src_is_indirect, src_vstride, src_width, src_hstride, \
2345 expected_result) \
2346 { \
2347 BRW_OPCODE_##opcode, \
2348 BRW_EXECUTE_##exec_size, \
2349 BRW_REGISTER_TYPE_##dst_type, \
2350 dst_is_indirect, \
2351 BRW_HORIZONTAL_STRIDE_##dst_stride, \
2352 BRW_REGISTER_TYPE_##src_type, \
2353 src_is_indirect, \
2354 BRW_VERTICAL_STRIDE_##src_vstride, \
2355 BRW_WIDTH_##src_width, \
2356 BRW_HORIZONTAL_STRIDE_##src_hstride, \
2357 expected_result, \
2358 }
2359
2360 /* Some instruction that violate no restrictions, as a control */
2361 INST(MOV, 4, DF, 0, 1, DF, 0, 4, 4, 1, true ),
2362 INST(MOV, 4, Q, 0, 1, Q, 0, 4, 4, 1, true ),
2363 INST(MOV, 4, UQ, 0, 1, UQ, 0, 4, 4, 1, true ),
2364
2365 INST(MUL, 8, D, 0, 2, D, 0, 8, 4, 2, true ),
2366 INST(MUL, 8, UD, 0, 2, UD, 0, 8, 4, 2, true ),
2367
2368 INST(MOV, 4, F, 1, 1, F, 0, 4, 4, 1, true ),
2369 INST(MOV, 4, F, 0, 1, F, 1, 4, 4, 1, true ),
2370 INST(MOV, 4, F, 1, 1, F, 1, 4, 4, 1, true ),
2371
2372 /* The PRMs say that for CHV, BXT:
2373 *
2374 * When source or destination datatype is 64b or operation is integer
2375 * DWord multiply, indirect addressing must not be used.
2376 */
2377 INST(MOV, 4, DF, 1, 1, DF, 0, 4, 4, 1, false),
2378 INST(MOV, 4, Q, 1, 1, Q, 0, 4, 4, 1, false),
2379 INST(MOV, 4, UQ, 1, 1, UQ, 0, 4, 4, 1, false),
2380
2381 INST(MOV, 4, DF, 0, 1, DF, 1, 4, 4, 1, false),
2382 INST(MOV, 4, Q, 0, 1, Q, 1, 4, 4, 1, false),
2383 INST(MOV, 4, UQ, 0, 1, UQ, 1, 4, 4, 1, false),
2384
2385 INST(MOV, 4, DF, 1, 1, F, 0, 8, 4, 2, false),
2386 INST(MOV, 4, Q, 1, 1, D, 0, 8, 4, 2, false),
2387 INST(MOV, 4, UQ, 1, 1, UD, 0, 8, 4, 2, false),
2388
2389 INST(MOV, 4, DF, 0, 1, F, 1, 8, 4, 2, false),
2390 INST(MOV, 4, Q, 0, 1, D, 1, 8, 4, 2, false),
2391 INST(MOV, 4, UQ, 0, 1, UD, 1, 8, 4, 2, false),
2392
2393 INST(MOV, 4, F, 1, 2, DF, 0, 4, 4, 1, false),
2394 INST(MOV, 4, D, 1, 2, Q, 0, 4, 4, 1, false),
2395 INST(MOV, 4, UD, 1, 2, UQ, 0, 4, 4, 1, false),
2396
2397 INST(MOV, 4, F, 0, 2, DF, 1, 4, 4, 1, false),
2398 INST(MOV, 4, D, 0, 2, Q, 1, 4, 4, 1, false),
2399 INST(MOV, 4, UD, 0, 2, UQ, 1, 4, 4, 1, false),
2400
2401 INST(MUL, 8, D, 1, 2, D, 0, 8, 4, 2, false),
2402 INST(MUL, 8, UD, 1, 2, UD, 0, 8, 4, 2, false),
2403
2404 INST(MUL, 8, D, 0, 2, D, 1, 8, 4, 2, false),
2405 INST(MUL, 8, UD, 0, 2, UD, 1, 8, 4, 2, false),
2406
2407 #undef INST
2408 };
2409
2410 /* These restrictions only apply to Gfx8+ */
2411 if (devinfo.ver < 8)
2412 return;
2413
2414 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
2415 if (!devinfo.has_64bit_float &&
2416 (inst[i].dst_type == BRW_REGISTER_TYPE_DF ||
2417 inst[i].src_type == BRW_REGISTER_TYPE_DF))
2418 continue;
2419
2420 if (!devinfo.has_64bit_int &&
2421 (inst[i].dst_type == BRW_REGISTER_TYPE_Q ||
2422 inst[i].dst_type == BRW_REGISTER_TYPE_UQ ||
2423 inst[i].src_type == BRW_REGISTER_TYPE_Q ||
2424 inst[i].src_type == BRW_REGISTER_TYPE_UQ))
2425 continue;
2426
2427 if (inst[i].opcode == BRW_OPCODE_MOV) {
2428 brw_MOV(p, retype(g0, inst[i].dst_type),
2429 retype(g0, inst[i].src_type));
2430 } else {
2431 assert(inst[i].opcode == BRW_OPCODE_MUL);
2432 brw_MUL(p, retype(g0, inst[i].dst_type),
2433 retype(g0, inst[i].src_type),
2434 retype(zero, inst[i].src_type));
2435 }
2436 brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
2437
2438 brw_inst_set_dst_address_mode(&devinfo, last_inst, inst[i].dst_is_indirect);
2439 brw_inst_set_src0_address_mode(&devinfo, last_inst, inst[i].src_is_indirect);
2440
2441 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
2442
2443 brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride);
2444 brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width);
2445 brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride);
2446
2447 if (devinfo.is_cherryview || intel_device_info_is_9lp(&devinfo)) {
2448 EXPECT_EQ(inst[i].expected_result, validate(p));
2449 } else {
2450 EXPECT_TRUE(validate(p));
2451 }
2452
2453 clear_instructions(p);
2454 }
2455 }
2456
TEST_P(validation_test,qword_low_power_no_64bit_arf)2457 TEST_P(validation_test, qword_low_power_no_64bit_arf)
2458 {
2459 static const struct {
2460 enum opcode opcode;
2461 unsigned exec_size;
2462
2463 struct brw_reg dst;
2464 enum brw_reg_type dst_type;
2465 unsigned dst_stride;
2466
2467 struct brw_reg src;
2468 enum brw_reg_type src_type;
2469 unsigned src_vstride;
2470 unsigned src_width;
2471 unsigned src_hstride;
2472
2473 bool acc_wr;
2474 bool expected_result;
2475 } inst[] = {
2476 #define INST(opcode, exec_size, dst, dst_type, dst_stride, \
2477 src, src_type, src_vstride, src_width, src_hstride, \
2478 acc_wr, expected_result) \
2479 { \
2480 BRW_OPCODE_##opcode, \
2481 BRW_EXECUTE_##exec_size, \
2482 dst, \
2483 BRW_REGISTER_TYPE_##dst_type, \
2484 BRW_HORIZONTAL_STRIDE_##dst_stride, \
2485 src, \
2486 BRW_REGISTER_TYPE_##src_type, \
2487 BRW_VERTICAL_STRIDE_##src_vstride, \
2488 BRW_WIDTH_##src_width, \
2489 BRW_HORIZONTAL_STRIDE_##src_hstride, \
2490 acc_wr, \
2491 expected_result, \
2492 }
2493
2494 /* Some instruction that violate no restrictions, as a control */
2495 INST(MOV, 4, g0, DF, 1, g0, F, 4, 2, 2, 0, true ),
2496 INST(MOV, 4, g0, F, 2, g0, DF, 4, 4, 1, 0, true ),
2497
2498 INST(MOV, 4, g0, Q, 1, g0, D, 4, 2, 2, 0, true ),
2499 INST(MOV, 4, g0, D, 2, g0, Q, 4, 4, 1, 0, true ),
2500
2501 INST(MOV, 4, g0, UQ, 1, g0, UD, 4, 2, 2, 0, true ),
2502 INST(MOV, 4, g0, UD, 2, g0, UQ, 4, 4, 1, 0, true ),
2503
2504 INST(MOV, 4, null, F, 1, g0, F, 4, 4, 1, 0, true ),
2505 INST(MOV, 4, acc0, F, 1, g0, F, 4, 4, 1, 0, true ),
2506 INST(MOV, 4, g0, F, 1, acc0, F, 4, 4, 1, 0, true ),
2507
2508 INST(MOV, 4, null, D, 1, g0, D, 4, 4, 1, 0, true ),
2509 INST(MOV, 4, acc0, D, 1, g0, D, 4, 4, 1, 0, true ),
2510 INST(MOV, 4, g0, D, 1, acc0, D, 4, 4, 1, 0, true ),
2511
2512 INST(MOV, 4, null, UD, 1, g0, UD, 4, 4, 1, 0, true ),
2513 INST(MOV, 4, acc0, UD, 1, g0, UD, 4, 4, 1, 0, true ),
2514 INST(MOV, 4, g0, UD, 1, acc0, UD, 4, 4, 1, 0, true ),
2515
2516 INST(MUL, 4, g0, D, 2, g0, D, 4, 2, 2, 0, true ),
2517 INST(MUL, 4, g0, UD, 2, g0, UD, 4, 2, 2, 0, true ),
2518
2519 /* The PRMs say that for CHV, BXT:
2520 *
2521 * ARF registers must never be used with 64b datatype or when
2522 * operation is integer DWord multiply.
2523 */
2524 INST(MOV, 4, acc0, DF, 1, g0, F, 4, 2, 2, 0, false),
2525 INST(MOV, 4, g0, DF, 1, acc0, F, 4, 2, 2, 0, false),
2526
2527 INST(MOV, 4, acc0, Q, 1, g0, D, 4, 2, 2, 0, false),
2528 INST(MOV, 4, g0, Q, 1, acc0, D, 4, 2, 2, 0, false),
2529
2530 INST(MOV, 4, acc0, UQ, 1, g0, UD, 4, 2, 2, 0, false),
2531 INST(MOV, 4, g0, UQ, 1, acc0, UD, 4, 2, 2, 0, false),
2532
2533 INST(MOV, 4, acc0, F, 2, g0, DF, 4, 4, 1, 0, false),
2534 INST(MOV, 4, g0, F, 2, acc0, DF, 4, 4, 1, 0, false),
2535
2536 INST(MOV, 4, acc0, D, 2, g0, Q, 4, 4, 1, 0, false),
2537 INST(MOV, 4, g0, D, 2, acc0, Q, 4, 4, 1, 0, false),
2538
2539 INST(MOV, 4, acc0, UD, 2, g0, UQ, 4, 4, 1, 0, false),
2540 INST(MOV, 4, g0, UD, 2, acc0, UQ, 4, 4, 1, 0, false),
2541
2542 INST(MUL, 4, acc0, D, 2, g0, D, 4, 2, 2, 0, false),
2543 INST(MUL, 4, acc0, UD, 2, g0, UD, 4, 2, 2, 0, false),
2544 /* MUL cannot have integer accumulator sources, so don't test that */
2545
2546 /* We assume that the restriction does not apply to the null register */
2547 INST(MOV, 4, null, DF, 1, g0, F, 4, 2, 2, 0, true ),
2548 INST(MOV, 4, null, Q, 1, g0, D, 4, 2, 2, 0, true ),
2549 INST(MOV, 4, null, UQ, 1, g0, UD, 4, 2, 2, 0, true ),
2550
2551 /* Check implicit accumulator write control */
2552 INST(MOV, 4, null, DF, 1, g0, F, 4, 2, 2, 1, false),
2553 INST(MUL, 4, null, DF, 1, g0, F, 4, 2, 2, 1, false),
2554
2555 #undef INST
2556 };
2557
2558 /* These restrictions only apply to Gfx8+ */
2559 if (devinfo.ver < 8)
2560 return;
2561
2562 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
2563 if (!devinfo.has_64bit_float &&
2564 (inst[i].dst_type == BRW_REGISTER_TYPE_DF ||
2565 inst[i].src_type == BRW_REGISTER_TYPE_DF))
2566 continue;
2567
2568 if (!devinfo.has_64bit_int &&
2569 (inst[i].dst_type == BRW_REGISTER_TYPE_Q ||
2570 inst[i].dst_type == BRW_REGISTER_TYPE_UQ ||
2571 inst[i].src_type == BRW_REGISTER_TYPE_Q ||
2572 inst[i].src_type == BRW_REGISTER_TYPE_UQ))
2573 continue;
2574
2575 if (inst[i].opcode == BRW_OPCODE_MOV) {
2576 brw_MOV(p, retype(inst[i].dst, inst[i].dst_type),
2577 retype(inst[i].src, inst[i].src_type));
2578 } else {
2579 assert(inst[i].opcode == BRW_OPCODE_MUL);
2580 brw_MUL(p, retype(inst[i].dst, inst[i].dst_type),
2581 retype(inst[i].src, inst[i].src_type),
2582 retype(zero, inst[i].src_type));
2583 brw_inst_set_opcode(&devinfo, last_inst, inst[i].opcode);
2584 }
2585 brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
2586 brw_inst_set_acc_wr_control(&devinfo, last_inst, inst[i].acc_wr);
2587
2588 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
2589
2590 brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride);
2591 brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width);
2592 brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride);
2593
2594 if (devinfo.is_cherryview || intel_device_info_is_9lp(&devinfo)) {
2595 EXPECT_EQ(inst[i].expected_result, validate(p));
2596 } else {
2597 EXPECT_TRUE(validate(p));
2598 }
2599
2600 clear_instructions(p);
2601 }
2602
2603 if (!devinfo.has_64bit_float)
2604 return;
2605
2606 /* MAC implicitly reads the accumulator */
2607 brw_MAC(p, retype(g0, BRW_REGISTER_TYPE_DF),
2608 retype(stride(g0, 4, 4, 1), BRW_REGISTER_TYPE_DF),
2609 retype(stride(g0, 4, 4, 1), BRW_REGISTER_TYPE_DF));
2610 if (devinfo.is_cherryview || intel_device_info_is_9lp(&devinfo)) {
2611 EXPECT_FALSE(validate(p));
2612 } else {
2613 EXPECT_TRUE(validate(p));
2614 }
2615 }
2616
TEST_P(validation_test,align16_64_bit_integer)2617 TEST_P(validation_test, align16_64_bit_integer)
2618 {
2619 static const struct {
2620 enum opcode opcode;
2621 unsigned exec_size;
2622
2623 enum brw_reg_type dst_type;
2624 enum brw_reg_type src_type;
2625
2626 bool expected_result;
2627 } inst[] = {
2628 #define INST(opcode, exec_size, dst_type, src_type, expected_result) \
2629 { \
2630 BRW_OPCODE_##opcode, \
2631 BRW_EXECUTE_##exec_size, \
2632 BRW_REGISTER_TYPE_##dst_type, \
2633 BRW_REGISTER_TYPE_##src_type, \
2634 expected_result, \
2635 }
2636
2637 /* Some instruction that violate no restrictions, as a control */
2638 INST(MOV, 2, Q, D, true ),
2639 INST(MOV, 2, UQ, UD, true ),
2640 INST(MOV, 2, DF, F, true ),
2641
2642 INST(ADD, 2, Q, D, true ),
2643 INST(ADD, 2, UQ, UD, true ),
2644 INST(ADD, 2, DF, F, true ),
2645
2646 /* The PRMs say that for BDW, SKL:
2647 *
2648 * If Align16 is required for an operation with QW destination and non-QW
2649 * source datatypes, the execution size cannot exceed 2.
2650 */
2651
2652 INST(MOV, 4, Q, D, false),
2653 INST(MOV, 4, UQ, UD, false),
2654 INST(MOV, 4, DF, F, false),
2655
2656 INST(ADD, 4, Q, D, false),
2657 INST(ADD, 4, UQ, UD, false),
2658 INST(ADD, 4, DF, F, false),
2659
2660 #undef INST
2661 };
2662
2663 /* 64-bit integer types exist on Gfx8+ */
2664 if (devinfo.ver < 8)
2665 return;
2666
2667 /* Align16 does not exist on Gfx11+ */
2668 if (devinfo.ver >= 11)
2669 return;
2670
2671 brw_set_default_access_mode(p, BRW_ALIGN_16);
2672
2673 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
2674 if (inst[i].opcode == BRW_OPCODE_MOV) {
2675 brw_MOV(p, retype(g0, inst[i].dst_type),
2676 retype(g0, inst[i].src_type));
2677 } else {
2678 assert(inst[i].opcode == BRW_OPCODE_ADD);
2679 brw_ADD(p, retype(g0, inst[i].dst_type),
2680 retype(g0, inst[i].src_type),
2681 retype(g0, inst[i].src_type));
2682 }
2683 brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
2684
2685 EXPECT_EQ(inst[i].expected_result, validate(p));
2686
2687 clear_instructions(p);
2688 }
2689 }
2690
TEST_P(validation_test,qword_low_power_no_depctrl)2691 TEST_P(validation_test, qword_low_power_no_depctrl)
2692 {
2693 static const struct {
2694 enum opcode opcode;
2695 unsigned exec_size;
2696
2697 enum brw_reg_type dst_type;
2698 unsigned dst_stride;
2699
2700 enum brw_reg_type src_type;
2701 unsigned src_vstride;
2702 unsigned src_width;
2703 unsigned src_hstride;
2704
2705 bool no_dd_check;
2706 bool no_dd_clear;
2707
2708 bool expected_result;
2709 } inst[] = {
2710 #define INST(opcode, exec_size, dst_type, dst_stride, \
2711 src_type, src_vstride, src_width, src_hstride, \
2712 no_dd_check, no_dd_clear, expected_result) \
2713 { \
2714 BRW_OPCODE_##opcode, \
2715 BRW_EXECUTE_##exec_size, \
2716 BRW_REGISTER_TYPE_##dst_type, \
2717 BRW_HORIZONTAL_STRIDE_##dst_stride, \
2718 BRW_REGISTER_TYPE_##src_type, \
2719 BRW_VERTICAL_STRIDE_##src_vstride, \
2720 BRW_WIDTH_##src_width, \
2721 BRW_HORIZONTAL_STRIDE_##src_hstride, \
2722 no_dd_check, \
2723 no_dd_clear, \
2724 expected_result, \
2725 }
2726
2727 /* Some instruction that violate no restrictions, as a control */
2728 INST(MOV, 4, DF, 1, F, 8, 4, 2, 0, 0, true ),
2729 INST(MOV, 4, Q, 1, D, 8, 4, 2, 0, 0, true ),
2730 INST(MOV, 4, UQ, 1, UD, 8, 4, 2, 0, 0, true ),
2731
2732 INST(MOV, 4, F, 2, DF, 4, 4, 1, 0, 0, true ),
2733 INST(MOV, 4, D, 2, Q, 4, 4, 1, 0, 0, true ),
2734 INST(MOV, 4, UD, 2, UQ, 4, 4, 1, 0, 0, true ),
2735
2736 INST(MUL, 8, D, 2, D, 8, 4, 2, 0, 0, true ),
2737 INST(MUL, 8, UD, 2, UD, 8, 4, 2, 0, 0, true ),
2738
2739 INST(MOV, 4, F, 1, F, 4, 4, 1, 1, 1, true ),
2740
2741 /* The PRMs say that for CHV, BXT:
2742 *
2743 * When source or destination datatype is 64b or operation is integer
2744 * DWord multiply, DepCtrl must not be used.
2745 */
2746 INST(MOV, 4, DF, 1, F, 8, 4, 2, 1, 0, false),
2747 INST(MOV, 4, Q, 1, D, 8, 4, 2, 1, 0, false),
2748 INST(MOV, 4, UQ, 1, UD, 8, 4, 2, 1, 0, false),
2749
2750 INST(MOV, 4, F, 2, DF, 4, 4, 1, 1, 0, false),
2751 INST(MOV, 4, D, 2, Q, 4, 4, 1, 1, 0, false),
2752 INST(MOV, 4, UD, 2, UQ, 4, 4, 1, 1, 0, false),
2753
2754 INST(MOV, 4, DF, 1, F, 8, 4, 2, 0, 1, false),
2755 INST(MOV, 4, Q, 1, D, 8, 4, 2, 0, 1, false),
2756 INST(MOV, 4, UQ, 1, UD, 8, 4, 2, 0, 1, false),
2757
2758 INST(MOV, 4, F, 2, DF, 4, 4, 1, 0, 1, false),
2759 INST(MOV, 4, D, 2, Q, 4, 4, 1, 0, 1, false),
2760 INST(MOV, 4, UD, 2, UQ, 4, 4, 1, 0, 1, false),
2761
2762 INST(MUL, 8, D, 2, D, 8, 4, 2, 1, 0, false),
2763 INST(MUL, 8, UD, 2, UD, 8, 4, 2, 1, 0, false),
2764
2765 INST(MUL, 8, D, 2, D, 8, 4, 2, 0, 1, false),
2766 INST(MUL, 8, UD, 2, UD, 8, 4, 2, 0, 1, false),
2767
2768 #undef INST
2769 };
2770
2771 /* These restrictions only apply to Gfx8+ */
2772 if (devinfo.ver < 8)
2773 return;
2774
2775 /* NoDDChk/NoDDClr does not exist on Gfx12+ */
2776 if (devinfo.ver >= 12)
2777 return;
2778
2779 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
2780 if (!devinfo.has_64bit_float &&
2781 (inst[i].dst_type == BRW_REGISTER_TYPE_DF ||
2782 inst[i].src_type == BRW_REGISTER_TYPE_DF))
2783 continue;
2784
2785 if (!devinfo.has_64bit_int &&
2786 (inst[i].dst_type == BRW_REGISTER_TYPE_Q ||
2787 inst[i].dst_type == BRW_REGISTER_TYPE_UQ ||
2788 inst[i].src_type == BRW_REGISTER_TYPE_Q ||
2789 inst[i].src_type == BRW_REGISTER_TYPE_UQ))
2790 continue;
2791
2792 if (inst[i].opcode == BRW_OPCODE_MOV) {
2793 brw_MOV(p, retype(g0, inst[i].dst_type),
2794 retype(g0, inst[i].src_type));
2795 } else {
2796 assert(inst[i].opcode == BRW_OPCODE_MUL);
2797 brw_MUL(p, retype(g0, inst[i].dst_type),
2798 retype(g0, inst[i].src_type),
2799 retype(zero, inst[i].src_type));
2800 }
2801 brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
2802
2803 brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
2804
2805 brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride);
2806 brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width);
2807 brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride);
2808
2809 brw_inst_set_no_dd_check(&devinfo, last_inst, inst[i].no_dd_check);
2810 brw_inst_set_no_dd_clear(&devinfo, last_inst, inst[i].no_dd_clear);
2811
2812 if (devinfo.is_cherryview || intel_device_info_is_9lp(&devinfo)) {
2813 EXPECT_EQ(inst[i].expected_result, validate(p));
2814 } else {
2815 EXPECT_TRUE(validate(p));
2816 }
2817
2818 clear_instructions(p);
2819 }
2820 }
2821
TEST_P(validation_test,gfx11_no_byte_src_1_2)2822 TEST_P(validation_test, gfx11_no_byte_src_1_2)
2823 {
2824 static const struct {
2825 enum opcode opcode;
2826 unsigned access_mode;
2827
2828 enum brw_reg_type dst_type;
2829 struct {
2830 enum brw_reg_type type;
2831 unsigned vstride;
2832 unsigned width;
2833 unsigned hstride;
2834 } srcs[3];
2835
2836 int gfx_ver;
2837 bool expected_result;
2838 } inst[] = {
2839 #define INST(opcode, access_mode, dst_type, \
2840 src0_type, src0_vstride, src0_width, src0_hstride, \
2841 src1_type, src1_vstride, src1_width, src1_hstride, \
2842 src2_type, \
2843 gfx_ver, expected_result) \
2844 { \
2845 BRW_OPCODE_##opcode, \
2846 BRW_ALIGN_##access_mode, \
2847 BRW_REGISTER_TYPE_##dst_type, \
2848 { \
2849 { \
2850 BRW_REGISTER_TYPE_##src0_type, \
2851 BRW_VERTICAL_STRIDE_##src0_vstride, \
2852 BRW_WIDTH_##src0_width, \
2853 BRW_HORIZONTAL_STRIDE_##src0_hstride, \
2854 }, \
2855 { \
2856 BRW_REGISTER_TYPE_##src1_type, \
2857 BRW_VERTICAL_STRIDE_##src1_vstride, \
2858 BRW_WIDTH_##src1_width, \
2859 BRW_HORIZONTAL_STRIDE_##src1_hstride, \
2860 }, \
2861 { \
2862 BRW_REGISTER_TYPE_##src2_type, \
2863 }, \
2864 }, \
2865 gfx_ver, \
2866 expected_result, \
2867 }
2868
2869 /* Passes on < 11 */
2870 INST(MOV, 16, F, B, 2, 4, 0, UD, 0, 4, 0, D, 8, true ),
2871 INST(ADD, 16, UD, F, 0, 4, 0, UB, 0, 1, 0, D, 7, true ),
2872 INST(MAD, 16, D, B, 0, 4, 0, UB, 0, 1, 0, B, 10, true ),
2873
2874 /* Fails on 11+ */
2875 INST(MAD, 1, UB, W, 1, 1, 0, D, 0, 4, 0, B, 11, false ),
2876 INST(MAD, 1, UB, W, 1, 1, 1, UB, 1, 1, 0, W, 11, false ),
2877 INST(ADD, 1, W, W, 1, 4, 1, B, 1, 1, 0, D, 11, false ),
2878
2879 /* Passes on 11+ */
2880 INST(MOV, 1, W, B, 8, 8, 1, D, 8, 8, 1, D, 11, true ),
2881 INST(ADD, 1, UD, B, 8, 8, 1, W, 8, 8, 1, D, 11, true ),
2882 INST(MAD, 1, B, B, 0, 1, 0, D, 0, 4, 0, W, 11, true ),
2883
2884 #undef INST
2885 };
2886
2887
2888 for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) {
2889 /* Skip instruction not meant for this gfx_ver. */
2890 if (devinfo.ver != inst[i].gfx_ver)
2891 continue;
2892
2893 brw_push_insn_state(p);
2894
2895 brw_set_default_exec_size(p, BRW_EXECUTE_8);
2896 brw_set_default_access_mode(p, inst[i].access_mode);
2897
2898 switch (inst[i].opcode) {
2899 case BRW_OPCODE_MOV:
2900 brw_MOV(p, retype(g0, inst[i].dst_type),
2901 retype(g0, inst[i].srcs[0].type));
2902 brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].srcs[0].vstride);
2903 brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].srcs[0].hstride);
2904 break;
2905 case BRW_OPCODE_ADD:
2906 brw_ADD(p, retype(g0, inst[i].dst_type),
2907 retype(g0, inst[i].srcs[0].type),
2908 retype(g0, inst[i].srcs[1].type));
2909 brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].srcs[0].vstride);
2910 brw_inst_set_src0_width(&devinfo, last_inst, inst[i].srcs[0].width);
2911 brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].srcs[0].hstride);
2912 brw_inst_set_src1_vstride(&devinfo, last_inst, inst[i].srcs[1].vstride);
2913 brw_inst_set_src1_width(&devinfo, last_inst, inst[i].srcs[1].width);
2914 brw_inst_set_src1_hstride(&devinfo, last_inst, inst[i].srcs[1].hstride);
2915 break;
2916 case BRW_OPCODE_MAD:
2917 brw_MAD(p, retype(g0, inst[i].dst_type),
2918 retype(g0, inst[i].srcs[0].type),
2919 retype(g0, inst[i].srcs[1].type),
2920 retype(g0, inst[i].srcs[2].type));
2921 brw_inst_set_3src_a1_src0_vstride(&devinfo, last_inst, inst[i].srcs[0].vstride);
2922 brw_inst_set_3src_a1_src0_hstride(&devinfo, last_inst, inst[i].srcs[0].hstride);
2923 brw_inst_set_3src_a1_src1_vstride(&devinfo, last_inst, inst[i].srcs[0].vstride);
2924 brw_inst_set_3src_a1_src1_hstride(&devinfo, last_inst, inst[i].srcs[0].hstride);
2925 break;
2926 default:
2927 unreachable("invalid opcode");
2928 }
2929
2930 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
2931
2932 brw_inst_set_src0_width(&devinfo, last_inst, inst[i].srcs[0].width);
2933 brw_inst_set_src1_width(&devinfo, last_inst, inst[i].srcs[1].width);
2934
2935 brw_pop_insn_state(p);
2936
2937 EXPECT_EQ(inst[i].expected_result, validate(p));
2938
2939 clear_instructions(p);
2940 }
2941 }
2942