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