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