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