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