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