101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2016 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2101e04c3fSmrg * IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg#include <gtest/gtest.h> 2501e04c3fSmrg#include "brw_eu.h" 267ec681f3Smrg#include "brw_eu_defines.h" 277ec681f3Smrg#include "util/bitset.h" 2801e04c3fSmrg#include "util/ralloc.h" 2901e04c3fSmrg 307ec681f3Smrgstatic const struct intel_gfx_info { 3101e04c3fSmrg const char *name; 327ec681f3Smrg} gfx_names[] = { 3301e04c3fSmrg { "brw", }, 3401e04c3fSmrg { "g4x", }, 3501e04c3fSmrg { "ilk", }, 3601e04c3fSmrg { "snb", }, 3701e04c3fSmrg { "ivb", }, 3801e04c3fSmrg { "byt", }, 3901e04c3fSmrg { "hsw", }, 4001e04c3fSmrg { "bdw", }, 4101e04c3fSmrg { "chv", }, 4201e04c3fSmrg { "skl", }, 4301e04c3fSmrg { "bxt", }, 4401e04c3fSmrg { "kbl", }, 4501e04c3fSmrg { "aml", }, 4601e04c3fSmrg { "glk", }, 4701e04c3fSmrg { "cfl", }, 4801e04c3fSmrg { "whl", }, 4901e04c3fSmrg { "icl", }, 507ec681f3Smrg { "tgl", }, 5101e04c3fSmrg}; 5201e04c3fSmrg 537ec681f3Smrgclass validation_test: public ::testing::TestWithParam<struct intel_gfx_info> { 5401e04c3fSmrg virtual void SetUp(); 5501e04c3fSmrg 5601e04c3fSmrgpublic: 5701e04c3fSmrg validation_test(); 5801e04c3fSmrg virtual ~validation_test(); 5901e04c3fSmrg 6001e04c3fSmrg struct brw_codegen *p; 617ec681f3Smrg struct intel_device_info devinfo; 6201e04c3fSmrg}; 6301e04c3fSmrg 6401e04c3fSmrgvalidation_test::validation_test() 6501e04c3fSmrg{ 6601e04c3fSmrg p = rzalloc(NULL, struct brw_codegen); 6701e04c3fSmrg memset(&devinfo, 0, sizeof(devinfo)); 6801e04c3fSmrg} 6901e04c3fSmrg 7001e04c3fSmrgvalidation_test::~validation_test() 7101e04c3fSmrg{ 7201e04c3fSmrg ralloc_free(p); 7301e04c3fSmrg} 7401e04c3fSmrg 7501e04c3fSmrgvoid validation_test::SetUp() 7601e04c3fSmrg{ 777ec681f3Smrg struct intel_gfx_info info = GetParam(); 787ec681f3Smrg int devid = intel_device_name_to_pci_device_id(info.name); 7901e04c3fSmrg 807ec681f3Smrg intel_get_device_info_from_pci_id(devid, &devinfo); 8101e04c3fSmrg 8201e04c3fSmrg brw_init_codegen(&devinfo, p, p); 8301e04c3fSmrg} 8401e04c3fSmrg 857ec681f3Smrgstruct gfx_name { 8601e04c3fSmrg template <class ParamType> 8701e04c3fSmrg std::string 8801e04c3fSmrg operator()(const ::testing::TestParamInfo<ParamType>& info) const { 8901e04c3fSmrg return info.param.name; 9001e04c3fSmrg } 9101e04c3fSmrg}; 9201e04c3fSmrg 9301e04c3fSmrgINSTANTIATE_TEST_CASE_P(eu_assembly, validation_test, 947ec681f3Smrg ::testing::ValuesIn(gfx_names), 957ec681f3Smrg gfx_name()); 9601e04c3fSmrg 9701e04c3fSmrgstatic bool 9801e04c3fSmrgvalidate(struct brw_codegen *p) 9901e04c3fSmrg{ 10001e04c3fSmrg const bool print = getenv("TEST_DEBUG"); 10101e04c3fSmrg struct disasm_info *disasm = disasm_initialize(p->devinfo, NULL); 10201e04c3fSmrg 10301e04c3fSmrg if (print) { 10401e04c3fSmrg disasm_new_inst_group(disasm, 0); 10501e04c3fSmrg disasm_new_inst_group(disasm, p->next_insn_offset); 10601e04c3fSmrg } 10701e04c3fSmrg 10801e04c3fSmrg bool ret = brw_validate_instructions(p->devinfo, p->store, 0, 10901e04c3fSmrg p->next_insn_offset, disasm); 11001e04c3fSmrg 11101e04c3fSmrg if (print) { 1127ec681f3Smrg dump_assembly(p->store, 0, p->next_insn_offset, disasm, NULL); 11301e04c3fSmrg } 11401e04c3fSmrg ralloc_free(disasm); 11501e04c3fSmrg 11601e04c3fSmrg return ret; 11701e04c3fSmrg} 11801e04c3fSmrg 11901e04c3fSmrg#define last_inst (&p->store[p->nr_insn - 1]) 12001e04c3fSmrg#define g0 brw_vec8_grf(0, 0) 12101e04c3fSmrg#define acc0 brw_acc_reg(8) 12201e04c3fSmrg#define null brw_null_reg() 12301e04c3fSmrg#define zero brw_imm_f(0.0f) 12401e04c3fSmrg 12501e04c3fSmrgstatic void 12601e04c3fSmrgclear_instructions(struct brw_codegen *p) 12701e04c3fSmrg{ 12801e04c3fSmrg p->next_insn_offset = 0; 12901e04c3fSmrg p->nr_insn = 0; 13001e04c3fSmrg} 13101e04c3fSmrg 13201e04c3fSmrgTEST_P(validation_test, sanity) 13301e04c3fSmrg{ 13401e04c3fSmrg brw_ADD(p, g0, g0, g0); 13501e04c3fSmrg 13601e04c3fSmrg EXPECT_TRUE(validate(p)); 13701e04c3fSmrg} 13801e04c3fSmrg 13901e04c3fSmrgTEST_P(validation_test, src0_null_reg) 14001e04c3fSmrg{ 14101e04c3fSmrg brw_MOV(p, g0, null); 14201e04c3fSmrg 14301e04c3fSmrg EXPECT_FALSE(validate(p)); 14401e04c3fSmrg} 14501e04c3fSmrg 14601e04c3fSmrgTEST_P(validation_test, src1_null_reg) 14701e04c3fSmrg{ 14801e04c3fSmrg brw_ADD(p, g0, g0, null); 14901e04c3fSmrg 15001e04c3fSmrg EXPECT_FALSE(validate(p)); 15101e04c3fSmrg} 15201e04c3fSmrg 15301e04c3fSmrgTEST_P(validation_test, math_src0_null_reg) 15401e04c3fSmrg{ 1557ec681f3Smrg if (devinfo.ver >= 6) { 1567ec681f3Smrg gfx6_math(p, g0, BRW_MATH_FUNCTION_SIN, null, null); 15701e04c3fSmrg } else { 1587ec681f3Smrg gfx4_math(p, g0, BRW_MATH_FUNCTION_SIN, 0, null, BRW_MATH_PRECISION_FULL); 15901e04c3fSmrg } 16001e04c3fSmrg 16101e04c3fSmrg EXPECT_FALSE(validate(p)); 16201e04c3fSmrg} 16301e04c3fSmrg 16401e04c3fSmrgTEST_P(validation_test, math_src1_null_reg) 16501e04c3fSmrg{ 1667ec681f3Smrg if (devinfo.ver >= 6) { 1677ec681f3Smrg gfx6_math(p, g0, BRW_MATH_FUNCTION_POW, g0, null); 16801e04c3fSmrg EXPECT_FALSE(validate(p)); 16901e04c3fSmrg } else { 1707ec681f3Smrg /* Math instructions on Gfx4/5 are actually SEND messages with payloads. 1717ec681f3Smrg * src1 is an immediate message descriptor set by gfx4_math. 17201e04c3fSmrg */ 17301e04c3fSmrg } 17401e04c3fSmrg} 17501e04c3fSmrg 17601e04c3fSmrgTEST_P(validation_test, opcode46) 17701e04c3fSmrg{ 17801e04c3fSmrg /* opcode 46 is "push" on Gen 4 and 5 17901e04c3fSmrg * "fork" on Gen 6 18001e04c3fSmrg * reserved on Gen 7 1817ec681f3Smrg * "goto" on Gfx8+ 18201e04c3fSmrg */ 1837ec681f3Smrg brw_next_insn(p, brw_opcode_decode(&devinfo, 46)); 18401e04c3fSmrg 1857ec681f3Smrg if (devinfo.ver == 7) { 18601e04c3fSmrg EXPECT_FALSE(validate(p)); 18701e04c3fSmrg } else { 18801e04c3fSmrg EXPECT_TRUE(validate(p)); 18901e04c3fSmrg } 19001e04c3fSmrg} 19101e04c3fSmrg 1927ec681f3SmrgTEST_P(validation_test, invalid_exec_size_encoding) 1937ec681f3Smrg{ 1947ec681f3Smrg const struct { 1957ec681f3Smrg enum brw_execution_size exec_size; 1967ec681f3Smrg bool expected_result; 1977ec681f3Smrg } test_case[] = { 1987ec681f3Smrg { BRW_EXECUTE_1, true }, 1997ec681f3Smrg { BRW_EXECUTE_2, true }, 2007ec681f3Smrg { BRW_EXECUTE_4, true }, 2017ec681f3Smrg { BRW_EXECUTE_8, true }, 2027ec681f3Smrg { BRW_EXECUTE_16, true }, 2037ec681f3Smrg { BRW_EXECUTE_32, true }, 2047ec681f3Smrg 2057ec681f3Smrg { (enum brw_execution_size)((int)BRW_EXECUTE_32 + 1), false }, 2067ec681f3Smrg { (enum brw_execution_size)((int)BRW_EXECUTE_32 + 2), false }, 2077ec681f3Smrg }; 2087ec681f3Smrg 2097ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(test_case); i++) { 2107ec681f3Smrg brw_MOV(p, g0, g0); 2117ec681f3Smrg 2127ec681f3Smrg brw_inst_set_exec_size(&devinfo, last_inst, test_case[i].exec_size); 2137ec681f3Smrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 2147ec681f3Smrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 2157ec681f3Smrg 2167ec681f3Smrg if (test_case[i].exec_size == BRW_EXECUTE_1) { 2177ec681f3Smrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0); 2187ec681f3Smrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1); 2197ec681f3Smrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0); 2207ec681f3Smrg } else { 2217ec681f3Smrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_2); 2227ec681f3Smrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_2); 2237ec681f3Smrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 2247ec681f3Smrg } 2257ec681f3Smrg 2267ec681f3Smrg EXPECT_EQ(test_case[i].expected_result, validate(p)); 2277ec681f3Smrg 2287ec681f3Smrg clear_instructions(p); 2297ec681f3Smrg } 2307ec681f3Smrg} 2317ec681f3Smrg 2327ec681f3SmrgTEST_P(validation_test, invalid_file_encoding) 2337ec681f3Smrg{ 2347ec681f3Smrg /* Register file on Gfx12 is only one bit */ 2357ec681f3Smrg if (devinfo.ver >= 12) 2367ec681f3Smrg return; 2377ec681f3Smrg 2387ec681f3Smrg brw_MOV(p, g0, g0); 2397ec681f3Smrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_MESSAGE_REGISTER_FILE, BRW_REGISTER_TYPE_F); 2407ec681f3Smrg 2417ec681f3Smrg if (devinfo.ver > 6) { 2427ec681f3Smrg EXPECT_FALSE(validate(p)); 2437ec681f3Smrg } else { 2447ec681f3Smrg EXPECT_TRUE(validate(p)); 2457ec681f3Smrg } 2467ec681f3Smrg 2477ec681f3Smrg clear_instructions(p); 2487ec681f3Smrg 2497ec681f3Smrg if (devinfo.ver < 6) { 2507ec681f3Smrg gfx4_math(p, g0, BRW_MATH_FUNCTION_SIN, 0, g0, BRW_MATH_PRECISION_FULL); 2517ec681f3Smrg } else { 2527ec681f3Smrg gfx6_math(p, g0, BRW_MATH_FUNCTION_SIN, g0, null); 2537ec681f3Smrg } 2547ec681f3Smrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_MESSAGE_REGISTER_FILE, BRW_REGISTER_TYPE_F); 2557ec681f3Smrg 2567ec681f3Smrg if (devinfo.ver > 6) { 2577ec681f3Smrg EXPECT_FALSE(validate(p)); 2587ec681f3Smrg } else { 2597ec681f3Smrg EXPECT_TRUE(validate(p)); 2607ec681f3Smrg } 2617ec681f3Smrg} 2627ec681f3Smrg 2637ec681f3SmrgTEST_P(validation_test, invalid_type_encoding) 2647ec681f3Smrg{ 2657ec681f3Smrg enum brw_reg_file files[2] = { 2667ec681f3Smrg BRW_GENERAL_REGISTER_FILE, 2677ec681f3Smrg BRW_IMMEDIATE_VALUE, 2687ec681f3Smrg }; 2697ec681f3Smrg 2707ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(files); i++) { 2717ec681f3Smrg const enum brw_reg_file file = files[i]; 2727ec681f3Smrg const int num_bits = devinfo.ver >= 8 ? 4 : 3; 2737ec681f3Smrg const int num_encodings = 1 << num_bits; 2747ec681f3Smrg 2757ec681f3Smrg /* The data types are encoded into <num_bits> bits to be used in hardware 2767ec681f3Smrg * instructions, so keep a record in a bitset the invalid patterns so 2777ec681f3Smrg * they can be verified to be invalid when used. 2787ec681f3Smrg */ 2797ec681f3Smrg BITSET_DECLARE(invalid_encodings, num_encodings); 2807ec681f3Smrg 2817ec681f3Smrg const struct { 2827ec681f3Smrg enum brw_reg_type type; 2837ec681f3Smrg bool expected_result; 2847ec681f3Smrg } test_case[] = { 2857ec681f3Smrg { BRW_REGISTER_TYPE_NF, devinfo.ver == 11 && file != IMM }, 2867ec681f3Smrg { BRW_REGISTER_TYPE_DF, devinfo.has_64bit_float && (devinfo.ver >= 8 || file != IMM) }, 2877ec681f3Smrg { BRW_REGISTER_TYPE_F, true }, 2887ec681f3Smrg { BRW_REGISTER_TYPE_HF, devinfo.ver >= 8 }, 2897ec681f3Smrg { BRW_REGISTER_TYPE_VF, file == IMM }, 2907ec681f3Smrg { BRW_REGISTER_TYPE_Q, devinfo.has_64bit_int }, 2917ec681f3Smrg { BRW_REGISTER_TYPE_UQ, devinfo.has_64bit_int }, 2927ec681f3Smrg { BRW_REGISTER_TYPE_D, true }, 2937ec681f3Smrg { BRW_REGISTER_TYPE_UD, true }, 2947ec681f3Smrg { BRW_REGISTER_TYPE_W, true }, 2957ec681f3Smrg { BRW_REGISTER_TYPE_UW, true }, 2967ec681f3Smrg { BRW_REGISTER_TYPE_B, file == FIXED_GRF }, 2977ec681f3Smrg { BRW_REGISTER_TYPE_UB, file == FIXED_GRF }, 2987ec681f3Smrg { BRW_REGISTER_TYPE_V, file == IMM }, 2997ec681f3Smrg { BRW_REGISTER_TYPE_UV, devinfo.ver >= 6 && file == IMM }, 3007ec681f3Smrg }; 3017ec681f3Smrg 3027ec681f3Smrg /* Initially assume all hardware encodings are invalid */ 3037ec681f3Smrg BITSET_ONES(invalid_encodings); 3047ec681f3Smrg 3057ec681f3Smrg brw_set_default_exec_size(p, BRW_EXECUTE_4); 3067ec681f3Smrg 3077ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(test_case); i++) { 3087ec681f3Smrg if (test_case[i].expected_result) { 3097ec681f3Smrg unsigned hw_type = brw_reg_type_to_hw_type(&devinfo, file, test_case[i].type); 3107ec681f3Smrg if (hw_type != INVALID_REG_TYPE) { 3117ec681f3Smrg /* ... and remove valid encodings from the set */ 3127ec681f3Smrg assert(BITSET_TEST(invalid_encodings, hw_type)); 3137ec681f3Smrg BITSET_CLEAR(invalid_encodings, hw_type); 3147ec681f3Smrg } 3157ec681f3Smrg 3167ec681f3Smrg if (file == FIXED_GRF) { 3177ec681f3Smrg struct brw_reg g = retype(g0, test_case[i].type); 3187ec681f3Smrg brw_MOV(p, g, g); 3197ec681f3Smrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 3207ec681f3Smrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4); 3217ec681f3Smrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 3227ec681f3Smrg } else { 3237ec681f3Smrg enum brw_reg_type t; 3247ec681f3Smrg 3257ec681f3Smrg switch (test_case[i].type) { 3267ec681f3Smrg case BRW_REGISTER_TYPE_V: 3277ec681f3Smrg t = BRW_REGISTER_TYPE_W; 3287ec681f3Smrg break; 3297ec681f3Smrg case BRW_REGISTER_TYPE_UV: 3307ec681f3Smrg t = BRW_REGISTER_TYPE_UW; 3317ec681f3Smrg break; 3327ec681f3Smrg case BRW_REGISTER_TYPE_VF: 3337ec681f3Smrg t = BRW_REGISTER_TYPE_F; 3347ec681f3Smrg break; 3357ec681f3Smrg default: 3367ec681f3Smrg t = test_case[i].type; 3377ec681f3Smrg break; 3387ec681f3Smrg } 3397ec681f3Smrg 3407ec681f3Smrg struct brw_reg g = retype(g0, t); 3417ec681f3Smrg brw_MOV(p, g, retype(brw_imm_w(0), test_case[i].type)); 3427ec681f3Smrg } 3437ec681f3Smrg 3447ec681f3Smrg EXPECT_TRUE(validate(p)); 3457ec681f3Smrg 3467ec681f3Smrg clear_instructions(p); 3477ec681f3Smrg } 3487ec681f3Smrg } 3497ec681f3Smrg 3507ec681f3Smrg /* The remaining encodings in invalid_encodings do not have a mapping 3517ec681f3Smrg * from BRW_REGISTER_TYPE_* and must be invalid. Verify that invalid 3527ec681f3Smrg * encodings are rejected by the validator. 3537ec681f3Smrg */ 3547ec681f3Smrg int e; 3557ec681f3Smrg BITSET_FOREACH_SET(e, invalid_encodings, num_encodings) { 3567ec681f3Smrg if (file == FIXED_GRF) { 3577ec681f3Smrg brw_MOV(p, g0, g0); 3587ec681f3Smrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 3597ec681f3Smrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4); 3607ec681f3Smrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 3617ec681f3Smrg } else { 3627ec681f3Smrg brw_MOV(p, g0, brw_imm_w(0)); 3637ec681f3Smrg } 3647ec681f3Smrg brw_inst_set_dst_reg_hw_type(&devinfo, last_inst, e); 3657ec681f3Smrg brw_inst_set_src0_reg_hw_type(&devinfo, last_inst, e); 3667ec681f3Smrg 3677ec681f3Smrg EXPECT_FALSE(validate(p)); 3687ec681f3Smrg 3697ec681f3Smrg clear_instructions(p); 3707ec681f3Smrg } 3717ec681f3Smrg } 3727ec681f3Smrg} 3737ec681f3Smrg 3747ec681f3SmrgTEST_P(validation_test, invalid_type_encoding_3src_a16) 3757ec681f3Smrg{ 3767ec681f3Smrg /* 3-src instructions in align16 mode only supported on Gfx6-10 */ 3777ec681f3Smrg if (devinfo.ver < 6 || devinfo.ver > 10) 3787ec681f3Smrg return; 3797ec681f3Smrg 3807ec681f3Smrg const int num_bits = devinfo.ver >= 8 ? 3 : 2; 3817ec681f3Smrg const int num_encodings = 1 << num_bits; 3827ec681f3Smrg 3837ec681f3Smrg /* The data types are encoded into <num_bits> bits to be used in hardware 3847ec681f3Smrg * instructions, so keep a record in a bitset the invalid patterns so 3857ec681f3Smrg * they can be verified to be invalid when used. 3867ec681f3Smrg */ 3877ec681f3Smrg BITSET_DECLARE(invalid_encodings, num_encodings); 3887ec681f3Smrg 3897ec681f3Smrg const struct { 3907ec681f3Smrg enum brw_reg_type type; 3917ec681f3Smrg bool expected_result; 3927ec681f3Smrg } test_case[] = { 3937ec681f3Smrg { BRW_REGISTER_TYPE_DF, devinfo.ver >= 7 }, 3947ec681f3Smrg { BRW_REGISTER_TYPE_F, true }, 3957ec681f3Smrg { BRW_REGISTER_TYPE_HF, devinfo.ver >= 8 }, 3967ec681f3Smrg { BRW_REGISTER_TYPE_D, devinfo.ver >= 7 }, 3977ec681f3Smrg { BRW_REGISTER_TYPE_UD, devinfo.ver >= 7 }, 3987ec681f3Smrg }; 3997ec681f3Smrg 4007ec681f3Smrg /* Initially assume all hardware encodings are invalid */ 4017ec681f3Smrg BITSET_ONES(invalid_encodings); 4027ec681f3Smrg 4037ec681f3Smrg brw_set_default_access_mode(p, BRW_ALIGN_16); 4047ec681f3Smrg brw_set_default_exec_size(p, BRW_EXECUTE_4); 4057ec681f3Smrg 4067ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(test_case); i++) { 4077ec681f3Smrg if (test_case[i].expected_result) { 4087ec681f3Smrg unsigned hw_type = brw_reg_type_to_a16_hw_3src_type(&devinfo, test_case[i].type); 4097ec681f3Smrg if (hw_type != INVALID_HW_REG_TYPE) { 4107ec681f3Smrg /* ... and remove valid encodings from the set */ 4117ec681f3Smrg assert(BITSET_TEST(invalid_encodings, hw_type)); 4127ec681f3Smrg BITSET_CLEAR(invalid_encodings, hw_type); 4137ec681f3Smrg } 4147ec681f3Smrg 4157ec681f3Smrg struct brw_reg g = retype(g0, test_case[i].type); 4167ec681f3Smrg if (!brw_reg_type_is_integer(test_case[i].type)) { 4177ec681f3Smrg brw_MAD(p, g, g, g, g); 4187ec681f3Smrg } else { 4197ec681f3Smrg brw_BFE(p, g, g, g, g); 4207ec681f3Smrg } 4217ec681f3Smrg 4227ec681f3Smrg EXPECT_TRUE(validate(p)); 4237ec681f3Smrg 4247ec681f3Smrg clear_instructions(p); 4257ec681f3Smrg } 4267ec681f3Smrg } 4277ec681f3Smrg 4287ec681f3Smrg /* The remaining encodings in invalid_encodings do not have a mapping 4297ec681f3Smrg * from BRW_REGISTER_TYPE_* and must be invalid. Verify that invalid 4307ec681f3Smrg * encodings are rejected by the validator. 4317ec681f3Smrg */ 4327ec681f3Smrg int e; 4337ec681f3Smrg BITSET_FOREACH_SET(e, invalid_encodings, num_encodings) { 4347ec681f3Smrg for (unsigned i = 0; i < 2; i++) { 4357ec681f3Smrg if (i == 0) { 4367ec681f3Smrg brw_MAD(p, g0, g0, g0, g0); 4377ec681f3Smrg } else { 4387ec681f3Smrg brw_BFE(p, g0, g0, g0, g0); 4397ec681f3Smrg } 4407ec681f3Smrg 4417ec681f3Smrg brw_inst_set_3src_a16_dst_hw_type(&devinfo, last_inst, e); 4427ec681f3Smrg brw_inst_set_3src_a16_src_hw_type(&devinfo, last_inst, e); 4437ec681f3Smrg 4447ec681f3Smrg EXPECT_FALSE(validate(p)); 4457ec681f3Smrg 4467ec681f3Smrg clear_instructions(p); 4477ec681f3Smrg 4487ec681f3Smrg if (devinfo.ver == 6) 4497ec681f3Smrg break; 4507ec681f3Smrg } 4517ec681f3Smrg } 4527ec681f3Smrg} 4537ec681f3Smrg 4547ec681f3SmrgTEST_P(validation_test, invalid_type_encoding_3src_a1) 4557ec681f3Smrg{ 4567ec681f3Smrg /* 3-src instructions in align1 mode only supported on Gfx10+ */ 4577ec681f3Smrg if (devinfo.ver < 10) 4587ec681f3Smrg return; 4597ec681f3Smrg 4607ec681f3Smrg const int num_bits = 3 + 1 /* for exec_type */; 4617ec681f3Smrg const int num_encodings = 1 << num_bits; 4627ec681f3Smrg 4637ec681f3Smrg /* The data types are encoded into <num_bits> bits to be used in hardware 4647ec681f3Smrg * instructions, so keep a record in a bitset the invalid patterns so 4657ec681f3Smrg * they can be verified to be invalid when used. 4667ec681f3Smrg */ 4677ec681f3Smrg BITSET_DECLARE(invalid_encodings, num_encodings); 4687ec681f3Smrg 4697ec681f3Smrg const struct { 4707ec681f3Smrg enum brw_reg_type type; 4717ec681f3Smrg unsigned exec_type; 4727ec681f3Smrg bool expected_result; 4737ec681f3Smrg } test_case[] = { 4747ec681f3Smrg#define E(x) ((unsigned)BRW_ALIGN1_3SRC_EXEC_TYPE_##x) 4757ec681f3Smrg { BRW_REGISTER_TYPE_NF, E(FLOAT), devinfo.ver == 11 }, 4767ec681f3Smrg { BRW_REGISTER_TYPE_DF, E(FLOAT), devinfo.has_64bit_float }, 4777ec681f3Smrg { BRW_REGISTER_TYPE_F, E(FLOAT), true }, 4787ec681f3Smrg { BRW_REGISTER_TYPE_HF, E(FLOAT), true }, 4797ec681f3Smrg { BRW_REGISTER_TYPE_D, E(INT), true }, 4807ec681f3Smrg { BRW_REGISTER_TYPE_UD, E(INT), true }, 4817ec681f3Smrg { BRW_REGISTER_TYPE_W, E(INT), true }, 4827ec681f3Smrg { BRW_REGISTER_TYPE_UW, E(INT), true }, 4837ec681f3Smrg 4847ec681f3Smrg /* There are no ternary instructions that can operate on B-type sources 4857ec681f3Smrg * on Gfx11-12. Src1/Src2 cannot be B-typed either. 4867ec681f3Smrg */ 4877ec681f3Smrg { BRW_REGISTER_TYPE_B, E(INT), false }, 4887ec681f3Smrg { BRW_REGISTER_TYPE_UB, E(INT), false }, 4897ec681f3Smrg }; 4907ec681f3Smrg 4917ec681f3Smrg /* Initially assume all hardware encodings are invalid */ 4927ec681f3Smrg BITSET_ONES(invalid_encodings); 4937ec681f3Smrg 4947ec681f3Smrg brw_set_default_access_mode(p, BRW_ALIGN_1); 4957ec681f3Smrg brw_set_default_exec_size(p, BRW_EXECUTE_4); 4967ec681f3Smrg 4977ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(test_case); i++) { 4987ec681f3Smrg if (test_case[i].expected_result) { 4997ec681f3Smrg unsigned hw_type = brw_reg_type_to_a1_hw_3src_type(&devinfo, test_case[i].type); 5007ec681f3Smrg unsigned hw_exec_type = hw_type | (test_case[i].exec_type << 3); 5017ec681f3Smrg if (hw_type != INVALID_HW_REG_TYPE) { 5027ec681f3Smrg /* ... and remove valid encodings from the set */ 5037ec681f3Smrg assert(BITSET_TEST(invalid_encodings, hw_exec_type)); 5047ec681f3Smrg BITSET_CLEAR(invalid_encodings, hw_exec_type); 5057ec681f3Smrg } 5067ec681f3Smrg 5077ec681f3Smrg struct brw_reg g = retype(g0, test_case[i].type); 5087ec681f3Smrg if (!brw_reg_type_is_integer(test_case[i].type)) { 5097ec681f3Smrg brw_MAD(p, g, g, g, g); 5107ec681f3Smrg } else { 5117ec681f3Smrg brw_BFE(p, g, g, g, g); 5127ec681f3Smrg } 5137ec681f3Smrg 5147ec681f3Smrg EXPECT_TRUE(validate(p)); 5157ec681f3Smrg 5167ec681f3Smrg clear_instructions(p); 5177ec681f3Smrg } 5187ec681f3Smrg } 5197ec681f3Smrg 5207ec681f3Smrg /* The remaining encodings in invalid_encodings do not have a mapping 5217ec681f3Smrg * from BRW_REGISTER_TYPE_* and must be invalid. Verify that invalid 5227ec681f3Smrg * encodings are rejected by the validator. 5237ec681f3Smrg */ 5247ec681f3Smrg int e; 5257ec681f3Smrg BITSET_FOREACH_SET(e, invalid_encodings, num_encodings) { 5267ec681f3Smrg const unsigned hw_type = e & 0x7; 5277ec681f3Smrg const unsigned exec_type = e >> 3; 5287ec681f3Smrg 5297ec681f3Smrg for (unsigned i = 0; i < 2; i++) { 5307ec681f3Smrg if (i == 0) { 5317ec681f3Smrg brw_MAD(p, g0, g0, g0, g0); 5327ec681f3Smrg brw_inst_set_3src_a1_exec_type(&devinfo, last_inst, BRW_ALIGN1_3SRC_EXEC_TYPE_FLOAT); 5337ec681f3Smrg } else { 5347ec681f3Smrg brw_CSEL(p, g0, g0, g0, g0); 5357ec681f3Smrg brw_inst_set_3src_cond_modifier(&devinfo, last_inst, BRW_CONDITIONAL_NZ); 5367ec681f3Smrg brw_inst_set_3src_a1_exec_type(&devinfo, last_inst, BRW_ALIGN1_3SRC_EXEC_TYPE_INT); 5377ec681f3Smrg } 5387ec681f3Smrg 5397ec681f3Smrg brw_inst_set_3src_a1_exec_type(&devinfo, last_inst, exec_type); 5407ec681f3Smrg brw_inst_set_3src_a1_dst_hw_type (&devinfo, last_inst, hw_type); 5417ec681f3Smrg brw_inst_set_3src_a1_src0_hw_type(&devinfo, last_inst, hw_type); 5427ec681f3Smrg brw_inst_set_3src_a1_src1_hw_type(&devinfo, last_inst, hw_type); 5437ec681f3Smrg brw_inst_set_3src_a1_src2_hw_type(&devinfo, last_inst, hw_type); 5447ec681f3Smrg 5457ec681f3Smrg EXPECT_FALSE(validate(p)); 5467ec681f3Smrg 5477ec681f3Smrg clear_instructions(p); 5487ec681f3Smrg } 5497ec681f3Smrg } 5507ec681f3Smrg} 5517ec681f3Smrg 5527ec681f3SmrgTEST_P(validation_test, 3src_inst_access_mode) 5537ec681f3Smrg{ 5547ec681f3Smrg /* 3-src instructions only supported on Gfx6+ */ 5557ec681f3Smrg if (devinfo.ver < 6) 5567ec681f3Smrg return; 5577ec681f3Smrg 5587ec681f3Smrg /* No access mode bit on Gfx12+ */ 5597ec681f3Smrg if (devinfo.ver >= 12) 5607ec681f3Smrg return; 5617ec681f3Smrg 5627ec681f3Smrg const struct { 5637ec681f3Smrg unsigned mode; 5647ec681f3Smrg bool expected_result; 5657ec681f3Smrg } test_case[] = { 5667ec681f3Smrg { BRW_ALIGN_1, devinfo.ver >= 10 }, 5677ec681f3Smrg { BRW_ALIGN_16, devinfo.ver <= 10 }, 5687ec681f3Smrg }; 5697ec681f3Smrg 5707ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(test_case); i++) { 5717ec681f3Smrg if (devinfo.ver < 10) 5727ec681f3Smrg brw_set_default_access_mode(p, BRW_ALIGN_16); 5737ec681f3Smrg 5747ec681f3Smrg brw_MAD(p, g0, g0, g0, g0); 5757ec681f3Smrg brw_inst_set_access_mode(&devinfo, last_inst, test_case[i].mode); 5767ec681f3Smrg 5777ec681f3Smrg EXPECT_EQ(test_case[i].expected_result, validate(p)); 5787ec681f3Smrg 5797ec681f3Smrg clear_instructions(p); 5807ec681f3Smrg } 5817ec681f3Smrg} 5827ec681f3Smrg 58301e04c3fSmrg/* When the Execution Data Type is wider than the destination data type, the 58401e04c3fSmrg * destination must [...] specify a HorzStride equal to the ratio in sizes of 58501e04c3fSmrg * the two data types. 58601e04c3fSmrg */ 58701e04c3fSmrgTEST_P(validation_test, dest_stride_must_be_equal_to_the_ratio_of_exec_size_to_dest_size) 58801e04c3fSmrg{ 58901e04c3fSmrg brw_ADD(p, g0, g0, g0); 59001e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 59101e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D); 59201e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D); 59301e04c3fSmrg 59401e04c3fSmrg EXPECT_FALSE(validate(p)); 59501e04c3fSmrg 59601e04c3fSmrg clear_instructions(p); 59701e04c3fSmrg 59801e04c3fSmrg brw_ADD(p, g0, g0, g0); 59901e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 60001e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 60101e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D); 60201e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D); 60301e04c3fSmrg 60401e04c3fSmrg EXPECT_TRUE(validate(p)); 60501e04c3fSmrg} 60601e04c3fSmrg 60701e04c3fSmrg/* When the Execution Data Type is wider than the destination data type, the 60801e04c3fSmrg * destination must be aligned as required by the wider execution data type 60901e04c3fSmrg * [...] 61001e04c3fSmrg */ 61101e04c3fSmrgTEST_P(validation_test, dst_subreg_must_be_aligned_to_exec_type_size) 61201e04c3fSmrg{ 61301e04c3fSmrg brw_ADD(p, g0, g0, g0); 61401e04c3fSmrg brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 2); 61501e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 61601e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 61701e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D); 61801e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D); 61901e04c3fSmrg 62001e04c3fSmrg EXPECT_FALSE(validate(p)); 62101e04c3fSmrg 62201e04c3fSmrg clear_instructions(p); 62301e04c3fSmrg 62401e04c3fSmrg brw_ADD(p, g0, g0, g0); 62501e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4); 62601e04c3fSmrg brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 8); 62701e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 62801e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 62901e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D); 63001e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 63101e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4); 63201e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 63301e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D); 63401e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 63501e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4); 63601e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 63701e04c3fSmrg 63801e04c3fSmrg EXPECT_TRUE(validate(p)); 63901e04c3fSmrg} 64001e04c3fSmrg 64101e04c3fSmrg/* ExecSize must be greater than or equal to Width. */ 64201e04c3fSmrgTEST_P(validation_test, exec_size_less_than_width) 64301e04c3fSmrg{ 64401e04c3fSmrg brw_ADD(p, g0, g0, g0); 64501e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_16); 64601e04c3fSmrg 64701e04c3fSmrg EXPECT_FALSE(validate(p)); 64801e04c3fSmrg 64901e04c3fSmrg clear_instructions(p); 65001e04c3fSmrg 65101e04c3fSmrg brw_ADD(p, g0, g0, g0); 65201e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_16); 65301e04c3fSmrg 65401e04c3fSmrg EXPECT_FALSE(validate(p)); 65501e04c3fSmrg} 65601e04c3fSmrg 65701e04c3fSmrg/* If ExecSize = Width and HorzStride ≠ 0, 65801e04c3fSmrg * VertStride must be set to Width * HorzStride. 65901e04c3fSmrg */ 66001e04c3fSmrgTEST_P(validation_test, vertical_stride_is_width_by_horizontal_stride) 66101e04c3fSmrg{ 66201e04c3fSmrg brw_ADD(p, g0, g0, g0); 66301e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 66401e04c3fSmrg 66501e04c3fSmrg EXPECT_FALSE(validate(p)); 66601e04c3fSmrg 66701e04c3fSmrg clear_instructions(p); 66801e04c3fSmrg 66901e04c3fSmrg brw_ADD(p, g0, g0, g0); 67001e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 67101e04c3fSmrg 67201e04c3fSmrg EXPECT_FALSE(validate(p)); 67301e04c3fSmrg} 67401e04c3fSmrg 67501e04c3fSmrg/* If Width = 1, HorzStride must be 0 regardless of the values 67601e04c3fSmrg * of ExecSize and VertStride. 67701e04c3fSmrg */ 67801e04c3fSmrgTEST_P(validation_test, horizontal_stride_must_be_0_if_width_is_1) 67901e04c3fSmrg{ 68001e04c3fSmrg brw_ADD(p, g0, g0, g0); 68101e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0); 68201e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1); 68301e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 68401e04c3fSmrg 68501e04c3fSmrg EXPECT_FALSE(validate(p)); 68601e04c3fSmrg 68701e04c3fSmrg clear_instructions(p); 68801e04c3fSmrg 68901e04c3fSmrg brw_ADD(p, g0, g0, g0); 69001e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0); 69101e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_1); 69201e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 69301e04c3fSmrg 69401e04c3fSmrg EXPECT_FALSE(validate(p)); 69501e04c3fSmrg} 69601e04c3fSmrg 69701e04c3fSmrg/* If ExecSize = Width = 1, both VertStride and HorzStride must be 0. */ 69801e04c3fSmrgTEST_P(validation_test, scalar_region_must_be_0_1_0) 69901e04c3fSmrg{ 70001e04c3fSmrg struct brw_reg g0_0 = brw_vec1_grf(0, 0); 70101e04c3fSmrg 70201e04c3fSmrg brw_ADD(p, g0, g0, g0_0); 70301e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_1); 70401e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_1); 70501e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1); 70601e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0); 70701e04c3fSmrg 70801e04c3fSmrg EXPECT_FALSE(validate(p)); 70901e04c3fSmrg 71001e04c3fSmrg clear_instructions(p); 71101e04c3fSmrg 71201e04c3fSmrg brw_ADD(p, g0, g0_0, g0); 71301e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_1); 71401e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_1); 71501e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_1); 71601e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0); 71701e04c3fSmrg 71801e04c3fSmrg EXPECT_FALSE(validate(p)); 71901e04c3fSmrg} 72001e04c3fSmrg 72101e04c3fSmrg/* If VertStride = HorzStride = 0, Width must be 1 regardless of the value 72201e04c3fSmrg * of ExecSize. 72301e04c3fSmrg */ 72401e04c3fSmrgTEST_P(validation_test, zero_stride_implies_0_1_0) 72501e04c3fSmrg{ 72601e04c3fSmrg brw_ADD(p, g0, g0, g0); 72701e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0); 72801e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_2); 72901e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0); 73001e04c3fSmrg 73101e04c3fSmrg EXPECT_FALSE(validate(p)); 73201e04c3fSmrg 73301e04c3fSmrg clear_instructions(p); 73401e04c3fSmrg 73501e04c3fSmrg brw_ADD(p, g0, g0, g0); 73601e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0); 73701e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2); 73801e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0); 73901e04c3fSmrg 74001e04c3fSmrg EXPECT_FALSE(validate(p)); 74101e04c3fSmrg} 74201e04c3fSmrg 74301e04c3fSmrg/* Dst.HorzStride must not be 0. */ 74401e04c3fSmrgTEST_P(validation_test, dst_horizontal_stride_0) 74501e04c3fSmrg{ 74601e04c3fSmrg brw_ADD(p, g0, g0, g0); 74701e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0); 74801e04c3fSmrg 74901e04c3fSmrg EXPECT_FALSE(validate(p)); 75001e04c3fSmrg 75101e04c3fSmrg clear_instructions(p); 75201e04c3fSmrg 7537ec681f3Smrg /* Align16 does not exist on Gfx11+ */ 7547ec681f3Smrg if (devinfo.ver >= 11) 75501e04c3fSmrg return; 75601e04c3fSmrg 75701e04c3fSmrg brw_set_default_access_mode(p, BRW_ALIGN_16); 75801e04c3fSmrg 75901e04c3fSmrg brw_ADD(p, g0, g0, g0); 76001e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0); 76101e04c3fSmrg 76201e04c3fSmrg EXPECT_FALSE(validate(p)); 76301e04c3fSmrg} 76401e04c3fSmrg 76501e04c3fSmrg/* VertStride must be used to cross BRW_GENERAL_REGISTER_FILE register boundaries. This rule implies 76601e04c3fSmrg * that elements within a 'Width' cannot cross BRW_GENERAL_REGISTER_FILE boundaries. 76701e04c3fSmrg */ 76801e04c3fSmrgTEST_P(validation_test, must_not_cross_grf_boundary_in_a_width) 76901e04c3fSmrg{ 77001e04c3fSmrg brw_ADD(p, g0, g0, g0); 77101e04c3fSmrg brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 4); 77201e04c3fSmrg 77301e04c3fSmrg EXPECT_FALSE(validate(p)); 77401e04c3fSmrg 77501e04c3fSmrg clear_instructions(p); 77601e04c3fSmrg 77701e04c3fSmrg brw_ADD(p, g0, g0, g0); 77801e04c3fSmrg brw_inst_set_src1_da1_subreg_nr(&devinfo, last_inst, 4); 77901e04c3fSmrg 78001e04c3fSmrg EXPECT_FALSE(validate(p)); 78101e04c3fSmrg 78201e04c3fSmrg clear_instructions(p); 78301e04c3fSmrg 78401e04c3fSmrg brw_ADD(p, g0, g0, g0); 78501e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 78601e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4); 78701e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 78801e04c3fSmrg 78901e04c3fSmrg EXPECT_FALSE(validate(p)); 79001e04c3fSmrg 79101e04c3fSmrg clear_instructions(p); 79201e04c3fSmrg 79301e04c3fSmrg brw_ADD(p, g0, g0, g0); 79401e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 79501e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4); 79601e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 79701e04c3fSmrg 79801e04c3fSmrg EXPECT_FALSE(validate(p)); 79901e04c3fSmrg} 80001e04c3fSmrg 80101e04c3fSmrg/* Destination Horizontal must be 1 in Align16 */ 80201e04c3fSmrgTEST_P(validation_test, dst_hstride_on_align16_must_be_1) 80301e04c3fSmrg{ 8047ec681f3Smrg /* Align16 does not exist on Gfx11+ */ 8057ec681f3Smrg if (devinfo.ver >= 11) 80601e04c3fSmrg return; 80701e04c3fSmrg 80801e04c3fSmrg brw_set_default_access_mode(p, BRW_ALIGN_16); 80901e04c3fSmrg 81001e04c3fSmrg brw_ADD(p, g0, g0, g0); 81101e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 81201e04c3fSmrg 81301e04c3fSmrg EXPECT_FALSE(validate(p)); 81401e04c3fSmrg 81501e04c3fSmrg clear_instructions(p); 81601e04c3fSmrg 81701e04c3fSmrg brw_ADD(p, g0, g0, g0); 81801e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 81901e04c3fSmrg 82001e04c3fSmrg EXPECT_TRUE(validate(p)); 82101e04c3fSmrg} 82201e04c3fSmrg 82301e04c3fSmrg/* VertStride must be 0 or 4 in Align16 */ 82401e04c3fSmrgTEST_P(validation_test, vstride_on_align16_must_be_0_or_4) 82501e04c3fSmrg{ 8267ec681f3Smrg /* Align16 does not exist on Gfx11+ */ 8277ec681f3Smrg if (devinfo.ver >= 11) 82801e04c3fSmrg return; 82901e04c3fSmrg 83001e04c3fSmrg const struct { 83101e04c3fSmrg enum brw_vertical_stride vstride; 83201e04c3fSmrg bool expected_result; 83301e04c3fSmrg } vstride[] = { 83401e04c3fSmrg { BRW_VERTICAL_STRIDE_0, true }, 83501e04c3fSmrg { BRW_VERTICAL_STRIDE_1, false }, 8367ec681f3Smrg { BRW_VERTICAL_STRIDE_2, devinfo.verx10 >= 75 }, 83701e04c3fSmrg { BRW_VERTICAL_STRIDE_4, true }, 83801e04c3fSmrg { BRW_VERTICAL_STRIDE_8, false }, 83901e04c3fSmrg { BRW_VERTICAL_STRIDE_16, false }, 84001e04c3fSmrg { BRW_VERTICAL_STRIDE_32, false }, 84101e04c3fSmrg { BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL, false }, 84201e04c3fSmrg }; 84301e04c3fSmrg 84401e04c3fSmrg brw_set_default_access_mode(p, BRW_ALIGN_16); 84501e04c3fSmrg 8467ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(vstride); i++) { 84701e04c3fSmrg brw_ADD(p, g0, g0, g0); 84801e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, vstride[i].vstride); 84901e04c3fSmrg 85001e04c3fSmrg EXPECT_EQ(vstride[i].expected_result, validate(p)); 85101e04c3fSmrg 85201e04c3fSmrg clear_instructions(p); 85301e04c3fSmrg } 85401e04c3fSmrg 8557ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(vstride); i++) { 85601e04c3fSmrg brw_ADD(p, g0, g0, g0); 85701e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, vstride[i].vstride); 85801e04c3fSmrg 85901e04c3fSmrg EXPECT_EQ(vstride[i].expected_result, validate(p)); 86001e04c3fSmrg 86101e04c3fSmrg clear_instructions(p); 86201e04c3fSmrg } 86301e04c3fSmrg} 86401e04c3fSmrg 86501e04c3fSmrg/* In Direct Addressing mode, a source cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE 86601e04c3fSmrg * registers. 86701e04c3fSmrg */ 86801e04c3fSmrgTEST_P(validation_test, source_cannot_span_more_than_2_registers) 86901e04c3fSmrg{ 87001e04c3fSmrg brw_ADD(p, g0, g0, g0); 87101e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_32); 87201e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 87301e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 87401e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 87501e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16); 87601e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8); 87701e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 87801e04c3fSmrg 87901e04c3fSmrg EXPECT_FALSE(validate(p)); 88001e04c3fSmrg 88101e04c3fSmrg clear_instructions(p); 88201e04c3fSmrg 88301e04c3fSmrg brw_ADD(p, g0, g0, g0); 88401e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16); 88501e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 88601e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 88701e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 88801e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16); 88901e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8); 89001e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 89101e04c3fSmrg brw_inst_set_src1_da1_subreg_nr(&devinfo, last_inst, 2); 89201e04c3fSmrg 89301e04c3fSmrg EXPECT_TRUE(validate(p)); 89401e04c3fSmrg 89501e04c3fSmrg clear_instructions(p); 89601e04c3fSmrg 89701e04c3fSmrg brw_ADD(p, g0, g0, g0); 89801e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16); 89901e04c3fSmrg 90001e04c3fSmrg EXPECT_TRUE(validate(p)); 90101e04c3fSmrg} 90201e04c3fSmrg 90301e04c3fSmrg/* A destination cannot span more than 2 adjacent BRW_GENERAL_REGISTER_FILE registers. */ 90401e04c3fSmrgTEST_P(validation_test, destination_cannot_span_more_than_2_registers) 90501e04c3fSmrg{ 90601e04c3fSmrg brw_ADD(p, g0, g0, g0); 90701e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_32); 90801e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 90901e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 91001e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 91101e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 91201e04c3fSmrg 91301e04c3fSmrg EXPECT_FALSE(validate(p)); 91401e04c3fSmrg 91501e04c3fSmrg clear_instructions(p); 91601e04c3fSmrg 91701e04c3fSmrg brw_ADD(p, g0, g0, g0); 91801e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_8); 91901e04c3fSmrg brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 6); 92001e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4); 92101e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 92201e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 92301e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16); 92401e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4); 92501e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 92601e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 92701e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16); 92801e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4); 92901e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 93001e04c3fSmrg 93101e04c3fSmrg EXPECT_TRUE(validate(p)); 93201e04c3fSmrg} 93301e04c3fSmrg 93401e04c3fSmrgTEST_P(validation_test, src_region_spans_two_regs_dst_region_spans_one) 93501e04c3fSmrg{ 93601e04c3fSmrg /* Writes to dest are to the lower OWord */ 93701e04c3fSmrg brw_ADD(p, g0, g0, g0); 93801e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 93901e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 94001e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 94101e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16); 94201e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4); 94301e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 94401e04c3fSmrg 94501e04c3fSmrg EXPECT_TRUE(validate(p)); 94601e04c3fSmrg 94701e04c3fSmrg clear_instructions(p); 94801e04c3fSmrg 94901e04c3fSmrg /* Writes to dest are to the upper OWord */ 95001e04c3fSmrg brw_ADD(p, g0, g0, g0); 95101e04c3fSmrg brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 16); 95201e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 95301e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 95401e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 95501e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16); 95601e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4); 95701e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 95801e04c3fSmrg 95901e04c3fSmrg EXPECT_TRUE(validate(p)); 96001e04c3fSmrg 96101e04c3fSmrg clear_instructions(p); 96201e04c3fSmrg 96301e04c3fSmrg /* Writes to dest are evenly split between OWords */ 96401e04c3fSmrg brw_ADD(p, g0, g0, g0); 96501e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16); 96601e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 96701e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 96801e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 96901e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16); 97001e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_8); 97101e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 97201e04c3fSmrg 97301e04c3fSmrg EXPECT_TRUE(validate(p)); 97401e04c3fSmrg 97501e04c3fSmrg clear_instructions(p); 97601e04c3fSmrg 97701e04c3fSmrg /* Writes to dest are uneven between OWords */ 97801e04c3fSmrg brw_ADD(p, g0, g0, g0); 97901e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4); 98001e04c3fSmrg brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 10); 98101e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 98201e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 98301e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 98401e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4); 98501e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 98601e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 98701e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_16); 98801e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2); 98901e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 99001e04c3fSmrg 9917ec681f3Smrg if (devinfo.ver >= 9) { 99201e04c3fSmrg EXPECT_TRUE(validate(p)); 99301e04c3fSmrg } else { 99401e04c3fSmrg EXPECT_FALSE(validate(p)); 99501e04c3fSmrg } 99601e04c3fSmrg} 99701e04c3fSmrg 99801e04c3fSmrgTEST_P(validation_test, dst_elements_must_be_evenly_split_between_registers) 99901e04c3fSmrg{ 100001e04c3fSmrg brw_ADD(p, g0, g0, g0); 100101e04c3fSmrg brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 4); 100201e04c3fSmrg 10037ec681f3Smrg if (devinfo.ver >= 9) { 100401e04c3fSmrg EXPECT_TRUE(validate(p)); 100501e04c3fSmrg } else { 100601e04c3fSmrg EXPECT_FALSE(validate(p)); 100701e04c3fSmrg } 100801e04c3fSmrg 100901e04c3fSmrg clear_instructions(p); 101001e04c3fSmrg 101101e04c3fSmrg brw_ADD(p, g0, g0, g0); 101201e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16); 101301e04c3fSmrg 101401e04c3fSmrg EXPECT_TRUE(validate(p)); 101501e04c3fSmrg 101601e04c3fSmrg clear_instructions(p); 101701e04c3fSmrg 10187ec681f3Smrg if (devinfo.ver >= 6) { 10197ec681f3Smrg gfx6_math(p, g0, BRW_MATH_FUNCTION_SIN, g0, null); 102001e04c3fSmrg 102101e04c3fSmrg EXPECT_TRUE(validate(p)); 102201e04c3fSmrg 102301e04c3fSmrg clear_instructions(p); 102401e04c3fSmrg 10257ec681f3Smrg gfx6_math(p, g0, BRW_MATH_FUNCTION_SIN, g0, null); 102601e04c3fSmrg brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 4); 102701e04c3fSmrg 102801e04c3fSmrg EXPECT_FALSE(validate(p)); 102901e04c3fSmrg } 103001e04c3fSmrg} 103101e04c3fSmrg 103201e04c3fSmrgTEST_P(validation_test, two_src_two_dst_source_offsets_must_be_same) 103301e04c3fSmrg{ 103401e04c3fSmrg brw_ADD(p, g0, g0, g0); 103501e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4); 103601e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4); 103701e04c3fSmrg brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 16); 103801e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_2); 103901e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1); 104001e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0); 104101e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 104201e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4); 104301e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 104401e04c3fSmrg 10457ec681f3Smrg if (devinfo.ver <= 7) { 104601e04c3fSmrg EXPECT_FALSE(validate(p)); 104701e04c3fSmrg } else { 104801e04c3fSmrg EXPECT_TRUE(validate(p)); 104901e04c3fSmrg } 105001e04c3fSmrg 105101e04c3fSmrg clear_instructions(p); 105201e04c3fSmrg 105301e04c3fSmrg brw_ADD(p, g0, g0, g0); 105401e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4); 105501e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_4); 105601e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 105701e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1); 105801e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0); 105901e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_8); 106001e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_2); 106101e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 106201e04c3fSmrg 106301e04c3fSmrg EXPECT_TRUE(validate(p)); 106401e04c3fSmrg} 106501e04c3fSmrg 106601e04c3fSmrgTEST_P(validation_test, two_src_two_dst_each_dst_must_be_derived_from_one_src) 106701e04c3fSmrg{ 106801e04c3fSmrg brw_MOV(p, g0, g0); 106901e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16); 107001e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 107101e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 107201e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 107301e04c3fSmrg brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 8); 107401e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 107501e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4); 107601e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 107701e04c3fSmrg 10787ec681f3Smrg if (devinfo.ver <= 7) { 107901e04c3fSmrg EXPECT_FALSE(validate(p)); 108001e04c3fSmrg } else { 108101e04c3fSmrg EXPECT_TRUE(validate(p)); 108201e04c3fSmrg } 108301e04c3fSmrg 108401e04c3fSmrg clear_instructions(p); 108501e04c3fSmrg 108601e04c3fSmrg brw_MOV(p, g0, g0); 108701e04c3fSmrg brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 16); 108801e04c3fSmrg brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, 8); 108901e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_2); 109001e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_2); 109101e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 109201e04c3fSmrg 10937ec681f3Smrg if (devinfo.ver <= 7) { 109401e04c3fSmrg EXPECT_FALSE(validate(p)); 109501e04c3fSmrg } else { 109601e04c3fSmrg EXPECT_TRUE(validate(p)); 109701e04c3fSmrg } 109801e04c3fSmrg} 109901e04c3fSmrg 110001e04c3fSmrgTEST_P(validation_test, one_src_two_dst) 110101e04c3fSmrg{ 110201e04c3fSmrg struct brw_reg g0_0 = brw_vec1_grf(0, 0); 110301e04c3fSmrg 110401e04c3fSmrg brw_ADD(p, g0, g0_0, g0_0); 110501e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16); 110601e04c3fSmrg 110701e04c3fSmrg EXPECT_TRUE(validate(p)); 110801e04c3fSmrg 110901e04c3fSmrg clear_instructions(p); 111001e04c3fSmrg 111101e04c3fSmrg brw_ADD(p, g0, g0, g0); 111201e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16); 111301e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_D); 111401e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 111501e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 111601e04c3fSmrg 111701e04c3fSmrg EXPECT_TRUE(validate(p)); 111801e04c3fSmrg 111901e04c3fSmrg clear_instructions(p); 112001e04c3fSmrg 112101e04c3fSmrg brw_ADD(p, g0, g0, g0); 112201e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16); 112301e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 112401e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 112501e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 112601e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 112701e04c3fSmrg brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0); 112801e04c3fSmrg brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_1); 112901e04c3fSmrg brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0); 113001e04c3fSmrg 11317ec681f3Smrg if (devinfo.ver >= 8) { 113201e04c3fSmrg EXPECT_TRUE(validate(p)); 113301e04c3fSmrg } else { 113401e04c3fSmrg EXPECT_FALSE(validate(p)); 113501e04c3fSmrg } 113601e04c3fSmrg 113701e04c3fSmrg clear_instructions(p); 113801e04c3fSmrg 113901e04c3fSmrg brw_ADD(p, g0, g0, g0); 114001e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_16); 114101e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 114201e04c3fSmrg brw_inst_set_dst_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 114301e04c3fSmrg brw_inst_set_src0_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 114401e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_0); 114501e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_1); 114601e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_0); 114701e04c3fSmrg brw_inst_set_src1_file_type(&devinfo, last_inst, BRW_GENERAL_REGISTER_FILE, BRW_REGISTER_TYPE_W); 114801e04c3fSmrg 11497ec681f3Smrg if (devinfo.ver >= 8) { 115001e04c3fSmrg EXPECT_TRUE(validate(p)); 115101e04c3fSmrg } else { 115201e04c3fSmrg EXPECT_FALSE(validate(p)); 115301e04c3fSmrg } 115401e04c3fSmrg} 115501e04c3fSmrg 115601e04c3fSmrgTEST_P(validation_test, packed_byte_destination) 115701e04c3fSmrg{ 115801e04c3fSmrg static const struct { 115901e04c3fSmrg enum brw_reg_type dst_type; 116001e04c3fSmrg enum brw_reg_type src_type; 116101e04c3fSmrg bool neg, abs, sat; 116201e04c3fSmrg bool expected_result; 116301e04c3fSmrg } move[] = { 116401e04c3fSmrg { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 0, 0, 0, true }, 116501e04c3fSmrg { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 0, 0, 0, true }, 116601e04c3fSmrg { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 0, 0, 0, true }, 116701e04c3fSmrg { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 0, 0, 0, true }, 116801e04c3fSmrg 116901e04c3fSmrg { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 1, 0, 0, false }, 117001e04c3fSmrg { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 1, 0, 0, false }, 117101e04c3fSmrg { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 1, 0, 0, false }, 117201e04c3fSmrg { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 1, 0, 0, false }, 117301e04c3fSmrg 117401e04c3fSmrg { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 0, 1, 0, false }, 117501e04c3fSmrg { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 0, 1, 0, false }, 117601e04c3fSmrg { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 0, 1, 0, false }, 117701e04c3fSmrg { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 0, 1, 0, false }, 117801e04c3fSmrg 117901e04c3fSmrg { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UB, 0, 0, 1, false }, 118001e04c3fSmrg { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_B , 0, 0, 1, false }, 118101e04c3fSmrg { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_B , 0, 0, 1, false }, 118201e04c3fSmrg { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_UB, 0, 0, 1, false }, 118301e04c3fSmrg 118401e04c3fSmrg { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UW, 0, 0, 0, false }, 118501e04c3fSmrg { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_W , 0, 0, 0, false }, 118601e04c3fSmrg { BRW_REGISTER_TYPE_UB, BRW_REGISTER_TYPE_UD, 0, 0, 0, false }, 118701e04c3fSmrg { BRW_REGISTER_TYPE_B , BRW_REGISTER_TYPE_D , 0, 0, 0, false }, 118801e04c3fSmrg }; 118901e04c3fSmrg 11907ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(move); i++) { 119101e04c3fSmrg brw_MOV(p, retype(g0, move[i].dst_type), retype(g0, move[i].src_type)); 119201e04c3fSmrg brw_inst_set_src0_negate(&devinfo, last_inst, move[i].neg); 119301e04c3fSmrg brw_inst_set_src0_abs(&devinfo, last_inst, move[i].abs); 119401e04c3fSmrg brw_inst_set_saturate(&devinfo, last_inst, move[i].sat); 119501e04c3fSmrg 119601e04c3fSmrg EXPECT_EQ(move[i].expected_result, validate(p)); 119701e04c3fSmrg 119801e04c3fSmrg clear_instructions(p); 119901e04c3fSmrg } 120001e04c3fSmrg 120101e04c3fSmrg brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_UB), 120201e04c3fSmrg retype(g0, BRW_REGISTER_TYPE_UB), 120301e04c3fSmrg retype(g0, BRW_REGISTER_TYPE_UB)); 120401e04c3fSmrg brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL); 120501e04c3fSmrg 120601e04c3fSmrg EXPECT_FALSE(validate(p)); 120701e04c3fSmrg 120801e04c3fSmrg clear_instructions(p); 120901e04c3fSmrg 121001e04c3fSmrg brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_B), 121101e04c3fSmrg retype(g0, BRW_REGISTER_TYPE_B), 121201e04c3fSmrg retype(g0, BRW_REGISTER_TYPE_B)); 121301e04c3fSmrg brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL); 121401e04c3fSmrg 121501e04c3fSmrg EXPECT_FALSE(validate(p)); 121601e04c3fSmrg} 121701e04c3fSmrg 121801e04c3fSmrgTEST_P(validation_test, byte_destination_relaxed_alignment) 121901e04c3fSmrg{ 122001e04c3fSmrg brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_B), 122101e04c3fSmrg retype(g0, BRW_REGISTER_TYPE_W), 122201e04c3fSmrg retype(g0, BRW_REGISTER_TYPE_W)); 122301e04c3fSmrg brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL); 122401e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 122501e04c3fSmrg 122601e04c3fSmrg EXPECT_TRUE(validate(p)); 122701e04c3fSmrg 122801e04c3fSmrg clear_instructions(p); 122901e04c3fSmrg 123001e04c3fSmrg brw_SEL(p, retype(g0, BRW_REGISTER_TYPE_B), 123101e04c3fSmrg retype(g0, BRW_REGISTER_TYPE_W), 123201e04c3fSmrg retype(g0, BRW_REGISTER_TYPE_W)); 123301e04c3fSmrg brw_inst_set_pred_control(&devinfo, last_inst, BRW_PREDICATE_NORMAL); 123401e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 123501e04c3fSmrg brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, 1); 123601e04c3fSmrg 12377ec681f3Smrg if (devinfo.ver > 4 || devinfo.is_g4x) { 123801e04c3fSmrg EXPECT_TRUE(validate(p)); 123901e04c3fSmrg } else { 124001e04c3fSmrg EXPECT_FALSE(validate(p)); 124101e04c3fSmrg } 124201e04c3fSmrg} 124301e04c3fSmrg 12449f464c52SmayaTEST_P(validation_test, byte_64bit_conversion) 12459f464c52Smaya{ 12469f464c52Smaya static const struct { 12479f464c52Smaya enum brw_reg_type dst_type; 12489f464c52Smaya enum brw_reg_type src_type; 12499f464c52Smaya unsigned dst_stride; 12509f464c52Smaya bool expected_result; 12519f464c52Smaya } inst[] = { 12529f464c52Smaya#define INST(dst_type, src_type, dst_stride, expected_result) \ 12539f464c52Smaya { \ 12549f464c52Smaya BRW_REGISTER_TYPE_##dst_type, \ 12559f464c52Smaya BRW_REGISTER_TYPE_##src_type, \ 12569f464c52Smaya BRW_HORIZONTAL_STRIDE_##dst_stride, \ 12579f464c52Smaya expected_result, \ 12589f464c52Smaya } 12599f464c52Smaya 12609f464c52Smaya INST(B, Q, 1, false), 12619f464c52Smaya INST(B, UQ, 1, false), 12629f464c52Smaya INST(B, DF, 1, false), 12639f464c52Smaya INST(UB, Q, 1, false), 12649f464c52Smaya INST(UB, UQ, 1, false), 12659f464c52Smaya INST(UB, DF, 1, false), 12669f464c52Smaya 12679f464c52Smaya INST(B, Q, 2, false), 12689f464c52Smaya INST(B, UQ, 2, false), 12699f464c52Smaya INST(B , DF, 2, false), 12709f464c52Smaya INST(UB, Q, 2, false), 12719f464c52Smaya INST(UB, UQ, 2, false), 12729f464c52Smaya INST(UB, DF, 2, false), 12739f464c52Smaya 12749f464c52Smaya INST(B, Q, 4, false), 12759f464c52Smaya INST(B, UQ, 4, false), 12769f464c52Smaya INST(B, DF, 4, false), 12779f464c52Smaya INST(UB, Q, 4, false), 12789f464c52Smaya INST(UB, UQ, 4, false), 12799f464c52Smaya INST(UB, DF, 4, false), 12809f464c52Smaya 12819f464c52Smaya#undef INST 12829f464c52Smaya }; 12839f464c52Smaya 12847ec681f3Smrg if (devinfo.ver < 8) 12859f464c52Smaya return; 12869f464c52Smaya 12877ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 12887ec681f3Smrg if (!devinfo.has_64bit_float && 12897ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_DF) 12907ec681f3Smrg continue; 12917ec681f3Smrg 12927ec681f3Smrg if (!devinfo.has_64bit_int && 12937ec681f3Smrg (inst[i].src_type == BRW_REGISTER_TYPE_Q || 12947ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_UQ)) 12959f464c52Smaya continue; 12969f464c52Smaya 12979f464c52Smaya brw_MOV(p, retype(g0, inst[i].dst_type), retype(g0, inst[i].src_type)); 12989f464c52Smaya brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride); 12999f464c52Smaya EXPECT_EQ(inst[i].expected_result, validate(p)); 13009f464c52Smaya 13019f464c52Smaya clear_instructions(p); 13029f464c52Smaya } 13039f464c52Smaya} 13049f464c52Smaya 13059f464c52SmayaTEST_P(validation_test, half_float_conversion) 13069f464c52Smaya{ 13079f464c52Smaya static const struct { 13089f464c52Smaya enum brw_reg_type dst_type; 13099f464c52Smaya enum brw_reg_type src_type; 13109f464c52Smaya unsigned dst_stride; 13119f464c52Smaya unsigned dst_subnr; 13129f464c52Smaya bool expected_result_bdw; 13137ec681f3Smrg bool expected_result_chv_gfx9; 13149f464c52Smaya } inst[] = { 13159f464c52Smaya#define INST_C(dst_type, src_type, dst_stride, dst_subnr, expected_result) \ 13169f464c52Smaya { \ 13179f464c52Smaya BRW_REGISTER_TYPE_##dst_type, \ 13189f464c52Smaya BRW_REGISTER_TYPE_##src_type, \ 13199f464c52Smaya BRW_HORIZONTAL_STRIDE_##dst_stride, \ 13209f464c52Smaya dst_subnr, \ 13219f464c52Smaya expected_result, \ 13229f464c52Smaya expected_result, \ 13239f464c52Smaya } 13249f464c52Smaya#define INST_S(dst_type, src_type, dst_stride, dst_subnr, \ 13257ec681f3Smrg expected_result_bdw, expected_result_chv_gfx9) \ 13269f464c52Smaya { \ 13279f464c52Smaya BRW_REGISTER_TYPE_##dst_type, \ 13289f464c52Smaya BRW_REGISTER_TYPE_##src_type, \ 13299f464c52Smaya BRW_HORIZONTAL_STRIDE_##dst_stride, \ 13309f464c52Smaya dst_subnr, \ 13319f464c52Smaya expected_result_bdw, \ 13327ec681f3Smrg expected_result_chv_gfx9, \ 13339f464c52Smaya } 13349f464c52Smaya 13359f464c52Smaya /* MOV to half-float destination */ 13369f464c52Smaya INST_C(HF, B, 1, 0, false), 13379f464c52Smaya INST_C(HF, W, 1, 0, false), 13389f464c52Smaya INST_C(HF, HF, 1, 0, true), 13399f464c52Smaya INST_C(HF, HF, 1, 2, true), 13409f464c52Smaya INST_C(HF, D, 1, 0, false), 13419f464c52Smaya INST_S(HF, F, 1, 0, false, true), 13429f464c52Smaya INST_C(HF, Q, 1, 0, false), 13439f464c52Smaya INST_C(HF, B, 2, 0, true), 13449f464c52Smaya INST_C(HF, B, 2, 2, false), 13459f464c52Smaya INST_C(HF, W, 2, 0, true), 13469f464c52Smaya INST_C(HF, W, 2, 2, false), 13479f464c52Smaya INST_C(HF, HF, 2, 0, true), 13489f464c52Smaya INST_C(HF, HF, 2, 2, true), 13499f464c52Smaya INST_C(HF, D, 2, 0, true), 13509f464c52Smaya INST_C(HF, D, 2, 2, false), 13519f464c52Smaya INST_C(HF, F, 2, 0, true), 13529f464c52Smaya INST_S(HF, F, 2, 2, false, true), 13539f464c52Smaya INST_C(HF, Q, 2, 0, false), 13549f464c52Smaya INST_C(HF, DF, 2, 0, false), 13559f464c52Smaya INST_C(HF, B, 4, 0, false), 13569f464c52Smaya INST_C(HF, W, 4, 0, false), 13579f464c52Smaya INST_C(HF, HF, 4, 0, true), 13589f464c52Smaya INST_C(HF, HF, 4, 2, true), 13599f464c52Smaya INST_C(HF, D, 4, 0, false), 13609f464c52Smaya INST_C(HF, F, 4, 0, false), 13619f464c52Smaya INST_C(HF, Q, 4, 0, false), 13629f464c52Smaya INST_C(HF, DF, 4, 0, false), 13639f464c52Smaya 13649f464c52Smaya /* MOV from half-float source */ 13659f464c52Smaya INST_C( B, HF, 1, 0, false), 13669f464c52Smaya INST_C( W, HF, 1, 0, false), 13679f464c52Smaya INST_C( D, HF, 1, 0, true), 13689f464c52Smaya INST_C( D, HF, 1, 4, true), 13699f464c52Smaya INST_C( F, HF, 1, 0, true), 13709f464c52Smaya INST_C( F, HF, 1, 4, true), 13719f464c52Smaya INST_C( Q, HF, 1, 0, false), 13729f464c52Smaya INST_C(DF, HF, 1, 0, false), 13739f464c52Smaya INST_C( B, HF, 2, 0, false), 13749f464c52Smaya INST_C( W, HF, 2, 0, true), 13759f464c52Smaya INST_C( W, HF, 2, 2, false), 13769f464c52Smaya INST_C( D, HF, 2, 0, false), 13779f464c52Smaya INST_C( F, HF, 2, 0, true), 13789f464c52Smaya INST_C( B, HF, 4, 0, true), 13799f464c52Smaya INST_C( B, HF, 4, 1, false), 13809f464c52Smaya INST_C( W, HF, 4, 0, false), 13819f464c52Smaya 13829f464c52Smaya#undef INST_C 13839f464c52Smaya#undef INST_S 13849f464c52Smaya }; 13859f464c52Smaya 13867ec681f3Smrg if (devinfo.ver < 8) 13879f464c52Smaya return; 13889f464c52Smaya 13897ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 13907ec681f3Smrg if (!devinfo.has_64bit_float && 13917ec681f3Smrg (inst[i].dst_type == BRW_REGISTER_TYPE_DF || 13927ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_DF)) 13937ec681f3Smrg continue; 13947ec681f3Smrg 13957ec681f3Smrg if (!devinfo.has_64bit_int && 13967ec681f3Smrg (inst[i].dst_type == BRW_REGISTER_TYPE_Q || 13977ec681f3Smrg inst[i].dst_type == BRW_REGISTER_TYPE_UQ || 13987ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_Q || 13997ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_UQ)) 14009f464c52Smaya continue; 14019f464c52Smaya 14029f464c52Smaya brw_MOV(p, retype(g0, inst[i].dst_type), retype(g0, inst[i].src_type)); 14039f464c52Smaya 14049f464c52Smaya brw_inst_set_exec_size(&devinfo, last_inst, BRW_EXECUTE_4); 14059f464c52Smaya 14069f464c52Smaya brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride); 14079f464c52Smaya brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, inst[i].dst_subnr); 14089f464c52Smaya 14099f464c52Smaya if (inst[i].src_type == BRW_REGISTER_TYPE_B) { 14109f464c52Smaya brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 14119f464c52Smaya brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_2); 14129f464c52Smaya brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_2); 14139f464c52Smaya } else { 14149f464c52Smaya brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 14159f464c52Smaya brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4); 14169f464c52Smaya brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 14179f464c52Smaya } 14189f464c52Smaya 14197ec681f3Smrg if (devinfo.is_cherryview || devinfo.ver >= 9) 14207ec681f3Smrg EXPECT_EQ(inst[i].expected_result_chv_gfx9, validate(p)); 14219f464c52Smaya else 14229f464c52Smaya EXPECT_EQ(inst[i].expected_result_bdw, validate(p)); 14239f464c52Smaya 14249f464c52Smaya clear_instructions(p); 14259f464c52Smaya } 14269f464c52Smaya} 14279f464c52Smaya 14289f464c52SmayaTEST_P(validation_test, mixed_float_source_indirect_addressing) 14299f464c52Smaya{ 14309f464c52Smaya static const struct { 14319f464c52Smaya enum brw_reg_type dst_type; 14329f464c52Smaya enum brw_reg_type src0_type; 14339f464c52Smaya enum brw_reg_type src1_type; 14349f464c52Smaya unsigned dst_stride; 14359f464c52Smaya bool dst_indirect; 14369f464c52Smaya bool src0_indirect; 14379f464c52Smaya bool expected_result; 14389f464c52Smaya } inst[] = { 14399f464c52Smaya#define INST(dst_type, src0_type, src1_type, \ 14409f464c52Smaya dst_stride, dst_indirect, src0_indirect, expected_result) \ 14419f464c52Smaya { \ 14429f464c52Smaya BRW_REGISTER_TYPE_##dst_type, \ 14439f464c52Smaya BRW_REGISTER_TYPE_##src0_type, \ 14449f464c52Smaya BRW_REGISTER_TYPE_##src1_type, \ 14459f464c52Smaya BRW_HORIZONTAL_STRIDE_##dst_stride, \ 14469f464c52Smaya dst_indirect, \ 14479f464c52Smaya src0_indirect, \ 14489f464c52Smaya expected_result, \ 14499f464c52Smaya } 14509f464c52Smaya 14519f464c52Smaya /* Source and dest are mixed float: indirect src addressing not allowed */ 14529f464c52Smaya INST(HF, F, F, 2, false, false, true), 14539f464c52Smaya INST(HF, F, F, 2, true, false, true), 14549f464c52Smaya INST(HF, F, F, 2, false, true, false), 14559f464c52Smaya INST(HF, F, F, 2, true, true, false), 14569f464c52Smaya INST( F, HF, F, 1, false, false, true), 14579f464c52Smaya INST( F, HF, F, 1, true, false, true), 14589f464c52Smaya INST( F, HF, F, 1, false, true, false), 14599f464c52Smaya INST( F, HF, F, 1, true, true, false), 14609f464c52Smaya 14619f464c52Smaya INST(HF, HF, F, 2, false, false, true), 14629f464c52Smaya INST(HF, HF, F, 2, true, false, true), 14639f464c52Smaya INST(HF, HF, F, 2, false, true, false), 14649f464c52Smaya INST(HF, HF, F, 2, true, true, false), 14659f464c52Smaya INST( F, F, HF, 1, false, false, true), 14669f464c52Smaya INST( F, F, HF, 1, true, false, true), 14679f464c52Smaya INST( F, F, HF, 1, false, true, false), 14689f464c52Smaya INST( F, F, HF, 1, true, true, false), 14699f464c52Smaya 14709f464c52Smaya#undef INST 14719f464c52Smaya }; 14729f464c52Smaya 14737ec681f3Smrg if (devinfo.ver < 8) 14749f464c52Smaya return; 14759f464c52Smaya 14767ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 14779f464c52Smaya brw_ADD(p, retype(g0, inst[i].dst_type), 14789f464c52Smaya retype(g0, inst[i].src0_type), 14799f464c52Smaya retype(g0, inst[i].src1_type)); 14809f464c52Smaya 14819f464c52Smaya brw_inst_set_dst_address_mode(&devinfo, last_inst, inst[i].dst_indirect); 14829f464c52Smaya brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride); 14839f464c52Smaya brw_inst_set_src0_address_mode(&devinfo, last_inst, inst[i].src0_indirect); 14849f464c52Smaya 14859f464c52Smaya EXPECT_EQ(inst[i].expected_result, validate(p)); 14869f464c52Smaya 14879f464c52Smaya clear_instructions(p); 14889f464c52Smaya } 14899f464c52Smaya} 14909f464c52Smaya 14919f464c52SmayaTEST_P(validation_test, mixed_float_align1_simd16) 14929f464c52Smaya{ 14939f464c52Smaya static const struct { 14949f464c52Smaya unsigned exec_size; 14959f464c52Smaya enum brw_reg_type dst_type; 14969f464c52Smaya enum brw_reg_type src0_type; 14979f464c52Smaya enum brw_reg_type src1_type; 14989f464c52Smaya unsigned dst_stride; 14999f464c52Smaya bool expected_result; 15009f464c52Smaya } inst[] = { 15019f464c52Smaya#define INST(exec_size, dst_type, src0_type, src1_type, \ 15029f464c52Smaya dst_stride, expected_result) \ 15039f464c52Smaya { \ 15049f464c52Smaya BRW_EXECUTE_##exec_size, \ 15059f464c52Smaya BRW_REGISTER_TYPE_##dst_type, \ 15069f464c52Smaya BRW_REGISTER_TYPE_##src0_type, \ 15079f464c52Smaya BRW_REGISTER_TYPE_##src1_type, \ 15089f464c52Smaya BRW_HORIZONTAL_STRIDE_##dst_stride, \ 15099f464c52Smaya expected_result, \ 15109f464c52Smaya } 15119f464c52Smaya 15129f464c52Smaya /* No SIMD16 in mixed mode when destination is packed f16 */ 15139f464c52Smaya INST( 8, HF, F, HF, 2, true), 15149f464c52Smaya INST(16, HF, HF, F, 2, true), 15159f464c52Smaya INST(16, HF, HF, F, 1, false), 15169f464c52Smaya INST(16, HF, F, HF, 1, false), 15179f464c52Smaya 15189f464c52Smaya /* No SIMD16 in mixed mode when destination is f32 */ 15199f464c52Smaya INST( 8, F, HF, F, 1, true), 15209f464c52Smaya INST( 8, F, F, HF, 1, true), 15219f464c52Smaya INST(16, F, HF, F, 1, false), 15229f464c52Smaya INST(16, F, F, HF, 1, false), 15239f464c52Smaya 15249f464c52Smaya#undef INST 15259f464c52Smaya }; 15269f464c52Smaya 15277ec681f3Smrg if (devinfo.ver < 8) 15289f464c52Smaya return; 15299f464c52Smaya 15307ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 15319f464c52Smaya brw_ADD(p, retype(g0, inst[i].dst_type), 15329f464c52Smaya retype(g0, inst[i].src0_type), 15339f464c52Smaya retype(g0, inst[i].src1_type)); 15349f464c52Smaya 15359f464c52Smaya brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size); 15369f464c52Smaya 15379f464c52Smaya brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride); 15389f464c52Smaya 15399f464c52Smaya EXPECT_EQ(inst[i].expected_result, validate(p)); 15409f464c52Smaya 15419f464c52Smaya clear_instructions(p); 15429f464c52Smaya } 15439f464c52Smaya} 15449f464c52Smaya 15459f464c52SmayaTEST_P(validation_test, mixed_float_align1_packed_fp16_dst_acc_read_offset_0) 15469f464c52Smaya{ 15479f464c52Smaya static const struct { 15489f464c52Smaya enum brw_reg_type dst_type; 15499f464c52Smaya enum brw_reg_type src0_type; 15509f464c52Smaya enum brw_reg_type src1_type; 15519f464c52Smaya unsigned dst_stride; 15529f464c52Smaya bool read_acc; 15539f464c52Smaya unsigned subnr; 15549f464c52Smaya bool expected_result_bdw; 15559f464c52Smaya bool expected_result_chv_skl; 15569f464c52Smaya } inst[] = { 15579f464c52Smaya#define INST(dst_type, src0_type, src1_type, dst_stride, read_acc, subnr, \ 15589f464c52Smaya expected_result_bdw, expected_result_chv_skl) \ 15599f464c52Smaya { \ 15609f464c52Smaya BRW_REGISTER_TYPE_##dst_type, \ 15619f464c52Smaya BRW_REGISTER_TYPE_##src0_type, \ 15629f464c52Smaya BRW_REGISTER_TYPE_##src1_type, \ 15639f464c52Smaya BRW_HORIZONTAL_STRIDE_##dst_stride, \ 15649f464c52Smaya read_acc, \ 15659f464c52Smaya subnr, \ 15669f464c52Smaya expected_result_bdw, \ 15679f464c52Smaya expected_result_chv_skl, \ 15689f464c52Smaya } 15699f464c52Smaya 15709f464c52Smaya /* Destination is not packed */ 15719f464c52Smaya INST(HF, HF, F, 2, true, 0, true, true), 15729f464c52Smaya INST(HF, HF, F, 2, true, 2, true, true), 15739f464c52Smaya INST(HF, HF, F, 2, true, 4, true, true), 15749f464c52Smaya INST(HF, HF, F, 2, true, 8, true, true), 15759f464c52Smaya INST(HF, HF, F, 2, true, 16, true, true), 15769f464c52Smaya 15779f464c52Smaya /* Destination is packed, we don't read acc */ 15789f464c52Smaya INST(HF, HF, F, 1, false, 0, false, true), 15799f464c52Smaya INST(HF, HF, F, 1, false, 2, false, true), 15809f464c52Smaya INST(HF, HF, F, 1, false, 4, false, true), 15819f464c52Smaya INST(HF, HF, F, 1, false, 8, false, true), 15829f464c52Smaya INST(HF, HF, F, 1, false, 16, false, true), 15839f464c52Smaya 15849f464c52Smaya /* Destination is packed, we read acc */ 15859f464c52Smaya INST(HF, HF, F, 1, true, 0, false, false), 15869f464c52Smaya INST(HF, HF, F, 1, true, 2, false, false), 15879f464c52Smaya INST(HF, HF, F, 1, true, 4, false, false), 15889f464c52Smaya INST(HF, HF, F, 1, true, 8, false, false), 15899f464c52Smaya INST(HF, HF, F, 1, true, 16, false, false), 15909f464c52Smaya 15919f464c52Smaya#undef INST 15929f464c52Smaya }; 15939f464c52Smaya 15947ec681f3Smrg if (devinfo.ver < 8) 15959f464c52Smaya return; 15969f464c52Smaya 15977ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 15989f464c52Smaya brw_ADD(p, retype(g0, inst[i].dst_type), 15999f464c52Smaya retype(inst[i].read_acc ? acc0 : g0, inst[i].src0_type), 16009f464c52Smaya retype(g0, inst[i].src1_type)); 16019f464c52Smaya 16029f464c52Smaya brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride); 16039f464c52Smaya 16049f464c52Smaya brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, inst[i].subnr); 16059f464c52Smaya 16067ec681f3Smrg if (devinfo.is_cherryview || devinfo.ver >= 9) 16079f464c52Smaya EXPECT_EQ(inst[i].expected_result_chv_skl, validate(p)); 16089f464c52Smaya else 16099f464c52Smaya EXPECT_EQ(inst[i].expected_result_bdw, validate(p)); 16109f464c52Smaya 16119f464c52Smaya clear_instructions(p); 16129f464c52Smaya } 16139f464c52Smaya} 16149f464c52Smaya 16159f464c52SmayaTEST_P(validation_test, mixed_float_fp16_dest_with_acc) 16169f464c52Smaya{ 16179f464c52Smaya static const struct { 16189f464c52Smaya unsigned exec_size; 16199f464c52Smaya unsigned opcode; 16209f464c52Smaya enum brw_reg_type dst_type; 16219f464c52Smaya enum brw_reg_type src0_type; 16229f464c52Smaya enum brw_reg_type src1_type; 16239f464c52Smaya unsigned dst_stride; 16249f464c52Smaya bool read_acc; 16259f464c52Smaya bool expected_result_bdw; 16269f464c52Smaya bool expected_result_chv_skl; 16279f464c52Smaya } inst[] = { 16289f464c52Smaya#define INST(exec_size, opcode, dst_type, src0_type, src1_type, \ 16299f464c52Smaya dst_stride, read_acc,expected_result_bdw, \ 16309f464c52Smaya expected_result_chv_skl) \ 16319f464c52Smaya { \ 16329f464c52Smaya BRW_EXECUTE_##exec_size, \ 16339f464c52Smaya BRW_OPCODE_##opcode, \ 16349f464c52Smaya BRW_REGISTER_TYPE_##dst_type, \ 16359f464c52Smaya BRW_REGISTER_TYPE_##src0_type, \ 16369f464c52Smaya BRW_REGISTER_TYPE_##src1_type, \ 16379f464c52Smaya BRW_HORIZONTAL_STRIDE_##dst_stride, \ 16389f464c52Smaya read_acc, \ 16399f464c52Smaya expected_result_bdw, \ 16409f464c52Smaya expected_result_chv_skl, \ 16419f464c52Smaya } 16429f464c52Smaya 16439f464c52Smaya /* Packed fp16 dest with implicit acc needs hstride=2 */ 16449f464c52Smaya INST(8, MAC, HF, HF, F, 1, false, false, false), 16459f464c52Smaya INST(8, MAC, HF, HF, F, 2, false, true, true), 16469f464c52Smaya INST(8, MAC, HF, F, HF, 1, false, false, false), 16479f464c52Smaya INST(8, MAC, HF, F, HF, 2, false, true, true), 16489f464c52Smaya 16499f464c52Smaya /* Packed fp16 dest with explicit acc needs hstride=2 */ 16509f464c52Smaya INST(8, ADD, HF, HF, F, 1, true, false, false), 16519f464c52Smaya INST(8, ADD, HF, HF, F, 2, true, true, true), 16529f464c52Smaya INST(8, ADD, HF, F, HF, 1, true, false, false), 16539f464c52Smaya INST(8, ADD, HF, F, HF, 2, true, true, true), 16549f464c52Smaya 16559f464c52Smaya /* If destination is not fp16, restriction doesn't apply */ 16569f464c52Smaya INST(8, MAC, F, HF, F, 1, false, true, true), 16579f464c52Smaya INST(8, MAC, F, HF, F, 2, false, true, true), 16589f464c52Smaya 16599f464c52Smaya /* If there is no implicit/explicit acc, restriction doesn't apply */ 16609f464c52Smaya INST(8, ADD, HF, HF, F, 1, false, false, true), 16619f464c52Smaya INST(8, ADD, HF, HF, F, 2, false, true, true), 16629f464c52Smaya INST(8, ADD, HF, F, HF, 1, false, false, true), 16639f464c52Smaya INST(8, ADD, HF, F, HF, 2, false, true, true), 16649f464c52Smaya INST(8, ADD, F, HF, F, 1, false, true, true), 16659f464c52Smaya INST(8, ADD, F, HF, F, 2, false, true, true), 16669f464c52Smaya 16679f464c52Smaya#undef INST 16689f464c52Smaya }; 16699f464c52Smaya 16707ec681f3Smrg if (devinfo.ver < 8) 16719f464c52Smaya return; 16729f464c52Smaya 16737ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 16749f464c52Smaya if (inst[i].opcode == BRW_OPCODE_MAC) { 16759f464c52Smaya brw_MAC(p, retype(g0, inst[i].dst_type), 16769f464c52Smaya retype(g0, inst[i].src0_type), 16779f464c52Smaya retype(g0, inst[i].src1_type)); 16789f464c52Smaya } else { 16799f464c52Smaya assert(inst[i].opcode == BRW_OPCODE_ADD); 16809f464c52Smaya brw_ADD(p, retype(g0, inst[i].dst_type), 16819f464c52Smaya retype(inst[i].read_acc ? acc0: g0, inst[i].src0_type), 16829f464c52Smaya retype(g0, inst[i].src1_type)); 16839f464c52Smaya } 16849f464c52Smaya 16859f464c52Smaya brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size); 16869f464c52Smaya 16879f464c52Smaya brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride); 16889f464c52Smaya 16897ec681f3Smrg if (devinfo.is_cherryview || devinfo.ver >= 9) 16909f464c52Smaya EXPECT_EQ(inst[i].expected_result_chv_skl, validate(p)); 16919f464c52Smaya else 16929f464c52Smaya EXPECT_EQ(inst[i].expected_result_bdw, validate(p)); 16939f464c52Smaya 16949f464c52Smaya clear_instructions(p); 16959f464c52Smaya } 16969f464c52Smaya} 16979f464c52Smaya 16989f464c52SmayaTEST_P(validation_test, mixed_float_align1_math_strided_fp16_inputs) 16999f464c52Smaya{ 17009f464c52Smaya static const struct { 17019f464c52Smaya enum brw_reg_type dst_type; 17029f464c52Smaya enum brw_reg_type src0_type; 17039f464c52Smaya enum brw_reg_type src1_type; 17049f464c52Smaya unsigned dst_stride; 17059f464c52Smaya unsigned src0_stride; 17069f464c52Smaya unsigned src1_stride; 17079f464c52Smaya bool expected_result; 17089f464c52Smaya } inst[] = { 17099f464c52Smaya#define INST(dst_type, src0_type, src1_type, \ 17109f464c52Smaya dst_stride, src0_stride, src1_stride, expected_result) \ 17119f464c52Smaya { \ 17129f464c52Smaya BRW_REGISTER_TYPE_##dst_type, \ 17139f464c52Smaya BRW_REGISTER_TYPE_##src0_type, \ 17149f464c52Smaya BRW_REGISTER_TYPE_##src1_type, \ 17159f464c52Smaya BRW_HORIZONTAL_STRIDE_##dst_stride, \ 17169f464c52Smaya BRW_HORIZONTAL_STRIDE_##src0_stride, \ 17179f464c52Smaya BRW_HORIZONTAL_STRIDE_##src1_stride, \ 17189f464c52Smaya expected_result, \ 17199f464c52Smaya } 17209f464c52Smaya 17219f464c52Smaya INST(HF, HF, F, 2, 2, 1, true), 17229f464c52Smaya INST(HF, F, HF, 2, 1, 2, true), 17239f464c52Smaya INST(HF, F, HF, 1, 1, 2, true), 17249f464c52Smaya INST(HF, F, HF, 2, 1, 1, false), 17259f464c52Smaya INST(HF, HF, F, 2, 1, 1, false), 17269f464c52Smaya INST(HF, HF, F, 1, 1, 1, false), 17279f464c52Smaya INST(HF, HF, F, 2, 1, 1, false), 17289f464c52Smaya INST( F, HF, F, 1, 1, 1, false), 17299f464c52Smaya INST( F, F, HF, 1, 1, 2, true), 17309f464c52Smaya INST( F, HF, HF, 1, 2, 1, false), 17319f464c52Smaya INST( F, HF, HF, 1, 2, 2, true), 17329f464c52Smaya 17339f464c52Smaya#undef INST 17349f464c52Smaya }; 17359f464c52Smaya 17367ec681f3Smrg /* No half-float math in gfx8 */ 17377ec681f3Smrg if (devinfo.ver < 9) 17389f464c52Smaya return; 17399f464c52Smaya 17407ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 17417ec681f3Smrg gfx6_math(p, retype(g0, inst[i].dst_type), 17429f464c52Smaya BRW_MATH_FUNCTION_POW, 17439f464c52Smaya retype(g0, inst[i].src0_type), 17449f464c52Smaya retype(g0, inst[i].src1_type)); 17459f464c52Smaya 17469f464c52Smaya brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride); 17479f464c52Smaya 17489f464c52Smaya brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 17499f464c52Smaya brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4); 17509f464c52Smaya brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src0_stride); 17519f464c52Smaya 17529f464c52Smaya brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 17539f464c52Smaya brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4); 17549f464c52Smaya brw_inst_set_src1_hstride(&devinfo, last_inst, inst[i].src1_stride); 17559f464c52Smaya 17569f464c52Smaya EXPECT_EQ(inst[i].expected_result, validate(p)); 17579f464c52Smaya 17589f464c52Smaya clear_instructions(p); 17599f464c52Smaya } 17609f464c52Smaya} 17619f464c52Smaya 17629f464c52SmayaTEST_P(validation_test, mixed_float_align1_packed_fp16_dst) 17639f464c52Smaya{ 17649f464c52Smaya static const struct { 17659f464c52Smaya unsigned exec_size; 17669f464c52Smaya enum brw_reg_type dst_type; 17679f464c52Smaya enum brw_reg_type src0_type; 17689f464c52Smaya enum brw_reg_type src1_type; 17699f464c52Smaya unsigned dst_stride; 17709f464c52Smaya unsigned dst_subnr; 17719f464c52Smaya bool expected_result_bdw; 17729f464c52Smaya bool expected_result_chv_skl; 17739f464c52Smaya } inst[] = { 17749f464c52Smaya#define INST(exec_size, dst_type, src0_type, src1_type, dst_stride, dst_subnr, \ 17759f464c52Smaya expected_result_bdw, expected_result_chv_skl) \ 17769f464c52Smaya { \ 17779f464c52Smaya BRW_EXECUTE_##exec_size, \ 17789f464c52Smaya BRW_REGISTER_TYPE_##dst_type, \ 17799f464c52Smaya BRW_REGISTER_TYPE_##src0_type, \ 17809f464c52Smaya BRW_REGISTER_TYPE_##src1_type, \ 17819f464c52Smaya BRW_HORIZONTAL_STRIDE_##dst_stride, \ 17829f464c52Smaya dst_subnr, \ 17839f464c52Smaya expected_result_bdw, \ 17849f464c52Smaya expected_result_chv_skl \ 17859f464c52Smaya } 17869f464c52Smaya 17879f464c52Smaya /* SIMD8 packed fp16 dst won't cross oword boundaries if region is 17889f464c52Smaya * oword-aligned 17899f464c52Smaya */ 17909f464c52Smaya INST( 8, HF, HF, F, 1, 0, false, true), 17919f464c52Smaya INST( 8, HF, HF, F, 1, 2, false, false), 17929f464c52Smaya INST( 8, HF, HF, F, 1, 4, false, false), 17939f464c52Smaya INST( 8, HF, HF, F, 1, 8, false, false), 17949f464c52Smaya INST( 8, HF, HF, F, 1, 16, false, true), 17959f464c52Smaya 17969f464c52Smaya /* SIMD16 packed fp16 always crosses oword boundaries */ 17979f464c52Smaya INST(16, HF, HF, F, 1, 0, false, false), 17989f464c52Smaya INST(16, HF, HF, F, 1, 2, false, false), 17999f464c52Smaya INST(16, HF, HF, F, 1, 4, false, false), 18009f464c52Smaya INST(16, HF, HF, F, 1, 8, false, false), 18019f464c52Smaya INST(16, HF, HF, F, 1, 16, false, false), 18029f464c52Smaya 18039f464c52Smaya /* If destination is not packed (or not fp16) we can cross oword 18049f464c52Smaya * boundaries 18059f464c52Smaya */ 18069f464c52Smaya INST( 8, HF, HF, F, 2, 0, true, true), 18079f464c52Smaya INST( 8, F, HF, F, 1, 0, true, true), 18089f464c52Smaya 18099f464c52Smaya#undef INST 18109f464c52Smaya }; 18119f464c52Smaya 18127ec681f3Smrg if (devinfo.ver < 8) 18139f464c52Smaya return; 18149f464c52Smaya 18157ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 18169f464c52Smaya brw_ADD(p, retype(g0, inst[i].dst_type), 18179f464c52Smaya retype(g0, inst[i].src0_type), 18189f464c52Smaya retype(g0, inst[i].src1_type)); 18199f464c52Smaya 18209f464c52Smaya brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride); 18219f464c52Smaya brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, inst[i].dst_subnr); 18229f464c52Smaya 18239f464c52Smaya brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 18249f464c52Smaya brw_inst_set_src0_width(&devinfo, last_inst, BRW_WIDTH_4); 18259f464c52Smaya brw_inst_set_src0_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 18269f464c52Smaya 18279f464c52Smaya brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 18289f464c52Smaya brw_inst_set_src1_width(&devinfo, last_inst, BRW_WIDTH_4); 18299f464c52Smaya brw_inst_set_src1_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 18309f464c52Smaya 18319f464c52Smaya brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size); 18329f464c52Smaya 18337ec681f3Smrg if (devinfo.is_cherryview || devinfo.ver >= 9) 18349f464c52Smaya EXPECT_EQ(inst[i].expected_result_chv_skl, validate(p)); 18359f464c52Smaya else 18369f464c52Smaya EXPECT_EQ(inst[i].expected_result_bdw, validate(p)); 18379f464c52Smaya 18389f464c52Smaya clear_instructions(p); 18399f464c52Smaya } 18409f464c52Smaya} 18419f464c52Smaya 18429f464c52SmayaTEST_P(validation_test, mixed_float_align16_packed_data) 18439f464c52Smaya{ 18449f464c52Smaya static const struct { 18459f464c52Smaya enum brw_reg_type dst_type; 18469f464c52Smaya enum brw_reg_type src0_type; 18479f464c52Smaya enum brw_reg_type src1_type; 18489f464c52Smaya unsigned src0_vstride; 18499f464c52Smaya unsigned src1_vstride; 18509f464c52Smaya bool expected_result; 18519f464c52Smaya } inst[] = { 18529f464c52Smaya#define INST(dst_type, src0_type, src1_type, \ 18539f464c52Smaya src0_vstride, src1_vstride, expected_result) \ 18549f464c52Smaya { \ 18559f464c52Smaya BRW_REGISTER_TYPE_##dst_type, \ 18569f464c52Smaya BRW_REGISTER_TYPE_##src0_type, \ 18579f464c52Smaya BRW_REGISTER_TYPE_##src1_type, \ 18589f464c52Smaya BRW_VERTICAL_STRIDE_##src0_vstride, \ 18599f464c52Smaya BRW_VERTICAL_STRIDE_##src1_vstride, \ 18609f464c52Smaya expected_result, \ 18619f464c52Smaya } 18629f464c52Smaya 18639f464c52Smaya /* We only test with F destination because there is a restriction 18649f464c52Smaya * by which F->HF conversions need to be DWord aligned but Align16 also 18659f464c52Smaya * requires that destination horizontal stride is 1. 18669f464c52Smaya */ 18679f464c52Smaya INST(F, F, HF, 4, 4, true), 18689f464c52Smaya INST(F, F, HF, 2, 4, false), 18699f464c52Smaya INST(F, F, HF, 4, 2, false), 18709f464c52Smaya INST(F, F, HF, 0, 4, false), 18719f464c52Smaya INST(F, F, HF, 4, 0, false), 18729f464c52Smaya INST(F, HF, F, 4, 4, true), 18739f464c52Smaya INST(F, HF, F, 4, 2, false), 18749f464c52Smaya INST(F, HF, F, 2, 4, false), 18759f464c52Smaya INST(F, HF, F, 0, 4, false), 18769f464c52Smaya INST(F, HF, F, 4, 0, false), 18779f464c52Smaya 18789f464c52Smaya#undef INST 18799f464c52Smaya }; 18809f464c52Smaya 18817ec681f3Smrg if (devinfo.ver < 8 || devinfo.ver >= 11) 18829f464c52Smaya return; 18839f464c52Smaya 18849f464c52Smaya brw_set_default_access_mode(p, BRW_ALIGN_16); 18859f464c52Smaya 18867ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 18879f464c52Smaya brw_ADD(p, retype(g0, inst[i].dst_type), 18889f464c52Smaya retype(g0, inst[i].src0_type), 18899f464c52Smaya retype(g0, inst[i].src1_type)); 18909f464c52Smaya 18919f464c52Smaya brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src0_vstride); 18929f464c52Smaya brw_inst_set_src1_vstride(&devinfo, last_inst, inst[i].src1_vstride); 18939f464c52Smaya 18949f464c52Smaya EXPECT_EQ(inst[i].expected_result, validate(p)); 18959f464c52Smaya 18969f464c52Smaya clear_instructions(p); 18979f464c52Smaya } 18989f464c52Smaya} 18999f464c52Smaya 19009f464c52SmayaTEST_P(validation_test, mixed_float_align16_no_simd16) 19019f464c52Smaya{ 19029f464c52Smaya static const struct { 19039f464c52Smaya unsigned exec_size; 19049f464c52Smaya enum brw_reg_type dst_type; 19059f464c52Smaya enum brw_reg_type src0_type; 19069f464c52Smaya enum brw_reg_type src1_type; 19079f464c52Smaya bool expected_result; 19089f464c52Smaya } inst[] = { 19099f464c52Smaya#define INST(exec_size, dst_type, src0_type, src1_type, expected_result) \ 19109f464c52Smaya { \ 19119f464c52Smaya BRW_EXECUTE_##exec_size, \ 19129f464c52Smaya BRW_REGISTER_TYPE_##dst_type, \ 19139f464c52Smaya BRW_REGISTER_TYPE_##src0_type, \ 19149f464c52Smaya BRW_REGISTER_TYPE_##src1_type, \ 19159f464c52Smaya expected_result, \ 19169f464c52Smaya } 19179f464c52Smaya 19189f464c52Smaya /* We only test with F destination because there is a restriction 19199f464c52Smaya * by which F->HF conversions need to be DWord aligned but Align16 also 19209f464c52Smaya * requires that destination horizontal stride is 1. 19219f464c52Smaya */ 19229f464c52Smaya INST( 8, F, F, HF, true), 19239f464c52Smaya INST( 8, F, HF, F, true), 19249f464c52Smaya INST( 8, F, F, HF, true), 19259f464c52Smaya INST(16, F, F, HF, false), 19269f464c52Smaya INST(16, F, HF, F, false), 19279f464c52Smaya INST(16, F, F, HF, false), 19289f464c52Smaya 19299f464c52Smaya#undef INST 19309f464c52Smaya }; 19319f464c52Smaya 19327ec681f3Smrg if (devinfo.ver < 8 || devinfo.ver >= 11) 19339f464c52Smaya return; 19349f464c52Smaya 19359f464c52Smaya brw_set_default_access_mode(p, BRW_ALIGN_16); 19369f464c52Smaya 19377ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 19389f464c52Smaya brw_ADD(p, retype(g0, inst[i].dst_type), 19399f464c52Smaya retype(g0, inst[i].src0_type), 19409f464c52Smaya retype(g0, inst[i].src1_type)); 19419f464c52Smaya 19429f464c52Smaya brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size); 19439f464c52Smaya 19449f464c52Smaya brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 19459f464c52Smaya brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 19469f464c52Smaya 19479f464c52Smaya EXPECT_EQ(inst[i].expected_result, validate(p)); 19489f464c52Smaya 19499f464c52Smaya clear_instructions(p); 19509f464c52Smaya } 19519f464c52Smaya} 19529f464c52Smaya 19539f464c52SmayaTEST_P(validation_test, mixed_float_align16_no_acc_read) 19549f464c52Smaya{ 19559f464c52Smaya static const struct { 19569f464c52Smaya enum brw_reg_type dst_type; 19579f464c52Smaya enum brw_reg_type src0_type; 19589f464c52Smaya enum brw_reg_type src1_type; 19599f464c52Smaya bool read_acc; 19609f464c52Smaya bool expected_result; 19619f464c52Smaya } inst[] = { 19629f464c52Smaya#define INST(dst_type, src0_type, src1_type, read_acc, expected_result) \ 19639f464c52Smaya { \ 19649f464c52Smaya BRW_REGISTER_TYPE_##dst_type, \ 19659f464c52Smaya BRW_REGISTER_TYPE_##src0_type, \ 19669f464c52Smaya BRW_REGISTER_TYPE_##src1_type, \ 19679f464c52Smaya read_acc, \ 19689f464c52Smaya expected_result, \ 19699f464c52Smaya } 19709f464c52Smaya 19719f464c52Smaya /* We only test with F destination because there is a restriction 19729f464c52Smaya * by which F->HF conversions need to be DWord aligned but Align16 also 19739f464c52Smaya * requires that destination horizontal stride is 1. 19749f464c52Smaya */ 19759f464c52Smaya INST( F, F, HF, false, true), 19769f464c52Smaya INST( F, F, HF, true, false), 19779f464c52Smaya INST( F, HF, F, false, true), 19789f464c52Smaya INST( F, HF, F, true, false), 19799f464c52Smaya 19809f464c52Smaya#undef INST 19819f464c52Smaya }; 19829f464c52Smaya 19837ec681f3Smrg if (devinfo.ver < 8 || devinfo.ver >= 11) 19849f464c52Smaya return; 19859f464c52Smaya 19869f464c52Smaya brw_set_default_access_mode(p, BRW_ALIGN_16); 19879f464c52Smaya 19887ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 19899f464c52Smaya brw_ADD(p, retype(g0, inst[i].dst_type), 19909f464c52Smaya retype(inst[i].read_acc ? acc0 : g0, inst[i].src0_type), 19919f464c52Smaya retype(g0, inst[i].src1_type)); 19929f464c52Smaya 19939f464c52Smaya brw_inst_set_src0_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 19949f464c52Smaya brw_inst_set_src1_vstride(&devinfo, last_inst, BRW_VERTICAL_STRIDE_4); 19959f464c52Smaya 19969f464c52Smaya EXPECT_EQ(inst[i].expected_result, validate(p)); 19979f464c52Smaya 19989f464c52Smaya clear_instructions(p); 19999f464c52Smaya } 20009f464c52Smaya} 20019f464c52Smaya 20029f464c52SmayaTEST_P(validation_test, mixed_float_align16_math_packed_format) 20039f464c52Smaya{ 20049f464c52Smaya static const struct { 20059f464c52Smaya enum brw_reg_type dst_type; 20069f464c52Smaya enum brw_reg_type src0_type; 20079f464c52Smaya enum brw_reg_type src1_type; 20089f464c52Smaya unsigned src0_vstride; 20099f464c52Smaya unsigned src1_vstride; 20109f464c52Smaya bool expected_result; 20119f464c52Smaya } inst[] = { 20129f464c52Smaya#define INST(dst_type, src0_type, src1_type, \ 20139f464c52Smaya src0_vstride, src1_vstride, expected_result) \ 20149f464c52Smaya { \ 20159f464c52Smaya BRW_REGISTER_TYPE_##dst_type, \ 20169f464c52Smaya BRW_REGISTER_TYPE_##src0_type, \ 20179f464c52Smaya BRW_REGISTER_TYPE_##src1_type, \ 20189f464c52Smaya BRW_VERTICAL_STRIDE_##src0_vstride, \ 20199f464c52Smaya BRW_VERTICAL_STRIDE_##src1_vstride, \ 20209f464c52Smaya expected_result, \ 20219f464c52Smaya } 20229f464c52Smaya 20239f464c52Smaya /* We only test with F destination because there is a restriction 20249f464c52Smaya * by which F->HF conversions need to be DWord aligned but Align16 also 20259f464c52Smaya * requires that destination horizontal stride is 1. 20269f464c52Smaya */ 20279f464c52Smaya INST( F, HF, F, 4, 0, false), 20289f464c52Smaya INST( F, HF, HF, 4, 4, true), 20299f464c52Smaya INST( F, F, HF, 4, 0, false), 20309f464c52Smaya INST( F, F, HF, 2, 4, false), 20319f464c52Smaya INST( F, F, HF, 4, 2, false), 20329f464c52Smaya INST( F, HF, HF, 0, 4, false), 20339f464c52Smaya 20349f464c52Smaya#undef INST 20359f464c52Smaya }; 20369f464c52Smaya 20377ec681f3Smrg /* Align16 Math for mixed float mode is not supported in gfx8 */ 20387ec681f3Smrg if (devinfo.ver < 9 || devinfo.ver >= 11) 20399f464c52Smaya return; 20409f464c52Smaya 20419f464c52Smaya brw_set_default_access_mode(p, BRW_ALIGN_16); 20429f464c52Smaya 20437ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 20447ec681f3Smrg gfx6_math(p, retype(g0, inst[i].dst_type), 20459f464c52Smaya BRW_MATH_FUNCTION_POW, 20469f464c52Smaya retype(g0, inst[i].src0_type), 20479f464c52Smaya retype(g0, inst[i].src1_type)); 20489f464c52Smaya 20499f464c52Smaya brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src0_vstride); 20509f464c52Smaya brw_inst_set_src1_vstride(&devinfo, last_inst, inst[i].src1_vstride); 20519f464c52Smaya 20529f464c52Smaya EXPECT_EQ(inst[i].expected_result, validate(p)); 20539f464c52Smaya 20549f464c52Smaya clear_instructions(p); 20559f464c52Smaya } 20569f464c52Smaya} 20579f464c52Smaya 205801e04c3fSmrgTEST_P(validation_test, vector_immediate_destination_alignment) 205901e04c3fSmrg{ 206001e04c3fSmrg static const struct { 206101e04c3fSmrg enum brw_reg_type dst_type; 206201e04c3fSmrg enum brw_reg_type src_type; 206301e04c3fSmrg unsigned subnr; 206401e04c3fSmrg unsigned exec_size; 206501e04c3fSmrg bool expected_result; 206601e04c3fSmrg } move[] = { 206701e04c3fSmrg { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, 0, BRW_EXECUTE_4, true }, 206801e04c3fSmrg { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, 16, BRW_EXECUTE_4, true }, 206901e04c3fSmrg { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, 1, BRW_EXECUTE_4, false }, 207001e04c3fSmrg 207101e04c3fSmrg { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, 0, BRW_EXECUTE_8, true }, 207201e04c3fSmrg { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, 16, BRW_EXECUTE_8, true }, 207301e04c3fSmrg { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, 1, BRW_EXECUTE_8, false }, 207401e04c3fSmrg 207501e04c3fSmrg { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, 0, BRW_EXECUTE_8, true }, 207601e04c3fSmrg { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, 16, BRW_EXECUTE_8, true }, 207701e04c3fSmrg { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, 1, BRW_EXECUTE_8, false }, 207801e04c3fSmrg }; 207901e04c3fSmrg 20807ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(move); i++) { 20817ec681f3Smrg /* UV type is Gfx6+ */ 20827ec681f3Smrg if (devinfo.ver < 6 && 208301e04c3fSmrg move[i].src_type == BRW_REGISTER_TYPE_UV) 208401e04c3fSmrg continue; 208501e04c3fSmrg 208601e04c3fSmrg brw_MOV(p, retype(g0, move[i].dst_type), retype(zero, move[i].src_type)); 208701e04c3fSmrg brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, move[i].subnr); 208801e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, move[i].exec_size); 208901e04c3fSmrg 209001e04c3fSmrg EXPECT_EQ(move[i].expected_result, validate(p)); 209101e04c3fSmrg 209201e04c3fSmrg clear_instructions(p); 209301e04c3fSmrg } 209401e04c3fSmrg} 209501e04c3fSmrg 209601e04c3fSmrgTEST_P(validation_test, vector_immediate_destination_stride) 209701e04c3fSmrg{ 209801e04c3fSmrg static const struct { 209901e04c3fSmrg enum brw_reg_type dst_type; 210001e04c3fSmrg enum brw_reg_type src_type; 210101e04c3fSmrg unsigned stride; 210201e04c3fSmrg bool expected_result; 210301e04c3fSmrg } move[] = { 210401e04c3fSmrg { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_1, true }, 210501e04c3fSmrg { BRW_REGISTER_TYPE_F, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, false }, 210601e04c3fSmrg { BRW_REGISTER_TYPE_D, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_1, true }, 210701e04c3fSmrg { BRW_REGISTER_TYPE_D, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, false }, 210801e04c3fSmrg { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_2, true }, 210901e04c3fSmrg { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_VF, BRW_HORIZONTAL_STRIDE_4, true }, 211001e04c3fSmrg 211101e04c3fSmrg { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_1, true }, 211201e04c3fSmrg { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_2, false }, 211301e04c3fSmrg { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_4, false }, 211401e04c3fSmrg { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_V, BRW_HORIZONTAL_STRIDE_2, true }, 211501e04c3fSmrg 211601e04c3fSmrg { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_1, true }, 211701e04c3fSmrg { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_2, false }, 211801e04c3fSmrg { BRW_REGISTER_TYPE_W, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_4, false }, 211901e04c3fSmrg { BRW_REGISTER_TYPE_B, BRW_REGISTER_TYPE_UV, BRW_HORIZONTAL_STRIDE_2, true }, 212001e04c3fSmrg }; 212101e04c3fSmrg 21227ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(move); i++) { 21237ec681f3Smrg /* UV type is Gfx6+ */ 21247ec681f3Smrg if (devinfo.ver < 6 && 212501e04c3fSmrg move[i].src_type == BRW_REGISTER_TYPE_UV) 212601e04c3fSmrg continue; 212701e04c3fSmrg 212801e04c3fSmrg brw_MOV(p, retype(g0, move[i].dst_type), retype(zero, move[i].src_type)); 212901e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, move[i].stride); 213001e04c3fSmrg 213101e04c3fSmrg EXPECT_EQ(move[i].expected_result, validate(p)); 213201e04c3fSmrg 213301e04c3fSmrg clear_instructions(p); 213401e04c3fSmrg } 213501e04c3fSmrg} 213601e04c3fSmrg 213701e04c3fSmrgTEST_P(validation_test, qword_low_power_align1_regioning_restrictions) 213801e04c3fSmrg{ 213901e04c3fSmrg static const struct { 214001e04c3fSmrg enum opcode opcode; 214101e04c3fSmrg unsigned exec_size; 214201e04c3fSmrg 214301e04c3fSmrg enum brw_reg_type dst_type; 214401e04c3fSmrg unsigned dst_subreg; 214501e04c3fSmrg unsigned dst_stride; 214601e04c3fSmrg 214701e04c3fSmrg enum brw_reg_type src_type; 214801e04c3fSmrg unsigned src_subreg; 214901e04c3fSmrg unsigned src_vstride; 215001e04c3fSmrg unsigned src_width; 215101e04c3fSmrg unsigned src_hstride; 215201e04c3fSmrg 215301e04c3fSmrg bool expected_result; 215401e04c3fSmrg } inst[] = { 215501e04c3fSmrg#define INST(opcode, exec_size, dst_type, dst_subreg, dst_stride, src_type, \ 215601e04c3fSmrg src_subreg, src_vstride, src_width, src_hstride, expected_result) \ 215701e04c3fSmrg { \ 215801e04c3fSmrg BRW_OPCODE_##opcode, \ 215901e04c3fSmrg BRW_EXECUTE_##exec_size, \ 216001e04c3fSmrg BRW_REGISTER_TYPE_##dst_type, \ 216101e04c3fSmrg dst_subreg, \ 216201e04c3fSmrg BRW_HORIZONTAL_STRIDE_##dst_stride, \ 216301e04c3fSmrg BRW_REGISTER_TYPE_##src_type, \ 216401e04c3fSmrg src_subreg, \ 216501e04c3fSmrg BRW_VERTICAL_STRIDE_##src_vstride, \ 216601e04c3fSmrg BRW_WIDTH_##src_width, \ 216701e04c3fSmrg BRW_HORIZONTAL_STRIDE_##src_hstride, \ 216801e04c3fSmrg expected_result, \ 216901e04c3fSmrg } 217001e04c3fSmrg 217101e04c3fSmrg /* Some instruction that violate no restrictions, as a control */ 217201e04c3fSmrg INST(MOV, 4, DF, 0, 1, DF, 0, 4, 4, 1, true ), 217301e04c3fSmrg INST(MOV, 4, Q, 0, 1, Q, 0, 4, 4, 1, true ), 217401e04c3fSmrg INST(MOV, 4, UQ, 0, 1, UQ, 0, 4, 4, 1, true ), 217501e04c3fSmrg 217601e04c3fSmrg INST(MOV, 4, DF, 0, 1, F, 0, 8, 4, 2, true ), 217701e04c3fSmrg INST(MOV, 4, Q, 0, 1, D, 0, 8, 4, 2, true ), 217801e04c3fSmrg INST(MOV, 4, UQ, 0, 1, UD, 0, 8, 4, 2, true ), 217901e04c3fSmrg 218001e04c3fSmrg INST(MOV, 4, F, 0, 2, DF, 0, 4, 4, 1, true ), 218101e04c3fSmrg INST(MOV, 4, D, 0, 2, Q, 0, 4, 4, 1, true ), 218201e04c3fSmrg INST(MOV, 4, UD, 0, 2, UQ, 0, 4, 4, 1, true ), 218301e04c3fSmrg 218401e04c3fSmrg INST(MUL, 8, D, 0, 2, D, 0, 8, 4, 2, true ), 218501e04c3fSmrg INST(MUL, 8, UD, 0, 2, UD, 0, 8, 4, 2, true ), 218601e04c3fSmrg 218701e04c3fSmrg /* Something with subreg nrs */ 218801e04c3fSmrg INST(MOV, 2, DF, 8, 1, DF, 8, 2, 2, 1, true ), 218901e04c3fSmrg INST(MOV, 2, Q, 8, 1, Q, 8, 2, 2, 1, true ), 219001e04c3fSmrg INST(MOV, 2, UQ, 8, 1, UQ, 8, 2, 2, 1, true ), 219101e04c3fSmrg 219201e04c3fSmrg INST(MUL, 2, D, 4, 2, D, 4, 4, 2, 2, true ), 219301e04c3fSmrg INST(MUL, 2, UD, 4, 2, UD, 4, 4, 2, 2, true ), 219401e04c3fSmrg 219501e04c3fSmrg /* The PRMs say that for CHV, BXT: 219601e04c3fSmrg * 219701e04c3fSmrg * When source or destination datatype is 64b or operation is integer 219801e04c3fSmrg * DWord multiply, regioning in Align1 must follow these rules: 219901e04c3fSmrg * 220001e04c3fSmrg * 1. Source and Destination horizontal stride must be aligned to the 220101e04c3fSmrg * same qword. 220201e04c3fSmrg */ 220301e04c3fSmrg INST(MOV, 4, DF, 0, 2, DF, 0, 4, 4, 1, false), 220401e04c3fSmrg INST(MOV, 4, Q, 0, 2, Q, 0, 4, 4, 1, false), 220501e04c3fSmrg INST(MOV, 4, UQ, 0, 2, UQ, 0, 4, 4, 1, false), 220601e04c3fSmrg 220701e04c3fSmrg INST(MOV, 4, DF, 0, 2, F, 0, 8, 4, 2, false), 220801e04c3fSmrg INST(MOV, 4, Q, 0, 2, D, 0, 8, 4, 2, false), 220901e04c3fSmrg INST(MOV, 4, UQ, 0, 2, UD, 0, 8, 4, 2, false), 221001e04c3fSmrg 221101e04c3fSmrg INST(MOV, 4, DF, 0, 2, F, 0, 4, 4, 1, false), 221201e04c3fSmrg INST(MOV, 4, Q, 0, 2, D, 0, 4, 4, 1, false), 221301e04c3fSmrg INST(MOV, 4, UQ, 0, 2, UD, 0, 4, 4, 1, false), 221401e04c3fSmrg 221501e04c3fSmrg INST(MUL, 4, D, 0, 2, D, 0, 4, 4, 1, false), 221601e04c3fSmrg INST(MUL, 4, UD, 0, 2, UD, 0, 4, 4, 1, false), 221701e04c3fSmrg 221801e04c3fSmrg INST(MUL, 4, D, 0, 1, D, 0, 8, 4, 2, false), 221901e04c3fSmrg INST(MUL, 4, UD, 0, 1, UD, 0, 8, 4, 2, false), 222001e04c3fSmrg 222101e04c3fSmrg /* 2. Regioning must ensure Src.Vstride = Src.Width * Src.Hstride. */ 222201e04c3fSmrg INST(MOV, 4, DF, 0, 1, DF, 0, 0, 2, 1, false), 222301e04c3fSmrg INST(MOV, 4, Q, 0, 1, Q, 0, 0, 2, 1, false), 222401e04c3fSmrg INST(MOV, 4, UQ, 0, 1, UQ, 0, 0, 2, 1, false), 222501e04c3fSmrg 222601e04c3fSmrg INST(MOV, 4, DF, 0, 1, F, 0, 0, 2, 2, false), 222701e04c3fSmrg INST(MOV, 4, Q, 0, 1, D, 0, 0, 2, 2, false), 222801e04c3fSmrg INST(MOV, 4, UQ, 0, 1, UD, 0, 0, 2, 2, false), 222901e04c3fSmrg 223001e04c3fSmrg INST(MOV, 8, F, 0, 2, DF, 0, 0, 2, 1, false), 223101e04c3fSmrg INST(MOV, 8, D, 0, 2, Q, 0, 0, 2, 1, false), 223201e04c3fSmrg INST(MOV, 8, UD, 0, 2, UQ, 0, 0, 2, 1, false), 223301e04c3fSmrg 223401e04c3fSmrg INST(MUL, 8, D, 0, 2, D, 0, 0, 4, 2, false), 223501e04c3fSmrg INST(MUL, 8, UD, 0, 2, UD, 0, 0, 4, 2, false), 223601e04c3fSmrg 223701e04c3fSmrg INST(MUL, 8, D, 0, 2, D, 0, 0, 4, 2, false), 223801e04c3fSmrg INST(MUL, 8, UD, 0, 2, UD, 0, 0, 4, 2, false), 223901e04c3fSmrg 224001e04c3fSmrg /* 3. Source and Destination offset must be the same, except the case 224101e04c3fSmrg * of scalar source. 224201e04c3fSmrg */ 224301e04c3fSmrg INST(MOV, 2, DF, 8, 1, DF, 0, 2, 2, 1, false), 224401e04c3fSmrg INST(MOV, 2, Q, 8, 1, Q, 0, 2, 2, 1, false), 224501e04c3fSmrg INST(MOV, 2, UQ, 8, 1, UQ, 0, 2, 2, 1, false), 224601e04c3fSmrg 224701e04c3fSmrg INST(MOV, 2, DF, 0, 1, DF, 8, 2, 2, 1, false), 224801e04c3fSmrg INST(MOV, 2, Q, 0, 1, Q, 8, 2, 2, 1, false), 224901e04c3fSmrg INST(MOV, 2, UQ, 0, 1, UQ, 8, 2, 2, 1, false), 225001e04c3fSmrg 225101e04c3fSmrg INST(MUL, 4, D, 4, 2, D, 0, 4, 2, 2, false), 225201e04c3fSmrg INST(MUL, 4, UD, 4, 2, UD, 0, 4, 2, 2, false), 225301e04c3fSmrg 225401e04c3fSmrg INST(MUL, 4, D, 0, 2, D, 4, 4, 2, 2, false), 225501e04c3fSmrg INST(MUL, 4, UD, 0, 2, UD, 4, 4, 2, 2, false), 225601e04c3fSmrg 225701e04c3fSmrg INST(MOV, 2, DF, 8, 1, DF, 0, 0, 1, 0, true ), 225801e04c3fSmrg INST(MOV, 2, Q, 8, 1, Q, 0, 0, 1, 0, true ), 225901e04c3fSmrg INST(MOV, 2, UQ, 8, 1, UQ, 0, 0, 1, 0, true ), 226001e04c3fSmrg 226101e04c3fSmrg INST(MOV, 2, DF, 8, 1, F, 4, 0, 1, 0, true ), 226201e04c3fSmrg INST(MOV, 2, Q, 8, 1, D, 4, 0, 1, 0, true ), 226301e04c3fSmrg INST(MOV, 2, UQ, 8, 1, UD, 4, 0, 1, 0, true ), 226401e04c3fSmrg 226501e04c3fSmrg INST(MUL, 4, D, 4, 1, D, 0, 0, 1, 0, true ), 226601e04c3fSmrg INST(MUL, 4, UD, 4, 1, UD, 0, 0, 1, 0, true ), 226701e04c3fSmrg 226801e04c3fSmrg INST(MUL, 4, D, 0, 1, D, 4, 0, 1, 0, true ), 226901e04c3fSmrg INST(MUL, 4, UD, 0, 1, UD, 4, 0, 1, 0, true ), 227001e04c3fSmrg 227101e04c3fSmrg#undef INST 227201e04c3fSmrg }; 227301e04c3fSmrg 22747ec681f3Smrg /* These restrictions only apply to Gfx8+ */ 22757ec681f3Smrg if (devinfo.ver < 8) 22767ec681f3Smrg return; 22777ec681f3Smrg 22787ec681f3Smrg /* NoDDChk/NoDDClr does not exist on Gfx12+ */ 22797ec681f3Smrg if (devinfo.ver >= 12) 228001e04c3fSmrg return; 228101e04c3fSmrg 22827ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 22837ec681f3Smrg if (!devinfo.has_64bit_float && 22847ec681f3Smrg (inst[i].dst_type == BRW_REGISTER_TYPE_DF || 22857ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_DF)) 22867ec681f3Smrg continue; 22877ec681f3Smrg 22887ec681f3Smrg if (!devinfo.has_64bit_int && 22897ec681f3Smrg (inst[i].dst_type == BRW_REGISTER_TYPE_Q || 22907ec681f3Smrg inst[i].dst_type == BRW_REGISTER_TYPE_UQ || 22917ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_Q || 22927ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_UQ)) 229301e04c3fSmrg continue; 229401e04c3fSmrg 229501e04c3fSmrg if (inst[i].opcode == BRW_OPCODE_MOV) { 229601e04c3fSmrg brw_MOV(p, retype(g0, inst[i].dst_type), 229701e04c3fSmrg retype(g0, inst[i].src_type)); 229801e04c3fSmrg } else { 229901e04c3fSmrg assert(inst[i].opcode == BRW_OPCODE_MUL); 230001e04c3fSmrg brw_MUL(p, retype(g0, inst[i].dst_type), 230101e04c3fSmrg retype(g0, inst[i].src_type), 230201e04c3fSmrg retype(zero, inst[i].src_type)); 230301e04c3fSmrg } 230401e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size); 230501e04c3fSmrg 230601e04c3fSmrg brw_inst_set_dst_da1_subreg_nr(&devinfo, last_inst, inst[i].dst_subreg); 230701e04c3fSmrg brw_inst_set_src0_da1_subreg_nr(&devinfo, last_inst, inst[i].src_subreg); 230801e04c3fSmrg 230901e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride); 231001e04c3fSmrg 231101e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride); 231201e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width); 231301e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride); 231401e04c3fSmrg 23157ec681f3Smrg if (devinfo.is_cherryview || intel_device_info_is_9lp(&devinfo)) { 231601e04c3fSmrg EXPECT_EQ(inst[i].expected_result, validate(p)); 231701e04c3fSmrg } else { 231801e04c3fSmrg EXPECT_TRUE(validate(p)); 231901e04c3fSmrg } 232001e04c3fSmrg 232101e04c3fSmrg clear_instructions(p); 232201e04c3fSmrg } 232301e04c3fSmrg} 232401e04c3fSmrg 232501e04c3fSmrgTEST_P(validation_test, qword_low_power_no_indirect_addressing) 232601e04c3fSmrg{ 232701e04c3fSmrg static const struct { 232801e04c3fSmrg enum opcode opcode; 232901e04c3fSmrg unsigned exec_size; 233001e04c3fSmrg 233101e04c3fSmrg enum brw_reg_type dst_type; 233201e04c3fSmrg bool dst_is_indirect; 233301e04c3fSmrg unsigned dst_stride; 233401e04c3fSmrg 233501e04c3fSmrg enum brw_reg_type src_type; 233601e04c3fSmrg bool src_is_indirect; 233701e04c3fSmrg unsigned src_vstride; 233801e04c3fSmrg unsigned src_width; 233901e04c3fSmrg unsigned src_hstride; 234001e04c3fSmrg 234101e04c3fSmrg bool expected_result; 234201e04c3fSmrg } inst[] = { 234301e04c3fSmrg#define INST(opcode, exec_size, dst_type, dst_is_indirect, dst_stride, \ 234401e04c3fSmrg src_type, src_is_indirect, src_vstride, src_width, src_hstride, \ 234501e04c3fSmrg expected_result) \ 234601e04c3fSmrg { \ 234701e04c3fSmrg BRW_OPCODE_##opcode, \ 234801e04c3fSmrg BRW_EXECUTE_##exec_size, \ 234901e04c3fSmrg BRW_REGISTER_TYPE_##dst_type, \ 235001e04c3fSmrg dst_is_indirect, \ 235101e04c3fSmrg BRW_HORIZONTAL_STRIDE_##dst_stride, \ 235201e04c3fSmrg BRW_REGISTER_TYPE_##src_type, \ 235301e04c3fSmrg src_is_indirect, \ 235401e04c3fSmrg BRW_VERTICAL_STRIDE_##src_vstride, \ 235501e04c3fSmrg BRW_WIDTH_##src_width, \ 235601e04c3fSmrg BRW_HORIZONTAL_STRIDE_##src_hstride, \ 235701e04c3fSmrg expected_result, \ 235801e04c3fSmrg } 235901e04c3fSmrg 236001e04c3fSmrg /* Some instruction that violate no restrictions, as a control */ 236101e04c3fSmrg INST(MOV, 4, DF, 0, 1, DF, 0, 4, 4, 1, true ), 236201e04c3fSmrg INST(MOV, 4, Q, 0, 1, Q, 0, 4, 4, 1, true ), 236301e04c3fSmrg INST(MOV, 4, UQ, 0, 1, UQ, 0, 4, 4, 1, true ), 236401e04c3fSmrg 236501e04c3fSmrg INST(MUL, 8, D, 0, 2, D, 0, 8, 4, 2, true ), 236601e04c3fSmrg INST(MUL, 8, UD, 0, 2, UD, 0, 8, 4, 2, true ), 236701e04c3fSmrg 236801e04c3fSmrg INST(MOV, 4, F, 1, 1, F, 0, 4, 4, 1, true ), 236901e04c3fSmrg INST(MOV, 4, F, 0, 1, F, 1, 4, 4, 1, true ), 237001e04c3fSmrg INST(MOV, 4, F, 1, 1, F, 1, 4, 4, 1, true ), 237101e04c3fSmrg 237201e04c3fSmrg /* The PRMs say that for CHV, BXT: 237301e04c3fSmrg * 237401e04c3fSmrg * When source or destination datatype is 64b or operation is integer 237501e04c3fSmrg * DWord multiply, indirect addressing must not be used. 237601e04c3fSmrg */ 237701e04c3fSmrg INST(MOV, 4, DF, 1, 1, DF, 0, 4, 4, 1, false), 237801e04c3fSmrg INST(MOV, 4, Q, 1, 1, Q, 0, 4, 4, 1, false), 237901e04c3fSmrg INST(MOV, 4, UQ, 1, 1, UQ, 0, 4, 4, 1, false), 238001e04c3fSmrg 238101e04c3fSmrg INST(MOV, 4, DF, 0, 1, DF, 1, 4, 4, 1, false), 238201e04c3fSmrg INST(MOV, 4, Q, 0, 1, Q, 1, 4, 4, 1, false), 238301e04c3fSmrg INST(MOV, 4, UQ, 0, 1, UQ, 1, 4, 4, 1, false), 238401e04c3fSmrg 238501e04c3fSmrg INST(MOV, 4, DF, 1, 1, F, 0, 8, 4, 2, false), 238601e04c3fSmrg INST(MOV, 4, Q, 1, 1, D, 0, 8, 4, 2, false), 238701e04c3fSmrg INST(MOV, 4, UQ, 1, 1, UD, 0, 8, 4, 2, false), 238801e04c3fSmrg 238901e04c3fSmrg INST(MOV, 4, DF, 0, 1, F, 1, 8, 4, 2, false), 239001e04c3fSmrg INST(MOV, 4, Q, 0, 1, D, 1, 8, 4, 2, false), 239101e04c3fSmrg INST(MOV, 4, UQ, 0, 1, UD, 1, 8, 4, 2, false), 239201e04c3fSmrg 239301e04c3fSmrg INST(MOV, 4, F, 1, 2, DF, 0, 4, 4, 1, false), 239401e04c3fSmrg INST(MOV, 4, D, 1, 2, Q, 0, 4, 4, 1, false), 239501e04c3fSmrg INST(MOV, 4, UD, 1, 2, UQ, 0, 4, 4, 1, false), 239601e04c3fSmrg 239701e04c3fSmrg INST(MOV, 4, F, 0, 2, DF, 1, 4, 4, 1, false), 239801e04c3fSmrg INST(MOV, 4, D, 0, 2, Q, 1, 4, 4, 1, false), 239901e04c3fSmrg INST(MOV, 4, UD, 0, 2, UQ, 1, 4, 4, 1, false), 240001e04c3fSmrg 240101e04c3fSmrg INST(MUL, 8, D, 1, 2, D, 0, 8, 4, 2, false), 240201e04c3fSmrg INST(MUL, 8, UD, 1, 2, UD, 0, 8, 4, 2, false), 240301e04c3fSmrg 240401e04c3fSmrg INST(MUL, 8, D, 0, 2, D, 1, 8, 4, 2, false), 240501e04c3fSmrg INST(MUL, 8, UD, 0, 2, UD, 1, 8, 4, 2, false), 240601e04c3fSmrg 240701e04c3fSmrg#undef INST 240801e04c3fSmrg }; 240901e04c3fSmrg 24107ec681f3Smrg /* These restrictions only apply to Gfx8+ */ 24117ec681f3Smrg if (devinfo.ver < 8) 241201e04c3fSmrg return; 241301e04c3fSmrg 24147ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 24157ec681f3Smrg if (!devinfo.has_64bit_float && 24167ec681f3Smrg (inst[i].dst_type == BRW_REGISTER_TYPE_DF || 24177ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_DF)) 24187ec681f3Smrg continue; 24197ec681f3Smrg 24207ec681f3Smrg if (!devinfo.has_64bit_int && 24217ec681f3Smrg (inst[i].dst_type == BRW_REGISTER_TYPE_Q || 24227ec681f3Smrg inst[i].dst_type == BRW_REGISTER_TYPE_UQ || 24237ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_Q || 24247ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_UQ)) 242501e04c3fSmrg continue; 242601e04c3fSmrg 242701e04c3fSmrg if (inst[i].opcode == BRW_OPCODE_MOV) { 242801e04c3fSmrg brw_MOV(p, retype(g0, inst[i].dst_type), 242901e04c3fSmrg retype(g0, inst[i].src_type)); 243001e04c3fSmrg } else { 243101e04c3fSmrg assert(inst[i].opcode == BRW_OPCODE_MUL); 243201e04c3fSmrg brw_MUL(p, retype(g0, inst[i].dst_type), 243301e04c3fSmrg retype(g0, inst[i].src_type), 243401e04c3fSmrg retype(zero, inst[i].src_type)); 243501e04c3fSmrg } 243601e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size); 243701e04c3fSmrg 243801e04c3fSmrg brw_inst_set_dst_address_mode(&devinfo, last_inst, inst[i].dst_is_indirect); 243901e04c3fSmrg brw_inst_set_src0_address_mode(&devinfo, last_inst, inst[i].src_is_indirect); 244001e04c3fSmrg 244101e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride); 244201e04c3fSmrg 244301e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride); 244401e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width); 244501e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride); 244601e04c3fSmrg 24477ec681f3Smrg if (devinfo.is_cherryview || intel_device_info_is_9lp(&devinfo)) { 244801e04c3fSmrg EXPECT_EQ(inst[i].expected_result, validate(p)); 244901e04c3fSmrg } else { 245001e04c3fSmrg EXPECT_TRUE(validate(p)); 245101e04c3fSmrg } 245201e04c3fSmrg 245301e04c3fSmrg clear_instructions(p); 245401e04c3fSmrg } 245501e04c3fSmrg} 245601e04c3fSmrg 245701e04c3fSmrgTEST_P(validation_test, qword_low_power_no_64bit_arf) 245801e04c3fSmrg{ 245901e04c3fSmrg static const struct { 246001e04c3fSmrg enum opcode opcode; 246101e04c3fSmrg unsigned exec_size; 246201e04c3fSmrg 246301e04c3fSmrg struct brw_reg dst; 246401e04c3fSmrg enum brw_reg_type dst_type; 246501e04c3fSmrg unsigned dst_stride; 246601e04c3fSmrg 246701e04c3fSmrg struct brw_reg src; 246801e04c3fSmrg enum brw_reg_type src_type; 246901e04c3fSmrg unsigned src_vstride; 247001e04c3fSmrg unsigned src_width; 247101e04c3fSmrg unsigned src_hstride; 247201e04c3fSmrg 247301e04c3fSmrg bool acc_wr; 247401e04c3fSmrg bool expected_result; 247501e04c3fSmrg } inst[] = { 247601e04c3fSmrg#define INST(opcode, exec_size, dst, dst_type, dst_stride, \ 247701e04c3fSmrg src, src_type, src_vstride, src_width, src_hstride, \ 247801e04c3fSmrg acc_wr, expected_result) \ 247901e04c3fSmrg { \ 248001e04c3fSmrg BRW_OPCODE_##opcode, \ 248101e04c3fSmrg BRW_EXECUTE_##exec_size, \ 248201e04c3fSmrg dst, \ 248301e04c3fSmrg BRW_REGISTER_TYPE_##dst_type, \ 248401e04c3fSmrg BRW_HORIZONTAL_STRIDE_##dst_stride, \ 248501e04c3fSmrg src, \ 248601e04c3fSmrg BRW_REGISTER_TYPE_##src_type, \ 248701e04c3fSmrg BRW_VERTICAL_STRIDE_##src_vstride, \ 248801e04c3fSmrg BRW_WIDTH_##src_width, \ 248901e04c3fSmrg BRW_HORIZONTAL_STRIDE_##src_hstride, \ 249001e04c3fSmrg acc_wr, \ 249101e04c3fSmrg expected_result, \ 249201e04c3fSmrg } 249301e04c3fSmrg 249401e04c3fSmrg /* Some instruction that violate no restrictions, as a control */ 249501e04c3fSmrg INST(MOV, 4, g0, DF, 1, g0, F, 4, 2, 2, 0, true ), 249601e04c3fSmrg INST(MOV, 4, g0, F, 2, g0, DF, 4, 4, 1, 0, true ), 249701e04c3fSmrg 249801e04c3fSmrg INST(MOV, 4, g0, Q, 1, g0, D, 4, 2, 2, 0, true ), 249901e04c3fSmrg INST(MOV, 4, g0, D, 2, g0, Q, 4, 4, 1, 0, true ), 250001e04c3fSmrg 250101e04c3fSmrg INST(MOV, 4, g0, UQ, 1, g0, UD, 4, 2, 2, 0, true ), 250201e04c3fSmrg INST(MOV, 4, g0, UD, 2, g0, UQ, 4, 4, 1, 0, true ), 250301e04c3fSmrg 250401e04c3fSmrg INST(MOV, 4, null, F, 1, g0, F, 4, 4, 1, 0, true ), 250501e04c3fSmrg INST(MOV, 4, acc0, F, 1, g0, F, 4, 4, 1, 0, true ), 250601e04c3fSmrg INST(MOV, 4, g0, F, 1, acc0, F, 4, 4, 1, 0, true ), 250701e04c3fSmrg 250801e04c3fSmrg INST(MOV, 4, null, D, 1, g0, D, 4, 4, 1, 0, true ), 250901e04c3fSmrg INST(MOV, 4, acc0, D, 1, g0, D, 4, 4, 1, 0, true ), 251001e04c3fSmrg INST(MOV, 4, g0, D, 1, acc0, D, 4, 4, 1, 0, true ), 251101e04c3fSmrg 251201e04c3fSmrg INST(MOV, 4, null, UD, 1, g0, UD, 4, 4, 1, 0, true ), 251301e04c3fSmrg INST(MOV, 4, acc0, UD, 1, g0, UD, 4, 4, 1, 0, true ), 251401e04c3fSmrg INST(MOV, 4, g0, UD, 1, acc0, UD, 4, 4, 1, 0, true ), 251501e04c3fSmrg 251601e04c3fSmrg INST(MUL, 4, g0, D, 2, g0, D, 4, 2, 2, 0, true ), 251701e04c3fSmrg INST(MUL, 4, g0, UD, 2, g0, UD, 4, 2, 2, 0, true ), 251801e04c3fSmrg 251901e04c3fSmrg /* The PRMs say that for CHV, BXT: 252001e04c3fSmrg * 252101e04c3fSmrg * ARF registers must never be used with 64b datatype or when 252201e04c3fSmrg * operation is integer DWord multiply. 252301e04c3fSmrg */ 252401e04c3fSmrg INST(MOV, 4, acc0, DF, 1, g0, F, 4, 2, 2, 0, false), 252501e04c3fSmrg INST(MOV, 4, g0, DF, 1, acc0, F, 4, 2, 2, 0, false), 252601e04c3fSmrg 252701e04c3fSmrg INST(MOV, 4, acc0, Q, 1, g0, D, 4, 2, 2, 0, false), 252801e04c3fSmrg INST(MOV, 4, g0, Q, 1, acc0, D, 4, 2, 2, 0, false), 252901e04c3fSmrg 253001e04c3fSmrg INST(MOV, 4, acc0, UQ, 1, g0, UD, 4, 2, 2, 0, false), 253101e04c3fSmrg INST(MOV, 4, g0, UQ, 1, acc0, UD, 4, 2, 2, 0, false), 253201e04c3fSmrg 253301e04c3fSmrg INST(MOV, 4, acc0, F, 2, g0, DF, 4, 4, 1, 0, false), 253401e04c3fSmrg INST(MOV, 4, g0, F, 2, acc0, DF, 4, 4, 1, 0, false), 253501e04c3fSmrg 253601e04c3fSmrg INST(MOV, 4, acc0, D, 2, g0, Q, 4, 4, 1, 0, false), 253701e04c3fSmrg INST(MOV, 4, g0, D, 2, acc0, Q, 4, 4, 1, 0, false), 253801e04c3fSmrg 253901e04c3fSmrg INST(MOV, 4, acc0, UD, 2, g0, UQ, 4, 4, 1, 0, false), 254001e04c3fSmrg INST(MOV, 4, g0, UD, 2, acc0, UQ, 4, 4, 1, 0, false), 254101e04c3fSmrg 254201e04c3fSmrg INST(MUL, 4, acc0, D, 2, g0, D, 4, 2, 2, 0, false), 254301e04c3fSmrg INST(MUL, 4, acc0, UD, 2, g0, UD, 4, 2, 2, 0, false), 254401e04c3fSmrg /* MUL cannot have integer accumulator sources, so don't test that */ 254501e04c3fSmrg 254601e04c3fSmrg /* We assume that the restriction does not apply to the null register */ 254701e04c3fSmrg INST(MOV, 4, null, DF, 1, g0, F, 4, 2, 2, 0, true ), 254801e04c3fSmrg INST(MOV, 4, null, Q, 1, g0, D, 4, 2, 2, 0, true ), 254901e04c3fSmrg INST(MOV, 4, null, UQ, 1, g0, UD, 4, 2, 2, 0, true ), 255001e04c3fSmrg 255101e04c3fSmrg /* Check implicit accumulator write control */ 255201e04c3fSmrg INST(MOV, 4, null, DF, 1, g0, F, 4, 2, 2, 1, false), 255301e04c3fSmrg INST(MUL, 4, null, DF, 1, g0, F, 4, 2, 2, 1, false), 255401e04c3fSmrg 255501e04c3fSmrg#undef INST 255601e04c3fSmrg }; 255701e04c3fSmrg 25587ec681f3Smrg /* These restrictions only apply to Gfx8+ */ 25597ec681f3Smrg if (devinfo.ver < 8) 256001e04c3fSmrg return; 256101e04c3fSmrg 25627ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 25637ec681f3Smrg if (!devinfo.has_64bit_float && 25647ec681f3Smrg (inst[i].dst_type == BRW_REGISTER_TYPE_DF || 25657ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_DF)) 25667ec681f3Smrg continue; 25677ec681f3Smrg 25687ec681f3Smrg if (!devinfo.has_64bit_int && 25697ec681f3Smrg (inst[i].dst_type == BRW_REGISTER_TYPE_Q || 25707ec681f3Smrg inst[i].dst_type == BRW_REGISTER_TYPE_UQ || 25717ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_Q || 25727ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_UQ)) 257301e04c3fSmrg continue; 257401e04c3fSmrg 257501e04c3fSmrg if (inst[i].opcode == BRW_OPCODE_MOV) { 257601e04c3fSmrg brw_MOV(p, retype(inst[i].dst, inst[i].dst_type), 257701e04c3fSmrg retype(inst[i].src, inst[i].src_type)); 257801e04c3fSmrg } else { 257901e04c3fSmrg assert(inst[i].opcode == BRW_OPCODE_MUL); 258001e04c3fSmrg brw_MUL(p, retype(inst[i].dst, inst[i].dst_type), 258101e04c3fSmrg retype(inst[i].src, inst[i].src_type), 258201e04c3fSmrg retype(zero, inst[i].src_type)); 258301e04c3fSmrg brw_inst_set_opcode(&devinfo, last_inst, inst[i].opcode); 258401e04c3fSmrg } 258501e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size); 258601e04c3fSmrg brw_inst_set_acc_wr_control(&devinfo, last_inst, inst[i].acc_wr); 258701e04c3fSmrg 258801e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride); 258901e04c3fSmrg 259001e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride); 259101e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width); 259201e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride); 259301e04c3fSmrg 25947ec681f3Smrg if (devinfo.is_cherryview || intel_device_info_is_9lp(&devinfo)) { 259501e04c3fSmrg EXPECT_EQ(inst[i].expected_result, validate(p)); 259601e04c3fSmrg } else { 259701e04c3fSmrg EXPECT_TRUE(validate(p)); 259801e04c3fSmrg } 259901e04c3fSmrg 260001e04c3fSmrg clear_instructions(p); 260101e04c3fSmrg } 260201e04c3fSmrg 26037ec681f3Smrg if (!devinfo.has_64bit_float) 260401e04c3fSmrg return; 260501e04c3fSmrg 260601e04c3fSmrg /* MAC implicitly reads the accumulator */ 260701e04c3fSmrg brw_MAC(p, retype(g0, BRW_REGISTER_TYPE_DF), 260801e04c3fSmrg retype(stride(g0, 4, 4, 1), BRW_REGISTER_TYPE_DF), 260901e04c3fSmrg retype(stride(g0, 4, 4, 1), BRW_REGISTER_TYPE_DF)); 26107ec681f3Smrg if (devinfo.is_cherryview || intel_device_info_is_9lp(&devinfo)) { 261101e04c3fSmrg EXPECT_FALSE(validate(p)); 261201e04c3fSmrg } else { 261301e04c3fSmrg EXPECT_TRUE(validate(p)); 261401e04c3fSmrg } 261501e04c3fSmrg} 261601e04c3fSmrg 261701e04c3fSmrgTEST_P(validation_test, align16_64_bit_integer) 261801e04c3fSmrg{ 261901e04c3fSmrg static const struct { 262001e04c3fSmrg enum opcode opcode; 262101e04c3fSmrg unsigned exec_size; 262201e04c3fSmrg 262301e04c3fSmrg enum brw_reg_type dst_type; 262401e04c3fSmrg enum brw_reg_type src_type; 262501e04c3fSmrg 262601e04c3fSmrg bool expected_result; 262701e04c3fSmrg } inst[] = { 262801e04c3fSmrg#define INST(opcode, exec_size, dst_type, src_type, expected_result) \ 262901e04c3fSmrg { \ 263001e04c3fSmrg BRW_OPCODE_##opcode, \ 263101e04c3fSmrg BRW_EXECUTE_##exec_size, \ 263201e04c3fSmrg BRW_REGISTER_TYPE_##dst_type, \ 263301e04c3fSmrg BRW_REGISTER_TYPE_##src_type, \ 263401e04c3fSmrg expected_result, \ 263501e04c3fSmrg } 263601e04c3fSmrg 263701e04c3fSmrg /* Some instruction that violate no restrictions, as a control */ 263801e04c3fSmrg INST(MOV, 2, Q, D, true ), 263901e04c3fSmrg INST(MOV, 2, UQ, UD, true ), 264001e04c3fSmrg INST(MOV, 2, DF, F, true ), 264101e04c3fSmrg 264201e04c3fSmrg INST(ADD, 2, Q, D, true ), 264301e04c3fSmrg INST(ADD, 2, UQ, UD, true ), 264401e04c3fSmrg INST(ADD, 2, DF, F, true ), 264501e04c3fSmrg 264601e04c3fSmrg /* The PRMs say that for BDW, SKL: 264701e04c3fSmrg * 264801e04c3fSmrg * If Align16 is required for an operation with QW destination and non-QW 264901e04c3fSmrg * source datatypes, the execution size cannot exceed 2. 265001e04c3fSmrg */ 265101e04c3fSmrg 265201e04c3fSmrg INST(MOV, 4, Q, D, false), 265301e04c3fSmrg INST(MOV, 4, UQ, UD, false), 265401e04c3fSmrg INST(MOV, 4, DF, F, false), 265501e04c3fSmrg 265601e04c3fSmrg INST(ADD, 4, Q, D, false), 265701e04c3fSmrg INST(ADD, 4, UQ, UD, false), 265801e04c3fSmrg INST(ADD, 4, DF, F, false), 265901e04c3fSmrg 266001e04c3fSmrg#undef INST 266101e04c3fSmrg }; 266201e04c3fSmrg 26637ec681f3Smrg /* 64-bit integer types exist on Gfx8+ */ 26647ec681f3Smrg if (devinfo.ver < 8) 266501e04c3fSmrg return; 266601e04c3fSmrg 26677ec681f3Smrg /* Align16 does not exist on Gfx11+ */ 26687ec681f3Smrg if (devinfo.ver >= 11) 266901e04c3fSmrg return; 267001e04c3fSmrg 267101e04c3fSmrg brw_set_default_access_mode(p, BRW_ALIGN_16); 267201e04c3fSmrg 26737ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 267401e04c3fSmrg if (inst[i].opcode == BRW_OPCODE_MOV) { 267501e04c3fSmrg brw_MOV(p, retype(g0, inst[i].dst_type), 267601e04c3fSmrg retype(g0, inst[i].src_type)); 267701e04c3fSmrg } else { 267801e04c3fSmrg assert(inst[i].opcode == BRW_OPCODE_ADD); 267901e04c3fSmrg brw_ADD(p, retype(g0, inst[i].dst_type), 268001e04c3fSmrg retype(g0, inst[i].src_type), 268101e04c3fSmrg retype(g0, inst[i].src_type)); 268201e04c3fSmrg } 268301e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size); 268401e04c3fSmrg 268501e04c3fSmrg EXPECT_EQ(inst[i].expected_result, validate(p)); 268601e04c3fSmrg 268701e04c3fSmrg clear_instructions(p); 268801e04c3fSmrg } 268901e04c3fSmrg} 269001e04c3fSmrg 269101e04c3fSmrgTEST_P(validation_test, qword_low_power_no_depctrl) 269201e04c3fSmrg{ 269301e04c3fSmrg static const struct { 269401e04c3fSmrg enum opcode opcode; 269501e04c3fSmrg unsigned exec_size; 269601e04c3fSmrg 269701e04c3fSmrg enum brw_reg_type dst_type; 269801e04c3fSmrg unsigned dst_stride; 269901e04c3fSmrg 270001e04c3fSmrg enum brw_reg_type src_type; 270101e04c3fSmrg unsigned src_vstride; 270201e04c3fSmrg unsigned src_width; 270301e04c3fSmrg unsigned src_hstride; 270401e04c3fSmrg 270501e04c3fSmrg bool no_dd_check; 270601e04c3fSmrg bool no_dd_clear; 270701e04c3fSmrg 270801e04c3fSmrg bool expected_result; 270901e04c3fSmrg } inst[] = { 271001e04c3fSmrg#define INST(opcode, exec_size, dst_type, dst_stride, \ 271101e04c3fSmrg src_type, src_vstride, src_width, src_hstride, \ 271201e04c3fSmrg no_dd_check, no_dd_clear, expected_result) \ 271301e04c3fSmrg { \ 271401e04c3fSmrg BRW_OPCODE_##opcode, \ 271501e04c3fSmrg BRW_EXECUTE_##exec_size, \ 271601e04c3fSmrg BRW_REGISTER_TYPE_##dst_type, \ 271701e04c3fSmrg BRW_HORIZONTAL_STRIDE_##dst_stride, \ 271801e04c3fSmrg BRW_REGISTER_TYPE_##src_type, \ 271901e04c3fSmrg BRW_VERTICAL_STRIDE_##src_vstride, \ 272001e04c3fSmrg BRW_WIDTH_##src_width, \ 272101e04c3fSmrg BRW_HORIZONTAL_STRIDE_##src_hstride, \ 272201e04c3fSmrg no_dd_check, \ 272301e04c3fSmrg no_dd_clear, \ 272401e04c3fSmrg expected_result, \ 272501e04c3fSmrg } 272601e04c3fSmrg 272701e04c3fSmrg /* Some instruction that violate no restrictions, as a control */ 272801e04c3fSmrg INST(MOV, 4, DF, 1, F, 8, 4, 2, 0, 0, true ), 272901e04c3fSmrg INST(MOV, 4, Q, 1, D, 8, 4, 2, 0, 0, true ), 273001e04c3fSmrg INST(MOV, 4, UQ, 1, UD, 8, 4, 2, 0, 0, true ), 273101e04c3fSmrg 273201e04c3fSmrg INST(MOV, 4, F, 2, DF, 4, 4, 1, 0, 0, true ), 273301e04c3fSmrg INST(MOV, 4, D, 2, Q, 4, 4, 1, 0, 0, true ), 273401e04c3fSmrg INST(MOV, 4, UD, 2, UQ, 4, 4, 1, 0, 0, true ), 273501e04c3fSmrg 273601e04c3fSmrg INST(MUL, 8, D, 2, D, 8, 4, 2, 0, 0, true ), 273701e04c3fSmrg INST(MUL, 8, UD, 2, UD, 8, 4, 2, 0, 0, true ), 273801e04c3fSmrg 273901e04c3fSmrg INST(MOV, 4, F, 1, F, 4, 4, 1, 1, 1, true ), 274001e04c3fSmrg 274101e04c3fSmrg /* The PRMs say that for CHV, BXT: 274201e04c3fSmrg * 274301e04c3fSmrg * When source or destination datatype is 64b or operation is integer 274401e04c3fSmrg * DWord multiply, DepCtrl must not be used. 274501e04c3fSmrg */ 274601e04c3fSmrg INST(MOV, 4, DF, 1, F, 8, 4, 2, 1, 0, false), 274701e04c3fSmrg INST(MOV, 4, Q, 1, D, 8, 4, 2, 1, 0, false), 274801e04c3fSmrg INST(MOV, 4, UQ, 1, UD, 8, 4, 2, 1, 0, false), 274901e04c3fSmrg 275001e04c3fSmrg INST(MOV, 4, F, 2, DF, 4, 4, 1, 1, 0, false), 275101e04c3fSmrg INST(MOV, 4, D, 2, Q, 4, 4, 1, 1, 0, false), 275201e04c3fSmrg INST(MOV, 4, UD, 2, UQ, 4, 4, 1, 1, 0, false), 275301e04c3fSmrg 275401e04c3fSmrg INST(MOV, 4, DF, 1, F, 8, 4, 2, 0, 1, false), 275501e04c3fSmrg INST(MOV, 4, Q, 1, D, 8, 4, 2, 0, 1, false), 275601e04c3fSmrg INST(MOV, 4, UQ, 1, UD, 8, 4, 2, 0, 1, false), 275701e04c3fSmrg 275801e04c3fSmrg INST(MOV, 4, F, 2, DF, 4, 4, 1, 0, 1, false), 275901e04c3fSmrg INST(MOV, 4, D, 2, Q, 4, 4, 1, 0, 1, false), 276001e04c3fSmrg INST(MOV, 4, UD, 2, UQ, 4, 4, 1, 0, 1, false), 276101e04c3fSmrg 276201e04c3fSmrg INST(MUL, 8, D, 2, D, 8, 4, 2, 1, 0, false), 276301e04c3fSmrg INST(MUL, 8, UD, 2, UD, 8, 4, 2, 1, 0, false), 276401e04c3fSmrg 276501e04c3fSmrg INST(MUL, 8, D, 2, D, 8, 4, 2, 0, 1, false), 276601e04c3fSmrg INST(MUL, 8, UD, 2, UD, 8, 4, 2, 0, 1, false), 276701e04c3fSmrg 276801e04c3fSmrg#undef INST 276901e04c3fSmrg }; 277001e04c3fSmrg 27717ec681f3Smrg /* These restrictions only apply to Gfx8+ */ 27727ec681f3Smrg if (devinfo.ver < 8) 277301e04c3fSmrg return; 277401e04c3fSmrg 27757ec681f3Smrg /* NoDDChk/NoDDClr does not exist on Gfx12+ */ 27767ec681f3Smrg if (devinfo.ver >= 12) 27777ec681f3Smrg return; 27787ec681f3Smrg 27797ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 27807ec681f3Smrg if (!devinfo.has_64bit_float && 27817ec681f3Smrg (inst[i].dst_type == BRW_REGISTER_TYPE_DF || 27827ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_DF)) 27837ec681f3Smrg continue; 27847ec681f3Smrg 27857ec681f3Smrg if (!devinfo.has_64bit_int && 27867ec681f3Smrg (inst[i].dst_type == BRW_REGISTER_TYPE_Q || 27877ec681f3Smrg inst[i].dst_type == BRW_REGISTER_TYPE_UQ || 27887ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_Q || 27897ec681f3Smrg inst[i].src_type == BRW_REGISTER_TYPE_UQ)) 279001e04c3fSmrg continue; 279101e04c3fSmrg 279201e04c3fSmrg if (inst[i].opcode == BRW_OPCODE_MOV) { 279301e04c3fSmrg brw_MOV(p, retype(g0, inst[i].dst_type), 279401e04c3fSmrg retype(g0, inst[i].src_type)); 279501e04c3fSmrg } else { 279601e04c3fSmrg assert(inst[i].opcode == BRW_OPCODE_MUL); 279701e04c3fSmrg brw_MUL(p, retype(g0, inst[i].dst_type), 279801e04c3fSmrg retype(g0, inst[i].src_type), 279901e04c3fSmrg retype(zero, inst[i].src_type)); 280001e04c3fSmrg } 280101e04c3fSmrg brw_inst_set_exec_size(&devinfo, last_inst, inst[i].exec_size); 280201e04c3fSmrg 280301e04c3fSmrg brw_inst_set_dst_hstride(&devinfo, last_inst, inst[i].dst_stride); 280401e04c3fSmrg 280501e04c3fSmrg brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].src_vstride); 280601e04c3fSmrg brw_inst_set_src0_width(&devinfo, last_inst, inst[i].src_width); 280701e04c3fSmrg brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].src_hstride); 280801e04c3fSmrg 280901e04c3fSmrg brw_inst_set_no_dd_check(&devinfo, last_inst, inst[i].no_dd_check); 281001e04c3fSmrg brw_inst_set_no_dd_clear(&devinfo, last_inst, inst[i].no_dd_clear); 281101e04c3fSmrg 28127ec681f3Smrg if (devinfo.is_cherryview || intel_device_info_is_9lp(&devinfo)) { 281301e04c3fSmrg EXPECT_EQ(inst[i].expected_result, validate(p)); 281401e04c3fSmrg } else { 281501e04c3fSmrg EXPECT_TRUE(validate(p)); 281601e04c3fSmrg } 281701e04c3fSmrg 281801e04c3fSmrg clear_instructions(p); 281901e04c3fSmrg } 282001e04c3fSmrg} 28219f464c52Smaya 28227ec681f3SmrgTEST_P(validation_test, gfx11_no_byte_src_1_2) 28239f464c52Smaya{ 28249f464c52Smaya static const struct { 28259f464c52Smaya enum opcode opcode; 28269f464c52Smaya unsigned access_mode; 28279f464c52Smaya 28289f464c52Smaya enum brw_reg_type dst_type; 28299f464c52Smaya struct { 28309f464c52Smaya enum brw_reg_type type; 28319f464c52Smaya unsigned vstride; 28329f464c52Smaya unsigned width; 28339f464c52Smaya unsigned hstride; 28349f464c52Smaya } srcs[3]; 28359f464c52Smaya 28367ec681f3Smrg int gfx_ver; 28379f464c52Smaya bool expected_result; 28389f464c52Smaya } inst[] = { 28399f464c52Smaya#define INST(opcode, access_mode, dst_type, \ 28409f464c52Smaya src0_type, src0_vstride, src0_width, src0_hstride, \ 28419f464c52Smaya src1_type, src1_vstride, src1_width, src1_hstride, \ 28429f464c52Smaya src2_type, \ 28437ec681f3Smrg gfx_ver, expected_result) \ 28449f464c52Smaya { \ 28459f464c52Smaya BRW_OPCODE_##opcode, \ 28469f464c52Smaya BRW_ALIGN_##access_mode, \ 28479f464c52Smaya BRW_REGISTER_TYPE_##dst_type, \ 28489f464c52Smaya { \ 28499f464c52Smaya { \ 28509f464c52Smaya BRW_REGISTER_TYPE_##src0_type, \ 28519f464c52Smaya BRW_VERTICAL_STRIDE_##src0_vstride, \ 28529f464c52Smaya BRW_WIDTH_##src0_width, \ 28539f464c52Smaya BRW_HORIZONTAL_STRIDE_##src0_hstride, \ 28549f464c52Smaya }, \ 28559f464c52Smaya { \ 28569f464c52Smaya BRW_REGISTER_TYPE_##src1_type, \ 28579f464c52Smaya BRW_VERTICAL_STRIDE_##src1_vstride, \ 28589f464c52Smaya BRW_WIDTH_##src1_width, \ 28599f464c52Smaya BRW_HORIZONTAL_STRIDE_##src1_hstride, \ 28609f464c52Smaya }, \ 28619f464c52Smaya { \ 28629f464c52Smaya BRW_REGISTER_TYPE_##src2_type, \ 28639f464c52Smaya }, \ 28649f464c52Smaya }, \ 28657ec681f3Smrg gfx_ver, \ 28669f464c52Smaya expected_result, \ 28679f464c52Smaya } 28689f464c52Smaya 28699f464c52Smaya /* Passes on < 11 */ 28709f464c52Smaya INST(MOV, 16, F, B, 2, 4, 0, UD, 0, 4, 0, D, 8, true ), 28719f464c52Smaya INST(ADD, 16, UD, F, 0, 4, 0, UB, 0, 1, 0, D, 7, true ), 28729f464c52Smaya INST(MAD, 16, D, B, 0, 4, 0, UB, 0, 1, 0, B, 10, true ), 28739f464c52Smaya 28749f464c52Smaya /* Fails on 11+ */ 28759f464c52Smaya INST(MAD, 1, UB, W, 1, 1, 0, D, 0, 4, 0, B, 11, false ), 28769f464c52Smaya INST(MAD, 1, UB, W, 1, 1, 1, UB, 1, 1, 0, W, 11, false ), 28779f464c52Smaya INST(ADD, 1, W, W, 1, 4, 1, B, 1, 1, 0, D, 11, false ), 28789f464c52Smaya 28799f464c52Smaya /* Passes on 11+ */ 28809f464c52Smaya INST(MOV, 1, W, B, 8, 8, 1, D, 8, 8, 1, D, 11, true ), 28819f464c52Smaya INST(ADD, 1, UD, B, 8, 8, 1, W, 8, 8, 1, D, 11, true ), 28829f464c52Smaya INST(MAD, 1, B, B, 0, 1, 0, D, 0, 4, 0, W, 11, true ), 28839f464c52Smaya 28849f464c52Smaya#undef INST 28859f464c52Smaya }; 28869f464c52Smaya 28879f464c52Smaya 28889f464c52Smaya for (unsigned i = 0; i < ARRAY_SIZE(inst); i++) { 28897ec681f3Smrg /* Skip instruction not meant for this gfx_ver. */ 28907ec681f3Smrg if (devinfo.ver != inst[i].gfx_ver) 28919f464c52Smaya continue; 28929f464c52Smaya 28939f464c52Smaya brw_push_insn_state(p); 28949f464c52Smaya 28959f464c52Smaya brw_set_default_exec_size(p, BRW_EXECUTE_8); 28969f464c52Smaya brw_set_default_access_mode(p, inst[i].access_mode); 28979f464c52Smaya 28989f464c52Smaya switch (inst[i].opcode) { 28999f464c52Smaya case BRW_OPCODE_MOV: 29009f464c52Smaya brw_MOV(p, retype(g0, inst[i].dst_type), 29019f464c52Smaya retype(g0, inst[i].srcs[0].type)); 29029f464c52Smaya brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].srcs[0].vstride); 29039f464c52Smaya brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].srcs[0].hstride); 29049f464c52Smaya break; 29059f464c52Smaya case BRW_OPCODE_ADD: 29069f464c52Smaya brw_ADD(p, retype(g0, inst[i].dst_type), 29079f464c52Smaya retype(g0, inst[i].srcs[0].type), 29089f464c52Smaya retype(g0, inst[i].srcs[1].type)); 29099f464c52Smaya brw_inst_set_src0_vstride(&devinfo, last_inst, inst[i].srcs[0].vstride); 29109f464c52Smaya brw_inst_set_src0_width(&devinfo, last_inst, inst[i].srcs[0].width); 29119f464c52Smaya brw_inst_set_src0_hstride(&devinfo, last_inst, inst[i].srcs[0].hstride); 29129f464c52Smaya brw_inst_set_src1_vstride(&devinfo, last_inst, inst[i].srcs[1].vstride); 29139f464c52Smaya brw_inst_set_src1_width(&devinfo, last_inst, inst[i].srcs[1].width); 29149f464c52Smaya brw_inst_set_src1_hstride(&devinfo, last_inst, inst[i].srcs[1].hstride); 29159f464c52Smaya break; 29169f464c52Smaya case BRW_OPCODE_MAD: 29179f464c52Smaya brw_MAD(p, retype(g0, inst[i].dst_type), 29189f464c52Smaya retype(g0, inst[i].srcs[0].type), 29199f464c52Smaya retype(g0, inst[i].srcs[1].type), 29209f464c52Smaya retype(g0, inst[i].srcs[2].type)); 29219f464c52Smaya brw_inst_set_3src_a1_src0_vstride(&devinfo, last_inst, inst[i].srcs[0].vstride); 29229f464c52Smaya brw_inst_set_3src_a1_src0_hstride(&devinfo, last_inst, inst[i].srcs[0].hstride); 29239f464c52Smaya brw_inst_set_3src_a1_src1_vstride(&devinfo, last_inst, inst[i].srcs[0].vstride); 29249f464c52Smaya brw_inst_set_3src_a1_src1_hstride(&devinfo, last_inst, inst[i].srcs[0].hstride); 29259f464c52Smaya break; 29269f464c52Smaya default: 29279f464c52Smaya unreachable("invalid opcode"); 29289f464c52Smaya } 29299f464c52Smaya 29309f464c52Smaya brw_inst_set_dst_hstride(&devinfo, last_inst, BRW_HORIZONTAL_STRIDE_1); 29319f464c52Smaya 29329f464c52Smaya brw_inst_set_src0_width(&devinfo, last_inst, inst[i].srcs[0].width); 29339f464c52Smaya brw_inst_set_src1_width(&devinfo, last_inst, inst[i].srcs[1].width); 29349f464c52Smaya 29359f464c52Smaya brw_pop_insn_state(p); 29369f464c52Smaya 29379f464c52Smaya EXPECT_EQ(inst[i].expected_result, validate(p)); 29389f464c52Smaya 29399f464c52Smaya clear_instructions(p); 29409f464c52Smaya } 29419f464c52Smaya} 2942