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