101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2014 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2101e04c3fSmrg * IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg/** 2501e04c3fSmrg * @file brw_inst.h 2601e04c3fSmrg * 2701e04c3fSmrg * A representation of i965 EU assembly instructions, with helper methods to 2801e04c3fSmrg * get and set various fields. This is the actual hardware format. 2901e04c3fSmrg */ 3001e04c3fSmrg 3101e04c3fSmrg#ifndef BRW_INST_H 3201e04c3fSmrg#define BRW_INST_H 3301e04c3fSmrg 3401e04c3fSmrg#include <assert.h> 3501e04c3fSmrg#include <stdint.h> 3601e04c3fSmrg 3701e04c3fSmrg#include "brw_eu_defines.h" 3801e04c3fSmrg#include "brw_reg_type.h" 397ec681f3Smrg#include "dev/intel_device_info.h" 4001e04c3fSmrg 4101e04c3fSmrg#ifdef __cplusplus 4201e04c3fSmrgextern "C" { 4301e04c3fSmrg#endif 4401e04c3fSmrg 4501e04c3fSmrg/* brw_context.h has a forward declaration of brw_inst, so name the struct. */ 4601e04c3fSmrgtypedef struct brw_inst { 4701e04c3fSmrg uint64_t data[2]; 4801e04c3fSmrg} brw_inst; 4901e04c3fSmrg 5001e04c3fSmrgstatic inline uint64_t brw_inst_bits(const brw_inst *inst, 5101e04c3fSmrg unsigned high, unsigned low); 5201e04c3fSmrgstatic inline void brw_inst_set_bits(brw_inst *inst, 5301e04c3fSmrg unsigned high, unsigned low, 5401e04c3fSmrg uint64_t value); 5501e04c3fSmrg 567ec681f3Smrg#define FC(name, hi4, lo4, hi12, lo12, assertions) \ 5701e04c3fSmrgstatic inline void \ 587ec681f3Smrgbrw_inst_set_##name(const struct intel_device_info *devinfo, \ 5901e04c3fSmrg brw_inst *inst, uint64_t v) \ 6001e04c3fSmrg{ \ 6101e04c3fSmrg assert(assertions); \ 627ec681f3Smrg if (devinfo->ver >= 12) \ 637ec681f3Smrg brw_inst_set_bits(inst, hi12, lo12, v); \ 647ec681f3Smrg else \ 657ec681f3Smrg brw_inst_set_bits(inst, hi4, lo4, v); \ 6601e04c3fSmrg} \ 6701e04c3fSmrgstatic inline uint64_t \ 687ec681f3Smrgbrw_inst_##name(const struct intel_device_info *devinfo, \ 6901e04c3fSmrg const brw_inst *inst) \ 7001e04c3fSmrg{ \ 7101e04c3fSmrg assert(assertions); \ 727ec681f3Smrg if (devinfo->ver >= 12) \ 737ec681f3Smrg return brw_inst_bits(inst, hi12, lo12); \ 747ec681f3Smrg else \ 757ec681f3Smrg return brw_inst_bits(inst, hi4, lo4); \ 7601e04c3fSmrg} 7701e04c3fSmrg 787ec681f3Smrg/* A simple macro for fields which stay in the same place on all generations, 797ec681f3Smrg * except for Gfx12! 807ec681f3Smrg */ 817ec681f3Smrg#define F(name, hi4, lo4, hi12, lo12) FC(name, hi4, lo4, hi12, lo12, true) 8201e04c3fSmrg 837ec681f3Smrg#define BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \ 847ec681f3Smrg hi7, lo7, hi8, lo8, hi12, lo12) \ 8501e04c3fSmrg unsigned high, low; \ 867ec681f3Smrg if (devinfo->ver >= 12) { \ 877ec681f3Smrg high = hi12; low = lo12; \ 887ec681f3Smrg } else if (devinfo->ver >= 8) { \ 8901e04c3fSmrg high = hi8; low = lo8; \ 907ec681f3Smrg } else if (devinfo->ver >= 7) { \ 9101e04c3fSmrg high = hi7; low = lo7; \ 927ec681f3Smrg } else if (devinfo->ver >= 6) { \ 9301e04c3fSmrg high = hi6; low = lo6; \ 947ec681f3Smrg } else if (devinfo->ver >= 5) { \ 9501e04c3fSmrg high = hi5; low = lo5; \ 9601e04c3fSmrg } else if (devinfo->is_g4x) { \ 9701e04c3fSmrg high = hi45; low = lo45; \ 9801e04c3fSmrg } else { \ 9901e04c3fSmrg high = hi4; low = lo4; \ 10001e04c3fSmrg } \ 10101e04c3fSmrg assert(((int) high) != -1 && ((int) low) != -1); 10201e04c3fSmrg 10301e04c3fSmrg/* A general macro for cases where the field has moved to several different 10401e04c3fSmrg * bit locations across generations. GCC appears to combine cases where the 10501e04c3fSmrg * bits are identical, removing some of the inefficiency. 10601e04c3fSmrg */ 1077ec681f3Smrg#define FF(name, hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \ 1087ec681f3Smrg hi7, lo7, hi8, lo8, hi12, lo12) \ 10901e04c3fSmrgstatic inline void \ 1107ec681f3Smrgbrw_inst_set_##name(const struct intel_device_info *devinfo, \ 11101e04c3fSmrg brw_inst *inst, uint64_t value) \ 11201e04c3fSmrg{ \ 1137ec681f3Smrg BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \ 1147ec681f3Smrg hi7, lo7, hi8, lo8, hi12, lo12) \ 11501e04c3fSmrg brw_inst_set_bits(inst, high, low, value); \ 11601e04c3fSmrg} \ 11701e04c3fSmrgstatic inline uint64_t \ 1187ec681f3Smrgbrw_inst_##name(const struct intel_device_info *devinfo, const brw_inst *inst)\ 11901e04c3fSmrg{ \ 1207ec681f3Smrg BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \ 1217ec681f3Smrg hi7, lo7, hi8, lo8, hi12, lo12) \ 12201e04c3fSmrg return brw_inst_bits(inst, high, low); \ 12301e04c3fSmrg} 12401e04c3fSmrg 1257ec681f3Smrg/* A macro for fields which moved as of Gfx8+. */ 1267ec681f3Smrg#define F8(name, gfx4_high, gfx4_low, gfx8_high, gfx8_low, \ 1277ec681f3Smrg gfx12_high, gfx12_low) \ 12801e04c3fSmrgFF(name, \ 1297ec681f3Smrg /* 4: */ gfx4_high, gfx4_low, \ 1307ec681f3Smrg /* 4.5: */ gfx4_high, gfx4_low, \ 1317ec681f3Smrg /* 5: */ gfx4_high, gfx4_low, \ 1327ec681f3Smrg /* 6: */ gfx4_high, gfx4_low, \ 1337ec681f3Smrg /* 7: */ gfx4_high, gfx4_low, \ 1347ec681f3Smrg /* 8: */ gfx8_high, gfx8_low, \ 1357ec681f3Smrg /* 12: */ gfx12_high, gfx12_low); 1367ec681f3Smrg 1377ec681f3Smrg/* Macro for fields that gained extra discontiguous MSBs in Gfx12 (specified 1387ec681f3Smrg * by hi12ex-lo12ex). 1397ec681f3Smrg */ 1407ec681f3Smrg#define FFDC(name, hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \ 1417ec681f3Smrg hi7, lo7, hi8, lo8, hi12ex, lo12ex, hi12, lo12, assertions) \ 1427ec681f3Smrgstatic inline void \ 1437ec681f3Smrgbrw_inst_set_##name(const struct intel_device_info *devinfo, \ 1447ec681f3Smrg brw_inst *inst, uint64_t value) \ 1457ec681f3Smrg{ \ 1467ec681f3Smrg assert(assertions); \ 1477ec681f3Smrg if (devinfo->ver >= 12) { \ 1487ec681f3Smrg const unsigned k = hi12 - lo12 + 1; \ 1497ec681f3Smrg if (hi12ex != -1 && lo12ex != -1) \ 1507ec681f3Smrg brw_inst_set_bits(inst, hi12ex, lo12ex, value >> k); \ 1517ec681f3Smrg brw_inst_set_bits(inst, hi12, lo12, value & ((1ull << k) - 1)); \ 1527ec681f3Smrg } else { \ 1537ec681f3Smrg BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \ 1547ec681f3Smrg hi7, lo7, hi8, lo8, -1, -1); \ 1557ec681f3Smrg brw_inst_set_bits(inst, high, low, value); \ 1567ec681f3Smrg } \ 1577ec681f3Smrg} \ 1587ec681f3Smrgstatic inline uint64_t \ 1597ec681f3Smrgbrw_inst_##name(const struct intel_device_info *devinfo, const brw_inst *inst)\ 1607ec681f3Smrg{ \ 1617ec681f3Smrg assert(assertions); \ 1627ec681f3Smrg if (devinfo->ver >= 12) { \ 1637ec681f3Smrg const unsigned k = hi12 - lo12 + 1; \ 1647ec681f3Smrg return (hi12ex == -1 || lo12ex == -1 ? 0 : \ 1657ec681f3Smrg brw_inst_bits(inst, hi12ex, lo12ex) << k) | \ 1667ec681f3Smrg brw_inst_bits(inst, hi12, lo12); \ 1677ec681f3Smrg } else { \ 1687ec681f3Smrg BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \ 1697ec681f3Smrg hi7, lo7, hi8, lo8, -1, -1); \ 1707ec681f3Smrg return brw_inst_bits(inst, high, low); \ 1717ec681f3Smrg } \ 1727ec681f3Smrg} 1737ec681f3Smrg 1747ec681f3Smrg#define FD(name, hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \ 1757ec681f3Smrg hi7, lo7, hi8, lo8, hi12ex, lo12ex, hi12, lo12) \ 1767ec681f3Smrg FFDC(name, hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, \ 1777ec681f3Smrg hi7, lo7, hi8, lo8, hi12ex, lo12ex, hi12, lo12, true) 1787ec681f3Smrg 1797ec681f3Smrg/* Macro for fields that didn't move across generations until Gfx12, and then 1807ec681f3Smrg * gained extra discontiguous bits. 1817ec681f3Smrg */ 1827ec681f3Smrg#define FDC(name, hi4, lo4, hi12ex, lo12ex, hi12, lo12, assertions) \ 1837ec681f3Smrg FFDC(name, hi4, lo4, hi4, lo4, hi4, lo4, hi4, lo4, \ 1847ec681f3Smrg hi4, lo4, hi4, lo4, hi12ex, lo12ex, hi12, lo12, assertions) 1857ec681f3Smrg 1867ec681f3Smrg 1877ec681f3Smrg/* Macro for the 2-bit register file field, which on Gfx12+ is stored as the 1887ec681f3Smrg * variable length combination of an IsImm (hi12) bit and an additional file 1897ec681f3Smrg * (lo12) bit. 1907ec681f3Smrg */ 1917ec681f3Smrg#define FI(name, hi4, lo4, hi8, lo8, hi12, lo12) \ 1927ec681f3Smrgstatic inline void \ 1937ec681f3Smrgbrw_inst_set_##name(const struct intel_device_info *devinfo, \ 1947ec681f3Smrg brw_inst *inst, uint64_t value) \ 1957ec681f3Smrg{ \ 1967ec681f3Smrg if (devinfo->ver >= 12) { \ 1977ec681f3Smrg brw_inst_set_bits(inst, hi12, hi12, value >> 1); \ 1987ec681f3Smrg if ((value >> 1) == 0) \ 1997ec681f3Smrg brw_inst_set_bits(inst, lo12, lo12, value & 1); \ 2007ec681f3Smrg } else { \ 2017ec681f3Smrg BOUNDS(hi4, lo4, hi4, lo4, hi4, lo4, hi4, lo4, \ 2027ec681f3Smrg hi4, lo4, hi8, lo8, -1, -1); \ 2037ec681f3Smrg brw_inst_set_bits(inst, high, low, value); \ 2047ec681f3Smrg } \ 2057ec681f3Smrg} \ 2067ec681f3Smrgstatic inline uint64_t \ 2077ec681f3Smrgbrw_inst_##name(const struct intel_device_info *devinfo, const brw_inst *inst)\ 2087ec681f3Smrg{ \ 2097ec681f3Smrg if (devinfo->ver >= 12) { \ 2107ec681f3Smrg return (brw_inst_bits(inst, hi12, hi12) << 1) | \ 2117ec681f3Smrg (brw_inst_bits(inst, hi12, hi12) == 0 ? \ 2127ec681f3Smrg brw_inst_bits(inst, lo12, lo12) : 1); \ 2137ec681f3Smrg } else { \ 2147ec681f3Smrg BOUNDS(hi4, lo4, hi4, lo4, hi4, lo4, hi4, lo4, \ 2157ec681f3Smrg hi4, lo4, hi8, lo8, -1, -1); \ 2167ec681f3Smrg return brw_inst_bits(inst, high, low); \ 2177ec681f3Smrg } \ 2187ec681f3Smrg} 2197ec681f3Smrg 2207ec681f3Smrg/* Macro for fields that become a constant in Gfx12+ not actually represented 2217ec681f3Smrg * in the instruction. 2227ec681f3Smrg */ 2237ec681f3Smrg#define FK(name, hi4, lo4, const12) \ 2247ec681f3Smrgstatic inline void \ 2257ec681f3Smrgbrw_inst_set_##name(const struct intel_device_info *devinfo, \ 2267ec681f3Smrg brw_inst *inst, uint64_t v) \ 2277ec681f3Smrg{ \ 2287ec681f3Smrg if (devinfo->ver >= 12) \ 2297ec681f3Smrg assert(v == (const12)); \ 2307ec681f3Smrg else \ 2317ec681f3Smrg brw_inst_set_bits(inst, hi4, lo4, v); \ 2327ec681f3Smrg} \ 2337ec681f3Smrgstatic inline uint64_t \ 2347ec681f3Smrgbrw_inst_##name(const struct intel_device_info *devinfo, \ 2357ec681f3Smrg const brw_inst *inst) \ 2367ec681f3Smrg{ \ 2377ec681f3Smrg if (devinfo->ver >= 12) \ 2387ec681f3Smrg return (const12); \ 2397ec681f3Smrg else \ 2407ec681f3Smrg return brw_inst_bits(inst, hi4, lo4); \ 2417ec681f3Smrg} 2427ec681f3Smrg 2437ec681f3SmrgF(src1_vstride, /* 4+ */ 120, 117, /* 12+ */ 119, 116) 2447ec681f3SmrgF(src1_width, /* 4+ */ 116, 114, /* 12+ */ 115, 113) 2457ec681f3SmrgF(src1_da16_swiz_w, /* 4+ */ 115, 114, /* 12+ */ -1, -1) 2467ec681f3SmrgF(src1_da16_swiz_z, /* 4+ */ 113, 112, /* 12+ */ -1, -1) 2477ec681f3SmrgF(src1_hstride, /* 4+ */ 113, 112, /* 12+ */ 97, 96) 2487ec681f3SmrgF(src1_address_mode, /* 4+ */ 111, 111, /* 12+ */ 112, 112) 24901e04c3fSmrg/** Src1.SrcMod @{ */ 2507ec681f3SmrgF(src1_negate, /* 4+ */ 110, 110, /* 12+ */ 121, 121) 2517ec681f3SmrgF(src1_abs, /* 4+ */ 109, 109, /* 12+ */ 120, 120) 25201e04c3fSmrg/** @} */ 2537ec681f3SmrgF8(src1_ia_subreg_nr, /* 4+ */ 108, 106, /* 8+ */ 108, 105, /* 12+ */ 111, 108) 2547ec681f3SmrgF(src1_da_reg_nr, /* 4+ */ 108, 101, /* 12+ */ 111, 104) 2557ec681f3SmrgF(src1_da16_subreg_nr, /* 4+ */ 100, 100, /* 12+ */ -1, -1) 2567ec681f3SmrgF(src1_da1_subreg_nr, /* 4+ */ 100, 96, /* 12+ */ 103, 99) 2577ec681f3SmrgF(src1_da16_swiz_y, /* 4+ */ 99, 98, /* 12+ */ -1, -1) 2587ec681f3SmrgF(src1_da16_swiz_x, /* 4+ */ 97, 96, /* 12+ */ -1, -1) 2597ec681f3SmrgF8(src1_reg_hw_type, /* 4+ */ 46, 44, /* 8+ */ 94, 91, /* 12+ */ 91, 88) 2607ec681f3SmrgFI(src1_reg_file, /* 4+ */ 43, 42, /* 8+ */ 90, 89, /* 12+ */ 47, 98) 2617ec681f3SmrgF(src1_is_imm, /* 4+ */ -1, -1, /* 12+ */ 47, 47) 2627ec681f3SmrgF(src0_vstride, /* 4+ */ 88, 85, /* 12+ */ 87, 84) 2637ec681f3SmrgF(src0_width, /* 4+ */ 84, 82, /* 12+ */ 83, 81) 2647ec681f3SmrgF(src0_da16_swiz_w, /* 4+ */ 83, 82, /* 12+ */ -1, -1) 2657ec681f3SmrgF(src0_da16_swiz_z, /* 4+ */ 81, 80, /* 12+ */ -1, -1) 2667ec681f3SmrgF(src0_hstride, /* 4+ */ 81, 80, /* 12+ */ 65, 64) 2677ec681f3SmrgF(src0_address_mode, /* 4+ */ 79, 79, /* 12+ */ 80, 80) 26801e04c3fSmrg/** Src0.SrcMod @{ */ 2697ec681f3SmrgF(src0_negate, /* 4+ */ 78, 78, /* 12+ */ 45, 45) 2707ec681f3SmrgF(src0_abs, /* 4+ */ 77, 77, /* 12+ */ 44, 44) 27101e04c3fSmrg/** @} */ 2727ec681f3SmrgF8(src0_ia_subreg_nr, /* 4+ */ 76, 74, /* 8+ */ 76, 73, /* 12+ */ 79, 76) 2737ec681f3SmrgF(src0_da_reg_nr, /* 4+ */ 76, 69, /* 12+ */ 79, 72) 2747ec681f3SmrgF(src0_da16_subreg_nr, /* 4+ */ 68, 68, /* 12+ */ -1, -1) 2757ec681f3SmrgF(src0_da1_subreg_nr, /* 4+ */ 68, 64, /* 12+ */ 71, 67) 2767ec681f3SmrgF(src0_da16_swiz_y, /* 4+ */ 67, 66, /* 12+ */ -1, -1) 2777ec681f3SmrgF(src0_da16_swiz_x, /* 4+ */ 65, 64, /* 12+ */ -1, -1) 2787ec681f3SmrgF(dst_address_mode, /* 4+ */ 63, 63, /* 12+ */ 35, 35) 2797ec681f3SmrgF(dst_hstride, /* 4+ */ 62, 61, /* 12+ */ 49, 48) 2807ec681f3SmrgF8(dst_ia_subreg_nr, /* 4+ */ 60, 58, /* 8+ */ 60, 57, /* 12+ */ 63, 60) 2817ec681f3SmrgF(dst_da_reg_nr, /* 4+ */ 60, 53, /* 12+ */ 63, 56) 2827ec681f3SmrgF(dst_da16_subreg_nr, /* 4+ */ 52, 52, /* 12+ */ -1, -1) 2837ec681f3SmrgF(dst_da1_subreg_nr, /* 4+ */ 52, 48, /* 12+ */ 55, 51) 2847ec681f3SmrgF(da16_writemask, /* 4+ */ 51, 48, /* 12+ */ -1, -1) /* Dst.ChanEn */ 2857ec681f3SmrgF8(src0_reg_hw_type, /* 4+ */ 41, 39, /* 8+ */ 46, 43, /* 12+ */ 43, 40) 2867ec681f3SmrgFI(src0_reg_file, /* 4+ */ 38, 37, /* 8+ */ 42, 41, /* 12+ */ 46, 66) 2877ec681f3SmrgF(src0_is_imm, /* 4+ */ -1, -1, /* 12+ */ 46, 46) 2887ec681f3SmrgF8(dst_reg_hw_type, /* 4+ */ 36, 34, /* 8+ */ 40, 37, /* 12+ */ 39, 36) 2897ec681f3SmrgF8(dst_reg_file, /* 4+ */ 33, 32, /* 8+ */ 36, 35, /* 12+ */ 50, 50) 2907ec681f3SmrgF8(mask_control, /* 4+ */ 9, 9, /* 8+ */ 34, 34, /* 12+ */ 31, 31) 29101e04c3fSmrgFF(flag_reg_nr, 29201e04c3fSmrg /* 4-6: doesn't exist */ -1, -1, -1, -1, -1, -1, -1, -1, 29301e04c3fSmrg /* 7: */ 90, 90, 2947ec681f3Smrg /* 8: */ 33, 33, 2957ec681f3Smrg /* 12: */ 23, 23) 2967ec681f3SmrgF8(flag_subreg_nr, /* 4+ */ 89, 89, /* 8+ */ 32, 32, /* 12+ */ 22, 22) 2977ec681f3SmrgF(saturate, /* 4+ */ 31, 31, /* 12+ */ 34, 34) 2987ec681f3SmrgF(debug_control, /* 4+ */ 30, 30, /* 12+ */ 30, 30) 2997ec681f3SmrgF(cmpt_control, /* 4+ */ 29, 29, /* 12+ */ 29, 29) 3007ec681f3SmrgFC(branch_control, /* 4+ */ 28, 28, /* 12+ */ 33, 33, devinfo->ver >= 8) 3017ec681f3SmrgFC(acc_wr_control, /* 4+ */ 28, 28, /* 12+ */ 33, 33, devinfo->ver >= 6) 3027ec681f3SmrgFC(mask_control_ex, /* 4+ */ 28, 28, /* 12+ */ -1, -1, devinfo->is_g4x || devinfo->ver == 5) 3037ec681f3SmrgF(cond_modifier, /* 4+ */ 27, 24, /* 12+ */ 95, 92) 3047ec681f3SmrgFC(math_function, /* 4+ */ 27, 24, /* 12+ */ 95, 92, devinfo->ver >= 6) 3057ec681f3SmrgF(exec_size, /* 4+ */ 23, 21, /* 12+ */ 18, 16) 3067ec681f3SmrgF(pred_inv, /* 4+ */ 20, 20, /* 12+ */ 28, 28) 3077ec681f3SmrgF(pred_control, /* 4+ */ 19, 16, /* 12+ */ 27, 24) 3087ec681f3SmrgF(thread_control, /* 4+ */ 15, 14, /* 12+ */ -1, -1) 3097ec681f3SmrgF(atomic_control, /* 4+ */ -1, -1, /* 12+ */ 32, 32) 3107ec681f3SmrgF(qtr_control, /* 4+ */ 13, 12, /* 12+ */ 21, 20) 31101e04c3fSmrgFF(nib_control, 31201e04c3fSmrg /* 4-6: doesn't exist */ -1, -1, -1, -1, -1, -1, -1, -1, 31301e04c3fSmrg /* 7: */ 47, 47, 3147ec681f3Smrg /* 8: */ 11, 11, 3157ec681f3Smrg /* 12: */ 19, 19) 3167ec681f3SmrgF8(no_dd_check, /* 4+ */ 11, 11, /* 8+ */ 10, 10, /* 12+ */ -1, -1) 3177ec681f3SmrgF8(no_dd_clear, /* 4+ */ 10, 10, /* 8+ */ 9, 9, /* 12+ */ -1, -1) 3187ec681f3SmrgF(swsb, /* 4+ */ -1, -1, /* 12+ */ 15, 8) 3197ec681f3SmrgFK(access_mode, /* 4+ */ 8, 8, /* 12+ */ BRW_ALIGN_1) 32001e04c3fSmrg/* Bit 7 is Reserved (for future Opcode expansion) */ 3217ec681f3SmrgF(hw_opcode, /* 4+ */ 6, 0, /* 12+ */ 6, 0) 32201e04c3fSmrg 32301e04c3fSmrg/** 32401e04c3fSmrg * Three-source instructions: 32501e04c3fSmrg * @{ 32601e04c3fSmrg */ 3277ec681f3SmrgF(3src_src2_reg_nr, /* 4+ */ 125, 118, /* 12+ */ 127, 120) /* same in align1 */ 3287ec681f3SmrgF(3src_a16_src2_subreg_nr, /* 4+ */ 117, 115, /* 12+ */ -1, -1) /* Extra discontiguous bit on CHV? */ 3297ec681f3SmrgF(3src_a16_src2_swizzle, /* 4+ */ 114, 107, /* 12+ */ -1, -1) 3307ec681f3SmrgF(3src_a16_src2_rep_ctrl, /* 4+ */ 106, 106, /* 12+ */ -1, -1) 3317ec681f3SmrgF(3src_src1_reg_nr, /* 4+ */ 104, 97, /* 12+ */ 111, 104) /* same in align1 */ 3327ec681f3SmrgF(3src_a16_src1_subreg_nr, /* 4+ */ 96, 94, /* 12+ */ -1, -1) /* Extra discontiguous bit on CHV? */ 3337ec681f3SmrgF(3src_a16_src1_swizzle, /* 4+ */ 93, 86, /* 12+ */ -1, -1) 3347ec681f3SmrgF(3src_a16_src1_rep_ctrl, /* 4+ */ 85, 85, /* 12+ */ -1, -1) 3357ec681f3SmrgF(3src_src0_reg_nr, /* 4+ */ 83, 76, /* 12+ */ 79, 72) /* same in align1 */ 3367ec681f3SmrgF(3src_a16_src0_subreg_nr, /* 4+ */ 75, 73, /* 12+ */ -1, -1) /* Extra discontiguous bit on CHV? */ 3377ec681f3SmrgF(3src_a16_src0_swizzle, /* 4+ */ 72, 65, /* 12+ */ -1, -1) 3387ec681f3SmrgF(3src_a16_src0_rep_ctrl, /* 4+ */ 64, 64, /* 12+ */ -1, -1) 3397ec681f3SmrgF(3src_dst_reg_nr, /* 4+ */ 63, 56, /* 12+ */ 63, 56) /* same in align1 */ 3407ec681f3SmrgF(3src_a16_dst_subreg_nr, /* 4+ */ 55, 53, /* 12+ */ -1, -1) 3417ec681f3SmrgF(3src_a16_dst_writemask, /* 4+ */ 52, 49, /* 12+ */ -1, -1) 3427ec681f3SmrgF8(3src_a16_nib_ctrl, /* 4+ */ 47, 47, /* 8+ */ 11, 11, /* 12+ */ -1, -1) /* only exists on IVB+ */ 3437ec681f3SmrgF8(3src_a16_dst_hw_type, /* 4+ */ 45, 44, /* 8+ */ 48, 46, /* 12+ */ -1, -1) /* only exists on IVB+ */ 3447ec681f3SmrgF8(3src_a16_src_hw_type, /* 4+ */ 43, 42, /* 8+ */ 45, 43, /* 12+ */ -1, -1) 3457ec681f3SmrgF8(3src_src2_negate, /* 4+ */ 41, 41, /* 8+ */ 42, 42, /* 12+ */ 85, 85) 3467ec681f3SmrgF8(3src_src2_abs, /* 4+ */ 40, 40, /* 8+ */ 41, 41, /* 12+ */ 84, 84) 3477ec681f3SmrgF8(3src_src1_negate, /* 4+ */ 39, 39, /* 8+ */ 40, 40, /* 12+ */ 87, 87) 3487ec681f3SmrgF8(3src_src1_abs, /* 4+ */ 38, 38, /* 8+ */ 39, 39, /* 12+ */ 86, 86) 3497ec681f3SmrgF8(3src_src0_negate, /* 4+ */ 37, 37, /* 8+ */ 38, 38, /* 12+ */ 45, 45) 3507ec681f3SmrgF8(3src_src0_abs, /* 4+ */ 36, 36, /* 8+ */ 37, 37, /* 12+ */ 44, 44) 3517ec681f3SmrgF8(3src_a16_src1_type, /* 4+ */ -1, -1, /* 8+ */ 36, 36, /* 12+ */ -1, -1) 3527ec681f3SmrgF8(3src_a16_src2_type, /* 4+ */ -1, -1, /* 8+ */ 35, 35, /* 12+ */ -1, -1) 3537ec681f3SmrgF8(3src_a16_flag_reg_nr, /* 4+ */ 34, 34, /* 8+ */ 33, 33, /* 12+ */ -1, -1) 3547ec681f3SmrgF8(3src_a16_flag_subreg_nr, /* 4+ */ 33, 33, /* 8+ */ 32, 32, /* 12+ */ -1, -1) 35501e04c3fSmrgFF(3src_a16_dst_reg_file, 35601e04c3fSmrg /* 4-5: doesn't exist - no 3-source instructions */ -1, -1, -1, -1, -1, -1, 35701e04c3fSmrg /* 6: */ 32, 32, 3587ec681f3Smrg /* 7-8: doesn't exist - no MRFs */ -1, -1, -1, -1, 3597ec681f3Smrg /* 12: */ -1, -1) 3607ec681f3SmrgF(3src_saturate, /* 4+ */ 31, 31, /* 12+ */ 34, 34) 3617ec681f3SmrgF(3src_debug_control, /* 4+ */ 30, 30, /* 12+ */ 30, 30) 3627ec681f3SmrgF(3src_cmpt_control, /* 4+ */ 29, 29, /* 12+ */ 29, 29) 3637ec681f3SmrgF(3src_acc_wr_control, /* 4+ */ 28, 28, /* 12+ */ 33, 33) 3647ec681f3SmrgF(3src_cond_modifier, /* 4+ */ 27, 24, /* 12+ */ 95, 92) 3657ec681f3SmrgF(3src_exec_size, /* 4+ */ 23, 21, /* 12+ */ 18, 16) 3667ec681f3SmrgF(3src_pred_inv, /* 4+ */ 20, 20, /* 12+ */ 28, 28) 3677ec681f3SmrgF(3src_pred_control, /* 4+ */ 19, 16, /* 12+ */ 27, 24) 3687ec681f3SmrgF(3src_thread_control, /* 4+ */ 15, 14, /* 12+ */ -1, -1) 3697ec681f3SmrgF(3src_atomic_control, /* 4+ */ -1, -1, /* 12+ */ 32, 32) 3707ec681f3SmrgF(3src_qtr_control, /* 4+ */ 13, 12, /* 12+ */ 21, 20) 3717ec681f3SmrgF8(3src_no_dd_check, /* 4+ */ 11, 11, /* 8+ */ 10, 10, /* 12+ */ -1, -1) 3727ec681f3SmrgF8(3src_no_dd_clear, /* 4+ */ 10, 10, /* 8+ */ 9, 9, /* 12+ */ -1, -1) 3737ec681f3SmrgF8(3src_mask_control, /* 4+ */ 9, 9, /* 8+ */ 34, 34, /* 12+ */ 31, 31) 3747ec681f3SmrgFK(3src_access_mode, /* 4+ */ 8, 8, /* 12+ */ BRW_ALIGN_1) 3757ec681f3SmrgF(3src_swsb, /* 4+ */ -1, -1, /* 12+ */ 15, 8) 37601e04c3fSmrg/* Bit 7 is Reserved (for future Opcode expansion) */ 3777ec681f3SmrgF(3src_hw_opcode, /* 4+ */ 6, 0, /* 12+ */ 6, 0) 37801e04c3fSmrg/** @} */ 37901e04c3fSmrg 38001e04c3fSmrg#define REG_TYPE(reg) \ 38101e04c3fSmrgstatic inline void \ 3827ec681f3Smrgbrw_inst_set_3src_a16_##reg##_type(const struct intel_device_info *devinfo, \ 38301e04c3fSmrg brw_inst *inst, enum brw_reg_type type) \ 38401e04c3fSmrg{ \ 38501e04c3fSmrg unsigned hw_type = brw_reg_type_to_a16_hw_3src_type(devinfo, type); \ 38601e04c3fSmrg brw_inst_set_3src_a16_##reg##_hw_type(devinfo, inst, hw_type); \ 38701e04c3fSmrg} \ 38801e04c3fSmrg \ 38901e04c3fSmrgstatic inline enum brw_reg_type \ 3907ec681f3Smrgbrw_inst_3src_a16_##reg##_type(const struct intel_device_info *devinfo, \ 39101e04c3fSmrg const brw_inst *inst) \ 39201e04c3fSmrg{ \ 39301e04c3fSmrg unsigned hw_type = brw_inst_3src_a16_##reg##_hw_type(devinfo, inst); \ 39401e04c3fSmrg return brw_a16_hw_3src_type_to_reg_type(devinfo, hw_type); \ 39501e04c3fSmrg} 39601e04c3fSmrg 39701e04c3fSmrgREG_TYPE(dst) 39801e04c3fSmrgREG_TYPE(src) 39901e04c3fSmrg#undef REG_TYPE 40001e04c3fSmrg 40101e04c3fSmrg/** 40201e04c3fSmrg * Three-source align1 instructions: 40301e04c3fSmrg * @{ 40401e04c3fSmrg */ 40501e04c3fSmrg/* Reserved 127:126 */ 40601e04c3fSmrg/* src2_reg_nr same in align16 */ 4077ec681f3SmrgFC(3src_a1_src2_subreg_nr, /* 4+ */ 117, 113, /* 12+ */ 119, 115, devinfo->ver >= 10) 4087ec681f3SmrgFC(3src_a1_src2_hstride, /* 4+ */ 112, 111, /* 12+ */ 113, 112, devinfo->ver >= 10) 40901e04c3fSmrg/* Reserved 110:109. src2 vstride is an implied parameter */ 4107ec681f3SmrgFC(3src_a1_src2_hw_type, /* 4+ */ 108, 106, /* 12+ */ 82, 80, devinfo->ver >= 10) 41101e04c3fSmrg/* Reserved 105 */ 41201e04c3fSmrg/* src1_reg_nr same in align16 */ 4137ec681f3SmrgFC(3src_a1_src1_subreg_nr, /* 4+ */ 96, 92, /* 12+ */ 103, 99, devinfo->ver >= 10) 4147ec681f3SmrgFC(3src_a1_src1_hstride, /* 4+ */ 91, 90, /* 12+ */ 97, 96, devinfo->ver >= 10) 4157ec681f3SmrgFDC(3src_a1_src1_vstride, /* 4+ */ 89, 88, /* 12+ */ 91, 91, 83, 83, devinfo->ver >= 10) 4167ec681f3SmrgFC(3src_a1_src1_hw_type, /* 4+ */ 87, 85, /* 12+ */ 90, 88, devinfo->ver >= 10) 41701e04c3fSmrg/* Reserved 84 */ 41801e04c3fSmrg/* src0_reg_nr same in align16 */ 4197ec681f3SmrgFC(3src_a1_src0_subreg_nr, /* 4+ */ 75, 71, /* 12+ */ 71, 67, devinfo->ver >= 10) 4207ec681f3SmrgFC(3src_a1_src0_hstride, /* 4+ */ 70, 69, /* 12+ */ 65, 64, devinfo->ver >= 10) 4217ec681f3SmrgFDC(3src_a1_src0_vstride, /* 4+ */ 68, 67, /* 12+ */ 43, 43, 35, 35, devinfo->ver >= 10) 4227ec681f3SmrgFC(3src_a1_src0_hw_type, /* 4+ */ 66, 64, /* 12+ */ 42, 40, devinfo->ver >= 10) 42301e04c3fSmrg/* dst_reg_nr same in align16 */ 4247ec681f3SmrgFC(3src_a1_dst_subreg_nr, /* 4+ */ 55, 54, /* 12+ */ 55, 54, devinfo->ver >= 10) 4257ec681f3SmrgFC(3src_a1_special_acc, /* 4+ */ 55, 52, /* 12+ */ 54, 51, devinfo->ver >= 10) /* aliases dst_subreg_nr */ 42601e04c3fSmrg/* Reserved 51:50 */ 4277ec681f3SmrgFC(3src_a1_dst_hstride, /* 4+ */ 49, 49, /* 12+ */ 48, 48, devinfo->ver >= 10) 4287ec681f3SmrgFC(3src_a1_dst_hw_type, /* 4+ */ 48, 46, /* 12+ */ 38, 36, devinfo->ver >= 10) 4297ec681f3SmrgFI(3src_a1_src2_reg_file, /* 4+ */ -1, -1, /* 8+ */ 45, 45, /* 12+ */ 47, 114) 4307ec681f3SmrgFC(3src_a1_src1_reg_file, /* 4+ */ 44, 44, /* 12+ */ 98, 98, devinfo->ver >= 10) 4317ec681f3SmrgFI(3src_a1_src0_reg_file, /* 4+ */ -1, -1, /* 8+ */ 43, 43, /* 12+ */ 46, 66) 4327ec681f3Smrg 4337ec681f3SmrgF(3src_a1_src2_is_imm, /* 4+ */ -1, -1, /* 12+ */ 47, 47) 4347ec681f3SmrgF(3src_a1_src0_is_imm, /* 4+ */ -1, -1, /* 12+ */ 46, 46) 4357ec681f3Smrg 43601e04c3fSmrg/* Source Modifier fields same in align16 */ 4377ec681f3SmrgFC(3src_a1_dst_reg_file, /* 4+ */ 36, 36, /* 12+ */ 50, 50, devinfo->ver >= 10) 4387ec681f3SmrgFC(3src_a1_exec_type, /* 4+ */ 35, 35, /* 12+ */ 39, 39, devinfo->ver >= 10) 43901e04c3fSmrg/* Fields below this same in align16 */ 44001e04c3fSmrg/** @} */ 44101e04c3fSmrg 44201e04c3fSmrg#define REG_TYPE(reg) \ 44301e04c3fSmrgstatic inline void \ 4447ec681f3Smrgbrw_inst_set_3src_a1_##reg##_type(const struct intel_device_info *devinfo, \ 44501e04c3fSmrg brw_inst *inst, enum brw_reg_type type) \ 44601e04c3fSmrg{ \ 4477ec681f3Smrg UNUSED enum gfx10_align1_3src_exec_type exec_type = \ 4487ec681f3Smrg (enum gfx10_align1_3src_exec_type) brw_inst_3src_a1_exec_type(devinfo, \ 44901e04c3fSmrg inst); \ 45001e04c3fSmrg if (brw_reg_type_is_floating_point(type)) { \ 45101e04c3fSmrg assert(exec_type == BRW_ALIGN1_3SRC_EXEC_TYPE_FLOAT); \ 45201e04c3fSmrg } else { \ 45301e04c3fSmrg assert(exec_type == BRW_ALIGN1_3SRC_EXEC_TYPE_INT); \ 45401e04c3fSmrg } \ 45501e04c3fSmrg unsigned hw_type = brw_reg_type_to_a1_hw_3src_type(devinfo, type); \ 45601e04c3fSmrg brw_inst_set_3src_a1_##reg##_hw_type(devinfo, inst, hw_type); \ 45701e04c3fSmrg} \ 45801e04c3fSmrg \ 45901e04c3fSmrgstatic inline enum brw_reg_type \ 4607ec681f3Smrgbrw_inst_3src_a1_##reg##_type(const struct intel_device_info *devinfo, \ 46101e04c3fSmrg const brw_inst *inst) \ 46201e04c3fSmrg{ \ 4637ec681f3Smrg enum gfx10_align1_3src_exec_type exec_type = \ 4647ec681f3Smrg (enum gfx10_align1_3src_exec_type) brw_inst_3src_a1_exec_type(devinfo, \ 46501e04c3fSmrg inst); \ 46601e04c3fSmrg unsigned hw_type = brw_inst_3src_a1_##reg##_hw_type(devinfo, inst); \ 46701e04c3fSmrg return brw_a1_hw_3src_type_to_reg_type(devinfo, hw_type, exec_type); \ 46801e04c3fSmrg} 46901e04c3fSmrg 47001e04c3fSmrgREG_TYPE(dst) 47101e04c3fSmrgREG_TYPE(src0) 47201e04c3fSmrgREG_TYPE(src1) 47301e04c3fSmrgREG_TYPE(src2) 47401e04c3fSmrg#undef REG_TYPE 47501e04c3fSmrg 47601e04c3fSmrg/** 47701e04c3fSmrg * Three-source align1 instruction immediates: 47801e04c3fSmrg * @{ 47901e04c3fSmrg */ 48001e04c3fSmrgstatic inline uint16_t 4817ec681f3Smrgbrw_inst_3src_a1_src0_imm(ASSERTED const struct intel_device_info *devinfo, 48201e04c3fSmrg const brw_inst *insn) 48301e04c3fSmrg{ 4847ec681f3Smrg assert(devinfo->ver >= 10); 4857ec681f3Smrg if (devinfo->ver >= 12) 4867ec681f3Smrg return brw_inst_bits(insn, 79, 64); 4877ec681f3Smrg else 4887ec681f3Smrg return brw_inst_bits(insn, 82, 67); 48901e04c3fSmrg} 49001e04c3fSmrg 49101e04c3fSmrgstatic inline uint16_t 4927ec681f3Smrgbrw_inst_3src_a1_src2_imm(ASSERTED const struct intel_device_info *devinfo, 49301e04c3fSmrg const brw_inst *insn) 49401e04c3fSmrg{ 4957ec681f3Smrg assert(devinfo->ver >= 10); 4967ec681f3Smrg if (devinfo->ver >= 12) 4977ec681f3Smrg return brw_inst_bits(insn, 127, 112); 4987ec681f3Smrg else 4997ec681f3Smrg return brw_inst_bits(insn, 124, 109); 50001e04c3fSmrg} 50101e04c3fSmrg 50201e04c3fSmrgstatic inline void 5037ec681f3Smrgbrw_inst_set_3src_a1_src0_imm(ASSERTED const struct intel_device_info *devinfo, 50401e04c3fSmrg brw_inst *insn, uint16_t value) 50501e04c3fSmrg{ 5067ec681f3Smrg assert(devinfo->ver >= 10); 5077ec681f3Smrg if (devinfo->ver >= 12) 5087ec681f3Smrg brw_inst_set_bits(insn, 79, 64, value); 5097ec681f3Smrg else 5107ec681f3Smrg brw_inst_set_bits(insn, 82, 67, value); 51101e04c3fSmrg} 51201e04c3fSmrg 51301e04c3fSmrgstatic inline void 5147ec681f3Smrgbrw_inst_set_3src_a1_src2_imm(ASSERTED const struct intel_device_info *devinfo, 51501e04c3fSmrg brw_inst *insn, uint16_t value) 51601e04c3fSmrg{ 5177ec681f3Smrg assert(devinfo->ver >= 10); 5187ec681f3Smrg if (devinfo->ver >= 12) 5197ec681f3Smrg brw_inst_set_bits(insn, 127, 112, value); 5207ec681f3Smrg else 5217ec681f3Smrg brw_inst_set_bits(insn, 124, 109, value); 52201e04c3fSmrg} 52301e04c3fSmrg/** @} */ 52401e04c3fSmrg 52501e04c3fSmrg/** 52601e04c3fSmrg * Flow control instruction bits: 52701e04c3fSmrg * @{ 52801e04c3fSmrg */ 52901e04c3fSmrgstatic inline void 5307ec681f3Smrgbrw_inst_set_uip(const struct intel_device_info *devinfo, 53101e04c3fSmrg brw_inst *inst, int32_t value) 53201e04c3fSmrg{ 5337ec681f3Smrg assert(devinfo->ver >= 6); 53401e04c3fSmrg 5357ec681f3Smrg if (devinfo->ver >= 12) 5367ec681f3Smrg brw_inst_set_src1_is_imm(devinfo, inst, 1); 5377ec681f3Smrg 5387ec681f3Smrg if (devinfo->ver >= 8) { 53901e04c3fSmrg brw_inst_set_bits(inst, 95, 64, (uint32_t)value); 54001e04c3fSmrg } else { 54101e04c3fSmrg assert(value <= (1 << 16) - 1); 54201e04c3fSmrg assert(value > -(1 << 16)); 54301e04c3fSmrg brw_inst_set_bits(inst, 127, 112, (uint16_t)value); 54401e04c3fSmrg } 54501e04c3fSmrg} 54601e04c3fSmrg 54701e04c3fSmrgstatic inline int32_t 5487ec681f3Smrgbrw_inst_uip(const struct intel_device_info *devinfo, const brw_inst *inst) 54901e04c3fSmrg{ 5507ec681f3Smrg assert(devinfo->ver >= 6); 55101e04c3fSmrg 5527ec681f3Smrg if (devinfo->ver >= 8) { 55301e04c3fSmrg return brw_inst_bits(inst, 95, 64); 55401e04c3fSmrg } else { 55501e04c3fSmrg return (int16_t)brw_inst_bits(inst, 127, 112); 55601e04c3fSmrg } 55701e04c3fSmrg} 55801e04c3fSmrg 55901e04c3fSmrgstatic inline void 5607ec681f3Smrgbrw_inst_set_jip(const struct intel_device_info *devinfo, 56101e04c3fSmrg brw_inst *inst, int32_t value) 56201e04c3fSmrg{ 5637ec681f3Smrg assert(devinfo->ver >= 6); 5647ec681f3Smrg 5657ec681f3Smrg if (devinfo->ver >= 12) 5667ec681f3Smrg brw_inst_set_src0_is_imm(devinfo, inst, 1); 56701e04c3fSmrg 5687ec681f3Smrg if (devinfo->ver >= 8) { 56901e04c3fSmrg brw_inst_set_bits(inst, 127, 96, (uint32_t)value); 57001e04c3fSmrg } else { 57101e04c3fSmrg assert(value <= (1 << 15) - 1); 57201e04c3fSmrg assert(value >= -(1 << 15)); 57301e04c3fSmrg brw_inst_set_bits(inst, 111, 96, (uint16_t)value); 57401e04c3fSmrg } 57501e04c3fSmrg} 57601e04c3fSmrg 57701e04c3fSmrgstatic inline int32_t 5787ec681f3Smrgbrw_inst_jip(const struct intel_device_info *devinfo, const brw_inst *inst) 57901e04c3fSmrg{ 5807ec681f3Smrg assert(devinfo->ver >= 6); 58101e04c3fSmrg 5827ec681f3Smrg if (devinfo->ver >= 8) { 58301e04c3fSmrg return brw_inst_bits(inst, 127, 96); 58401e04c3fSmrg } else { 58501e04c3fSmrg return (int16_t)brw_inst_bits(inst, 111, 96); 58601e04c3fSmrg } 58701e04c3fSmrg} 58801e04c3fSmrg 58901e04c3fSmrg/** Like FC, but using int16_t to handle negative jump targets. */ 59001e04c3fSmrg#define FJ(name, high, low, assertions) \ 59101e04c3fSmrgstatic inline void \ 5927ec681f3Smrgbrw_inst_set_##name(const struct intel_device_info *devinfo, brw_inst *inst, int16_t v) \ 59301e04c3fSmrg{ \ 59401e04c3fSmrg assert(assertions); \ 59501e04c3fSmrg (void) devinfo; \ 59601e04c3fSmrg brw_inst_set_bits(inst, high, low, (uint16_t) v); \ 59701e04c3fSmrg} \ 59801e04c3fSmrgstatic inline int16_t \ 5997ec681f3Smrgbrw_inst_##name(const struct intel_device_info *devinfo, const brw_inst *inst)\ 60001e04c3fSmrg{ \ 60101e04c3fSmrg assert(assertions); \ 60201e04c3fSmrg (void) devinfo; \ 60301e04c3fSmrg return brw_inst_bits(inst, high, low); \ 60401e04c3fSmrg} 60501e04c3fSmrg 6067ec681f3SmrgFJ(gfx6_jump_count, 63, 48, devinfo->ver == 6) 6077ec681f3SmrgFJ(gfx4_jump_count, 111, 96, devinfo->ver < 6) 6087ec681f3SmrgFC(gfx4_pop_count, /* 4+ */ 115, 112, /* 12+ */ -1, -1, devinfo->ver < 6) 60901e04c3fSmrg/** @} */ 61001e04c3fSmrg 6119f464c52Smaya/** 6129f464c52Smaya * SEND instructions: 6139f464c52Smaya * @{ 6149f464c52Smaya */ 6157ec681f3SmrgFC(send_ex_desc_ia_subreg_nr, /* 4+ */ 82, 80, /* 12+ */ 42, 40, devinfo->ver >= 9) 6167ec681f3SmrgFC(send_src0_address_mode, /* 4+ */ 79, 79, /* 12+ */ -1, -1, devinfo->ver >= 9) 6177ec681f3SmrgFC(send_sel_reg32_desc, /* 4+ */ 77, 77, /* 12+ */ 48, 48, devinfo->ver >= 9) 6187ec681f3SmrgFC(send_sel_reg32_ex_desc, /* 4+ */ 61, 61, /* 12+ */ 49, 49, devinfo->ver >= 9) 6197ec681f3SmrgF8(send_src0_reg_file, /* 4+ */ 38, 37, /* 8+ */ 42, 41, /* 12+ */ 66, 66) 6207ec681f3SmrgFC(send_src1_reg_nr, /* 4+ */ 51, 44, /* 12+ */ 111, 104, devinfo->ver >= 9) 6217ec681f3SmrgFC(send_src1_reg_file, /* 4+ */ 36, 36, /* 12+ */ 98, 98, devinfo->ver >= 9) 6227ec681f3SmrgFC(send_dst_reg_file, /* 4+ */ 35, 35, /* 12+ */ 50, 50, devinfo->ver >= 9) 6239f464c52Smaya/** @} */ 6249f464c52Smaya 62501e04c3fSmrg/* Message descriptor bits */ 62601e04c3fSmrg#define MD(x) ((x) + 96) 6277ec681f3Smrg#define MD12(x) ((x) >= 30 ? (x) - 30 + 122 : \ 6287ec681f3Smrg (x) >= 25 ? (x) - 25 + 67 : \ 6297ec681f3Smrg (x) >= 20 ? (x) - 20 + 51 : \ 6307ec681f3Smrg (x) >= 11 ? (x) - 11 + 113 : \ 6317ec681f3Smrg (x) - 0 + 81) 63201e04c3fSmrg 63301e04c3fSmrg/** 63401e04c3fSmrg * Set the SEND(C) message descriptor immediate. 63501e04c3fSmrg * 63601e04c3fSmrg * This doesn't include the SFID nor the EOT field that were considered to be 63701e04c3fSmrg * part of the message descriptor by ancient versions of the BSpec, because 63801e04c3fSmrg * they are present in the instruction even if the message descriptor is 63901e04c3fSmrg * provided indirectly in the address register, so we want to specify them 64001e04c3fSmrg * separately. 64101e04c3fSmrg */ 64201e04c3fSmrgstatic inline void 6437ec681f3Smrgbrw_inst_set_send_desc(const struct intel_device_info *devinfo, 64401e04c3fSmrg brw_inst *inst, uint32_t value) 64501e04c3fSmrg{ 6467ec681f3Smrg if (devinfo->ver >= 12) { 6477ec681f3Smrg brw_inst_set_bits(inst, 123, 122, GET_BITS(value, 31, 30)); 6487ec681f3Smrg brw_inst_set_bits(inst, 71, 67, GET_BITS(value, 29, 25)); 6497ec681f3Smrg brw_inst_set_bits(inst, 55, 51, GET_BITS(value, 24, 20)); 6507ec681f3Smrg brw_inst_set_bits(inst, 121, 113, GET_BITS(value, 19, 11)); 6517ec681f3Smrg brw_inst_set_bits(inst, 91, 81, GET_BITS(value, 10, 0)); 6527ec681f3Smrg } else if (devinfo->ver >= 9) { 65301e04c3fSmrg brw_inst_set_bits(inst, 126, 96, value); 65401e04c3fSmrg assert(value >> 31 == 0); 6557ec681f3Smrg } else if (devinfo->ver >= 5) { 65601e04c3fSmrg brw_inst_set_bits(inst, 124, 96, value); 65701e04c3fSmrg assert(value >> 29 == 0); 65801e04c3fSmrg } else { 65901e04c3fSmrg brw_inst_set_bits(inst, 119, 96, value); 66001e04c3fSmrg assert(value >> 24 == 0); 66101e04c3fSmrg } 66201e04c3fSmrg} 66301e04c3fSmrg 66401e04c3fSmrg/** 66501e04c3fSmrg * Get the SEND(C) message descriptor immediate. 66601e04c3fSmrg * 66701e04c3fSmrg * \sa brw_inst_set_send_desc(). 66801e04c3fSmrg */ 66901e04c3fSmrgstatic inline uint32_t 6707ec681f3Smrgbrw_inst_send_desc(const struct intel_device_info *devinfo, 6717ec681f3Smrg const brw_inst *inst) 67201e04c3fSmrg{ 6737ec681f3Smrg if (devinfo->ver >= 12) { 6747ec681f3Smrg return (brw_inst_bits(inst, 123, 122) << 30 | 6757ec681f3Smrg brw_inst_bits(inst, 71, 67) << 25 | 6767ec681f3Smrg brw_inst_bits(inst, 55, 51) << 20 | 6777ec681f3Smrg brw_inst_bits(inst, 121, 113) << 11 | 6787ec681f3Smrg brw_inst_bits(inst, 91, 81)); 6797ec681f3Smrg } else if (devinfo->ver >= 9) { 68001e04c3fSmrg return brw_inst_bits(inst, 126, 96); 6817ec681f3Smrg } else if (devinfo->ver >= 5) { 68201e04c3fSmrg return brw_inst_bits(inst, 124, 96); 6837ec681f3Smrg } else { 68401e04c3fSmrg return brw_inst_bits(inst, 119, 96); 6857ec681f3Smrg } 68601e04c3fSmrg} 68701e04c3fSmrg 68801e04c3fSmrg/** 68901e04c3fSmrg * Set the SEND(C) message extended descriptor immediate. 69001e04c3fSmrg * 69101e04c3fSmrg * This doesn't include the SFID nor the EOT field that were considered to be 69201e04c3fSmrg * part of the extended message descriptor by some versions of the BSpec, 69301e04c3fSmrg * because they are present in the instruction even if the extended message 69401e04c3fSmrg * descriptor is provided indirectly in a register, so we want to specify them 69501e04c3fSmrg * separately. 69601e04c3fSmrg */ 69701e04c3fSmrgstatic inline void 6987ec681f3Smrgbrw_inst_set_send_ex_desc(const struct intel_device_info *devinfo, 69901e04c3fSmrg brw_inst *inst, uint32_t value) 70001e04c3fSmrg{ 7017ec681f3Smrg if (devinfo->ver >= 12) { 7027ec681f3Smrg brw_inst_set_bits(inst, 127, 124, GET_BITS(value, 31, 28)); 7037ec681f3Smrg brw_inst_set_bits(inst, 97, 96, GET_BITS(value, 27, 26)); 7047ec681f3Smrg brw_inst_set_bits(inst, 65, 64, GET_BITS(value, 25, 24)); 7057ec681f3Smrg brw_inst_set_bits(inst, 47, 35, GET_BITS(value, 23, 11)); 7067ec681f3Smrg brw_inst_set_bits(inst, 103, 99, GET_BITS(value, 10, 6)); 7077ec681f3Smrg assert(GET_BITS(value, 5, 0) == 0); 7087ec681f3Smrg } else { 7097ec681f3Smrg assert(devinfo->ver >= 9); 7109f464c52Smaya brw_inst_set_bits(inst, 94, 91, GET_BITS(value, 31, 28)); 7119f464c52Smaya brw_inst_set_bits(inst, 88, 85, GET_BITS(value, 27, 24)); 7129f464c52Smaya brw_inst_set_bits(inst, 83, 80, GET_BITS(value, 23, 20)); 7139f464c52Smaya brw_inst_set_bits(inst, 67, 64, GET_BITS(value, 19, 16)); 7149f464c52Smaya assert(GET_BITS(value, 15, 0) == 0); 7157ec681f3Smrg } 7167ec681f3Smrg} 7177ec681f3Smrg 7187ec681f3Smrg/** 7197ec681f3Smrg * Set the SENDS(C) message extended descriptor immediate. 7207ec681f3Smrg * 7217ec681f3Smrg * This doesn't include the SFID nor the EOT field that were considered to be 7227ec681f3Smrg * part of the extended message descriptor by some versions of the BSpec, 7237ec681f3Smrg * because they are present in the instruction even if the extended message 7247ec681f3Smrg * descriptor is provided indirectly in a register, so we want to specify them 7257ec681f3Smrg * separately. 7267ec681f3Smrg */ 7277ec681f3Smrgstatic inline void 7287ec681f3Smrgbrw_inst_set_sends_ex_desc(const struct intel_device_info *devinfo, 7297ec681f3Smrg brw_inst *inst, uint32_t value) 7307ec681f3Smrg{ 7317ec681f3Smrg if (devinfo->ver >= 12) { 7327ec681f3Smrg brw_inst_set_send_ex_desc(devinfo, inst, value); 7339f464c52Smaya } else { 7349f464c52Smaya brw_inst_set_bits(inst, 95, 80, GET_BITS(value, 31, 16)); 7359f464c52Smaya assert(GET_BITS(value, 15, 10) == 0); 7369f464c52Smaya brw_inst_set_bits(inst, 67, 64, GET_BITS(value, 9, 6)); 7379f464c52Smaya assert(GET_BITS(value, 5, 0) == 0); 7389f464c52Smaya } 73901e04c3fSmrg} 74001e04c3fSmrg 74101e04c3fSmrg/** 74201e04c3fSmrg * Get the SEND(C) message extended descriptor immediate. 74301e04c3fSmrg * 74401e04c3fSmrg * \sa brw_inst_set_send_ex_desc(). 74501e04c3fSmrg */ 74601e04c3fSmrgstatic inline uint32_t 7477ec681f3Smrgbrw_inst_send_ex_desc(const struct intel_device_info *devinfo, 74801e04c3fSmrg const brw_inst *inst) 74901e04c3fSmrg{ 7507ec681f3Smrg if (devinfo->ver >= 12) { 7517ec681f3Smrg return (brw_inst_bits(inst, 127, 124) << 28 | 7527ec681f3Smrg brw_inst_bits(inst, 97, 96) << 26 | 7537ec681f3Smrg brw_inst_bits(inst, 65, 64) << 24 | 7547ec681f3Smrg brw_inst_bits(inst, 47, 35) << 11 | 7557ec681f3Smrg brw_inst_bits(inst, 103, 99) << 6); 7567ec681f3Smrg } else { 7577ec681f3Smrg assert(devinfo->ver >= 9); 7589f464c52Smaya return (brw_inst_bits(inst, 94, 91) << 28 | 7599f464c52Smaya brw_inst_bits(inst, 88, 85) << 24 | 7609f464c52Smaya brw_inst_bits(inst, 83, 80) << 20 | 7619f464c52Smaya brw_inst_bits(inst, 67, 64) << 16); 7627ec681f3Smrg } 7637ec681f3Smrg} 7647ec681f3Smrg 7657ec681f3Smrg/** 7667ec681f3Smrg * Get the SENDS(C) message extended descriptor immediate. 7677ec681f3Smrg * 7687ec681f3Smrg * \sa brw_inst_set_send_ex_desc(). 7697ec681f3Smrg */ 7707ec681f3Smrgstatic inline uint32_t 7717ec681f3Smrgbrw_inst_sends_ex_desc(const struct intel_device_info *devinfo, 7727ec681f3Smrg const brw_inst *inst) 7737ec681f3Smrg{ 7747ec681f3Smrg if (devinfo->ver >= 12) { 7757ec681f3Smrg return brw_inst_send_ex_desc(devinfo, inst); 7769f464c52Smaya } else { 7779f464c52Smaya return (brw_inst_bits(inst, 95, 80) << 16 | 7789f464c52Smaya brw_inst_bits(inst, 67, 64) << 6); 7799f464c52Smaya } 78001e04c3fSmrg} 78101e04c3fSmrg 78201e04c3fSmrg/** 78301e04c3fSmrg * Fields for SEND messages: 78401e04c3fSmrg * @{ 78501e04c3fSmrg */ 7867ec681f3SmrgF(eot, /* 4+ */ 127, 127, /* 12+ */ 34, 34) 78701e04c3fSmrgFF(mlen, 78801e04c3fSmrg /* 4: */ 119, 116, 78901e04c3fSmrg /* 4.5: */ 119, 116, 79001e04c3fSmrg /* 5: */ 124, 121, 79101e04c3fSmrg /* 6: */ 124, 121, 79201e04c3fSmrg /* 7: */ 124, 121, 7937ec681f3Smrg /* 8: */ 124, 121, 7947ec681f3Smrg /* 12: */ MD12(28), MD12(25)); 79501e04c3fSmrgFF(rlen, 79601e04c3fSmrg /* 4: */ 115, 112, 79701e04c3fSmrg /* 4.5: */ 115, 112, 79801e04c3fSmrg /* 5: */ 120, 116, 79901e04c3fSmrg /* 6: */ 120, 116, 80001e04c3fSmrg /* 7: */ 120, 116, 8017ec681f3Smrg /* 8: */ 120, 116, 8027ec681f3Smrg /* 12: */ MD12(24), MD12(20)); 80301e04c3fSmrgFF(header_present, 80401e04c3fSmrg /* 4: doesn't exist */ -1, -1, -1, -1, 80501e04c3fSmrg /* 5: */ 115, 115, 80601e04c3fSmrg /* 6: */ 115, 115, 80701e04c3fSmrg /* 7: */ 115, 115, 8087ec681f3Smrg /* 8: */ 115, 115, 8097ec681f3Smrg /* 12: */ MD12(19), MD12(19)) 8107ec681f3SmrgF(gateway_notify, /* 4+ */ MD(16), MD(15), /* 12+ */ -1, -1) 8117ec681f3SmrgFD(function_control, 81201e04c3fSmrg /* 4: */ 111, 96, 81301e04c3fSmrg /* 4.5: */ 111, 96, 81401e04c3fSmrg /* 5: */ 114, 96, 81501e04c3fSmrg /* 6: */ 114, 96, 81601e04c3fSmrg /* 7: */ 114, 96, 8177ec681f3Smrg /* 8: */ 114, 96, 8187ec681f3Smrg /* 12: */ MD12(18), MD12(11), MD12(10), MD12(0)) 81901e04c3fSmrgFF(gateway_subfuncid, 82001e04c3fSmrg /* 4: */ MD(1), MD(0), 82101e04c3fSmrg /* 4.5: */ MD(1), MD(0), 82201e04c3fSmrg /* 5: */ MD(1), MD(0), /* 2:0, but bit 2 is reserved MBZ */ 82301e04c3fSmrg /* 6: */ MD(2), MD(0), 82401e04c3fSmrg /* 7: */ MD(2), MD(0), 8257ec681f3Smrg /* 8: */ MD(2), MD(0), 8267ec681f3Smrg /* 12: */ MD12(2), MD12(0)) 82701e04c3fSmrgFF(sfid, 82801e04c3fSmrg /* 4: */ 123, 120, /* called msg_target */ 82901e04c3fSmrg /* 4.5 */ 123, 120, 83001e04c3fSmrg /* 5: */ 95, 92, 83101e04c3fSmrg /* 6: */ 27, 24, 83201e04c3fSmrg /* 7: */ 27, 24, 8337ec681f3Smrg /* 8: */ 27, 24, 8347ec681f3Smrg /* 12: */ 95, 92) 83501e04c3fSmrgFF(null_rt, 83601e04c3fSmrg /* 4-7: */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8377ec681f3Smrg /* 8: */ 80, 80, 8387ec681f3Smrg /* 12: */ 44, 44) /* actually only Gfx11+ */ 8397ec681f3SmrgFC(base_mrf, /* 4+ */ 27, 24, /* 12+ */ -1, -1, devinfo->ver < 6); 8407ec681f3SmrgFF(send_rta_index, 8417ec681f3Smrg /* 4: */ -1, -1, 8427ec681f3Smrg /* 4.5 */ -1, -1, 8437ec681f3Smrg /* 5: */ -1, -1, 8447ec681f3Smrg /* 6: */ -1, -1, 8457ec681f3Smrg /* 7: */ -1, -1, 8467ec681f3Smrg /* 8: */ -1, -1, 8477ec681f3Smrg /* 12: */ 38, 36) 84801e04c3fSmrg/** @} */ 84901e04c3fSmrg 85001e04c3fSmrg/** 85101e04c3fSmrg * URB message function control bits: 85201e04c3fSmrg * @{ 85301e04c3fSmrg */ 85401e04c3fSmrgFF(urb_per_slot_offset, 85501e04c3fSmrg /* 4-6: */ -1, -1, -1, -1, -1, -1, -1, -1, 85601e04c3fSmrg /* 7: */ MD(16), MD(16), 8577ec681f3Smrg /* 8: */ MD(17), MD(17), 8587ec681f3Smrg /* 12: */ MD12(17), MD12(17)) 8597ec681f3SmrgFC(urb_channel_mask_present, /* 4+ */ MD(15), MD(15), /* 12+ */ MD12(15), MD12(15), devinfo->ver >= 8) 8607ec681f3SmrgFC(urb_complete, /* 4+ */ MD(15), MD(15), /* 12+ */ -1, -1, devinfo->ver < 8) 8617ec681f3SmrgFC(urb_used, /* 4+ */ MD(14), MD(14), /* 12+ */ -1, -1, devinfo->ver < 7) 8627ec681f3SmrgFC(urb_allocate, /* 4+ */ MD(13), MD(13), /* 12+ */ -1, -1, devinfo->ver < 7) 86301e04c3fSmrgFF(urb_swizzle_control, 86401e04c3fSmrg /* 4: */ MD(11), MD(10), 86501e04c3fSmrg /* 4.5: */ MD(11), MD(10), 86601e04c3fSmrg /* 5: */ MD(11), MD(10), 86701e04c3fSmrg /* 6: */ MD(11), MD(10), 86801e04c3fSmrg /* 7: */ MD(14), MD(14), 8697ec681f3Smrg /* 8: */ MD(15), MD(15), 8707ec681f3Smrg /* 12: */ -1, -1) 8717ec681f3SmrgFD(urb_global_offset, 87201e04c3fSmrg /* 4: */ MD( 9), MD(4), 87301e04c3fSmrg /* 4.5: */ MD( 9), MD(4), 87401e04c3fSmrg /* 5: */ MD( 9), MD(4), 87501e04c3fSmrg /* 6: */ MD( 9), MD(4), 87601e04c3fSmrg /* 7: */ MD(13), MD(3), 8777ec681f3Smrg /* 8: */ MD(14), MD(4), 8787ec681f3Smrg /* 12: */ MD12(14), MD12(11), MD12(10), MD12(4)) 87901e04c3fSmrgFF(urb_opcode, 88001e04c3fSmrg /* 4: */ MD( 3), MD(0), 88101e04c3fSmrg /* 4.5: */ MD( 3), MD(0), 88201e04c3fSmrg /* 5: */ MD( 3), MD(0), 88301e04c3fSmrg /* 6: */ MD( 3), MD(0), 88401e04c3fSmrg /* 7: */ MD( 2), MD(0), 8857ec681f3Smrg /* 8: */ MD( 3), MD(0), 8867ec681f3Smrg /* 12: */ MD12(3), MD12(0)) 88701e04c3fSmrg/** @} */ 88801e04c3fSmrg 88901e04c3fSmrg/** 8907ec681f3Smrg * Gfx4-5 math messages: 89101e04c3fSmrg * @{ 89201e04c3fSmrg */ 8937ec681f3SmrgFC(math_msg_data_type, /* 4+ */ MD(7), MD(7), /* 12+ */ -1, -1, devinfo->ver < 6) 8947ec681f3SmrgFC(math_msg_saturate, /* 4+ */ MD(6), MD(6), /* 12+ */ -1, -1, devinfo->ver < 6) 8957ec681f3SmrgFC(math_msg_precision, /* 4+ */ MD(5), MD(5), /* 12+ */ -1, -1, devinfo->ver < 6) 8967ec681f3SmrgFC(math_msg_signed_int, /* 4+ */ MD(4), MD(4), /* 12+ */ -1, -1, devinfo->ver < 6) 8977ec681f3SmrgFC(math_msg_function, /* 4+ */ MD(3), MD(0), /* 12+ */ -1, -1, devinfo->ver < 6) 89801e04c3fSmrg/** @} */ 89901e04c3fSmrg 90001e04c3fSmrg/** 90101e04c3fSmrg * Sampler message function control bits: 90201e04c3fSmrg * @{ 90301e04c3fSmrg */ 90401e04c3fSmrgFF(sampler_simd_mode, 90501e04c3fSmrg /* 4: doesn't exist */ -1, -1, -1, -1, 90601e04c3fSmrg /* 5: */ MD(17), MD(16), 90701e04c3fSmrg /* 6: */ MD(17), MD(16), 90801e04c3fSmrg /* 7: */ MD(18), MD(17), 9097ec681f3Smrg /* 8: */ MD(18), MD(17), 9107ec681f3Smrg /* 12: */ MD12(18), MD12(17)) 91101e04c3fSmrgFF(sampler_msg_type, 91201e04c3fSmrg /* 4: */ MD(15), MD(14), 91301e04c3fSmrg /* 4.5: */ MD(15), MD(12), 91401e04c3fSmrg /* 5: */ MD(15), MD(12), 91501e04c3fSmrg /* 6: */ MD(15), MD(12), 91601e04c3fSmrg /* 7: */ MD(16), MD(12), 9177ec681f3Smrg /* 8: */ MD(16), MD(12), 9187ec681f3Smrg /* 12: */ MD12(16), MD12(12)) 9197ec681f3SmrgFC(sampler_return_format, /* 4+ */ MD(13), MD(12), /* 12+ */ -1, -1, devinfo->ver == 4 && !devinfo->is_g4x) 9207ec681f3SmrgFD(sampler, 9217ec681f3Smrg /* 4: */ MD(11), MD(8), 9227ec681f3Smrg /* 4.5: */ MD(11), MD(8), 9237ec681f3Smrg /* 5: */ MD(11), MD(8), 9247ec681f3Smrg /* 6: */ MD(11), MD(8), 9257ec681f3Smrg /* 7: */ MD(11), MD(8), 9267ec681f3Smrg /* 8: */ MD(11), MD(8), 9277ec681f3Smrg /* 12: */ MD12(11), MD12(11), MD12(10), MD12(8)) 9287ec681f3SmrgF(binding_table_index, /* 4+ */ MD(7), MD(0), /* 12+ */ MD12(7), MD12(0)) /* also used by other messages */ 92901e04c3fSmrg/** @} */ 93001e04c3fSmrg 93101e04c3fSmrg/** 93201e04c3fSmrg * Data port message function control bits: 93301e04c3fSmrg * @{ 93401e04c3fSmrg */ 9357ec681f3SmrgFC(dp_category, /* 4+ */ MD(18), MD(18), /* 12+ */ MD12(18), MD12(18), devinfo->ver >= 7) 93601e04c3fSmrg 9377ec681f3Smrg/* Gfx4-5 store fields in different bits for read/write messages. */ 93801e04c3fSmrgFF(dp_read_msg_type, 93901e04c3fSmrg /* 4: */ MD(13), MD(12), 94001e04c3fSmrg /* 4.5: */ MD(13), MD(11), 94101e04c3fSmrg /* 5: */ MD(13), MD(11), 94201e04c3fSmrg /* 6: */ MD(16), MD(13), 94301e04c3fSmrg /* 7: */ MD(17), MD(14), 9447ec681f3Smrg /* 8: */ MD(17), MD(14), 9457ec681f3Smrg /* 12: */ MD12(17), MD12(14)) 94601e04c3fSmrgFF(dp_write_msg_type, 94701e04c3fSmrg /* 4: */ MD(14), MD(12), 94801e04c3fSmrg /* 4.5: */ MD(14), MD(12), 94901e04c3fSmrg /* 5: */ MD(14), MD(12), 95001e04c3fSmrg /* 6: */ MD(16), MD(13), 95101e04c3fSmrg /* 7: */ MD(17), MD(14), 9527ec681f3Smrg /* 8: */ MD(17), MD(14), 9537ec681f3Smrg /* 12: */ MD12(17), MD12(14)) 9547ec681f3SmrgFD(dp_read_msg_control, 95501e04c3fSmrg /* 4: */ MD(11), MD( 8), 95601e04c3fSmrg /* 4.5: */ MD(10), MD( 8), 95701e04c3fSmrg /* 5: */ MD(10), MD( 8), 95801e04c3fSmrg /* 6: */ MD(12), MD( 8), 95901e04c3fSmrg /* 7: */ MD(13), MD( 8), 9607ec681f3Smrg /* 8: */ MD(13), MD( 8), 9617ec681f3Smrg /* 12: */ MD12(13), MD12(11), MD12(10), MD12(8)) 9627ec681f3SmrgFD(dp_write_msg_control, 96301e04c3fSmrg /* 4: */ MD(11), MD( 8), 96401e04c3fSmrg /* 4.5: */ MD(11), MD( 8), 96501e04c3fSmrg /* 5: */ MD(11), MD( 8), 96601e04c3fSmrg /* 6: */ MD(12), MD( 8), 96701e04c3fSmrg /* 7: */ MD(13), MD( 8), 9687ec681f3Smrg /* 8: */ MD(13), MD( 8), 9697ec681f3Smrg /* 12: */ MD12(13), MD12(11), MD12(10), MD12(8)) 9707ec681f3SmrgFC(dp_read_target_cache, /* 4+ */ MD(15), MD(14), /* 12+ */ -1, -1, devinfo->ver < 6); 97101e04c3fSmrg 97201e04c3fSmrgFF(dp_write_commit, 97301e04c3fSmrg /* 4: */ MD(15), MD(15), 97401e04c3fSmrg /* 4.5: */ MD(15), MD(15), 97501e04c3fSmrg /* 5: */ MD(15), MD(15), 97601e04c3fSmrg /* 6: */ MD(17), MD(17), 9777ec681f3Smrg /* 7+: does not exist */ -1, -1, -1, -1, 9787ec681f3Smrg /* 12: */ -1, -1) 97901e04c3fSmrg 9807ec681f3Smrg/* Gfx6+ use the same bit locations for everything. */ 98101e04c3fSmrgFF(dp_msg_type, 98201e04c3fSmrg /* 4-5: use dp_read_msg_type or dp_write_msg_type instead */ 98301e04c3fSmrg -1, -1, -1, -1, -1, -1, 98401e04c3fSmrg /* 6: */ MD(16), MD(13), 98501e04c3fSmrg /* 7: */ MD(17), MD(14), 9867ec681f3Smrg /* 8: */ MD(18), MD(14), 9877ec681f3Smrg /* 12: */ MD12(18), MD12(14)) 9887ec681f3SmrgFD(dp_msg_control, 98901e04c3fSmrg /* 4: */ MD(11), MD( 8), 99001e04c3fSmrg /* 4.5-5: use dp_read_msg_control or dp_write_msg_control */ -1, -1, -1, -1, 99101e04c3fSmrg /* 6: */ MD(12), MD( 8), 99201e04c3fSmrg /* 7: */ MD(13), MD( 8), 9937ec681f3Smrg /* 8: */ MD(13), MD( 8), 9947ec681f3Smrg /* 12: */ MD12(13), MD12(11), MD12(10), MD12(8)) 99501e04c3fSmrg/** @} */ 99601e04c3fSmrg 99701e04c3fSmrg/** 9987ec681f3Smrg * Scratch message bits (Gfx7+): 99901e04c3fSmrg * @{ 100001e04c3fSmrg */ 10017ec681f3SmrgFC(scratch_read_write, /* 4+ */ MD(17), MD(17), /* 12+ */ MD12(17), MD12(17), devinfo->ver >= 7) /* 0 = read, 1 = write */ 10027ec681f3SmrgFC(scratch_type, /* 4+ */ MD(16), MD(16), /* 12+ */ -1, -1, devinfo->ver >= 7) /* 0 = OWord, 1 = DWord */ 10037ec681f3SmrgFC(scratch_invalidate_after_read, /* 4+ */ MD(15), MD(15), /* 12+ */ MD12(15), MD12(15), devinfo->ver >= 7) 10047ec681f3SmrgFC(scratch_block_size, /* 4+ */ MD(13), MD(12), /* 12+ */ MD12(13), MD12(12), devinfo->ver >= 7) 10057ec681f3SmrgFD(scratch_addr_offset, 10067ec681f3Smrg /* 4: */ -1, -1, 10077ec681f3Smrg /* 4.5: */ -1, -1, 10087ec681f3Smrg /* 5: */ -1, -1, 10097ec681f3Smrg /* 6: */ -1, -1, 10107ec681f3Smrg /* 7: */ MD(11), MD(0), 10117ec681f3Smrg /* 8: */ MD(11), MD(0), 10127ec681f3Smrg /* 12: */ MD12(11), MD12(11), MD12(10), MD12(0)) 101301e04c3fSmrg/** @} */ 101401e04c3fSmrg 101501e04c3fSmrg/** 101601e04c3fSmrg * Render Target message function control bits: 101701e04c3fSmrg * @{ 101801e04c3fSmrg */ 101901e04c3fSmrgFF(rt_last, 102001e04c3fSmrg /* 4: */ MD(11), MD(11), 102101e04c3fSmrg /* 4.5: */ MD(11), MD(11), 102201e04c3fSmrg /* 5: */ MD(11), MD(11), 102301e04c3fSmrg /* 6: */ MD(12), MD(12), 102401e04c3fSmrg /* 7: */ MD(12), MD(12), 10257ec681f3Smrg /* 8: */ MD(12), MD(12), 10267ec681f3Smrg /* 12: */ MD12(12), MD12(12)) 10277ec681f3SmrgFC(rt_slot_group, /* 4+ */ MD(11), MD(11), /* 12+ */ MD12(11), MD12(11), devinfo->ver >= 6) 10287ec681f3SmrgF(rt_message_type, /* 4+ */ MD(10), MD( 8), /* 12+ */ MD12(10), MD12(8)) 102901e04c3fSmrg/** @} */ 103001e04c3fSmrg 103101e04c3fSmrg/** 103201e04c3fSmrg * Thread Spawn message function control bits: 103301e04c3fSmrg * @{ 103401e04c3fSmrg */ 10357ec681f3SmrgFC(ts_resource_select, /* 4+ */ MD( 4), MD( 4), /* 12+ */ -1, -1, devinfo->ver < 11) 10367ec681f3SmrgFC(ts_request_type, /* 4+ */ MD( 1), MD( 1), /* 12+ */ -1, -1, devinfo->ver < 11) 10377ec681f3SmrgF(ts_opcode, /* 4+ */ MD( 0), MD( 0), /* 12+ */ MD12(0), MD12(0)) 103801e04c3fSmrg/** @} */ 103901e04c3fSmrg 104001e04c3fSmrg/** 104101e04c3fSmrg * Pixel Interpolator message function control bits: 104201e04c3fSmrg * @{ 104301e04c3fSmrg */ 10447ec681f3SmrgF(pi_simd_mode, /* 4+ */ MD(16), MD(16), /* 12+ */ MD12(16), MD12(16)) 10457ec681f3SmrgF(pi_nopersp, /* 4+ */ MD(14), MD(14), /* 12+ */ MD12(14), MD12(14)) 10467ec681f3SmrgF(pi_message_type, /* 4+ */ MD(13), MD(12), /* 12+ */ MD12(13), MD12(12)) 10477ec681f3SmrgF(pi_slot_group, /* 4+ */ MD(11), MD(11), /* 12+ */ MD12(11), MD12(11)) 10487ec681f3SmrgF(pi_message_data, /* 4+ */ MD(7), MD(0), /* 12+ */ MD12(7), MD12(0)) 104901e04c3fSmrg/** @} */ 105001e04c3fSmrg 105101e04c3fSmrg/** 105201e04c3fSmrg * Immediates: 105301e04c3fSmrg * @{ 105401e04c3fSmrg */ 105501e04c3fSmrgstatic inline int 10567ec681f3Smrgbrw_inst_imm_d(const struct intel_device_info *devinfo, const brw_inst *insn) 105701e04c3fSmrg{ 105801e04c3fSmrg (void) devinfo; 105901e04c3fSmrg return brw_inst_bits(insn, 127, 96); 106001e04c3fSmrg} 106101e04c3fSmrg 106201e04c3fSmrgstatic inline unsigned 10637ec681f3Smrgbrw_inst_imm_ud(const struct intel_device_info *devinfo, const brw_inst *insn) 106401e04c3fSmrg{ 106501e04c3fSmrg (void) devinfo; 106601e04c3fSmrg return brw_inst_bits(insn, 127, 96); 106701e04c3fSmrg} 106801e04c3fSmrg 106901e04c3fSmrgstatic inline uint64_t 10707ec681f3Smrgbrw_inst_imm_uq(ASSERTED const struct intel_device_info *devinfo, 107101e04c3fSmrg const brw_inst *insn) 107201e04c3fSmrg{ 10737ec681f3Smrg assert(devinfo->ver >= 8); 107401e04c3fSmrg return brw_inst_bits(insn, 127, 64); 107501e04c3fSmrg} 107601e04c3fSmrg 107701e04c3fSmrgstatic inline float 10787ec681f3Smrgbrw_inst_imm_f(const struct intel_device_info *devinfo, const brw_inst *insn) 107901e04c3fSmrg{ 108001e04c3fSmrg union { 108101e04c3fSmrg float f; 108201e04c3fSmrg uint32_t u; 108301e04c3fSmrg } ft; 108401e04c3fSmrg (void) devinfo; 108501e04c3fSmrg ft.u = brw_inst_bits(insn, 127, 96); 108601e04c3fSmrg return ft.f; 108701e04c3fSmrg} 108801e04c3fSmrg 108901e04c3fSmrgstatic inline double 10907ec681f3Smrgbrw_inst_imm_df(const struct intel_device_info *devinfo, const brw_inst *insn) 109101e04c3fSmrg{ 109201e04c3fSmrg union { 109301e04c3fSmrg double d; 109401e04c3fSmrg uint64_t u; 109501e04c3fSmrg } dt; 109601e04c3fSmrg (void) devinfo; 109701e04c3fSmrg dt.u = brw_inst_bits(insn, 127, 64); 109801e04c3fSmrg return dt.d; 109901e04c3fSmrg} 110001e04c3fSmrg 110101e04c3fSmrgstatic inline void 11027ec681f3Smrgbrw_inst_set_imm_d(const struct intel_device_info *devinfo, 110301e04c3fSmrg brw_inst *insn, int value) 110401e04c3fSmrg{ 110501e04c3fSmrg (void) devinfo; 110601e04c3fSmrg return brw_inst_set_bits(insn, 127, 96, value); 110701e04c3fSmrg} 110801e04c3fSmrg 110901e04c3fSmrgstatic inline void 11107ec681f3Smrgbrw_inst_set_imm_ud(const struct intel_device_info *devinfo, 111101e04c3fSmrg brw_inst *insn, unsigned value) 111201e04c3fSmrg{ 111301e04c3fSmrg (void) devinfo; 111401e04c3fSmrg return brw_inst_set_bits(insn, 127, 96, value); 111501e04c3fSmrg} 111601e04c3fSmrg 111701e04c3fSmrgstatic inline void 11187ec681f3Smrgbrw_inst_set_imm_f(const struct intel_device_info *devinfo, 111901e04c3fSmrg brw_inst *insn, float value) 112001e04c3fSmrg{ 112101e04c3fSmrg union { 112201e04c3fSmrg float f; 112301e04c3fSmrg uint32_t u; 112401e04c3fSmrg } ft; 112501e04c3fSmrg (void) devinfo; 112601e04c3fSmrg ft.f = value; 112701e04c3fSmrg brw_inst_set_bits(insn, 127, 96, ft.u); 112801e04c3fSmrg} 112901e04c3fSmrg 113001e04c3fSmrgstatic inline void 11317ec681f3Smrgbrw_inst_set_imm_df(const struct intel_device_info *devinfo, 113201e04c3fSmrg brw_inst *insn, double value) 113301e04c3fSmrg{ 113401e04c3fSmrg union { 113501e04c3fSmrg double d; 113601e04c3fSmrg uint64_t u; 113701e04c3fSmrg } dt; 113801e04c3fSmrg (void) devinfo; 113901e04c3fSmrg dt.d = value; 11407ec681f3Smrg 11417ec681f3Smrg if (devinfo->ver >= 12) { 11427ec681f3Smrg brw_inst_set_bits(insn, 95, 64, dt.u >> 32); 11437ec681f3Smrg brw_inst_set_bits(insn, 127, 96, dt.u & 0xFFFFFFFF); 11447ec681f3Smrg } else { 11457ec681f3Smrg brw_inst_set_bits(insn, 127, 64, dt.u); 11467ec681f3Smrg } 114701e04c3fSmrg} 114801e04c3fSmrg 114901e04c3fSmrgstatic inline void 11507ec681f3Smrgbrw_inst_set_imm_uq(const struct intel_device_info *devinfo, 115101e04c3fSmrg brw_inst *insn, uint64_t value) 115201e04c3fSmrg{ 115301e04c3fSmrg (void) devinfo; 11547ec681f3Smrg if (devinfo->ver >= 12) { 11557ec681f3Smrg brw_inst_set_bits(insn, 95, 64, value >> 32); 11567ec681f3Smrg brw_inst_set_bits(insn, 127, 96, value & 0xFFFFFFFF); 11577ec681f3Smrg } else { 11587ec681f3Smrg brw_inst_set_bits(insn, 127, 64, value); 11597ec681f3Smrg } 116001e04c3fSmrg} 116101e04c3fSmrg 116201e04c3fSmrg/** @} */ 116301e04c3fSmrg 116401e04c3fSmrg#define REG_TYPE(reg) \ 116501e04c3fSmrgstatic inline void \ 11667ec681f3Smrgbrw_inst_set_##reg##_file_type(const struct intel_device_info *devinfo, \ 116701e04c3fSmrg brw_inst *inst, enum brw_reg_file file, \ 116801e04c3fSmrg enum brw_reg_type type) \ 116901e04c3fSmrg{ \ 117001e04c3fSmrg assert(file <= BRW_IMMEDIATE_VALUE); \ 117101e04c3fSmrg unsigned hw_type = brw_reg_type_to_hw_type(devinfo, file, type); \ 117201e04c3fSmrg brw_inst_set_##reg##_reg_file(devinfo, inst, file); \ 117301e04c3fSmrg brw_inst_set_##reg##_reg_hw_type(devinfo, inst, hw_type); \ 117401e04c3fSmrg} \ 117501e04c3fSmrg \ 117601e04c3fSmrgstatic inline enum brw_reg_type \ 11777ec681f3Smrgbrw_inst_##reg##_type(const struct intel_device_info *devinfo, \ 117801e04c3fSmrg const brw_inst *inst) \ 117901e04c3fSmrg{ \ 118001e04c3fSmrg unsigned file = __builtin_strcmp("dst", #reg) == 0 ? \ 118101e04c3fSmrg (unsigned) BRW_GENERAL_REGISTER_FILE : \ 118201e04c3fSmrg brw_inst_##reg##_reg_file(devinfo, inst); \ 118301e04c3fSmrg unsigned hw_type = brw_inst_##reg##_reg_hw_type(devinfo, inst); \ 118401e04c3fSmrg return brw_hw_type_to_reg_type(devinfo, (enum brw_reg_file)file, hw_type); \ 118501e04c3fSmrg} 118601e04c3fSmrg 118701e04c3fSmrgREG_TYPE(dst) 118801e04c3fSmrgREG_TYPE(src0) 118901e04c3fSmrgREG_TYPE(src1) 119001e04c3fSmrg#undef REG_TYPE 119101e04c3fSmrg 119201e04c3fSmrg 11937ec681f3Smrg/* The AddrImm fields are split into two discontiguous sections on Gfx8+ */ 11947ec681f3Smrg#define BRW_IA1_ADDR_IMM(reg, g4_high, g4_low, g8_nine, g8_high, g8_low, \ 11957ec681f3Smrg g12_high, g12_low) \ 119601e04c3fSmrgstatic inline void \ 11977ec681f3Smrgbrw_inst_set_##reg##_ia1_addr_imm(const struct \ 11987ec681f3Smrg intel_device_info *devinfo, \ 119901e04c3fSmrg brw_inst *inst, \ 120001e04c3fSmrg unsigned value) \ 120101e04c3fSmrg{ \ 120201e04c3fSmrg assert((value & ~0x3ff) == 0); \ 12037ec681f3Smrg if (devinfo->ver >= 12) { \ 12047ec681f3Smrg brw_inst_set_bits(inst, g12_high, g12_low, value); \ 12057ec681f3Smrg } else if (devinfo->ver >= 8) { \ 120601e04c3fSmrg brw_inst_set_bits(inst, g8_high, g8_low, value & 0x1ff); \ 120701e04c3fSmrg brw_inst_set_bits(inst, g8_nine, g8_nine, value >> 9); \ 120801e04c3fSmrg } else { \ 120901e04c3fSmrg brw_inst_set_bits(inst, g4_high, g4_low, value); \ 121001e04c3fSmrg } \ 121101e04c3fSmrg} \ 121201e04c3fSmrgstatic inline unsigned \ 12137ec681f3Smrgbrw_inst_##reg##_ia1_addr_imm(const struct intel_device_info *devinfo, \ 121401e04c3fSmrg const brw_inst *inst) \ 121501e04c3fSmrg{ \ 12167ec681f3Smrg if (devinfo->ver >= 12) { \ 12177ec681f3Smrg return brw_inst_bits(inst, g12_high, g12_low); \ 12187ec681f3Smrg } else if (devinfo->ver >= 8) { \ 121901e04c3fSmrg return brw_inst_bits(inst, g8_high, g8_low) | \ 122001e04c3fSmrg (brw_inst_bits(inst, g8_nine, g8_nine) << 9); \ 122101e04c3fSmrg } else { \ 122201e04c3fSmrg return brw_inst_bits(inst, g4_high, g4_low); \ 122301e04c3fSmrg } \ 122401e04c3fSmrg} 122501e04c3fSmrg 12267ec681f3Smrg/* AddrImm[9:0] for Align1 Indirect Addressing */ 12277ec681f3Smrg/* -Gen 4- ----Gfx8---- -Gfx12- */ 12287ec681f3SmrgBRW_IA1_ADDR_IMM(src1, 105, 96, 121, 104, 96, 107, 98) 12297ec681f3SmrgBRW_IA1_ADDR_IMM(src0, 73, 64, 95, 72, 64, 75, 66) 12307ec681f3SmrgBRW_IA1_ADDR_IMM(dst, 57, 48, 47, 56, 48, 59, 50) 123101e04c3fSmrg 123201e04c3fSmrg#define BRW_IA16_ADDR_IMM(reg, g4_high, g4_low, g8_nine, g8_high, g8_low) \ 123301e04c3fSmrgstatic inline void \ 12347ec681f3Smrgbrw_inst_set_##reg##_ia16_addr_imm(const struct \ 12357ec681f3Smrg intel_device_info *devinfo, \ 123601e04c3fSmrg brw_inst *inst, unsigned value) \ 123701e04c3fSmrg{ \ 12387ec681f3Smrg assert(devinfo->ver < 12); \ 123901e04c3fSmrg assert((value & ~0x3ff) == 0); \ 12407ec681f3Smrg if (devinfo->ver >= 8) { \ 12419f464c52Smaya assert(GET_BITS(value, 3, 0) == 0); \ 12429f464c52Smaya brw_inst_set_bits(inst, g8_high, g8_low, GET_BITS(value, 8, 4)); \ 12439f464c52Smaya brw_inst_set_bits(inst, g8_nine, g8_nine, GET_BITS(value, 9, 9)); \ 124401e04c3fSmrg } else { \ 12459f464c52Smaya brw_inst_set_bits(inst, g4_high, g4_low, value); \ 124601e04c3fSmrg } \ 124701e04c3fSmrg} \ 124801e04c3fSmrgstatic inline unsigned \ 12497ec681f3Smrgbrw_inst_##reg##_ia16_addr_imm(const struct intel_device_info *devinfo, \ 125001e04c3fSmrg const brw_inst *inst) \ 125101e04c3fSmrg{ \ 12527ec681f3Smrg assert(devinfo->ver < 12); \ 12537ec681f3Smrg if (devinfo->ver >= 8) { \ 12549f464c52Smaya return (brw_inst_bits(inst, g8_high, g8_low) << 4) | \ 125501e04c3fSmrg (brw_inst_bits(inst, g8_nine, g8_nine) << 9); \ 125601e04c3fSmrg } else { \ 125701e04c3fSmrg return brw_inst_bits(inst, g4_high, g4_low); \ 125801e04c3fSmrg } \ 125901e04c3fSmrg} 126001e04c3fSmrg 126101e04c3fSmrg/* AddrImm[9:0] for Align16 Indirect Addressing: 126201e04c3fSmrg * Compared to Align1, these are missing the low 4 bits. 12637ec681f3Smrg * -Gen 4- ----Gfx8---- 126401e04c3fSmrg */ 12659f464c52SmayaBRW_IA16_ADDR_IMM(src1, 105, 96, 121, 104, 100) 12669f464c52SmayaBRW_IA16_ADDR_IMM(src0, 73, 64, 95, 72, 68) 12679f464c52SmayaBRW_IA16_ADDR_IMM(dst, 57, 52, 47, 56, 52) 12689f464c52SmayaBRW_IA16_ADDR_IMM(send_src0, -1, -1, 78, 72, 68) 12699f464c52SmayaBRW_IA16_ADDR_IMM(send_dst, -1, -1, 62, 56, 52) 127001e04c3fSmrg 127101e04c3fSmrg/** 127201e04c3fSmrg * Fetch a set of contiguous bits from the instruction. 127301e04c3fSmrg * 127401e04c3fSmrg * Bits indices range from 0..127; fields may not cross 64-bit boundaries. 127501e04c3fSmrg */ 127601e04c3fSmrgstatic inline uint64_t 127701e04c3fSmrgbrw_inst_bits(const brw_inst *inst, unsigned high, unsigned low) 127801e04c3fSmrg{ 12797ec681f3Smrg assume(high < 128); 12807ec681f3Smrg assume(high >= low); 128101e04c3fSmrg /* We assume the field doesn't cross 64-bit boundaries. */ 128201e04c3fSmrg const unsigned word = high / 64; 128301e04c3fSmrg assert(word == low / 64); 128401e04c3fSmrg 128501e04c3fSmrg high %= 64; 128601e04c3fSmrg low %= 64; 128701e04c3fSmrg 128801e04c3fSmrg const uint64_t mask = (~0ull >> (64 - (high - low + 1))); 128901e04c3fSmrg 129001e04c3fSmrg return (inst->data[word] >> low) & mask; 129101e04c3fSmrg} 129201e04c3fSmrg 129301e04c3fSmrg/** 129401e04c3fSmrg * Set bits in the instruction, with proper shifting and masking. 129501e04c3fSmrg * 129601e04c3fSmrg * Bits indices range from 0..127; fields may not cross 64-bit boundaries. 129701e04c3fSmrg */ 129801e04c3fSmrgstatic inline void 129901e04c3fSmrgbrw_inst_set_bits(brw_inst *inst, unsigned high, unsigned low, uint64_t value) 130001e04c3fSmrg{ 13017ec681f3Smrg assume(high < 128); 13027ec681f3Smrg assume(high >= low); 130301e04c3fSmrg const unsigned word = high / 64; 130401e04c3fSmrg assert(word == low / 64); 130501e04c3fSmrg 130601e04c3fSmrg high %= 64; 130701e04c3fSmrg low %= 64; 130801e04c3fSmrg 130901e04c3fSmrg const uint64_t mask = (~0ull >> (64 - (high - low + 1))) << low; 131001e04c3fSmrg 131101e04c3fSmrg /* Make sure the supplied value actually fits in the given bitfield. */ 131201e04c3fSmrg assert((value & (mask >> low)) == value); 131301e04c3fSmrg 131401e04c3fSmrg inst->data[word] = (inst->data[word] & ~mask) | (value << low); 131501e04c3fSmrg} 131601e04c3fSmrg 131701e04c3fSmrg#undef BRW_IA16_ADDR_IMM 131801e04c3fSmrg#undef BRW_IA1_ADDR_IMM 131901e04c3fSmrg#undef MD 132001e04c3fSmrg#undef F8 132101e04c3fSmrg#undef FF 132201e04c3fSmrg#undef BOUNDS 132301e04c3fSmrg#undef F 132401e04c3fSmrg#undef FC 132501e04c3fSmrg 132601e04c3fSmrgtypedef struct { 132701e04c3fSmrg uint64_t data; 132801e04c3fSmrg} brw_compact_inst; 132901e04c3fSmrg 133001e04c3fSmrg/** 133101e04c3fSmrg * Fetch a set of contiguous bits from the compacted instruction. 133201e04c3fSmrg * 133301e04c3fSmrg * Bits indices range from 0..63. 133401e04c3fSmrg */ 133501e04c3fSmrgstatic inline unsigned 133601e04c3fSmrgbrw_compact_inst_bits(const brw_compact_inst *inst, unsigned high, unsigned low) 133701e04c3fSmrg{ 133801e04c3fSmrg const uint64_t mask = (1ull << (high - low + 1)) - 1; 133901e04c3fSmrg 134001e04c3fSmrg return (inst->data >> low) & mask; 134101e04c3fSmrg} 134201e04c3fSmrg 134301e04c3fSmrg/** 134401e04c3fSmrg * Set bits in the compacted instruction. 134501e04c3fSmrg * 134601e04c3fSmrg * Bits indices range from 0..63. 134701e04c3fSmrg */ 134801e04c3fSmrgstatic inline void 134901e04c3fSmrgbrw_compact_inst_set_bits(brw_compact_inst *inst, unsigned high, unsigned low, 135001e04c3fSmrg uint64_t value) 135101e04c3fSmrg{ 135201e04c3fSmrg const uint64_t mask = ((1ull << (high - low + 1)) - 1) << low; 135301e04c3fSmrg 135401e04c3fSmrg /* Make sure the supplied value actually fits in the given bitfield. */ 135501e04c3fSmrg assert((value & (mask >> low)) == value); 135601e04c3fSmrg 135701e04c3fSmrg inst->data = (inst->data & ~mask) | (value << low); 135801e04c3fSmrg} 135901e04c3fSmrg 13607ec681f3Smrg#define FC(name, high, low, gfx12_high, gfx12_low, assertions) \ 136101e04c3fSmrgstatic inline void \ 13627ec681f3Smrgbrw_compact_inst_set_##name(const struct \ 13637ec681f3Smrg intel_device_info *devinfo, \ 136401e04c3fSmrg brw_compact_inst *inst, unsigned v) \ 136501e04c3fSmrg{ \ 136601e04c3fSmrg assert(assertions); \ 13677ec681f3Smrg if (devinfo->ver >= 12) \ 13687ec681f3Smrg brw_compact_inst_set_bits(inst, gfx12_high, gfx12_low, v); \ 13697ec681f3Smrg else \ 13707ec681f3Smrg brw_compact_inst_set_bits(inst, high, low, v); \ 137101e04c3fSmrg} \ 137201e04c3fSmrgstatic inline unsigned \ 13737ec681f3Smrgbrw_compact_inst_##name(const struct intel_device_info *devinfo, \ 137401e04c3fSmrg const brw_compact_inst *inst) \ 137501e04c3fSmrg{ \ 137601e04c3fSmrg assert(assertions); \ 13777ec681f3Smrg if (devinfo->ver >= 12) \ 13787ec681f3Smrg return brw_compact_inst_bits(inst, gfx12_high, gfx12_low); \ 13797ec681f3Smrg else \ 13807ec681f3Smrg return brw_compact_inst_bits(inst, high, low); \ 138101e04c3fSmrg} 138201e04c3fSmrg 13837ec681f3Smrg/* A simple macro for fields which stay in the same place on all generations 13847ec681f3Smrg * except for Gfx12. 13857ec681f3Smrg */ 13867ec681f3Smrg#define F(name, high, low, gfx12_high, gfx12_low) \ 13877ec681f3Smrg FC(name, high, low, gfx12_high, gfx12_low, true) 13887ec681f3Smrg 13897ec681f3SmrgF(src1_reg_nr, /* 4+ */ 63, 56, /* 12+ */ 63, 56) 13907ec681f3SmrgF(src0_reg_nr, /* 4+ */ 55, 48, /* 12+ */ 47, 40) 13917ec681f3SmrgF(dst_reg_nr, /* 4+ */ 47, 40, /* 12+ */ 23, 16) 13927ec681f3SmrgF(src1_index, /* 4+ */ 39, 35, /* 12+ */ 55, 52) 13937ec681f3SmrgF(src0_index, /* 4+ */ 34, 30, /* 12+ */ 51, 48) 13947ec681f3SmrgF(cmpt_control, /* 4+ */ 29, 29, /* 12+ */ 29, 29) /* Same location as brw_inst */ 13957ec681f3SmrgFC(flag_subreg_nr, /* 4+ */ 28, 28, /* 12+ */ -1, -1, devinfo->ver <= 6) 13967ec681f3SmrgF(cond_modifier, /* 4+ */ 27, 24, /* 12+ */ -1, -1) /* Same location as brw_inst */ 13977ec681f3SmrgFC(acc_wr_control, /* 4+ */ 23, 23, /* 12+ */ -1, -1, devinfo->ver >= 6) 13987ec681f3SmrgFC(mask_control_ex, /* 4+ */ 23, 23, /* 12+ */ -1, -1, devinfo->is_g4x || devinfo->ver == 5) 13997ec681f3SmrgF(subreg_index, /* 4+ */ 22, 18, /* 12+ */ 39, 35) 14007ec681f3SmrgF(datatype_index, /* 4+ */ 17, 13, /* 12+ */ 34, 30) 14017ec681f3SmrgF(control_index, /* 4+ */ 12, 8, /* 12+ */ 28, 24) 14027ec681f3SmrgFC(swsb, /* 4+ */ -1, -1, /* 12+ */ 15, 8, devinfo->ver >= 12) 14037ec681f3SmrgF(debug_control, /* 4+ */ 7, 7, /* 12+ */ 7, 7) 14047ec681f3SmrgF(hw_opcode, /* 4+ */ 6, 0, /* 12+ */ 6, 0) /* Same location as brw_inst */ 14057ec681f3Smrg 14067ec681f3Smrgstatic inline unsigned 14077ec681f3Smrgbrw_compact_inst_imm(const struct intel_device_info *devinfo, 14087ec681f3Smrg const brw_compact_inst *inst) 14097ec681f3Smrg{ 14107ec681f3Smrg if (devinfo->ver >= 12) { 14117ec681f3Smrg return brw_compact_inst_bits(inst, 63, 52); 14127ec681f3Smrg } else { 14137ec681f3Smrg return (brw_compact_inst_bits(inst, 39, 35) << 8) | 14147ec681f3Smrg (brw_compact_inst_bits(inst, 63, 56)); 14157ec681f3Smrg } 14167ec681f3Smrg} 141701e04c3fSmrg 141801e04c3fSmrg/** 14197ec681f3Smrg * (Gfx8+) Compacted three-source instructions: 142001e04c3fSmrg * @{ 142101e04c3fSmrg */ 14227ec681f3SmrgFC(3src_src2_reg_nr, /* 4+ */ 63, 57, /* 12+ */ 55, 48, devinfo->ver >= 8) 14237ec681f3SmrgFC(3src_src1_reg_nr, /* 4+ */ 56, 50, /* 12+ */ 63, 56, devinfo->ver >= 8) 14247ec681f3SmrgFC(3src_src0_reg_nr, /* 4+ */ 49, 43, /* 12+ */ 47, 40, devinfo->ver >= 8) 14257ec681f3SmrgFC(3src_src2_subreg_nr, /* 4+ */ 42, 40, /* 12+ */ -1, -1, devinfo->ver >= 8) 14267ec681f3SmrgFC(3src_src1_subreg_nr, /* 4+ */ 39, 37, /* 12+ */ -1, -1, devinfo->ver >= 8) 14277ec681f3SmrgFC(3src_src0_subreg_nr, /* 4+ */ 36, 34, /* 12+ */ -1, -1, devinfo->ver >= 8) 14287ec681f3SmrgFC(3src_src2_rep_ctrl, /* 4+ */ 33, 33, /* 12+ */ -1, -1, devinfo->ver >= 8) 14297ec681f3SmrgFC(3src_src1_rep_ctrl, /* 4+ */ 32, 32, /* 12+ */ -1, -1, devinfo->ver >= 8) 14307ec681f3SmrgFC(3src_saturate, /* 4+ */ 31, 31, /* 12+ */ -1, -1, devinfo->ver >= 8) 14317ec681f3SmrgFC(3src_debug_control, /* 4+ */ 30, 30, /* 12+ */ 7, 7, devinfo->ver >= 8) 14327ec681f3SmrgFC(3src_cmpt_control, /* 4+ */ 29, 29, /* 12+ */ 29, 29, devinfo->ver >= 8) 14337ec681f3SmrgFC(3src_src0_rep_ctrl, /* 4+ */ 28, 28, /* 12+ */ -1, -1, devinfo->ver >= 8) 143401e04c3fSmrg/* Reserved */ 14357ec681f3SmrgFC(3src_dst_reg_nr, /* 4+ */ 18, 12, /* 12+ */ 23, 16, devinfo->ver >= 8) 14367ec681f3SmrgFC(3src_source_index, /* 4+ */ 11, 10, /* 12+ */ 34, 30, devinfo->ver >= 8) 14377ec681f3SmrgFC(3src_subreg_index, /* 4+ */ -1, -1, /* 12+ */ 39, 35, devinfo->ver >= 12) 14387ec681f3SmrgFC(3src_control_index, /* 4+ */ 9, 8, /* 12+ */ 28, 24, devinfo->ver >= 8) 14397ec681f3SmrgFC(3src_swsb, /* 4+ */ -1, -1, /* 12+ */ 15, 8, devinfo->ver >= 8) 144001e04c3fSmrg/* Bit 7 is Reserved (for future Opcode expansion) */ 14417ec681f3SmrgFC(3src_hw_opcode, /* 4+ */ 6, 0, /* 12+ */ 6, 0, devinfo->ver >= 8) 144201e04c3fSmrg/** @} */ 144301e04c3fSmrg 144401e04c3fSmrg#undef F 144501e04c3fSmrg 144601e04c3fSmrg#ifdef __cplusplus 144701e04c3fSmrg} 144801e04c3fSmrg#endif 144901e04c3fSmrg 145001e04c3fSmrg#endif 1451