• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2016 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include <gtest/gtest.h>
25 #include "brw_eu.h"
26 #include "util/ralloc.h"
27 
28 enum subgen {
29    IS_G45 = 1,
30    IS_BYT,
31    IS_HSW,
32    IS_CHV,
33    IS_BXT,
34    IS_KBL,
35    IS_GLK,
36    IS_CFL,
37 };
38 
39 static const struct gen_info {
40    const char *name;
41    int gen;
42    enum subgen subgen;
43 } gens[] = {
44    { "brw", 4 },
45    { "g45", 4, IS_G45 },
46    { "ilk", 5 },
47    { "snb", 6 },
48    { "ivb", 7 },
49    { "byt", 7, IS_BYT },
50    { "hsw", 7, IS_HSW },
51    { "bdw", 8 },
52    { "chv", 8, IS_CHV },
53    { "skl", 9 },
54    { "bxt", 9, IS_BXT },
55    { "kbl", 9, IS_KBL },
56    { "glk", 9, IS_GLK },
57    { "cfl", 9, IS_CFL },
58    { "cnl", 10 },
59 };
60 
61 class validation_test: public ::testing::TestWithParam<struct gen_info> {
62    virtual void SetUp();
63 
64 public:
65    validation_test();
66    virtual ~validation_test();
67 
68    struct brw_codegen *p;
69    struct gen_device_info devinfo;
70 };
71 
validation_test()72 validation_test::validation_test()
73 {
74    p = rzalloc(NULL, struct brw_codegen);
75    memset(&devinfo, 0, sizeof(devinfo));
76 }
77 
~validation_test()78 validation_test::~validation_test()
79 {
80    ralloc_free(p);
81 }
82 
SetUp()83 void validation_test::SetUp()
84 {
85    struct gen_info info = GetParam();
86 
87    devinfo.gen           = info.gen;
88    devinfo.is_g4x        = info.subgen == IS_G45;
89    devinfo.is_baytrail   = info.subgen == IS_BYT;
90    devinfo.is_haswell    = info.subgen == IS_HSW;
91    devinfo.is_cherryview = info.subgen == IS_CHV;
92    devinfo.is_broxton    = info.subgen == IS_BXT;
93    devinfo.is_kabylake   = info.subgen == IS_KBL;
94    devinfo.is_geminilake = info.subgen == IS_GLK;
95    devinfo.is_coffeelake = info.subgen == IS_CFL;
96 
97    brw_init_codegen(&devinfo, p, p);
98 }
99 
100 struct gen_name {
101    template <class ParamType>
102    std::string
operator ()gen_name103    operator()(const ::testing::TestParamInfo<ParamType>& info) const {
104       return info.param.name;
105    }
106 };
107 
108 INSTANTIATE_TEST_CASE_P(eu_assembly, validation_test,
109                         ::testing::ValuesIn(gens),
110                         gen_name());
111 
112 static bool
validate(struct brw_codegen * p)113 validate(struct brw_codegen *p)
114 {
115    const bool print = getenv("TEST_DEBUG");
116    struct disasm_info *disasm = disasm_initialize(p->devinfo, NULL);
117 
118    if (print) {
119       disasm_new_inst_group(disasm, 0);
120       disasm_new_inst_group(disasm, p->next_insn_offset);
121    }
122 
123    bool ret = brw_validate_instructions(p->devinfo, p->store, 0,
124                                         p->next_insn_offset, disasm);
125 
126    if (print) {
127       dump_assembly(p->store, disasm);
128    }
129    ralloc_free(disasm);
130 
131    return ret;
132 }
133 
134 #define last_inst    (&p->store[p->nr_insn - 1])
135 #define g0           brw_vec8_grf(0, 0)
136 #define acc0         brw_acc_reg(8)
137 #define null         brw_null_reg()
138 #define zero         brw_imm_f(0.0f)
139 
140 static void
clear_instructions(struct brw_codegen * p)141 clear_instructions(struct brw_codegen *p)
142 {
143    p->next_insn_offset = 0;
144    p->nr_insn = 0;
145 }
146 
TEST_P(validation_test,sanity)147 TEST_P(validation_test, sanity)
148 {
149    brw_ADD(p, g0, g0, g0);
150 
151    EXPECT_TRUE(validate(p));
152 }
153 
TEST_P(validation_test,src0_null_reg)154 TEST_P(validation_test, src0_null_reg)
155 {
156    brw_MOV(p, g0, null);
157 
158    EXPECT_FALSE(validate(p));
159 }
160 
TEST_P(validation_test,src1_null_reg)161 TEST_P(validation_test, src1_null_reg)
162 {
163    brw_ADD(p, g0, g0, null);
164 
165    EXPECT_FALSE(validate(p));
166 }
167 
TEST_P(validation_test,math_src0_null_reg)168 TEST_P(validation_test, math_src0_null_reg)
169 {
170    if (devinfo.gen >= 6) {
171       gen6_math(p, g0, BRW_MATH_FUNCTION_SIN, null, null);
172    } else {
173       gen4_math(p, g0, BRW_MATH_FUNCTION_SIN, 0, null, BRW_MATH_PRECISION_FULL);
174    }
175 
176    EXPECT_FALSE(validate(p));
177 }
178 
TEST_P(validation_test,math_src1_null_reg)179 TEST_P(validation_test, math_src1_null_reg)
180 {
181    if (devinfo.gen >= 6) {
182       gen6_math(p, g0, BRW_MATH_FUNCTION_POW, g0, null);
183       EXPECT_FALSE(validate(p));
184    } else {
185       /* Math instructions on Gen4/5 are actually SEND messages with payloads.
186        * src1 is an immediate message descriptor set by gen4_math.
187        */
188    }
189 }
190 
TEST_P(validation_test,opcode46)191 TEST_P(validation_test, opcode46)
192 {
193    /* opcode 46 is "push" on Gen 4 and 5
194     *              "fork" on Gen 6
195     *              reserved on Gen 7
196     *              "goto" on Gen8+
197     */
198    brw_next_insn(p, 46);
199 
200    if (devinfo.gen == 7) {
201       EXPECT_FALSE(validate(p));
202    } else {
203       EXPECT_TRUE(validate(p));
204    }
205 }
206 
207 /* When the Execution Data Type is wider than the destination data type, the
208  * destination must [...] specify a HorzStride equal to the ratio in sizes of
209  * the two data types.
210  */
TEST_P(validation_test,dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size)211 TEST_P(validation_test, dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size)
212 {
213    brw_ADD(p, g0, g0, g0);
214    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
215    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
216    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
217 
218    EXPECT_FALSE(validate(p));
219 
220    clear_instructions(p);
221 
222    brw_ADD(p, g0, g0, g0);
223    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
224    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
225    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
226    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
227 
228    EXPECT_TRUE(validate(p));
229 }
230 
231 /* When the Execution Data Type is wider than the destination data type, the
232  * destination must be aligned as required by the wider execution data type
233  * [...]
234  */
TEST_P(validation_test,dst_subreg_must_be_aligned_to_exec_type_size)235 TEST_P(validation_test, dst_subreg_must_be_aligned_to_exec_type_size)
236 {
237    brw_ADD(p, g0, g0, g0);
238    brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 2);
239    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
240    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
241    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
242    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
243 
244    EXPECT_FALSE(validate(p));
245 
246    clear_instructions(p);
247 
248    brw_ADD(p, g0, g0, g0);
249    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
250    brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 8);
251    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
252    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
253    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
254    brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
255    brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
256    brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
257    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
258    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
259    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
260    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
261 
262    EXPECT_TRUE(validate(p));
263 }
264 
265 /* ExecSize must be greater than or equal to Width. */
TEST_P(validation_test,exec_size_less_than_width)266 TEST_P(validation_test, exec_size_less_than_width)
267 {
268    brw_ADD(p, g0, g0, g0);
269    brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_16);
270 
271    EXPECT_FALSE(validate(p));
272 
273    clear_instructions(p);
274 
275    brw_ADD(p, g0, g0, g0);
276    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_16);
277 
278    EXPECT_FALSE(validate(p));
279 }
280 
281 /* If ExecSize = Width and HorzStride ≠ 0,
282  * VertStride must be set to Width * HorzStride.
283  */
TEST_P(validation_test,vertical_stride_is_width_by_horizontal_stride)284 TEST_P(validation_test, vertical_stride_is_width_by_horizontal_stride)
285 {
286    brw_ADD(p, g0, g0, g0);
287    brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
288 
289    EXPECT_FALSE(validate(p));
290 
291    clear_instructions(p);
292 
293    brw_ADD(p, g0, g0, g0);
294    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
295 
296    EXPECT_FALSE(validate(p));
297 }
298 
299 /* If Width = 1, HorzStride must be 0 regardless of the values
300  * of ExecSize and VertStride.
301  */
TEST_P(validation_test,horizontal_stride_must_be_0_if_width_is_1)302 TEST_P(validation_test, horizontal_stride_must_be_0_if_width_is_1)
303 {
304    brw_ADD(p, g0, g0, g0);
305    brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
306    brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
307    brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
308 
309    EXPECT_FALSE(validate(p));
310 
311    clear_instructions(p);
312 
313    brw_ADD(p, g0, g0, g0);
314    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
315    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_1);
316    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
317 
318    EXPECT_FALSE(validate(p));
319 }
320 
321 /* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */
TEST_P(validation_test,scalar_region_must_be_0_1_0)322 TEST_P(validation_test, scalar_region_must_be_0_1_0)
323 {
324    struct brw_reg g0_0 = brw_vec1_grf(0, 0);
325 
326    brw_ADD(p, g0, g0, g0_0);
327    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_1);
328    brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_1);
329    brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
330    brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
331 
332    EXPECT_FALSE(validate(p));
333 
334    clear_instructions(p);
335 
336    brw_ADD(p, g0, g0_0, g0);
337    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_1);
338    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_1);
339    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_1);
340    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
341 
342    EXPECT_FALSE(validate(p));
343 }
344 
345 /* If VertStride = HorzStride = 0, Width must be 1 regardless of the value
346  * of ExecSize.
347  */
TEST_P(validation_test,zero_stride_implies_0_1_0)348 TEST_P(validation_test, zero_stride_implies_0_1_0)
349 {
350    brw_ADD(p, g0, g0, g0);
351    brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
352    brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_2);
353    brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
354 
355    EXPECT_FALSE(validate(p));
356 
357    clear_instructions(p);
358 
359    brw_ADD(p, g0, g0, g0);
360    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
361    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2);
362    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
363 
364    EXPECT_FALSE(validate(p));
365 }
366 
367 /* Dst.HorzStride must not be 0. */
TEST_P(validation_test,dst_horizontal_stride_0)368 TEST_P(validation_test, dst_horizontal_stride_0)
369 {
370    brw_ADD(p, g0, g0, g0);
371    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
372 
373    EXPECT_FALSE(validate(p));
374 
375    clear_instructions(p);
376 
377    brw_set_default_access_mode(p, BRW_ALIGN_16);
378 
379    brw_ADD(p, g0, g0, g0);
380    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
381 
382    EXPECT_FALSE(validate(p));
383 }
384 
385 /* VertStride must be used to cross BRW_GENERAL_REGISTER_FILE register boundaries. This rule implies
386  * that elements within a 'Width' cannot cross BRW_GENERAL_REGISTER_FILE boundaries.
387  */
TEST_P(validation_test,must_not_cross_grf_boundary_in_a_width)388 TEST_P(validation_test, must_not_cross_grf_boundary_in_a_width)
389 {
390    brw_ADD(p, g0, g0, g0);
391    brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 4);
392 
393    EXPECT_FALSE(validate(p));
394 
395    clear_instructions(p);
396 
397    brw_ADD(p, g0, g0, g0);
398    brw_inst_set_src1_da1_subreg_nr(&devinfo, last_inst, 4);
399 
400    EXPECT_FALSE(validate(p));
401 
402    clear_instructions(p);
403 
404    brw_ADD(p, g0, g0, g0);
405    brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
406    brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
407    brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
408 
409    EXPECT_FALSE(validate(p));
410 
411    clear_instructions(p);
412 
413    brw_ADD(p, g0, g0, g0);
414    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
415    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
416    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
417 
418    EXPECT_FALSE(validate(p));
419 }
420 
421 /* Destination Horizontal must be 1 in Align16 */
TEST_P(validation_test,dst_hstride_on_align16_must_be_1)422 TEST_P(validation_test, dst_hstride_on_align16_must_be_1)
423 {
424    brw_set_default_access_mode(p, BRW_ALIGN_16);
425 
426    brw_ADD(p, g0, g0, g0);
427    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
428 
429    EXPECT_FALSE(validate(p));
430 
431    clear_instructions(p);
432 
433    brw_ADD(p, g0, g0, g0);
434    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
435 
436    EXPECT_TRUE(validate(p));
437 }
438 
439 /* VertStride must be 0 or 4 in Align16 */
TEST_P(validation_test,vstride_on_align16_must_be_0_or_4)440 TEST_P(validation_test, vstride_on_align16_must_be_0_or_4)
441 {
442    const struct {
443       enum brw_vertical_stride vstride;
444       bool expected_result;
445    } vstride[] = {
446       { BRW_VERTICAL_STRIDE_0, true },
447       { BRW_VERTICAL_STRIDE_1, false },
448       { BRW_VERTICAL_STRIDE_2, devinfo.is_haswell || devinfo.gen >= 8 },
449       { BRW_VERTICAL_STRIDE_4, true },
450       { BRW_VERTICAL_STRIDE_8, false },
451       { BRW_VERTICAL_STRIDE_16, false },
452       { BRW_VERTICAL_STRIDE_32, false },
453       { BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL, false },
454    };
455 
456    brw_set_default_access_mode(p, BRW_ALIGN_16);
457 
458    for (unsigned i = 0; i < sizeof(vstride) / sizeof(vstride[0]); i++) {
459       brw_ADD(p, g0, g0, g0);
460       brw_inst_set_src0_vstride(&devinfo, last_inst, vstride[i].vstride);
461 
462       EXPECT_EQ(vstride[i].expected_result, validate(p));
463 
464       clear_instructions(p);
465    }
466 
467    for (unsigned i = 0; i < sizeof(vstride) / sizeof(vstride[0]); i++) {
468       brw_ADD(p, g0, g0, g0);
469       brw_inst_set_src1_vstride(&devinfo, last_inst, vstride[i].vstride);
470 
471       EXPECT_EQ(vstride[i].expected_result, validate(p));
472 
473       clear_instructions(p);
474    }
475 }
476 
477 /* In Direct Addressing mode, a source cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE
478  * registers.
479  */
TEST_P(validation_test,source_cannot_span_more_than_2_registers)480 TEST_P(validation_test, source_cannot_span_more_than_2_registers)
481 {
482    brw_ADD(p, g0, g0, g0);
483    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_32);
484    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
485    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
486    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
487    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
488    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8);
489    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
490 
491    EXPECT_FALSE(validate(p));
492 
493    clear_instructions(p);
494 
495    brw_ADD(p, g0, g0, g0);
496    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
497    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
498    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
499    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
500    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
501    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8);
502    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
503    brw_inst_set_src1_da1_subreg_nr(&devinfo, last_inst, 2);
504 
505    EXPECT_TRUE(validate(p));
506 
507    clear_instructions(p);
508 
509    brw_ADD(p, g0, g0, g0);
510    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
511 
512    EXPECT_TRUE(validate(p));
513 }
514 
515 /* A destination cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE registers. */
TEST_P(validation_test,destination_cannot_span_more_than_2_registers)516 TEST_P(validation_test, destination_cannot_span_more_than_2_registers)
517 {
518    brw_ADD(p, g0, g0, g0);
519    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_32);
520    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
521    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
522    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
523    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
524 
525    EXPECT_FALSE(validate(p));
526 
527    clear_instructions(p);
528 
529    brw_ADD(p, g0, g0, g0);
530    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_8);
531    brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 6);
532    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4);
533    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
534    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
535    brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
536    brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
537    brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
538    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
539    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
540    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
541    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
542 
543    EXPECT_TRUE(validate(p));
544 }
545 
TEST_P(validation_test,src_region_spans_two_regs_dst_region_spans_one)546 TEST_P(validation_test, src_region_spans_two_regs_dst_region_spans_one)
547 {
548    /* Writes to dest are to the lower OWord */
549    brw_ADD(p, g0, g0, g0);
550    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
551    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
552    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
553    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
554    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
555    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
556 
557    EXPECT_TRUE(validate(p));
558 
559    clear_instructions(p);
560 
561    /* Writes to dest are to the upper OWord */
562    brw_ADD(p, g0, g0, g0);
563    brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 16);
564    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
565    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
566    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
567    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
568    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
569    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
570 
571    EXPECT_TRUE(validate(p));
572 
573    clear_instructions(p);
574 
575    /* Writes to dest are evenly split between OWords */
576    brw_ADD(p, g0, g0, g0);
577    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
578    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
579    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
580    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
581    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
582    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8);
583    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
584 
585    EXPECT_TRUE(validate(p));
586 
587    clear_instructions(p);
588 
589    /* Writes to dest are uneven between OWords */
590    brw_ADD(p, g0, g0, g0);
591    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
592    brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 10);
593    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
594    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
595    brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
596    brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
597    brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
598    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
599    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
600    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2);
601    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
602 
603    if (devinfo.gen >= 9) {
604       EXPECT_TRUE(validate(p));
605    } else {
606       EXPECT_FALSE(validate(p));
607    }
608 }
609 
TEST_P(validation_test,dst_elements_must_be_evenly_split_between_registers)610 TEST_P(validation_test, dst_elements_must_be_evenly_split_between_registers)
611 {
612    brw_ADD(p, g0, g0, g0);
613    brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 4);
614 
615    if (devinfo.gen >= 9) {
616       EXPECT_TRUE(validate(p));
617    } else {
618       EXPECT_FALSE(validate(p));
619    }
620 
621    clear_instructions(p);
622 
623    brw_ADD(p, g0, g0, g0);
624    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
625 
626    EXPECT_TRUE(validate(p));
627 
628    clear_instructions(p);
629 
630    if (devinfo.gen >= 6) {
631       gen6_math(p, g0, BRW_MATH_FUNCTION_SIN, g0, null);
632 
633       EXPECT_TRUE(validate(p));
634 
635       clear_instructions(p);
636 
637       gen6_math(p, g0, BRW_MATH_FUNCTION_SIN, g0, null);
638       brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 4);
639 
640       EXPECT_FALSE(validate(p));
641    }
642 }
643 
TEST_P(validation_test,two_src_two_dst_source_offsets_must_be_same)644 TEST_P(validation_test, two_src_two_dst_source_offsets_must_be_same)
645 {
646    brw_ADD(p, g0, g0, g0);
647    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
648    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4);
649    brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 16);
650    brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_2);
651    brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
652    brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
653    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
654    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
655    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
656 
657    if (devinfo.gen <= 7) {
658       EXPECT_FALSE(validate(p));
659    } else {
660       EXPECT_TRUE(validate(p));
661    }
662 
663    clear_instructions(p);
664 
665    brw_ADD(p, g0, g0, g0);
666    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
667    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4);
668    brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
669    brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
670    brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
671    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_8);
672    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2);
673    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
674 
675    EXPECT_TRUE(validate(p));
676 }
677 
TEST_P(validation_test,two_src_two_dst_each_dst_must_be_derived_from_one_src)678 TEST_P(validation_test, two_src_two_dst_each_dst_must_be_derived_from_one_src)
679 {
680    brw_MOV(p, g0, g0);
681    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
682    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
683    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
684    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
685    brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 8);
686    brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
687    brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
688    brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
689 
690    if (devinfo.gen <= 7) {
691       EXPECT_FALSE(validate(p));
692    } else {
693       EXPECT_TRUE(validate(p));
694    }
695 
696    clear_instructions(p);
697 
698    brw_MOV(p, g0, g0);
699    brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 16);
700    brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 8);
701    brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_2);
702    brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_2);
703    brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
704 
705    if (devinfo.gen <= 7) {
706       EXPECT_FALSE(validate(p));
707    } else {
708       EXPECT_TRUE(validate(p));
709    }
710 }
711 
TEST_P(validation_test,one_src_two_dst)712 TEST_P(validation_test, one_src_two_dst)
713 {
714    struct brw_reg g0_0 = brw_vec1_grf(0, 0);
715 
716    brw_ADD(p, g0, g0_0, g0_0);
717    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
718 
719    EXPECT_TRUE(validate(p));
720 
721    clear_instructions(p);
722 
723    brw_ADD(p, g0, g0, g0);
724    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
725    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
726    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
727    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
728 
729    EXPECT_TRUE(validate(p));
730 
731    clear_instructions(p);
732 
733    brw_ADD(p, g0, g0, g0);
734    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
735    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
736    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
737    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
738    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
739    brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
740    brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_1);
741    brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
742 
743    if (devinfo.gen >= 8) {
744       EXPECT_TRUE(validate(p));
745    } else {
746       EXPECT_FALSE(validate(p));
747    }
748 
749    clear_instructions(p);
750 
751    brw_ADD(p, g0, g0, g0);
752    brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
753    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
754    brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
755    brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
756    brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
757    brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
758    brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
759    brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
760 
761    if (devinfo.gen >= 8) {
762       EXPECT_TRUE(validate(p));
763    } else {
764       EXPECT_FALSE(validate(p));
765    }
766 }
767 
TEST_P(validation_test,packed_byte_destination)768 TEST_P(validation_test, packed_byte_destination)
769 {
770    static const struct {
771       enum brw_reg_type dst_type;
772       enum brw_reg_type src_type;
773       bool neg, abs, sat;
774       bool expected_result;
775    } move[] = {
776       { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 0, 0, 0, true },
777       { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 0, 0, 0, true },
778       { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 0, 0, 0, true },
779       { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 0, 0, 0, true },
780 
781       { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 1, 0, 0, false },
782       { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 1, 0, 0, false },
783       { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 1, 0, 0, false },
784       { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 1, 0, 0, false },
785 
786       { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 0, 1, 0, false },
787       { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 0, 1, 0, false },
788       { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 0, 1, 0, false },
789       { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 0, 1, 0, false },
790 
791       { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 0, 0, 1, false },
792       { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 0, 0, 1, false },
793       { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 0, 0, 1, false },
794       { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 0, 0, 1, false },
795 
796       { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UW, 0, 0, 0, false },
797       { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_W , 0, 0, 0, false },
798       { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UD, 0, 0, 0, false },
799       { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_D , 0, 0, 0, false },
800    };
801 
802    for (unsigned i = 0; i < sizeof(move) / sizeof(move[0]); i++) {
803       brw_MOV(p, retype(g0, move[i].dst_type), retype(g0, move[i].src_type));
804       brw_inst_set_src0_negate(&devinfo, last_inst, move[i].neg);
805       brw_inst_set_src0_abs(&devinfo, last_inst, move[i].abs);
806       brw_inst_set_saturate(&devinfo, last_inst, move[i].sat);
807 
808       EXPECT_EQ(move[i].expected_result, validate(p));
809 
810       clear_instructions(p);
811    }
812 
813    brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_UB),
814               retype(g0, BRW_REGISTER_TYPE_UB),
815               retype(g0, BRW_REGISTER_TYPE_UB));
816    brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL);
817 
818    EXPECT_FALSE(validate(p));
819 
820    clear_instructions(p);
821 
822    brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_B),
823               retype(g0, BRW_REGISTER_TYPE_B),
824               retype(g0, BRW_REGISTER_TYPE_B));
825    brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL);
826 
827    EXPECT_FALSE(validate(p));
828 }
829 
TEST_P(validation_test,byte_destination_relaxed_alignment)830 TEST_P(validation_test, byte_destination_relaxed_alignment)
831 {
832    brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_B),
833               retype(g0, BRW_REGISTER_TYPE_W),
834               retype(g0, BRW_REGISTER_TYPE_W));
835    brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL);
836    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
837 
838    EXPECT_TRUE(validate(p));
839 
840    clear_instructions(p);
841 
842    brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_B),
843               retype(g0, BRW_REGISTER_TYPE_W),
844               retype(g0, BRW_REGISTER_TYPE_W));
845    brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL);
846    brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
847    brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 1);
848 
849    if (devinfo.gen > 4 || devinfo.is_g4x) {
850       EXPECT_TRUE(validate(p));
851    } else {
852       EXPECT_FALSE(validate(p));
853    }
854 }
855 
TEST_P(validation_test,vector_immediate_destination_alignment)856 TEST_P(validation_test, vector_immediate_destination_alignment)
857 {
858    static const struct {
859       enum brw_reg_type dst_type;
860       enum brw_reg_type src_type;
861       unsigned subnr;
862       unsigned exec_size;
863       bool expected_result;
864    } move[] = {
865       { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF,  0, BRW_EXECUTE_4, true  },
866       { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, 16, BRW_EXECUTE_4, true  },
867       { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF,  1, BRW_EXECUTE_4, false },
868 
869       { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V,   0, BRW_EXECUTE_8, true  },
870       { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V,  16, BRW_EXECUTE_8, true  },
871       { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V,   1, BRW_EXECUTE_8, false },
872 
873       { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV,  0, BRW_EXECUTE_8, true  },
874       { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, 16, BRW_EXECUTE_8, true  },
875       { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV,  1, BRW_EXECUTE_8, false },
876    };
877 
878    for (unsigned i = 0; i < sizeof(move) / sizeof(move[0]); i++) {
879       /* UV type is Gen6+ */
880       if (devinfo.gen < 6 &&
881           move[i].src_type == BRW_REGISTER_TYPE_UV)
882          continue;
883 
884       brw_MOV(p, retype(g0, move[i].dst_type), retype(zero, move[i].src_type));
885       brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, move[i].subnr);
886       brw_inst_set_exec_size(&devinfo, last_inst, move[i].exec_size);
887 
888       EXPECT_EQ(move[i].expected_result, validate(p));
889 
890       clear_instructions(p);
891    }
892 }
893 
TEST_P(validation_test,vector_immediate_destination_stride)894 TEST_P(validation_test, vector_immediate_destination_stride)
895 {
896    static const struct {
897       enum brw_reg_type dst_type;
898       enum brw_reg_type src_type;
899       unsigned stride;
900       bool expected_result;
901    } move[] = {
902       { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_1, true  },
903       { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, false },
904       { BRW_REGISTER_TYPE_D, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_1, true  },
905       { BRW_REGISTER_TYPE_D, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, false },
906       { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, true  },
907       { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_4, true  },
908 
909       { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V,  BRW_HORIZONTAL_STRIDE_1, true  },
910       { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V,  BRW_HORIZONTAL_STRIDE_2, false },
911       { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V,  BRW_HORIZONTAL_STRIDE_4, false },
912       { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_V,  BRW_HORIZONTAL_STRIDE_2, true  },
913 
914       { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_1, true  },
915       { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_2, false },
916       { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_4, false },
917       { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_2, true  },
918    };
919 
920    for (unsigned i = 0; i < sizeof(move) / sizeof(move[0]); i++) {
921       /* UV type is Gen6+ */
922       if (devinfo.gen < 6 &&
923           move[i].src_type == BRW_REGISTER_TYPE_UV)
924          continue;
925 
926       brw_MOV(p, retype(g0, move[i].dst_type), retype(zero, move[i].src_type));
927       brw_inst_set_dst_hstride(&devinfo, last_inst, move[i].stride);
928 
929       EXPECT_EQ(move[i].expected_result, validate(p));
930 
931       clear_instructions(p);
932    }
933 }
934 
TEST_P(validation_test,qword_low_power_align1_regioning_restrictions)935 TEST_P(validation_test, qword_low_power_align1_regioning_restrictions)
936 {
937    static const struct {
938       enum opcode opcode;
939       unsigned exec_size;
940 
941       enum brw_reg_type dst_type;
942       unsigned dst_subreg;
943       unsigned dst_stride;
944 
945       enum brw_reg_type src_type;
946       unsigned src_subreg;
947       unsigned src_vstride;
948       unsigned src_width;
949       unsigned src_hstride;
950 
951       bool expected_result;
952    } inst[] = {
953 #define INST(opcode, exec_size, dst_type, dst_subreg, dst_stride, src_type,    \
954              src_subreg, src_vstride, src_width, src_hstride, expected_result) \
955       {                                                                        \
956          BRW_OPCODE_##opcode,                                                  \
957          BRW_EXECUTE_##exec_size,                                              \
958          BRW_REGISTER_TYPE_##dst_type,                                         \
959          dst_subreg,                                                           \
960          BRW_HORIZONTAL_STRIDE_##dst_stride,                                   \
961          BRW_REGISTER_TYPE_##src_type,                                         \
962          src_subreg,                                                           \
963          BRW_VERTICAL_STRIDE_##src_vstride,                                    \
964          BRW_WIDTH_##src_width,                                                \
965          BRW_HORIZONTAL_STRIDE_##src_hstride,                                  \
966          expected_result,                                                      \
967       }
968 
969       /* Some instruction that violate no restrictions, as a control */
970       INST(MOV, 4, DF, 0, 1, DF, 0, 4, 4, 1, true ),
971       INST(MOV, 4, Q,  0, 1, Q,  0, 4, 4, 1, true ),
972       INST(MOV, 4, UQ, 0, 1, UQ, 0, 4, 4, 1, true ),
973 
974       INST(MOV, 4, DF, 0, 1, F,  0, 8, 4, 2, true ),
975       INST(MOV, 4, Q,  0, 1, D,  0, 8, 4, 2, true ),
976       INST(MOV, 4, UQ, 0, 1, UD, 0, 8, 4, 2, true ),
977 
978       INST(MOV, 4, F,  0, 2, DF, 0, 4, 4, 1, true ),
979       INST(MOV, 4, D,  0, 2, Q,  0, 4, 4, 1, true ),
980       INST(MOV, 4, UD, 0, 2, UQ, 0, 4, 4, 1, true ),
981 
982       INST(MUL, 8, D,  0, 2, D,  0, 8, 4, 2, true ),
983       INST(MUL, 8, UD, 0, 2, UD, 0, 8, 4, 2, true ),
984 
985       /* Something with subreg nrs */
986       INST(MOV, 2, DF, 8, 1, DF, 8, 2, 2, 1, true ),
987       INST(MOV, 2, Q,  8, 1, Q,  8, 2, 2, 1, true ),
988       INST(MOV, 2, UQ, 8, 1, UQ, 8, 2, 2, 1, true ),
989 
990       INST(MUL, 2, D,  4, 2, D,  4, 4, 2, 2, true ),
991       INST(MUL, 2, UD, 4, 2, UD, 4, 4, 2, 2, true ),
992 
993       /* The PRMs say that for CHV, BXT:
994        *
995        *    When source or destination datatype is 64b or operation is integer
996        *    DWord multiply, regioning in Align1 must follow these rules:
997        *
998        *    1. Source and Destination horizontal stride must be aligned to the
999        *       same qword.
1000        */
1001       INST(MOV, 4, DF, 0, 2, DF, 0, 4, 4, 1, false),
1002       INST(MOV, 4, Q,  0, 2, Q,  0, 4, 4, 1, false),
1003       INST(MOV, 4, UQ, 0, 2, UQ, 0, 4, 4, 1, false),
1004 
1005       INST(MOV, 4, DF, 0, 2, F,  0, 8, 4, 2, false),
1006       INST(MOV, 4, Q,  0, 2, D,  0, 8, 4, 2, false),
1007       INST(MOV, 4, UQ, 0, 2, UD, 0, 8, 4, 2, false),
1008 
1009       INST(MOV, 4, DF, 0, 2, F,  0, 4, 4, 1, false),
1010       INST(MOV, 4, Q,  0, 2, D,  0, 4, 4, 1, false),
1011       INST(MOV, 4, UQ, 0, 2, UD, 0, 4, 4, 1, false),
1012 
1013       INST(MUL, 4, D,  0, 2, D,  0, 4, 4, 1, false),
1014       INST(MUL, 4, UD, 0, 2, UD, 0, 4, 4, 1, false),
1015 
1016       INST(MUL, 4, D,  0, 1, D,  0, 8, 4, 2, false),
1017       INST(MUL, 4, UD, 0, 1, UD, 0, 8, 4, 2, false),
1018 
1019       /*    2. Regioning must ensure Src.Vstride = Src.Width * Src.Hstride. */
1020       INST(MOV, 4, DF, 0, 1, DF, 0, 0, 2, 1, false),
1021       INST(MOV, 4, Q,  0, 1, Q,  0, 0, 2, 1, false),
1022       INST(MOV, 4, UQ, 0, 1, UQ, 0, 0, 2, 1, false),
1023 
1024       INST(MOV, 4, DF, 0, 1, F,  0, 0, 2, 2, false),
1025       INST(MOV, 4, Q,  0, 1, D,  0, 0, 2, 2, false),
1026       INST(MOV, 4, UQ, 0, 1, UD, 0, 0, 2, 2, false),
1027 
1028       INST(MOV, 8, F,  0, 2, DF, 0, 0, 2, 1, false),
1029       INST(MOV, 8, D,  0, 2, Q,  0, 0, 2, 1, false),
1030       INST(MOV, 8, UD, 0, 2, UQ, 0, 0, 2, 1, false),
1031 
1032       INST(MUL, 8, D,  0, 2, D,  0, 0, 4, 2, false),
1033       INST(MUL, 8, UD, 0, 2, UD, 0, 0, 4, 2, false),
1034 
1035       INST(MUL, 8, D,  0, 2, D,  0, 0, 4, 2, false),
1036       INST(MUL, 8, UD, 0, 2, UD, 0, 0, 4, 2, false),
1037 
1038       /*    3. Source and Destination offset must be the same, except the case
1039        *       of scalar source.
1040        */
1041       INST(MOV, 2, DF, 8, 1, DF, 0, 2, 2, 1, false),
1042       INST(MOV, 2, Q,  8, 1, Q,  0, 2, 2, 1, false),
1043       INST(MOV, 2, UQ, 8, 1, UQ, 0, 2, 2, 1, false),
1044 
1045       INST(MOV, 2, DF, 0, 1, DF, 8, 2, 2, 1, false),
1046       INST(MOV, 2, Q,  0, 1, Q,  8, 2, 2, 1, false),
1047       INST(MOV, 2, UQ, 0, 1, UQ, 8, 2, 2, 1, false),
1048 
1049       INST(MUL, 4, D,  4, 2, D,  0, 4, 2, 2, false),
1050       INST(MUL, 4, UD, 4, 2, UD, 0, 4, 2, 2, false),
1051 
1052       INST(MUL, 4, D,  0, 2, D,  4, 4, 2, 2, false),
1053       INST(MUL, 4, UD, 0, 2, UD, 4, 4, 2, 2, false),
1054 
1055       INST(MOV, 2, DF, 8, 1, DF, 0, 0, 1, 0, true ),
1056       INST(MOV, 2, Q,  8, 1, Q,  0, 0, 1, 0, true ),
1057       INST(MOV, 2, UQ, 8, 1, UQ, 0, 0, 1, 0, true ),
1058 
1059       INST(MOV, 2, DF, 8, 1, F,  4, 0, 1, 0, true ),
1060       INST(MOV, 2, Q,  8, 1, D,  4, 0, 1, 0, true ),
1061       INST(MOV, 2, UQ, 8, 1, UD, 4, 0, 1, 0, true ),
1062 
1063       INST(MUL, 4, D,  4, 1, D,  0, 0, 1, 0, true ),
1064       INST(MUL, 4, UD, 4, 1, UD, 0, 0, 1, 0, true ),
1065 
1066       INST(MUL, 4, D,  0, 1, D,  4, 0, 1, 0, true ),
1067       INST(MUL, 4, UD, 0, 1, UD, 4, 0, 1, 0, true ),
1068 
1069 #undef INST
1070    };
1071 
1072    /* These restrictions only apply to Gen8+ */
1073    if (devinfo.gen < 8)
1074       return;
1075 
1076    for (unsigned i = 0; i < sizeof(inst) / sizeof(inst[0]); i++) {
1077       if (inst[i].opcode == BRW_OPCODE_MOV) {
1078          brw_MOV(p, retype(g0, inst[i].dst_type),
1079                     retype(g0, inst[i].src_type));
1080       } else {
1081          assert(inst[i].opcode == BRW_OPCODE_MUL);
1082          brw_MUL(p, retype(g0, inst[i].dst_type),
1083                     retype(g0, inst[i].src_type),
1084                     retype(zero, inst[i].src_type));
1085       }
1086       brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
1087 
1088       brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, inst[i].dst_subreg);
1089       brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, inst[i].src_subreg);
1090 
1091       brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1092 
1093       brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride);
1094       brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width);
1095       brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride);
1096 
1097       if (devinfo.is_cherryview || gen_device_info_is_9lp(&devinfo)) {
1098          EXPECT_EQ(inst[i].expected_result, validate(p));
1099       } else {
1100          EXPECT_TRUE(validate(p));
1101       }
1102 
1103       clear_instructions(p);
1104    }
1105 }
1106 
TEST_P(validation_test,qword_low_power_no_indirect_addressing)1107 TEST_P(validation_test, qword_low_power_no_indirect_addressing)
1108 {
1109    static const struct {
1110       enum opcode opcode;
1111       unsigned exec_size;
1112 
1113       enum brw_reg_type dst_type;
1114       bool dst_is_indirect;
1115       unsigned dst_stride;
1116 
1117       enum brw_reg_type src_type;
1118       bool src_is_indirect;
1119       unsigned src_vstride;
1120       unsigned src_width;
1121       unsigned src_hstride;
1122 
1123       bool expected_result;
1124    } inst[] = {
1125 #define INST(opcode, exec_size, dst_type, dst_is_indirect, dst_stride,         \
1126              src_type, src_is_indirect, src_vstride, src_width, src_hstride,   \
1127              expected_result)                                                  \
1128       {                                                                        \
1129          BRW_OPCODE_##opcode,                                                  \
1130          BRW_EXECUTE_##exec_size,                                              \
1131          BRW_REGISTER_TYPE_##dst_type,                                         \
1132          dst_is_indirect,                                                      \
1133          BRW_HORIZONTAL_STRIDE_##dst_stride,                                   \
1134          BRW_REGISTER_TYPE_##src_type,                                         \
1135          src_is_indirect,                                                      \
1136          BRW_VERTICAL_STRIDE_##src_vstride,                                    \
1137          BRW_WIDTH_##src_width,                                                \
1138          BRW_HORIZONTAL_STRIDE_##src_hstride,                                  \
1139          expected_result,                                                      \
1140       }
1141 
1142       /* Some instruction that violate no restrictions, as a control */
1143       INST(MOV, 4, DF, 0, 1, DF, 0, 4, 4, 1, true ),
1144       INST(MOV, 4, Q,  0, 1, Q,  0, 4, 4, 1, true ),
1145       INST(MOV, 4, UQ, 0, 1, UQ, 0, 4, 4, 1, true ),
1146 
1147       INST(MUL, 8, D,  0, 2, D,  0, 8, 4, 2, true ),
1148       INST(MUL, 8, UD, 0, 2, UD, 0, 8, 4, 2, true ),
1149 
1150       INST(MOV, 4, F,  1, 1, F,  0, 4, 4, 1, true ),
1151       INST(MOV, 4, F,  0, 1, F,  1, 4, 4, 1, true ),
1152       INST(MOV, 4, F,  1, 1, F,  1, 4, 4, 1, true ),
1153 
1154       /* The PRMs say that for CHV, BXT:
1155        *
1156        *    When source or destination datatype is 64b or operation is integer
1157        *    DWord multiply, indirect addressing must not be used.
1158        */
1159       INST(MOV, 4, DF, 1, 1, DF, 0, 4, 4, 1, false),
1160       INST(MOV, 4, Q,  1, 1, Q,  0, 4, 4, 1, false),
1161       INST(MOV, 4, UQ, 1, 1, UQ, 0, 4, 4, 1, false),
1162 
1163       INST(MOV, 4, DF, 0, 1, DF, 1, 4, 4, 1, false),
1164       INST(MOV, 4, Q,  0, 1, Q,  1, 4, 4, 1, false),
1165       INST(MOV, 4, UQ, 0, 1, UQ, 1, 4, 4, 1, false),
1166 
1167       INST(MOV, 4, DF, 1, 1, F,  0, 8, 4, 2, false),
1168       INST(MOV, 4, Q,  1, 1, D,  0, 8, 4, 2, false),
1169       INST(MOV, 4, UQ, 1, 1, UD, 0, 8, 4, 2, false),
1170 
1171       INST(MOV, 4, DF, 0, 1, F,  1, 8, 4, 2, false),
1172       INST(MOV, 4, Q,  0, 1, D,  1, 8, 4, 2, false),
1173       INST(MOV, 4, UQ, 0, 1, UD, 1, 8, 4, 2, false),
1174 
1175       INST(MOV, 4, F,  1, 2, DF, 0, 4, 4, 1, false),
1176       INST(MOV, 4, D,  1, 2, Q,  0, 4, 4, 1, false),
1177       INST(MOV, 4, UD, 1, 2, UQ, 0, 4, 4, 1, false),
1178 
1179       INST(MOV, 4, F,  0, 2, DF, 1, 4, 4, 1, false),
1180       INST(MOV, 4, D,  0, 2, Q,  1, 4, 4, 1, false),
1181       INST(MOV, 4, UD, 0, 2, UQ, 1, 4, 4, 1, false),
1182 
1183       INST(MUL, 8, D,  1, 2, D,  0, 8, 4, 2, false),
1184       INST(MUL, 8, UD, 1, 2, UD, 0, 8, 4, 2, false),
1185 
1186       INST(MUL, 8, D,  0, 2, D,  1, 8, 4, 2, false),
1187       INST(MUL, 8, UD, 0, 2, UD, 1, 8, 4, 2, false),
1188 
1189 #undef INST
1190    };
1191 
1192    /* These restrictions only apply to Gen8+ */
1193    if (devinfo.gen < 8)
1194       return;
1195 
1196    for (unsigned i = 0; i < sizeof(inst) / sizeof(inst[0]); i++) {
1197       if (inst[i].opcode == BRW_OPCODE_MOV) {
1198          brw_MOV(p, retype(g0, inst[i].dst_type),
1199                     retype(g0, inst[i].src_type));
1200       } else {
1201          assert(inst[i].opcode == BRW_OPCODE_MUL);
1202          brw_MUL(p, retype(g0, inst[i].dst_type),
1203                     retype(g0, inst[i].src_type),
1204                     retype(zero, inst[i].src_type));
1205       }
1206       brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
1207 
1208       brw_inst_set_dst_address_mode(&devinfo, last_inst, inst[i].dst_is_indirect);
1209       brw_inst_set_src0_address_mode(&devinfo, last_inst, inst[i].src_is_indirect);
1210 
1211       brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1212 
1213       brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride);
1214       brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width);
1215       brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride);
1216 
1217       if (devinfo.is_cherryview || gen_device_info_is_9lp(&devinfo)) {
1218          EXPECT_EQ(inst[i].expected_result, validate(p));
1219       } else {
1220          EXPECT_TRUE(validate(p));
1221       }
1222 
1223       clear_instructions(p);
1224    }
1225 }
1226 
TEST_P(validation_test,qword_low_power_no_64bit_arf)1227 TEST_P(validation_test, qword_low_power_no_64bit_arf)
1228 {
1229    static const struct {
1230       enum opcode opcode;
1231       unsigned exec_size;
1232 
1233       struct brw_reg dst;
1234       enum brw_reg_type dst_type;
1235       unsigned dst_stride;
1236 
1237       struct brw_reg src;
1238       enum brw_reg_type src_type;
1239       unsigned src_vstride;
1240       unsigned src_width;
1241       unsigned src_hstride;
1242 
1243       bool acc_wr;
1244       bool expected_result;
1245    } inst[] = {
1246 #define INST(opcode, exec_size, dst, dst_type, dst_stride,                     \
1247              src, src_type, src_vstride, src_width, src_hstride,               \
1248              acc_wr, expected_result)                                          \
1249       {                                                                        \
1250          BRW_OPCODE_##opcode,                                                  \
1251          BRW_EXECUTE_##exec_size,                                              \
1252          dst,                                                                  \
1253          BRW_REGISTER_TYPE_##dst_type,                                         \
1254          BRW_HORIZONTAL_STRIDE_##dst_stride,                                   \
1255          src,                                                                  \
1256          BRW_REGISTER_TYPE_##src_type,                                         \
1257          BRW_VERTICAL_STRIDE_##src_vstride,                                    \
1258          BRW_WIDTH_##src_width,                                                \
1259          BRW_HORIZONTAL_STRIDE_##src_hstride,                                  \
1260          acc_wr,                                                               \
1261          expected_result,                                                      \
1262       }
1263 
1264       /* Some instruction that violate no restrictions, as a control */
1265       INST(MOV, 4, g0,   DF, 1, g0,   F,  4, 2, 2, 0, true ),
1266       INST(MOV, 4, g0,   F,  2, g0,   DF, 4, 4, 1, 0, true ),
1267 
1268       INST(MOV, 4, g0,   Q,  1, g0,   D,  4, 2, 2, 0, true ),
1269       INST(MOV, 4, g0,   D,  2, g0,   Q,  4, 4, 1, 0, true ),
1270 
1271       INST(MOV, 4, g0,   UQ, 1, g0,   UD, 4, 2, 2, 0, true ),
1272       INST(MOV, 4, g0,   UD, 2, g0,   UQ, 4, 4, 1, 0, true ),
1273 
1274       INST(MOV, 4, null, F,  1, g0,   F,  4, 4, 1, 0, true ),
1275       INST(MOV, 4, acc0, F,  1, g0,   F,  4, 4, 1, 0, true ),
1276       INST(MOV, 4, g0,   F,  1, acc0, F,  4, 4, 1, 0, true ),
1277 
1278       INST(MOV, 4, null, D,  1, g0,   D,  4, 4, 1, 0, true ),
1279       INST(MOV, 4, acc0, D,  1, g0,   D,  4, 4, 1, 0, true ),
1280       INST(MOV, 4, g0,   D,  1, acc0, D,  4, 4, 1, 0, true ),
1281 
1282       INST(MOV, 4, null, UD, 1, g0,   UD, 4, 4, 1, 0, true ),
1283       INST(MOV, 4, acc0, UD, 1, g0,   UD, 4, 4, 1, 0, true ),
1284       INST(MOV, 4, g0,   UD, 1, acc0, UD, 4, 4, 1, 0, true ),
1285 
1286       INST(MUL, 4, g0,   D,  2, g0,   D,  4, 2, 2, 0, true ),
1287       INST(MUL, 4, g0,   UD, 2, g0,   UD, 4, 2, 2, 0, true ),
1288 
1289       /* The PRMs say that for CHV, BXT:
1290        *
1291        *    ARF registers must never be used with 64b datatype or when
1292        *    operation is integer DWord multiply.
1293        */
1294       INST(MOV, 4, acc0, DF, 1, g0,   F,  4, 2, 2, 0, false),
1295       INST(MOV, 4, g0,   DF, 1, acc0, F,  4, 2, 2, 0, false),
1296 
1297       INST(MOV, 4, acc0, Q,  1, g0,   D,  4, 2, 2, 0, false),
1298       INST(MOV, 4, g0,   Q,  1, acc0, D,  4, 2, 2, 0, false),
1299 
1300       INST(MOV, 4, acc0, UQ, 1, g0,   UD, 4, 2, 2, 0, false),
1301       INST(MOV, 4, g0,   UQ, 1, acc0, UD, 4, 2, 2, 0, false),
1302 
1303       INST(MOV, 4, acc0, F,  2, g0,   DF, 4, 4, 1, 0, false),
1304       INST(MOV, 4, g0,   F,  2, acc0, DF, 4, 4, 1, 0, false),
1305 
1306       INST(MOV, 4, acc0, D,  2, g0,   Q,  4, 4, 1, 0, false),
1307       INST(MOV, 4, g0,   D,  2, acc0, Q,  4, 4, 1, 0, false),
1308 
1309       INST(MOV, 4, acc0, UD, 2, g0,   UQ, 4, 4, 1, 0, false),
1310       INST(MOV, 4, g0,   UD, 2, acc0, UQ, 4, 4, 1, 0, false),
1311 
1312       INST(MUL, 4, acc0, D,  2, g0,   D,  4, 2, 2, 0, false),
1313       INST(MUL, 4, acc0, UD, 2, g0,   UD, 4, 2, 2, 0, false),
1314       /* MUL cannot have integer accumulator sources, so don't test that */
1315 
1316       /* We assume that the restriction does not apply to the null register */
1317       INST(MOV, 4, null, DF, 1, g0,   F,  4, 2, 2, 0, true ),
1318       INST(MOV, 4, null, Q,  1, g0,   D,  4, 2, 2, 0, true ),
1319       INST(MOV, 4, null, UQ, 1, g0,   UD, 4, 2, 2, 0, true ),
1320 
1321       /* Check implicit accumulator write control */
1322       INST(MOV, 4, null, DF, 1, g0,   F,  4, 2, 2, 1, false),
1323       INST(MUL, 4, null, DF, 1, g0,   F,  4, 2, 2, 1, false),
1324 
1325 #undef INST
1326    };
1327 
1328    /* These restrictions only apply to Gen8+ */
1329    if (devinfo.gen < 8)
1330       return;
1331 
1332    for (unsigned i = 0; i < sizeof(inst) / sizeof(inst[0]); i++) {
1333       if (inst[i].opcode == BRW_OPCODE_MOV) {
1334          brw_MOV(p, retype(inst[i].dst, inst[i].dst_type),
1335                     retype(inst[i].src, inst[i].src_type));
1336       } else {
1337          assert(inst[i].opcode == BRW_OPCODE_MUL);
1338          brw_MUL(p, retype(inst[i].dst, inst[i].dst_type),
1339                     retype(inst[i].src, inst[i].src_type),
1340                     retype(zero, inst[i].src_type));
1341          brw_inst_set_opcode(&devinfo, last_inst, inst[i].opcode);
1342       }
1343       brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
1344       brw_inst_set_acc_wr_control(&devinfo, last_inst, inst[i].acc_wr);
1345 
1346       brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1347 
1348       brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride);
1349       brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width);
1350       brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride);
1351 
1352       if (devinfo.is_cherryview || gen_device_info_is_9lp(&devinfo)) {
1353          EXPECT_EQ(inst[i].expected_result, validate(p));
1354       } else {
1355          EXPECT_TRUE(validate(p));
1356       }
1357 
1358       clear_instructions(p);
1359    }
1360 
1361    /* MAC implicitly reads the accumulator */
1362    brw_MAC(p, retype(g0, BRW_REGISTER_TYPE_DF),
1363               retype(stride(g0, 4, 4, 1), BRW_REGISTER_TYPE_DF),
1364               retype(stride(g0, 4, 4, 1), BRW_REGISTER_TYPE_DF));
1365    if (devinfo.is_cherryview || gen_device_info_is_9lp(&devinfo)) {
1366       EXPECT_FALSE(validate(p));
1367    } else {
1368       EXPECT_TRUE(validate(p));
1369    }
1370 }
1371 
TEST_P(validation_test,align16_64_bit_integer)1372 TEST_P(validation_test, align16_64_bit_integer)
1373 {
1374    static const struct {
1375       enum opcode opcode;
1376       unsigned exec_size;
1377 
1378       enum brw_reg_type dst_type;
1379       enum brw_reg_type src_type;
1380 
1381       bool expected_result;
1382    } inst[] = {
1383 #define INST(opcode, exec_size, dst_type, src_type, expected_result)           \
1384       {                                                                        \
1385          BRW_OPCODE_##opcode,                                                  \
1386          BRW_EXECUTE_##exec_size,                                              \
1387          BRW_REGISTER_TYPE_##dst_type,                                         \
1388          BRW_REGISTER_TYPE_##src_type,                                         \
1389          expected_result,                                                      \
1390       }
1391 
1392       /* Some instruction that violate no restrictions, as a control */
1393       INST(MOV, 2, Q,  D,  true ),
1394       INST(MOV, 2, UQ, UD, true ),
1395       INST(MOV, 2, DF, F,  true ),
1396 
1397       INST(ADD, 2, Q,  D,  true ),
1398       INST(ADD, 2, UQ, UD, true ),
1399       INST(ADD, 2, DF, F,  true ),
1400 
1401       /* The PRMs say that for BDW, SKL:
1402        *
1403        *    If Align16 is required for an operation with QW destination and non-QW
1404        *    source datatypes, the execution size cannot exceed 2.
1405        */
1406 
1407       INST(MOV, 4, Q,  D,  false),
1408       INST(MOV, 4, UQ, UD, false),
1409       INST(MOV, 4, DF, F,  false),
1410 
1411       INST(ADD, 4, Q,  D,  false),
1412       INST(ADD, 4, UQ, UD, false),
1413       INST(ADD, 4, DF, F,  false),
1414 
1415 #undef INST
1416    };
1417 
1418    /* 64-bit integer types exist on Gen8+ */
1419    if (devinfo.gen < 8)
1420       return;
1421 
1422    brw_set_default_access_mode(p, BRW_ALIGN_16);
1423 
1424    for (unsigned i = 0; i < sizeof(inst) / sizeof(inst[0]); i++) {
1425       if (inst[i].opcode == BRW_OPCODE_MOV) {
1426          brw_MOV(p, retype(g0, inst[i].dst_type),
1427                     retype(g0, inst[i].src_type));
1428       } else {
1429          assert(inst[i].opcode == BRW_OPCODE_ADD);
1430          brw_ADD(p, retype(g0, inst[i].dst_type),
1431                     retype(g0, inst[i].src_type),
1432                     retype(g0, inst[i].src_type));
1433       }
1434       brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
1435 
1436       EXPECT_EQ(inst[i].expected_result, validate(p));
1437 
1438       clear_instructions(p);
1439    }
1440 }
1441 
TEST_P(validation_test,qword_low_power_no_depctrl)1442 TEST_P(validation_test, qword_low_power_no_depctrl)
1443 {
1444    static const struct {
1445       enum opcode opcode;
1446       unsigned exec_size;
1447 
1448       enum brw_reg_type dst_type;
1449       unsigned dst_stride;
1450 
1451       enum brw_reg_type src_type;
1452       unsigned src_vstride;
1453       unsigned src_width;
1454       unsigned src_hstride;
1455 
1456       bool no_dd_check;
1457       bool no_dd_clear;
1458 
1459       bool expected_result;
1460    } inst[] = {
1461 #define INST(opcode, exec_size, dst_type, dst_stride,                          \
1462              src_type, src_vstride, src_width, src_hstride,                    \
1463              no_dd_check, no_dd_clear, expected_result)                        \
1464       {                                                                        \
1465          BRW_OPCODE_##opcode,                                                  \
1466          BRW_EXECUTE_##exec_size,                                              \
1467          BRW_REGISTER_TYPE_##dst_type,                                         \
1468          BRW_HORIZONTAL_STRIDE_##dst_stride,                                   \
1469          BRW_REGISTER_TYPE_##src_type,                                         \
1470          BRW_VERTICAL_STRIDE_##src_vstride,                                    \
1471          BRW_WIDTH_##src_width,                                                \
1472          BRW_HORIZONTAL_STRIDE_##src_hstride,                                  \
1473          no_dd_check,                                                          \
1474          no_dd_clear,                                                          \
1475          expected_result,                                                      \
1476       }
1477 
1478       /* Some instruction that violate no restrictions, as a control */
1479       INST(MOV, 4, DF, 1, F,  8, 4, 2, 0, 0, true ),
1480       INST(MOV, 4, Q,  1, D,  8, 4, 2, 0, 0, true ),
1481       INST(MOV, 4, UQ, 1, UD, 8, 4, 2, 0, 0, true ),
1482 
1483       INST(MOV, 4, F,  2, DF, 4, 4, 1, 0, 0, true ),
1484       INST(MOV, 4, D,  2, Q,  4, 4, 1, 0, 0, true ),
1485       INST(MOV, 4, UD, 2, UQ, 4, 4, 1, 0, 0, true ),
1486 
1487       INST(MUL, 8, D,  2, D,  8, 4, 2, 0, 0, true ),
1488       INST(MUL, 8, UD, 2, UD, 8, 4, 2, 0, 0, true ),
1489 
1490       INST(MOV, 4, F,  1, F,  4, 4, 1, 1, 1, true ),
1491 
1492       /* The PRMs say that for CHV, BXT:
1493        *
1494        *    When source or destination datatype is 64b or operation is integer
1495        *    DWord multiply, DepCtrl must not be used.
1496        */
1497       INST(MOV, 4, DF, 1, F,  8, 4, 2, 1, 0, false),
1498       INST(MOV, 4, Q,  1, D,  8, 4, 2, 1, 0, false),
1499       INST(MOV, 4, UQ, 1, UD, 8, 4, 2, 1, 0, false),
1500 
1501       INST(MOV, 4, F,  2, DF, 4, 4, 1, 1, 0, false),
1502       INST(MOV, 4, D,  2, Q,  4, 4, 1, 1, 0, false),
1503       INST(MOV, 4, UD, 2, UQ, 4, 4, 1, 1, 0, false),
1504 
1505       INST(MOV, 4, DF, 1, F,  8, 4, 2, 0, 1, false),
1506       INST(MOV, 4, Q,  1, D,  8, 4, 2, 0, 1, false),
1507       INST(MOV, 4, UQ, 1, UD, 8, 4, 2, 0, 1, false),
1508 
1509       INST(MOV, 4, F,  2, DF, 4, 4, 1, 0, 1, false),
1510       INST(MOV, 4, D,  2, Q,  4, 4, 1, 0, 1, false),
1511       INST(MOV, 4, UD, 2, UQ, 4, 4, 1, 0, 1, false),
1512 
1513       INST(MUL, 8, D,  2, D,  8, 4, 2, 1, 0, false),
1514       INST(MUL, 8, UD, 2, UD, 8, 4, 2, 1, 0, false),
1515 
1516       INST(MUL, 8, D,  2, D,  8, 4, 2, 0, 1, false),
1517       INST(MUL, 8, UD, 2, UD, 8, 4, 2, 0, 1, false),
1518 
1519 #undef INST
1520    };
1521 
1522    /* These restrictions only apply to Gen8+ */
1523    if (devinfo.gen < 8)
1524       return;
1525 
1526    for (unsigned i = 0; i < sizeof(inst) / sizeof(inst[0]); i++) {
1527       if (inst[i].opcode == BRW_OPCODE_MOV) {
1528          brw_MOV(p, retype(g0, inst[i].dst_type),
1529                     retype(g0, inst[i].src_type));
1530       } else {
1531          assert(inst[i].opcode == BRW_OPCODE_MUL);
1532          brw_MUL(p, retype(g0, inst[i].dst_type),
1533                     retype(g0, inst[i].src_type),
1534                     retype(zero, inst[i].src_type));
1535       }
1536       brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size);
1537 
1538       brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride);
1539 
1540       brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride);
1541       brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width);
1542       brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride);
1543 
1544       brw_inst_set_no_dd_check(&devinfo, last_inst, inst[i].no_dd_check);
1545       brw_inst_set_no_dd_clear(&devinfo, last_inst, inst[i].no_dd_clear);
1546 
1547       if (devinfo.is_cherryview || gen_device_info_is_9lp(&devinfo)) {
1548          EXPECT_EQ(inst[i].expected_result, validate(p));
1549       } else {
1550          EXPECT_TRUE(validate(p));
1551       }
1552 
1553       clear_instructions(p);
1554    }
1555 }
1556