1 /* 2 * Copyright 2014 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24 /** 25 * @file brw_inst.h 26 * 27 * A representation of i965 EU assembly instructions, with helper methods to 28 * get and set various fields. This is the actual hardware format. 29 */ 30 31 #ifndef BRW_INST_H 32 #define BRW_INST_H 33 34 #include <assert.h> 35 #include <stdint.h> 36 37 #include "brw_eu_defines.h" 38 #include "brw_reg_type.h" 39 #include "common/gen_device_info.h" 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 /* brw_context.h has a forward declaration of brw_inst, so name the struct. */ 46 typedef struct brw_inst { 47 uint64_t data[2]; 48 } brw_inst; 49 50 static inline uint64_t brw_inst_bits(const brw_inst *inst, 51 unsigned high, unsigned low); 52 static inline void brw_inst_set_bits(brw_inst *inst, 53 unsigned high, unsigned low, 54 uint64_t value); 55 56 #define FC(name, high, low, assertions) \ 57 static inline void \ 58 brw_inst_set_##name(const struct gen_device_info *devinfo, \ 59 brw_inst *inst, uint64_t v) \ 60 { \ 61 assert(assertions); \ 62 (void) devinfo; \ 63 brw_inst_set_bits(inst, high, low, v); \ 64 } \ 65 static inline uint64_t \ 66 brw_inst_##name(const struct gen_device_info *devinfo, \ 67 const brw_inst *inst) \ 68 { \ 69 assert(assertions); \ 70 (void) devinfo; \ 71 return brw_inst_bits(inst, high, low); \ 72 } 73 74 /* A simple macro for fields which stay in the same place on all generations. */ 75 #define F(name, high, low) FC(name, high, low, true) 76 77 #define BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, hi7, lo7, hi8, lo8) \ 78 unsigned high, low; \ 79 if (devinfo->gen >= 8) { \ 80 high = hi8; low = lo8; \ 81 } else if (devinfo->gen >= 7) { \ 82 high = hi7; low = lo7; \ 83 } else if (devinfo->gen >= 6) { \ 84 high = hi6; low = lo6; \ 85 } else if (devinfo->gen >= 5) { \ 86 high = hi5; low = lo5; \ 87 } else if (devinfo->is_g4x) { \ 88 high = hi45; low = lo45; \ 89 } else { \ 90 high = hi4; low = lo4; \ 91 } \ 92 assert(((int) high) != -1 && ((int) low) != -1); 93 94 /* A general macro for cases where the field has moved to several different 95 * bit locations across generations. GCC appears to combine cases where the 96 * bits are identical, removing some of the inefficiency. 97 */ 98 #define FF(name, hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, hi7, lo7, hi8, lo8)\ 99 static inline void \ 100 brw_inst_set_##name(const struct gen_device_info *devinfo, \ 101 brw_inst *inst, uint64_t value) \ 102 { \ 103 BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, hi7, lo7, hi8, lo8) \ 104 brw_inst_set_bits(inst, high, low, value); \ 105 } \ 106 static inline uint64_t \ 107 brw_inst_##name(const struct gen_device_info *devinfo, const brw_inst *inst) \ 108 { \ 109 BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, hi7, lo7, hi8, lo8) \ 110 return brw_inst_bits(inst, high, low); \ 111 } 112 113 /* A macro for fields which moved as of Gen8+. */ 114 #define F8(name, gen4_high, gen4_low, gen8_high, gen8_low) \ 115 FF(name, \ 116 /* 4: */ gen4_high, gen4_low, \ 117 /* 4.5: */ gen4_high, gen4_low, \ 118 /* 5: */ gen4_high, gen4_low, \ 119 /* 6: */ gen4_high, gen4_low, \ 120 /* 7: */ gen4_high, gen4_low, \ 121 /* 8: */ gen8_high, gen8_low); 122 123 F(src1_vstride, 120, 117) 124 F(src1_width, 116, 114) 125 F(src1_da16_swiz_w, 115, 114) 126 F(src1_da16_swiz_z, 113, 112) 127 F(src1_hstride, 113, 112) 128 F(src1_address_mode, 111, 111) 129 /** Src1.SrcMod @{ */ 130 F(src1_negate, 110, 110) 131 F(src1_abs, 109, 109) 132 /** @} */ 133 F8(src1_ia_subreg_nr, /* 4+ */ 108, 106, /* 8+ */ 108, 105) 134 F(src1_da_reg_nr, 108, 101) 135 F(src1_da16_subreg_nr, 100, 100) 136 F(src1_da1_subreg_nr, 100, 96) 137 F(src1_da16_swiz_y, 99, 98) 138 F(src1_da16_swiz_x, 97, 96) 139 F8(src1_reg_hw_type, /* 4+ */ 46, 44, /* 8+ */ 94, 91) 140 F8(src1_reg_file, /* 4+ */ 43, 42, /* 8+ */ 90, 89) 141 F(src0_vstride, 88, 85) 142 F(src0_width, 84, 82) 143 F(src0_da16_swiz_w, 83, 82) 144 F(src0_da16_swiz_z, 81, 80) 145 F(src0_hstride, 81, 80) 146 F(src0_address_mode, 79, 79) 147 /** Src0.SrcMod @{ */ 148 F(src0_negate, 78, 78) 149 F(src0_abs, 77, 77) 150 /** @} */ 151 F8(src0_ia_subreg_nr, /* 4+ */ 76, 74, /* 8+ */ 76, 73) 152 F(src0_da_reg_nr, 76, 69) 153 F(src0_da16_subreg_nr, 68, 68) 154 F(src0_da1_subreg_nr, 68, 64) 155 F(src0_da16_swiz_y, 67, 66) 156 F(src0_da16_swiz_x, 65, 64) 157 F(dst_address_mode, 63, 63) 158 F(dst_hstride, 62, 61) 159 F8(dst_ia_subreg_nr, /* 4+ */ 60, 58, /* 8+ */ 60, 57) 160 F(dst_da_reg_nr, 60, 53) 161 F(dst_da16_subreg_nr, 52, 52) 162 F(dst_da1_subreg_nr, 52, 48) 163 F(da16_writemask, 51, 48) /* Dst.ChanEn */ 164 F8(src0_reg_hw_type, /* 4+ */ 41, 39, /* 8+ */ 46, 43) 165 F8(src0_reg_file, /* 4+ */ 38, 37, /* 8+ */ 42, 41) 166 F8(dst_reg_hw_type, /* 4+ */ 36, 34, /* 8+ */ 40, 37) 167 F8(dst_reg_file, /* 4+ */ 33, 32, /* 8+ */ 36, 35) 168 F8(mask_control, /* 4+ */ 9, 9, /* 8+ */ 34, 34) 169 FF(flag_reg_nr, 170 /* 4-6: doesn't exist */ -1, -1, -1, -1, -1, -1, -1, -1, 171 /* 7: */ 90, 90, 172 /* 8: */ 33, 33) 173 F8(flag_subreg_nr, /* 4+ */ 89, 89, /* 8+ */ 32, 32) 174 F(saturate, 31, 31) 175 F(debug_control, 30, 30) 176 F(cmpt_control, 29, 29) 177 FC(branch_control, 28, 28, devinfo->gen >= 8) 178 FC(acc_wr_control, 28, 28, devinfo->gen >= 6) 179 FC(mask_control_ex, 28, 28, devinfo->is_g4x || devinfo->gen == 5) 180 F(cond_modifier, 27, 24) 181 FC(math_function, 27, 24, devinfo->gen >= 6) 182 F(exec_size, 23, 21) 183 F(pred_inv, 20, 20) 184 F(pred_control, 19, 16) 185 F(thread_control, 15, 14) 186 F(qtr_control, 13, 12) 187 FF(nib_control, 188 /* 4-6: doesn't exist */ -1, -1, -1, -1, -1, -1, -1, -1, 189 /* 7: */ 47, 47, 190 /* 8: */ 11, 11) 191 F8(no_dd_check, /* 4+ */ 11, 11, /* 8+ */ 10, 10) 192 F8(no_dd_clear, /* 4+ */ 10, 10, /* 8+ */ 9, 9) 193 F(access_mode, 8, 8) 194 /* Bit 7 is Reserved (for future Opcode expansion) */ 195 F(opcode, 6, 0) 196 197 /** 198 * Three-source instructions: 199 * @{ 200 */ 201 F(3src_src2_reg_nr, 125, 118) /* same in align1 */ 202 F(3src_a16_src2_subreg_nr, 117, 115) /* Extra discontiguous bit on CHV? */ 203 F(3src_a16_src2_swizzle, 114, 107) 204 F(3src_a16_src2_rep_ctrl, 106, 106) 205 F(3src_src1_reg_nr, 104, 97) /* same in align1 */ 206 F(3src_a16_src1_subreg_nr, 96, 94) /* Extra discontiguous bit on CHV? */ 207 F(3src_a16_src1_swizzle, 93, 86) 208 F(3src_a16_src1_rep_ctrl, 85, 85) 209 F(3src_src0_reg_nr, 83, 76) /* same in align1 */ 210 F(3src_a16_src0_subreg_nr, 75, 73) /* Extra discontiguous bit on CHV? */ 211 F(3src_a16_src0_swizzle, 72, 65) 212 F(3src_a16_src0_rep_ctrl, 64, 64) 213 F(3src_dst_reg_nr, 63, 56) /* same in align1 */ 214 F(3src_a16_dst_subreg_nr, 55, 53) 215 F(3src_a16_dst_writemask, 52, 49) 216 F8(3src_a16_nib_ctrl, 47, 47, 11, 11) /* only exists on IVB+ */ 217 F8(3src_a16_dst_hw_type, 45, 44, 48, 46) /* only exists on IVB+ */ 218 F8(3src_a16_src_hw_type, 43, 42, 45, 43) 219 F8(3src_src2_negate, 41, 41, 42, 42) 220 F8(3src_src2_abs, 40, 40, 41, 41) 221 F8(3src_src1_negate, 39, 39, 40, 40) 222 F8(3src_src1_abs, 38, 38, 39, 39) 223 F8(3src_src0_negate, 37, 37, 38, 38) 224 F8(3src_src0_abs, 36, 36, 37, 37) 225 F8(3src_a16_flag_reg_nr, 34, 34, 33, 33) 226 F8(3src_a16_flag_subreg_nr, 33, 33, 32, 32) 227 FF(3src_a16_dst_reg_file, 228 /* 4-5: doesn't exist - no 3-source instructions */ -1, -1, -1, -1, -1, -1, 229 /* 6: */ 32, 32, 230 /* 7-8: doesn't exist - no MRFs */ -1, -1, -1, -1) 231 F(3src_saturate, 31, 31) 232 F(3src_debug_control, 30, 30) 233 F(3src_cmpt_control, 29, 29) 234 F(3src_acc_wr_control, 28, 28) 235 F(3src_cond_modifier, 27, 24) 236 F(3src_exec_size, 23, 21) 237 F(3src_pred_inv, 20, 20) 238 F(3src_pred_control, 19, 16) 239 F(3src_thread_control, 15, 14) 240 F(3src_qtr_control, 13, 12) 241 F8(3src_no_dd_check, 11, 11, 10, 10) 242 F8(3src_no_dd_clear, 10, 10, 9, 9) 243 F8(3src_mask_control, 9, 9, 34, 34) 244 F(3src_access_mode, 8, 8) 245 /* Bit 7 is Reserved (for future Opcode expansion) */ 246 F(3src_opcode, 6, 0) 247 /** @} */ 248 249 #define REG_TYPE(reg) \ 250 static inline void \ 251 brw_inst_set_3src_a16_##reg##_type(const struct gen_device_info *devinfo, \ 252 brw_inst *inst, enum brw_reg_type type) \ 253 { \ 254 unsigned hw_type = brw_reg_type_to_a16_hw_3src_type(devinfo, type); \ 255 brw_inst_set_3src_a16_##reg##_hw_type(devinfo, inst, hw_type); \ 256 } \ 257 \ 258 static inline enum brw_reg_type \ 259 brw_inst_3src_a16_##reg##_type(const struct gen_device_info *devinfo, \ 260 const brw_inst *inst) \ 261 { \ 262 unsigned hw_type = brw_inst_3src_a16_##reg##_hw_type(devinfo, inst); \ 263 return brw_a16_hw_3src_type_to_reg_type(devinfo, hw_type); \ 264 } 265 266 REG_TYPE(dst) 267 REG_TYPE(src) 268 #undef REG_TYPE 269 270 /** 271 * Three-source align1 instructions: 272 * @{ 273 */ 274 /* Reserved 127:126 */ 275 /* src2_reg_nr same in align16 */ 276 FC(3src_a1_src2_subreg_nr, 117, 113, devinfo->gen >= 10) 277 FC(3src_a1_src2_hstride, 112, 111, devinfo->gen >= 10) 278 /* Reserved 110:109. src2 vstride is an implied parameter */ 279 FC(3src_a1_src2_hw_type, 108, 106, devinfo->gen >= 10) 280 /* Reserved 105 */ 281 /* src1_reg_nr same in align16 */ 282 FC(3src_a1_src1_subreg_nr, 96, 92, devinfo->gen >= 10) 283 FC(3src_a1_src1_hstride, 91, 90, devinfo->gen >= 10) 284 FC(3src_a1_src1_vstride, 89, 88, devinfo->gen >= 10) 285 FC(3src_a1_src1_hw_type, 87, 85, devinfo->gen >= 10) 286 /* Reserved 84 */ 287 /* src0_reg_nr same in align16 */ 288 FC(3src_a1_src0_subreg_nr, 75, 71, devinfo->gen >= 10) 289 FC(3src_a1_src0_hstride, 70, 69, devinfo->gen >= 10) 290 FC(3src_a1_src0_vstride, 68, 67, devinfo->gen >= 10) 291 FC(3src_a1_src0_hw_type, 66, 64, devinfo->gen >= 10) 292 /* dst_reg_nr same in align16 */ 293 FC(3src_a1_dst_subreg_nr, 55, 54, devinfo->gen >= 10) 294 FC(3src_a1_special_acc, 55, 52, devinfo->gen >= 10) /* aliases dst_subreg_nr */ 295 /* Reserved 51:50 */ 296 FC(3src_a1_dst_hstride, 49, 49, devinfo->gen >= 10) 297 FC(3src_a1_dst_hw_type, 48, 46, devinfo->gen >= 10) 298 FC(3src_a1_src2_reg_file, 45, 45, devinfo->gen >= 10) 299 FC(3src_a1_src1_reg_file, 44, 44, devinfo->gen >= 10) 300 FC(3src_a1_src0_reg_file, 43, 43, devinfo->gen >= 10) 301 /* Source Modifier fields same in align16 */ 302 FC(3src_a1_dst_reg_file, 36, 36, devinfo->gen >= 10) 303 FC(3src_a1_exec_type, 35, 35, devinfo->gen >= 10) 304 /* Fields below this same in align16 */ 305 /** @} */ 306 307 #define REG_TYPE(reg) \ 308 static inline void \ 309 brw_inst_set_3src_a1_##reg##_type(const struct gen_device_info *devinfo, \ 310 brw_inst *inst, enum brw_reg_type type) \ 311 { \ 312 UNUSED enum gen10_align1_3src_exec_type exec_type = \ 313 (enum gen10_align1_3src_exec_type) brw_inst_3src_a1_exec_type(devinfo, \ 314 inst); \ 315 if (brw_reg_type_is_floating_point(type)) { \ 316 assert(exec_type == BRW_ALIGN1_3SRC_EXEC_TYPE_FLOAT); \ 317 } else { \ 318 assert(exec_type == BRW_ALIGN1_3SRC_EXEC_TYPE_INT); \ 319 } \ 320 unsigned hw_type = brw_reg_type_to_a1_hw_3src_type(devinfo, type); \ 321 brw_inst_set_3src_a1_##reg##_hw_type(devinfo, inst, hw_type); \ 322 } \ 323 \ 324 static inline enum brw_reg_type \ 325 brw_inst_3src_a1_##reg##_type(const struct gen_device_info *devinfo, \ 326 const brw_inst *inst) \ 327 { \ 328 enum gen10_align1_3src_exec_type exec_type = \ 329 (enum gen10_align1_3src_exec_type) brw_inst_3src_a1_exec_type(devinfo, \ 330 inst); \ 331 unsigned hw_type = brw_inst_3src_a1_##reg##_hw_type(devinfo, inst); \ 332 return brw_a1_hw_3src_type_to_reg_type(devinfo, hw_type, exec_type); \ 333 } 334 335 REG_TYPE(dst) 336 REG_TYPE(src0) 337 REG_TYPE(src1) 338 REG_TYPE(src2) 339 #undef REG_TYPE 340 341 /** 342 * Three-source align1 instruction immediates: 343 * @{ 344 */ 345 static inline uint16_t 346 brw_inst_3src_a1_src0_imm(const struct gen_device_info *devinfo, 347 const brw_inst *insn) 348 { 349 assert(devinfo->gen >= 10); 350 return brw_inst_bits(insn, 82, 67); 351 } 352 353 static inline uint16_t 354 brw_inst_3src_a1_src2_imm(const struct gen_device_info *devinfo, 355 const brw_inst *insn) 356 { 357 assert(devinfo->gen >= 10); 358 return brw_inst_bits(insn, 124, 109); 359 } 360 361 static inline void 362 brw_inst_set_3src_a1_src0_imm(const struct gen_device_info *devinfo, 363 brw_inst *insn, uint16_t value) 364 { 365 assert(devinfo->gen >= 10); 366 brw_inst_set_bits(insn, 82, 67, value); 367 } 368 369 static inline void 370 brw_inst_set_3src_a1_src2_imm(const struct gen_device_info *devinfo, 371 brw_inst *insn, uint16_t value) 372 { 373 assert(devinfo->gen >= 10); 374 brw_inst_set_bits(insn, 124, 109, value); 375 } 376 /** @} */ 377 378 /** 379 * Flow control instruction bits: 380 * @{ 381 */ 382 static inline void 383 brw_inst_set_uip(const struct gen_device_info *devinfo, 384 brw_inst *inst, int32_t value) 385 { 386 assert(devinfo->gen >= 6); 387 388 if (devinfo->gen >= 8) { 389 brw_inst_set_bits(inst, 95, 64, (uint32_t)value); 390 } else { 391 assert(value <= (1 << 16) - 1); 392 assert(value > -(1 << 16)); 393 brw_inst_set_bits(inst, 127, 112, (uint16_t)value); 394 } 395 } 396 397 static inline int32_t 398 brw_inst_uip(const struct gen_device_info *devinfo, const brw_inst *inst) 399 { 400 assert(devinfo->gen >= 6); 401 402 if (devinfo->gen >= 8) { 403 return brw_inst_bits(inst, 95, 64); 404 } else { 405 return (int16_t)brw_inst_bits(inst, 127, 112); 406 } 407 } 408 409 static inline void 410 brw_inst_set_jip(const struct gen_device_info *devinfo, 411 brw_inst *inst, int32_t value) 412 { 413 assert(devinfo->gen >= 6); 414 415 if (devinfo->gen >= 8) { 416 brw_inst_set_bits(inst, 127, 96, (uint32_t)value); 417 } else { 418 assert(value <= (1 << 15) - 1); 419 assert(value >= -(1 << 15)); 420 brw_inst_set_bits(inst, 111, 96, (uint16_t)value); 421 } 422 } 423 424 static inline int32_t 425 brw_inst_jip(const struct gen_device_info *devinfo, const brw_inst *inst) 426 { 427 assert(devinfo->gen >= 6); 428 429 if (devinfo->gen >= 8) { 430 return brw_inst_bits(inst, 127, 96); 431 } else { 432 return (int16_t)brw_inst_bits(inst, 111, 96); 433 } 434 } 435 436 /** Like FC, but using int16_t to handle negative jump targets. */ 437 #define FJ(name, high, low, assertions) \ 438 static inline void \ 439 brw_inst_set_##name(const struct gen_device_info *devinfo, brw_inst *inst, int16_t v) \ 440 { \ 441 assert(assertions); \ 442 (void) devinfo; \ 443 brw_inst_set_bits(inst, high, low, (uint16_t) v); \ 444 } \ 445 static inline int16_t \ 446 brw_inst_##name(const struct gen_device_info *devinfo, const brw_inst *inst) \ 447 { \ 448 assert(assertions); \ 449 (void) devinfo; \ 450 return brw_inst_bits(inst, high, low); \ 451 } 452 453 FJ(gen6_jump_count, 63, 48, devinfo->gen == 6) 454 FJ(gen4_jump_count, 111, 96, devinfo->gen < 6) 455 FC(gen4_pop_count, 115, 112, devinfo->gen < 6) 456 /** @} */ 457 458 /* Message descriptor bits */ 459 #define MD(x) ((x) + 96) 460 461 /** 462 * Fields for SEND messages: 463 * @{ 464 */ 465 F(eot, 127, 127) 466 FF(mlen, 467 /* 4: */ 119, 116, 468 /* 4.5: */ 119, 116, 469 /* 5: */ 124, 121, 470 /* 6: */ 124, 121, 471 /* 7: */ 124, 121, 472 /* 8: */ 124, 121); 473 FF(rlen, 474 /* 4: */ 115, 112, 475 /* 4.5: */ 115, 112, 476 /* 5: */ 120, 116, 477 /* 6: */ 120, 116, 478 /* 7: */ 120, 116, 479 /* 8: */ 120, 116); 480 FF(header_present, 481 /* 4: doesn't exist */ -1, -1, -1, -1, 482 /* 5: */ 115, 115, 483 /* 6: */ 115, 115, 484 /* 7: */ 115, 115, 485 /* 8: */ 115, 115) 486 F(gateway_notify, MD(16), MD(15)) 487 FF(function_control, 488 /* 4: */ 111, 96, 489 /* 4.5: */ 111, 96, 490 /* 5: */ 114, 96, 491 /* 6: */ 114, 96, 492 /* 7: */ 114, 96, 493 /* 8: */ 114, 96) 494 FF(gateway_subfuncid, 495 /* 4: */ MD(1), MD(0), 496 /* 4.5: */ MD(1), MD(0), 497 /* 5: */ MD(1), MD(0), /* 2:0, but bit 2 is reserved MBZ */ 498 /* 6: */ MD(2), MD(0), 499 /* 7: */ MD(2), MD(0), 500 /* 8: */ MD(2), MD(0)) 501 FF(sfid, 502 /* 4: */ 123, 120, /* called msg_target */ 503 /* 4.5 */ 123, 120, 504 /* 5: */ 95, 92, 505 /* 6: */ 27, 24, 506 /* 7: */ 27, 24, 507 /* 8: */ 27, 24) 508 FC(base_mrf, 27, 24, devinfo->gen < 6); 509 /** @} */ 510 511 /** 512 * URB message function control bits: 513 * @{ 514 */ 515 FF(urb_per_slot_offset, 516 /* 4-6: */ -1, -1, -1, -1, -1, -1, -1, -1, 517 /* 7: */ MD(16), MD(16), 518 /* 8: */ MD(17), MD(17)) 519 FC(urb_channel_mask_present, MD(15), MD(15), devinfo->gen >= 8) 520 FC(urb_complete, MD(15), MD(15), devinfo->gen < 8) 521 FC(urb_used, MD(14), MD(14), devinfo->gen < 7) 522 FC(urb_allocate, MD(13), MD(13), devinfo->gen < 7) 523 FF(urb_swizzle_control, 524 /* 4: */ MD(11), MD(10), 525 /* 4.5: */ MD(11), MD(10), 526 /* 5: */ MD(11), MD(10), 527 /* 6: */ MD(11), MD(10), 528 /* 7: */ MD(14), MD(14), 529 /* 8: */ MD(15), MD(15)) 530 FF(urb_global_offset, 531 /* 4: */ MD( 9), MD(4), 532 /* 4.5: */ MD( 9), MD(4), 533 /* 5: */ MD( 9), MD(4), 534 /* 6: */ MD( 9), MD(4), 535 /* 7: */ MD(13), MD(3), 536 /* 8: */ MD(14), MD(4)) 537 FF(urb_opcode, 538 /* 4: */ MD( 3), MD(0), 539 /* 4.5: */ MD( 3), MD(0), 540 /* 5: */ MD( 3), MD(0), 541 /* 6: */ MD( 3), MD(0), 542 /* 7: */ MD( 2), MD(0), 543 /* 8: */ MD( 3), MD(0)) 544 /** @} */ 545 546 /** 547 * Gen4-5 math messages: 548 * @{ 549 */ 550 FC(math_msg_data_type, MD(7), MD(7), devinfo->gen < 6) 551 FC(math_msg_saturate, MD(6), MD(6), devinfo->gen < 6) 552 FC(math_msg_precision, MD(5), MD(5), devinfo->gen < 6) 553 FC(math_msg_signed_int, MD(4), MD(4), devinfo->gen < 6) 554 FC(math_msg_function, MD(3), MD(0), devinfo->gen < 6) 555 /** @} */ 556 557 /** 558 * Sampler message function control bits: 559 * @{ 560 */ 561 FF(sampler_simd_mode, 562 /* 4: doesn't exist */ -1, -1, -1, -1, 563 /* 5: */ MD(17), MD(16), 564 /* 6: */ MD(17), MD(16), 565 /* 7: */ MD(18), MD(17), 566 /* 8: */ MD(18), MD(17)) 567 FF(sampler_msg_type, 568 /* 4: */ MD(15), MD(14), 569 /* 4.5: */ MD(15), MD(12), 570 /* 5: */ MD(15), MD(12), 571 /* 6: */ MD(15), MD(12), 572 /* 7: */ MD(16), MD(12), 573 /* 8: */ MD(16), MD(12)) 574 FC(sampler_return_format, MD(13), MD(12), devinfo->gen == 4 && !devinfo->is_g4x) 575 F(sampler, MD(11), MD(8)) 576 F(binding_table_index, MD( 7), MD(0)) /* also used by other messages */ 577 /** @} */ 578 579 /** 580 * Data port message function control bits: 581 * @{ 582 */ 583 FC(dp_category, MD(18), MD(18), devinfo->gen >= 7) 584 585 /* Gen4-5 store fields in different bits for read/write messages. */ 586 FF(dp_read_msg_type, 587 /* 4: */ MD(13), MD(12), 588 /* 4.5: */ MD(13), MD(11), 589 /* 5: */ MD(13), MD(11), 590 /* 6: */ MD(16), MD(13), 591 /* 7: */ MD(17), MD(14), 592 /* 8: */ MD(17), MD(14)) 593 FF(dp_write_msg_type, 594 /* 4: */ MD(14), MD(12), 595 /* 4.5: */ MD(14), MD(12), 596 /* 5: */ MD(14), MD(12), 597 /* 6: */ MD(16), MD(13), 598 /* 7: */ MD(17), MD(14), 599 /* 8: */ MD(17), MD(14)) 600 FF(dp_read_msg_control, 601 /* 4: */ MD(11), MD( 8), 602 /* 4.5: */ MD(10), MD( 8), 603 /* 5: */ MD(10), MD( 8), 604 /* 6: */ MD(12), MD( 8), 605 /* 7: */ MD(13), MD( 8), 606 /* 8: */ MD(13), MD( 8)) 607 FF(dp_write_msg_control, 608 /* 4: */ MD(11), MD( 8), 609 /* 4.5: */ MD(11), MD( 8), 610 /* 5: */ MD(11), MD( 8), 611 /* 6: */ MD(12), MD( 8), 612 /* 7: */ MD(13), MD( 8), 613 /* 8: */ MD(13), MD( 8)) 614 FC(dp_read_target_cache, MD(15), MD(14), devinfo->gen < 6); 615 616 FF(dp_write_commit, 617 /* 4: */ MD(15), MD(15), 618 /* 4.5: */ MD(15), MD(15), 619 /* 5: */ MD(15), MD(15), 620 /* 6: */ MD(17), MD(17), 621 /* 7+: does not exist */ -1, -1, -1, -1) 622 623 /* Gen6+ use the same bit locations for everything. */ 624 FF(dp_msg_type, 625 /* 4-5: use dp_read_msg_type or dp_write_msg_type instead */ 626 -1, -1, -1, -1, -1, -1, 627 /* 6: */ MD(16), MD(13), 628 /* 7: */ MD(17), MD(14), 629 /* 8: */ MD(17), MD(14)) 630 FF(dp_msg_control, 631 /* 4: */ MD(11), MD( 8), 632 /* 4.5-5: use dp_read_msg_control or dp_write_msg_control */ -1, -1, -1, -1, 633 /* 6: */ MD(12), MD( 8), 634 /* 7: */ MD(13), MD( 8), 635 /* 8: */ MD(13), MD( 8)) 636 /** @} */ 637 638 /** 639 * Scratch message bits (Gen7+): 640 * @{ 641 */ 642 FC(scratch_read_write, MD(17), MD(17), devinfo->gen >= 7) /* 0 = read, 1 = write */ 643 FC(scratch_type, MD(16), MD(16), devinfo->gen >= 7) /* 0 = OWord, 1 = DWord */ 644 FC(scratch_invalidate_after_read, MD(15), MD(15), devinfo->gen >= 7) 645 FC(scratch_block_size, MD(13), MD(12), devinfo->gen >= 7) 646 FC(scratch_addr_offset, MD(11), MD( 0), devinfo->gen >= 7) 647 /** @} */ 648 649 /** 650 * Render Target message function control bits: 651 * @{ 652 */ 653 FF(rt_last, 654 /* 4: */ MD(11), MD(11), 655 /* 4.5: */ MD(11), MD(11), 656 /* 5: */ MD(11), MD(11), 657 /* 6: */ MD(12), MD(12), 658 /* 7: */ MD(12), MD(12), 659 /* 8: */ MD(12), MD(12)) 660 FC(rt_slot_group, MD(11), MD(11), devinfo->gen >= 6) 661 F(rt_message_type, MD(10), MD( 8)) 662 /** @} */ 663 664 /** 665 * Thread Spawn message function control bits: 666 * @{ 667 */ 668 F(ts_resource_select, MD( 4), MD( 4)) 669 F(ts_request_type, MD( 1), MD( 1)) 670 F(ts_opcode, MD( 0), MD( 0)) 671 /** @} */ 672 673 /** 674 * Pixel Interpolator message function control bits: 675 * @{ 676 */ 677 F(pi_simd_mode, MD(16), MD(16)) 678 F(pi_nopersp, MD(14), MD(14)) 679 F(pi_message_type, MD(13), MD(12)) 680 F(pi_slot_group, MD(11), MD(11)) 681 F(pi_message_data, MD(7), MD(0)) 682 /** @} */ 683 684 /** 685 * Immediates: 686 * @{ 687 */ 688 static inline int 689 brw_inst_imm_d(const struct gen_device_info *devinfo, const brw_inst *insn) 690 { 691 (void) devinfo; 692 return brw_inst_bits(insn, 127, 96); 693 } 694 695 static inline unsigned 696 brw_inst_imm_ud(const struct gen_device_info *devinfo, const brw_inst *insn) 697 { 698 (void) devinfo; 699 return brw_inst_bits(insn, 127, 96); 700 } 701 702 static inline uint64_t 703 brw_inst_imm_uq(const struct gen_device_info *devinfo, const brw_inst *insn) 704 { 705 assert(devinfo->gen >= 8); 706 return brw_inst_bits(insn, 127, 64); 707 } 708 709 static inline float 710 brw_inst_imm_f(const struct gen_device_info *devinfo, const brw_inst *insn) 711 { 712 union { 713 float f; 714 uint32_t u; 715 } ft; 716 (void) devinfo; 717 ft.u = brw_inst_bits(insn, 127, 96); 718 return ft.f; 719 } 720 721 static inline double 722 brw_inst_imm_df(const struct gen_device_info *devinfo, const brw_inst *insn) 723 { 724 union { 725 double d; 726 uint64_t u; 727 } dt; 728 (void) devinfo; 729 dt.u = brw_inst_bits(insn, 127, 64); 730 return dt.d; 731 } 732 733 static inline void 734 brw_inst_set_imm_d(const struct gen_device_info *devinfo, 735 brw_inst *insn, int value) 736 { 737 (void) devinfo; 738 return brw_inst_set_bits(insn, 127, 96, value); 739 } 740 741 static inline void 742 brw_inst_set_imm_ud(const struct gen_device_info *devinfo, 743 brw_inst *insn, unsigned value) 744 { 745 (void) devinfo; 746 return brw_inst_set_bits(insn, 127, 96, value); 747 } 748 749 static inline void 750 brw_inst_set_imm_f(const struct gen_device_info *devinfo, 751 brw_inst *insn, float value) 752 { 753 union { 754 float f; 755 uint32_t u; 756 } ft; 757 (void) devinfo; 758 ft.f = value; 759 brw_inst_set_bits(insn, 127, 96, ft.u); 760 } 761 762 static inline void 763 brw_inst_set_imm_df(const struct gen_device_info *devinfo, 764 brw_inst *insn, double value) 765 { 766 union { 767 double d; 768 uint64_t u; 769 } dt; 770 (void) devinfo; 771 dt.d = value; 772 brw_inst_set_bits(insn, 127, 64, dt.u); 773 } 774 775 static inline void 776 brw_inst_set_imm_uq(const struct gen_device_info *devinfo, 777 brw_inst *insn, uint64_t value) 778 { 779 (void) devinfo; 780 brw_inst_set_bits(insn, 127, 64, value); 781 } 782 783 /** @} */ 784 785 #define REG_TYPE(reg) \ 786 static inline void \ 787 brw_inst_set_##reg##_file_type(const struct gen_device_info *devinfo, \ 788 brw_inst *inst, enum brw_reg_file file, \ 789 enum brw_reg_type type) \ 790 { \ 791 assert(file <= BRW_IMMEDIATE_VALUE); \ 792 unsigned hw_type = brw_reg_type_to_hw_type(devinfo, file, type); \ 793 brw_inst_set_##reg##_reg_file(devinfo, inst, file); \ 794 brw_inst_set_##reg##_reg_hw_type(devinfo, inst, hw_type); \ 795 } \ 796 \ 797 static inline enum brw_reg_type \ 798 brw_inst_##reg##_type(const struct gen_device_info *devinfo, \ 799 const brw_inst *inst) \ 800 { \ 801 unsigned file = __builtin_strcmp("dst", #reg) == 0 ? \ 802 BRW_GENERAL_REGISTER_FILE : \ 803 brw_inst_##reg##_reg_file(devinfo, inst); \ 804 unsigned hw_type = brw_inst_##reg##_reg_hw_type(devinfo, inst); \ 805 return brw_hw_type_to_reg_type(devinfo, (enum brw_reg_file)file, hw_type); \ 806 } 807 808 REG_TYPE(dst) 809 REG_TYPE(src0) 810 REG_TYPE(src1) 811 #undef REG_TYPE 812 813 814 /* The AddrImm fields are split into two discontiguous sections on Gen8+ */ 815 #define BRW_IA1_ADDR_IMM(reg, g4_high, g4_low, g8_nine, g8_high, g8_low) \ 816 static inline void \ 817 brw_inst_set_##reg##_ia1_addr_imm(const struct gen_device_info *devinfo, \ 818 brw_inst *inst, \ 819 unsigned value) \ 820 { \ 821 assert((value & ~0x3ff) == 0); \ 822 if (devinfo->gen >= 8) { \ 823 brw_inst_set_bits(inst, g8_high, g8_low, value & 0x1ff); \ 824 brw_inst_set_bits(inst, g8_nine, g8_nine, value >> 9); \ 825 } else { \ 826 brw_inst_set_bits(inst, g4_high, g4_low, value); \ 827 } \ 828 } \ 829 static inline unsigned \ 830 brw_inst_##reg##_ia1_addr_imm(const struct gen_device_info *devinfo, \ 831 const brw_inst *inst) \ 832 { \ 833 if (devinfo->gen >= 8) { \ 834 return brw_inst_bits(inst, g8_high, g8_low) | \ 835 (brw_inst_bits(inst, g8_nine, g8_nine) << 9); \ 836 } else { \ 837 return brw_inst_bits(inst, g4_high, g4_low); \ 838 } \ 839 } 840 841 /* AddrImm[9:0] for Align1 Indirect Addressing */ 842 /* -Gen 4- ----Gen8---- */ 843 BRW_IA1_ADDR_IMM(src1, 105, 96, 121, 104, 96) 844 BRW_IA1_ADDR_IMM(src0, 73, 64, 95, 72, 64) 845 BRW_IA1_ADDR_IMM(dst, 57, 48, 47, 56, 48) 846 847 #define BRW_IA16_ADDR_IMM(reg, g4_high, g4_low, g8_nine, g8_high, g8_low) \ 848 static inline void \ 849 brw_inst_set_##reg##_ia16_addr_imm(const struct gen_device_info *devinfo, \ 850 brw_inst *inst, unsigned value) \ 851 { \ 852 assert((value & ~0x3ff) == 0); \ 853 if (devinfo->gen >= 8) { \ 854 brw_inst_set_bits(inst, g8_high, g8_low, value & 0x1ff); \ 855 brw_inst_set_bits(inst, g8_nine, g8_nine, value >> 9); \ 856 } else { \ 857 brw_inst_set_bits(inst, g4_high, g4_low, value >> 9); \ 858 } \ 859 } \ 860 static inline unsigned \ 861 brw_inst_##reg##_ia16_addr_imm(const struct gen_device_info *devinfo, \ 862 const brw_inst *inst) \ 863 { \ 864 if (devinfo->gen >= 8) { \ 865 return brw_inst_bits(inst, g8_high, g8_low) | \ 866 (brw_inst_bits(inst, g8_nine, g8_nine) << 9); \ 867 } else { \ 868 return brw_inst_bits(inst, g4_high, g4_low); \ 869 } \ 870 } 871 872 /* AddrImm[9:0] for Align16 Indirect Addressing: 873 * Compared to Align1, these are missing the low 4 bits. 874 * -Gen 4- ----Gen8---- 875 */ 876 BRW_IA16_ADDR_IMM(src1, 105, 96, 121, 104, 100) 877 BRW_IA16_ADDR_IMM(src0, 73, 64, 95, 72, 68) 878 BRW_IA16_ADDR_IMM(dst, 57, 52, 47, 56, 52) 879 880 /** 881 * Fetch a set of contiguous bits from the instruction. 882 * 883 * Bits indices range from 0..127; fields may not cross 64-bit boundaries. 884 */ 885 static inline uint64_t 886 brw_inst_bits(const brw_inst *inst, unsigned high, unsigned low) 887 { 888 /* We assume the field doesn't cross 64-bit boundaries. */ 889 const unsigned word = high / 64; 890 assert(word == low / 64); 891 892 high %= 64; 893 low %= 64; 894 895 const uint64_t mask = (~0ull >> (64 - (high - low + 1))); 896 897 return (inst->data[word] >> low) & mask; 898 } 899 900 /** 901 * Set bits in the instruction, with proper shifting and masking. 902 * 903 * Bits indices range from 0..127; fields may not cross 64-bit boundaries. 904 */ 905 static inline void 906 brw_inst_set_bits(brw_inst *inst, unsigned high, unsigned low, uint64_t value) 907 { 908 const unsigned word = high / 64; 909 assert(word == low / 64); 910 911 high %= 64; 912 low %= 64; 913 914 const uint64_t mask = (~0ull >> (64 - (high - low + 1))) << low; 915 916 /* Make sure the supplied value actually fits in the given bitfield. */ 917 assert((value & (mask >> low)) == value); 918 919 inst->data[word] = (inst->data[word] & ~mask) | (value << low); 920 } 921 922 #undef BRW_IA16_ADDR_IMM 923 #undef BRW_IA1_ADDR_IMM 924 #undef MD 925 #undef F8 926 #undef FF 927 #undef BOUNDS 928 #undef F 929 #undef FC 930 931 typedef struct { 932 uint64_t data; 933 } brw_compact_inst; 934 935 /** 936 * Fetch a set of contiguous bits from the compacted instruction. 937 * 938 * Bits indices range from 0..63. 939 */ 940 static inline unsigned 941 brw_compact_inst_bits(const brw_compact_inst *inst, unsigned high, unsigned low) 942 { 943 const uint64_t mask = (1ull << (high - low + 1)) - 1; 944 945 return (inst->data >> low) & mask; 946 } 947 948 /** 949 * Set bits in the compacted instruction. 950 * 951 * Bits indices range from 0..63. 952 */ 953 static inline void 954 brw_compact_inst_set_bits(brw_compact_inst *inst, unsigned high, unsigned low, 955 uint64_t value) 956 { 957 const uint64_t mask = ((1ull << (high - low + 1)) - 1) << low; 958 959 /* Make sure the supplied value actually fits in the given bitfield. */ 960 assert((value & (mask >> low)) == value); 961 962 inst->data = (inst->data & ~mask) | (value << low); 963 } 964 965 #define FC(name, high, low, assertions) \ 966 static inline void \ 967 brw_compact_inst_set_##name(const struct gen_device_info *devinfo, \ 968 brw_compact_inst *inst, unsigned v) \ 969 { \ 970 assert(assertions); \ 971 (void) devinfo; \ 972 brw_compact_inst_set_bits(inst, high, low, v); \ 973 } \ 974 static inline unsigned \ 975 brw_compact_inst_##name(const struct gen_device_info *devinfo, \ 976 const brw_compact_inst *inst) \ 977 { \ 978 assert(assertions); \ 979 (void) devinfo; \ 980 return brw_compact_inst_bits(inst, high, low); \ 981 } 982 983 /* A simple macro for fields which stay in the same place on all generations. */ 984 #define F(name, high, low) FC(name, high, low, true) 985 986 F(src1_reg_nr, 63, 56) 987 F(src0_reg_nr, 55, 48) 988 F(dst_reg_nr, 47, 40) 989 F(src1_index, 39, 35) 990 F(src0_index, 34, 30) 991 F(cmpt_control, 29, 29) /* Same location as brw_inst */ 992 FC(flag_subreg_nr, 28, 28, devinfo->gen <= 6) 993 F(cond_modifier, 27, 24) /* Same location as brw_inst */ 994 FC(acc_wr_control, 23, 23, devinfo->gen >= 6) 995 FC(mask_control_ex, 23, 23, devinfo->is_g4x || devinfo->gen == 5) 996 F(subreg_index, 22, 18) 997 F(datatype_index, 17, 13) 998 F(control_index, 12, 8) 999 F(debug_control, 7, 7) 1000 F(opcode, 6, 0) /* Same location as brw_inst */ 1001 1002 /** 1003 * (Gen8+) Compacted three-source instructions: 1004 * @{ 1005 */ 1006 FC(3src_src2_reg_nr, 63, 57, devinfo->gen >= 8) 1007 FC(3src_src1_reg_nr, 56, 50, devinfo->gen >= 8) 1008 FC(3src_src0_reg_nr, 49, 43, devinfo->gen >= 8) 1009 FC(3src_src2_subreg_nr, 42, 40, devinfo->gen >= 8) 1010 FC(3src_src1_subreg_nr, 39, 37, devinfo->gen >= 8) 1011 FC(3src_src0_subreg_nr, 36, 34, devinfo->gen >= 8) 1012 FC(3src_src2_rep_ctrl, 33, 33, devinfo->gen >= 8) 1013 FC(3src_src1_rep_ctrl, 32, 32, devinfo->gen >= 8) 1014 FC(3src_saturate, 31, 31, devinfo->gen >= 8) 1015 FC(3src_debug_control, 30, 30, devinfo->gen >= 8) 1016 FC(3src_cmpt_control, 29, 29, devinfo->gen >= 8) 1017 FC(3src_src0_rep_ctrl, 28, 28, devinfo->gen >= 8) 1018 /* Reserved */ 1019 FC(3src_dst_reg_nr, 18, 12, devinfo->gen >= 8) 1020 FC(3src_source_index, 11, 10, devinfo->gen >= 8) 1021 FC(3src_control_index, 9, 8, devinfo->gen >= 8) 1022 /* Bit 7 is Reserved (for future Opcode expansion) */ 1023 FC(3src_opcode, 6, 0, devinfo->gen >= 8) 1024 /** @} */ 1025 1026 #undef F 1027 1028 #ifdef __cplusplus 1029 } 1030 #endif 1031 1032 #endif 1033