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