• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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