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
30static 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
53class validation_test: public ::testing::TestWithParam<struct intel_gfx_info> {
54   virtual void SetUp();
55
56public:
57   validation_test();
58   virtual ~validation_test();
59
60   struct brw_codegen *p;
61   struct intel_device_info devinfo;
62};
63
64validation_test::validation_test()
65{
66   p = rzalloc(NULL, struct brw_codegen);
67   memset(&devinfo, 0, sizeof(devinfo));
68}
69
70validation_test::~validation_test()
71{
72   ralloc_free(p);
73}
74
75void 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
85struct gfx_name {
86   template <class ParamType>
87   std::string
88   operator()(const ::testing::TestParamInfo<ParamType>& info) const {
89      return info.param.name;
90   }
91};
92
93INSTANTIATE_TEST_CASE_P(eu_assembly, validation_test,
94                        ::testing::ValuesIn(gfx_names),
95                        gfx_name());
96
97static bool
98validate(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
125static void
126clear_instructions(struct brw_codegen *p)
127{
128   p->next_insn_offset = 0;
129   p->nr_insn = 0;
130}
131
132TEST_P(validation_test, sanity)
133{
134   brw_ADD(p, g0, g0, g0);
135
136   EXPECT_TRUE(validate(p));
137}
138
139TEST_P(validation_test, src0_null_reg)
140{
141   brw_MOV(p, g0, null);
142
143   EXPECT_FALSE(validate(p));
144}
145
146TEST_P(validation_test, src1_null_reg)
147{
148   brw_ADD(p, g0, g0, null);
149
150   EXPECT_FALSE(validate(p));
151}
152
153TEST_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
164TEST_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
176TEST_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
192TEST_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
232TEST_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
263TEST_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
374TEST_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
454TEST_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
552TEST_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 */
587TEST_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 */
611TEST_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. */
642TEST_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 */
660TEST_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 */
678TEST_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. */
698TEST_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 */
724TEST_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. */
744TEST_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 */
768TEST_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 */
802TEST_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 */
824TEST_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 */
868TEST_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. */
904TEST_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
934TEST_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
998TEST_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
1032TEST_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
1066TEST_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
1100TEST_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
1156TEST_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
1218TEST_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
1244TEST_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
1305TEST_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
1428TEST_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
1491TEST_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
1545TEST_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
1615TEST_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
1698TEST_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
1762TEST_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
1842TEST_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
1900TEST_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
1953TEST_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
2002TEST_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
2058TEST_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
2096TEST_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
2137TEST_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
2325TEST_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
2457TEST_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
2617TEST_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
2691TEST_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
2822TEST_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