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