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