i965: Add GLK, CFL, CNL to test_eu_validate.c
[mesa.git] / src / intel / compiler / test_eu_validate.cpp
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
72 validation_test::validation_test()
73 {
74 p = rzalloc(NULL, struct brw_codegen);
75 memset(&devinfo, 0, sizeof(devinfo));
76 }
77
78 validation_test::~validation_test()
79 {
80 ralloc_free(p);
81 }
82
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
103 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
113 validate(struct brw_codegen *p)
114 {
115 const bool print = getenv("TEST_DEBUG");
116 struct annotation_info annotation;
117 memset(&annotation, 0, sizeof(annotation));
118
119 if (print) {
120 annotation.mem_ctx = ralloc_context(NULL);
121 annotation.ann_count = 1;
122 annotation.ann_size = 2;
123 annotation.ann = rzalloc_array(annotation.mem_ctx, struct annotation,
124 annotation.ann_size);
125 annotation.ann[annotation.ann_count].offset = p->next_insn_offset;
126 }
127
128 bool ret = brw_validate_instructions(p->devinfo, p->store, 0,
129 p->next_insn_offset, &annotation);
130
131 if (print) {
132 dump_assembly(p->store, annotation.ann_count, annotation.ann, p->devinfo);
133 ralloc_free(annotation.mem_ctx);
134 }
135
136 return ret;
137 }
138
139 #define last_inst (&p->store[p->nr_insn - 1])
140 #define g0 brw_vec8_grf(0, 0)
141 #define null brw_null_reg()
142 #define zero brw_imm_f(0.0f)
143
144 static void
145 clear_instructions(struct brw_codegen *p)
146 {
147 p->next_insn_offset = 0;
148 p->nr_insn = 0;
149 }
150
151 TEST_P(validation_test, sanity)
152 {
153 brw_ADD(p, g0, g0, g0);
154
155 EXPECT_TRUE(validate(p));
156 }
157
158 TEST_P(validation_test, src0_null_reg)
159 {
160 brw_MOV(p, g0, null);
161
162 EXPECT_FALSE(validate(p));
163 }
164
165 TEST_P(validation_test, src1_null_reg)
166 {
167 brw_ADD(p, g0, g0, null);
168
169 EXPECT_FALSE(validate(p));
170 }
171
172 TEST_P(validation_test, math_src0_null_reg)
173 {
174 if (devinfo.gen >= 6) {
175 gen6_math(p, g0, BRW_MATH_FUNCTION_SIN, null, null);
176 } else {
177 gen4_math(p, g0, BRW_MATH_FUNCTION_SIN, 0, null, BRW_MATH_PRECISION_FULL);
178 }
179
180 EXPECT_FALSE(validate(p));
181 }
182
183 TEST_P(validation_test, math_src1_null_reg)
184 {
185 if (devinfo.gen >= 6) {
186 gen6_math(p, g0, BRW_MATH_FUNCTION_POW, g0, null);
187 EXPECT_FALSE(validate(p));
188 } else {
189 /* Math instructions on Gen4/5 are actually SEND messages with payloads.
190 * src1 is an immediate message descriptor set by gen4_math.
191 */
192 }
193 }
194
195 TEST_P(validation_test, opcode46)
196 {
197 /* opcode 46 is "push" on Gen 4 and 5
198 * "fork" on Gen 6
199 * reserved on Gen 7
200 * "goto" on Gen8+
201 */
202 brw_next_insn(p, 46);
203
204 if (devinfo.gen == 7) {
205 EXPECT_FALSE(validate(p));
206 } else {
207 EXPECT_TRUE(validate(p));
208 }
209 }
210
211 /* When the Execution Data Type is wider than the destination data type, the
212 * destination must [...] specify a HorzStride equal to the ratio in sizes of
213 * the two data types.
214 */
215 TEST_P(validation_test, dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size)
216 {
217 brw_ADD(p, g0, g0, g0);
218 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
219 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
220 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
221
222 EXPECT_FALSE(validate(p));
223
224 clear_instructions(p);
225
226 brw_ADD(p, g0, g0, g0);
227 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
228 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
229 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
230 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
231
232 EXPECT_TRUE(validate(p));
233 }
234
235 /* When the Execution Data Type is wider than the destination data type, the
236 * destination must be aligned as required by the wider execution data type
237 * [...]
238 */
239 TEST_P(validation_test, dst_subreg_must_be_aligned_to_exec_type_size)
240 {
241 brw_ADD(p, g0, g0, g0);
242 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 2);
243 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
244 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
245 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
246 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
247
248 EXPECT_FALSE(validate(p));
249
250 clear_instructions(p);
251
252 brw_ADD(p, g0, g0, g0);
253 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
254 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 8);
255 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
256 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
257 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
258 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
259 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
260 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
261 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
262 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
263 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
264 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
265
266 EXPECT_TRUE(validate(p));
267 }
268
269 /* ExecSize must be greater than or equal to Width. */
270 TEST_P(validation_test, exec_size_less_than_width)
271 {
272 brw_ADD(p, g0, g0, g0);
273 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_16);
274
275 EXPECT_FALSE(validate(p));
276
277 clear_instructions(p);
278
279 brw_ADD(p, g0, g0, g0);
280 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_16);
281
282 EXPECT_FALSE(validate(p));
283 }
284
285 /* If ExecSize = Width and HorzStride ≠ 0,
286 * VertStride must be set to Width * HorzStride.
287 */
288 TEST_P(validation_test, vertical_stride_is_width_by_horizontal_stride)
289 {
290 brw_ADD(p, g0, g0, g0);
291 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
292
293 EXPECT_FALSE(validate(p));
294
295 clear_instructions(p);
296
297 brw_ADD(p, g0, g0, g0);
298 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
299
300 EXPECT_FALSE(validate(p));
301 }
302
303 /* If Width = 1, HorzStride must be 0 regardless of the values
304 * of ExecSize and VertStride.
305 */
306 TEST_P(validation_test, horizontal_stride_must_be_0_if_width_is_1)
307 {
308 brw_ADD(p, g0, g0, g0);
309 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
310 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
311 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
312
313 EXPECT_FALSE(validate(p));
314
315 clear_instructions(p);
316
317 brw_ADD(p, g0, g0, g0);
318 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
319 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_1);
320 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
321
322 EXPECT_FALSE(validate(p));
323 }
324
325 /* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */
326 TEST_P(validation_test, scalar_region_must_be_0_1_0)
327 {
328 struct brw_reg g0_0 = brw_vec1_grf(0, 0);
329
330 brw_ADD(p, g0, g0, g0_0);
331 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_1);
332 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_1);
333 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
334 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
335
336 EXPECT_FALSE(validate(p));
337
338 clear_instructions(p);
339
340 brw_ADD(p, g0, g0_0, g0);
341 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_1);
342 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_1);
343 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_1);
344 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
345
346 EXPECT_FALSE(validate(p));
347 }
348
349 /* If VertStride = HorzStride = 0, Width must be 1 regardless of the value
350 * of ExecSize.
351 */
352 TEST_P(validation_test, zero_stride_implies_0_1_0)
353 {
354 brw_ADD(p, g0, g0, g0);
355 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
356 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_2);
357 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
358
359 EXPECT_FALSE(validate(p));
360
361 clear_instructions(p);
362
363 brw_ADD(p, g0, g0, g0);
364 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
365 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2);
366 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
367
368 EXPECT_FALSE(validate(p));
369 }
370
371 /* Dst.HorzStride must not be 0. */
372 TEST_P(validation_test, dst_horizontal_stride_0)
373 {
374 brw_ADD(p, g0, g0, g0);
375 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
376
377 EXPECT_FALSE(validate(p));
378
379 clear_instructions(p);
380
381 brw_set_default_access_mode(p, BRW_ALIGN_16);
382
383 brw_ADD(p, g0, g0, g0);
384 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
385
386 EXPECT_FALSE(validate(p));
387 }
388
389 /* VertStride must be used to cross BRW_GENERAL_REGISTER_FILE register boundaries. This rule implies
390 * that elements within a 'Width' cannot cross BRW_GENERAL_REGISTER_FILE boundaries.
391 */
392 TEST_P(validation_test, must_not_cross_grf_boundary_in_a_width)
393 {
394 brw_ADD(p, g0, g0, g0);
395 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 4);
396
397 EXPECT_FALSE(validate(p));
398
399 clear_instructions(p);
400
401 brw_ADD(p, g0, g0, g0);
402 brw_inst_set_src1_da1_subreg_nr(&devinfo, last_inst, 4);
403
404 EXPECT_FALSE(validate(p));
405
406 clear_instructions(p);
407
408 brw_ADD(p, g0, g0, g0);
409 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
410 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
411 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
412
413 EXPECT_FALSE(validate(p));
414
415 clear_instructions(p);
416
417 brw_ADD(p, g0, g0, g0);
418 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
419 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
420 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
421
422 EXPECT_FALSE(validate(p));
423 }
424
425 /* Destination Horizontal must be 1 in Align16 */
426 TEST_P(validation_test, dst_hstride_on_align16_must_be_1)
427 {
428 brw_set_default_access_mode(p, BRW_ALIGN_16);
429
430 brw_ADD(p, g0, g0, g0);
431 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
432
433 EXPECT_FALSE(validate(p));
434
435 clear_instructions(p);
436
437 brw_ADD(p, g0, g0, g0);
438 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
439
440 EXPECT_TRUE(validate(p));
441 }
442
443 /* VertStride must be 0 or 4 in Align16 */
444 TEST_P(validation_test, vstride_on_align16_must_be_0_or_4)
445 {
446 const struct {
447 enum brw_vertical_stride vstride;
448 bool expected_result;
449 } vstride[] = {
450 { BRW_VERTICAL_STRIDE_0, true },
451 { BRW_VERTICAL_STRIDE_1, false },
452 { BRW_VERTICAL_STRIDE_2, devinfo.is_haswell || devinfo.gen >= 8 },
453 { BRW_VERTICAL_STRIDE_4, true },
454 { BRW_VERTICAL_STRIDE_8, false },
455 { BRW_VERTICAL_STRIDE_16, false },
456 { BRW_VERTICAL_STRIDE_32, false },
457 { BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL, false },
458 };
459
460 brw_set_default_access_mode(p, BRW_ALIGN_16);
461
462 for (unsigned i = 0; i < sizeof(vstride) / sizeof(vstride[0]); i++) {
463 brw_ADD(p, g0, g0, g0);
464 brw_inst_set_src0_vstride(&devinfo, last_inst, vstride[i].vstride);
465
466 EXPECT_EQ(vstride[i].expected_result, validate(p));
467
468 clear_instructions(p);
469 }
470
471 for (unsigned i = 0; i < sizeof(vstride) / sizeof(vstride[0]); i++) {
472 brw_ADD(p, g0, g0, g0);
473 brw_inst_set_src1_vstride(&devinfo, last_inst, vstride[i].vstride);
474
475 EXPECT_EQ(vstride[i].expected_result, validate(p));
476
477 clear_instructions(p);
478 }
479 }
480
481 /* In Direct Addressing mode, a source cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE
482 * registers.
483 */
484 TEST_P(validation_test, source_cannot_span_more_than_2_registers)
485 {
486 brw_ADD(p, g0, g0, g0);
487 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_32);
488 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
489 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
490 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
491 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
492 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8);
493 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
494
495 EXPECT_FALSE(validate(p));
496
497 clear_instructions(p);
498
499 brw_ADD(p, g0, g0, g0);
500 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
501 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
502 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
503 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
504 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
505 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8);
506 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
507 brw_inst_set_src1_da1_subreg_nr(&devinfo, last_inst, 2);
508
509 EXPECT_TRUE(validate(p));
510
511 clear_instructions(p);
512
513 brw_ADD(p, g0, g0, g0);
514 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
515
516 EXPECT_TRUE(validate(p));
517 }
518
519 /* A destination cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE registers. */
520 TEST_P(validation_test, destination_cannot_span_more_than_2_registers)
521 {
522 brw_ADD(p, g0, g0, g0);
523 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_32);
524 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
525 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
526 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
527 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
528
529 EXPECT_FALSE(validate(p));
530
531 clear_instructions(p);
532
533 brw_ADD(p, g0, g0, g0);
534 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_8);
535 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 6);
536 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4);
537 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
538 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
539 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
540 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
541 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
542 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
543 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
544 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
545 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
546
547 EXPECT_TRUE(validate(p));
548 }
549
550 TEST_P(validation_test, src_region_spans_two_regs_dst_region_spans_one)
551 {
552 /* Writes to dest are to the lower OWord */
553 brw_ADD(p, g0, g0, g0);
554 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
555 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
556 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
557 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
558 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
559 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
560
561 EXPECT_TRUE(validate(p));
562
563 clear_instructions(p);
564
565 /* Writes to dest are to the upper OWord */
566 brw_ADD(p, g0, g0, g0);
567 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 16);
568 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
569 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
570 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
571 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
572 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
573 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
574
575 EXPECT_TRUE(validate(p));
576
577 clear_instructions(p);
578
579 /* Writes to dest are evenly split between OWords */
580 brw_ADD(p, g0, g0, g0);
581 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
582 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
583 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
584 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
585 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
586 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8);
587 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
588
589 EXPECT_TRUE(validate(p));
590
591 clear_instructions(p);
592
593 /* Writes to dest are uneven between OWords */
594 brw_ADD(p, g0, g0, g0);
595 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
596 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 10);
597 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
598 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
599 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
600 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
601 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
602 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
603 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16);
604 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2);
605 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
606
607 if (devinfo.gen >= 9) {
608 EXPECT_TRUE(validate(p));
609 } else {
610 EXPECT_FALSE(validate(p));
611 }
612 }
613
614 TEST_P(validation_test, dst_elements_must_be_evenly_split_between_registers)
615 {
616 brw_ADD(p, g0, g0, g0);
617 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 4);
618
619 if (devinfo.gen >= 9) {
620 EXPECT_TRUE(validate(p));
621 } else {
622 EXPECT_FALSE(validate(p));
623 }
624
625 clear_instructions(p);
626
627 brw_ADD(p, g0, g0, g0);
628 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
629
630 EXPECT_TRUE(validate(p));
631
632 clear_instructions(p);
633
634 if (devinfo.gen >= 6) {
635 gen6_math(p, g0, BRW_MATH_FUNCTION_SIN, g0, null);
636
637 EXPECT_TRUE(validate(p));
638
639 clear_instructions(p);
640
641 gen6_math(p, g0, BRW_MATH_FUNCTION_SIN, g0, null);
642 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 4);
643
644 EXPECT_FALSE(validate(p));
645 }
646 }
647
648 TEST_P(validation_test, two_src_two_dst_source_offsets_must_be_same)
649 {
650 brw_ADD(p, g0, g0, g0);
651 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
652 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4);
653 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 16);
654 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_2);
655 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
656 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
657 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
658 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
659 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
660
661 if (devinfo.gen <= 7) {
662 EXPECT_FALSE(validate(p));
663 } else {
664 EXPECT_TRUE(validate(p));
665 }
666
667 clear_instructions(p);
668
669 brw_ADD(p, g0, g0, g0);
670 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4);
671 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4);
672 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
673 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
674 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
675 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_8);
676 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2);
677 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
678
679 EXPECT_TRUE(validate(p));
680 }
681
682 #if 0
683 TEST_P(validation_test, two_src_two_dst_each_dst_must_be_derived_from_one_src)
684 {
685 // mov (16) r10.0<2>:w r12.4<4;4,1>:w
686
687 brw_MOV(p, g0, g0);
688 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
689 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
690 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
691 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
692 brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 8);
693 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
694 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4);
695 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4);
696
697 EXPECT_FALSE(validate(p));
698
699 clear_instructions(p);
700
701 #if 0
702 brw_ADD(p, g0, g0, g0);
703 brw_inst_set_src1_da1_subreg_nr(&devinfo, last_inst, 16);
704 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4);
705 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4);
706 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1);
707
708 EXPECT_FALSE(validate(p));
709 #endif
710 }
711 #endif
712
713 TEST_P(validation_test, one_src_two_dst)
714 {
715 struct brw_reg g0_0 = brw_vec1_grf(0, 0);
716
717 brw_ADD(p, g0, g0_0, g0_0);
718 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
719
720 EXPECT_TRUE(validate(p));
721
722 clear_instructions(p);
723
724 brw_ADD(p, g0, g0, g0);
725 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
726 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D);
727 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
728 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
729
730 EXPECT_TRUE(validate(p));
731
732 clear_instructions(p);
733
734 brw_ADD(p, g0, g0, g0);
735 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
736 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
737 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
738 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
739 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
740 brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
741 brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_1);
742 brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
743
744 if (devinfo.gen >= 8) {
745 EXPECT_TRUE(validate(p));
746 } else {
747 EXPECT_FALSE(validate(p));
748 }
749
750 clear_instructions(p);
751
752 brw_ADD(p, g0, g0, g0);
753 brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16);
754 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
755 brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
756 brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
757 brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0);
758 brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1);
759 brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0);
760 brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W);
761
762 if (devinfo.gen >= 8) {
763 EXPECT_TRUE(validate(p));
764 } else {
765 EXPECT_FALSE(validate(p));
766 }
767 }
768
769 TEST_P(validation_test, packed_byte_destination)
770 {
771 static const struct {
772 enum brw_reg_type dst_type;
773 enum brw_reg_type src_type;
774 bool neg, abs, sat;
775 bool expected_result;
776 } move[] = {
777 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 0, 0, 0, true },
778 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 0, 0, 0, true },
779 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 0, 0, 0, true },
780 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 0, 0, 0, true },
781
782 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 1, 0, 0, false },
783 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 1, 0, 0, false },
784 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 1, 0, 0, false },
785 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 1, 0, 0, false },
786
787 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 0, 1, 0, false },
788 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 0, 1, 0, false },
789 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 0, 1, 0, false },
790 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 0, 1, 0, false },
791
792 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 0, 0, 1, false },
793 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 0, 0, 1, false },
794 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 0, 0, 1, false },
795 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 0, 0, 1, false },
796
797 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UW, 0, 0, 0, false },
798 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_W , 0, 0, 0, false },
799 { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UD, 0, 0, 0, false },
800 { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_D , 0, 0, 0, false },
801 };
802
803 for (unsigned i = 0; i < sizeof(move) / sizeof(move[0]); i++) {
804 brw_MOV(p, retype(g0, move[i].dst_type), retype(g0, move[i].src_type));
805 brw_inst_set_src0_negate(&devinfo, last_inst, move[i].neg);
806 brw_inst_set_src0_abs(&devinfo, last_inst, move[i].abs);
807 brw_inst_set_saturate(&devinfo, last_inst, move[i].sat);
808
809 EXPECT_EQ(move[i].expected_result, validate(p));
810
811 clear_instructions(p);
812 }
813
814 brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_UB),
815 retype(g0, BRW_REGISTER_TYPE_UB),
816 retype(g0, BRW_REGISTER_TYPE_UB));
817 brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL);
818
819 EXPECT_FALSE(validate(p));
820
821 clear_instructions(p);
822
823 brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_B),
824 retype(g0, BRW_REGISTER_TYPE_B),
825 retype(g0, BRW_REGISTER_TYPE_B));
826 brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL);
827
828 EXPECT_FALSE(validate(p));
829 }
830
831 TEST_P(validation_test, byte_destination_relaxed_alignment)
832 {
833 brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_B),
834 retype(g0, BRW_REGISTER_TYPE_W),
835 retype(g0, BRW_REGISTER_TYPE_W));
836 brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL);
837 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
838
839 EXPECT_TRUE(validate(p));
840
841 clear_instructions(p);
842
843 brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_B),
844 retype(g0, BRW_REGISTER_TYPE_W),
845 retype(g0, BRW_REGISTER_TYPE_W));
846 brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL);
847 brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2);
848 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 1);
849
850 if (devinfo.gen > 4 || devinfo.is_g4x) {
851 EXPECT_TRUE(validate(p));
852 } else {
853 EXPECT_FALSE(validate(p));
854 }
855 }
856
857 TEST_P(validation_test, vector_immediate_destination_alignment)
858 {
859 static const struct {
860 enum brw_reg_type dst_type;
861 enum brw_reg_type src_type;
862 unsigned subnr;
863 unsigned exec_size;
864 bool expected_result;
865 } move[] = {
866 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, 0, BRW_EXECUTE_4, true },
867 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, 16, BRW_EXECUTE_4, true },
868 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, 1, BRW_EXECUTE_4, false },
869
870 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, 0, BRW_EXECUTE_8, true },
871 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, 16, BRW_EXECUTE_8, true },
872 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, 1, BRW_EXECUTE_8, false },
873
874 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, 0, BRW_EXECUTE_8, true },
875 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, 16, BRW_EXECUTE_8, true },
876 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, 1, BRW_EXECUTE_8, false },
877 };
878
879 for (unsigned i = 0; i < sizeof(move) / sizeof(move[0]); i++) {
880 /* UV type is Gen6+ */
881 if (devinfo.gen < 6 &&
882 move[i].src_type == BRW_REGISTER_TYPE_UV)
883 continue;
884
885 brw_MOV(p, retype(g0, move[i].dst_type), retype(zero, move[i].src_type));
886 brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, move[i].subnr);
887 brw_inst_set_exec_size(&devinfo, last_inst, move[i].exec_size);
888
889 EXPECT_EQ(move[i].expected_result, validate(p));
890
891 clear_instructions(p);
892 }
893 }
894
895 TEST_P(validation_test, vector_immediate_destination_stride)
896 {
897 static const struct {
898 enum brw_reg_type dst_type;
899 enum brw_reg_type src_type;
900 unsigned stride;
901 bool expected_result;
902 } move[] = {
903 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_1, true },
904 { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, false },
905 { BRW_REGISTER_TYPE_D, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_1, true },
906 { BRW_REGISTER_TYPE_D, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, false },
907 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, true },
908 { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_4, true },
909
910 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_1, true },
911 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_2, false },
912 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_4, false },
913 { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_2, true },
914
915 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_1, true },
916 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_2, false },
917 { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_4, false },
918 { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_2, true },
919 };
920
921 for (unsigned i = 0; i < sizeof(move) / sizeof(move[0]); i++) {
922 /* UV type is Gen6+ */
923 if (devinfo.gen < 6 &&
924 move[i].src_type == BRW_REGISTER_TYPE_UV)
925 continue;
926
927 brw_MOV(p, retype(g0, move[i].dst_type), retype(zero, move[i].src_type));
928 brw_inst_set_dst_hstride(&devinfo, last_inst, move[i].stride);
929
930 EXPECT_EQ(move[i].expected_result, validate(p));
931
932 clear_instructions(p);
933 }
934 }