/* * Copyright © 2017 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include "brw_reg.h" #include "brw_eu_defines.h" #include "dev/intel_device_info.h" #define INVALID (-1) enum hw_reg_type { BRW_HW_REG_TYPE_UD = 0, BRW_HW_REG_TYPE_D = 1, BRW_HW_REG_TYPE_UW = 2, BRW_HW_REG_TYPE_W = 3, BRW_HW_REG_TYPE_F = 7, GFX8_HW_REG_TYPE_UQ = 8, GFX8_HW_REG_TYPE_Q = 9, BRW_HW_REG_TYPE_UB = 4, BRW_HW_REG_TYPE_B = 5, GFX7_HW_REG_TYPE_DF = 6, GFX8_HW_REG_TYPE_HF = 10, GFX11_HW_REG_TYPE_UD = 0, GFX11_HW_REG_TYPE_D = 1, GFX11_HW_REG_TYPE_UW = 2, GFX11_HW_REG_TYPE_W = 3, GFX11_HW_REG_TYPE_UB = 4, GFX11_HW_REG_TYPE_B = 5, GFX11_HW_REG_TYPE_UQ = 6, GFX11_HW_REG_TYPE_Q = 7, GFX11_HW_REG_TYPE_HF = 8, GFX11_HW_REG_TYPE_F = 9, GFX11_HW_REG_TYPE_DF = 10, GFX11_HW_REG_TYPE_NF = 11, }; enum hw_imm_type { BRW_HW_IMM_TYPE_UD = 0, BRW_HW_IMM_TYPE_D = 1, BRW_HW_IMM_TYPE_UW = 2, BRW_HW_IMM_TYPE_W = 3, BRW_HW_IMM_TYPE_F = 7, GFX8_HW_IMM_TYPE_UQ = 8, GFX8_HW_IMM_TYPE_Q = 9, BRW_HW_IMM_TYPE_UV = 4, BRW_HW_IMM_TYPE_VF = 5, BRW_HW_IMM_TYPE_V = 6, GFX8_HW_IMM_TYPE_DF = 10, GFX8_HW_IMM_TYPE_HF = 11, GFX11_HW_IMM_TYPE_UD = 0, GFX11_HW_IMM_TYPE_D = 1, GFX11_HW_IMM_TYPE_UW = 2, GFX11_HW_IMM_TYPE_W = 3, GFX11_HW_IMM_TYPE_UV = 4, GFX11_HW_IMM_TYPE_V = 5, GFX11_HW_IMM_TYPE_UQ = 6, GFX11_HW_IMM_TYPE_Q = 7, GFX11_HW_IMM_TYPE_HF = 8, GFX11_HW_IMM_TYPE_F = 9, GFX11_HW_IMM_TYPE_DF = 10, GFX11_HW_IMM_TYPE_VF = 11, }; #define GFX12_HW_REG_TYPE_UINT(n) (n) #define GFX12_HW_REG_TYPE_SINT(n) (0x4 | (n)) #define GFX12_HW_REG_TYPE_FLOAT(n) (0x8 | (n)) static const struct hw_type { enum hw_reg_type reg_type; enum hw_imm_type imm_type; } gfx4_hw_type[] = { [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID }, [BRW_REGISTER_TYPE_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F }, [BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF }, [BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D }, [BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD }, [BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W }, [BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW }, [BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID }, [BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID }, [BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V }, }, gfx6_hw_type[] = { [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID }, [BRW_REGISTER_TYPE_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F }, [BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF }, [BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D }, [BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD }, [BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W }, [BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW }, [BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID }, [BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID }, [BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V }, [BRW_REGISTER_TYPE_UV] = { INVALID, BRW_HW_IMM_TYPE_UV }, }, gfx7_hw_type[] = { [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID }, [BRW_REGISTER_TYPE_DF] = { GFX7_HW_REG_TYPE_DF, INVALID }, [BRW_REGISTER_TYPE_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F }, [BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF }, [BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D }, [BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD }, [BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W }, [BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW }, [BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID }, [BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID }, [BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V }, [BRW_REGISTER_TYPE_UV] = { INVALID, BRW_HW_IMM_TYPE_UV }, }, gfx8_hw_type[] = { [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID }, [BRW_REGISTER_TYPE_DF] = { GFX7_HW_REG_TYPE_DF, GFX8_HW_IMM_TYPE_DF }, [BRW_REGISTER_TYPE_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F }, [BRW_REGISTER_TYPE_HF] = { GFX8_HW_REG_TYPE_HF, GFX8_HW_IMM_TYPE_HF }, [BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF }, [BRW_REGISTER_TYPE_Q] = { GFX8_HW_REG_TYPE_Q, GFX8_HW_IMM_TYPE_Q }, [BRW_REGISTER_TYPE_UQ] = { GFX8_HW_REG_TYPE_UQ, GFX8_HW_IMM_TYPE_UQ }, [BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D }, [BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD }, [BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W }, [BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW }, [BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID }, [BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID }, [BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V }, [BRW_REGISTER_TYPE_UV] = { INVALID, BRW_HW_IMM_TYPE_UV }, }, gfx11_hw_type[] = { [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID }, [BRW_REGISTER_TYPE_NF] = { GFX11_HW_REG_TYPE_NF, INVALID }, [BRW_REGISTER_TYPE_F] = { GFX11_HW_REG_TYPE_F, GFX11_HW_IMM_TYPE_F }, [BRW_REGISTER_TYPE_HF] = { GFX11_HW_REG_TYPE_HF, GFX11_HW_IMM_TYPE_HF }, [BRW_REGISTER_TYPE_VF] = { INVALID, GFX11_HW_IMM_TYPE_VF }, [BRW_REGISTER_TYPE_D] = { GFX11_HW_REG_TYPE_D, GFX11_HW_IMM_TYPE_D }, [BRW_REGISTER_TYPE_UD] = { GFX11_HW_REG_TYPE_UD, GFX11_HW_IMM_TYPE_UD }, [BRW_REGISTER_TYPE_W] = { GFX11_HW_REG_TYPE_W, GFX11_HW_IMM_TYPE_W }, [BRW_REGISTER_TYPE_UW] = { GFX11_HW_REG_TYPE_UW, GFX11_HW_IMM_TYPE_UW }, [BRW_REGISTER_TYPE_B] = { GFX11_HW_REG_TYPE_B, INVALID }, [BRW_REGISTER_TYPE_UB] = { GFX11_HW_REG_TYPE_UB, INVALID }, [BRW_REGISTER_TYPE_V] = { INVALID, GFX11_HW_IMM_TYPE_V }, [BRW_REGISTER_TYPE_UV] = { INVALID, GFX11_HW_IMM_TYPE_UV }, }, gfx12_hw_type[] = { [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID }, [BRW_REGISTER_TYPE_F] = { GFX12_HW_REG_TYPE_FLOAT(2), GFX12_HW_REG_TYPE_FLOAT(2) }, [BRW_REGISTER_TYPE_HF] = { GFX12_HW_REG_TYPE_FLOAT(1), GFX12_HW_REG_TYPE_FLOAT(1) }, [BRW_REGISTER_TYPE_VF] = { INVALID, GFX12_HW_REG_TYPE_FLOAT(0) }, [BRW_REGISTER_TYPE_D] = { GFX12_HW_REG_TYPE_SINT(2), GFX12_HW_REG_TYPE_SINT(2) }, [BRW_REGISTER_TYPE_UD] = { GFX12_HW_REG_TYPE_UINT(2), GFX12_HW_REG_TYPE_UINT(2) }, [BRW_REGISTER_TYPE_W] = { GFX12_HW_REG_TYPE_SINT(1), GFX12_HW_REG_TYPE_SINT(1) }, [BRW_REGISTER_TYPE_UW] = { GFX12_HW_REG_TYPE_UINT(1), GFX12_HW_REG_TYPE_UINT(1) }, [BRW_REGISTER_TYPE_B] = { GFX12_HW_REG_TYPE_SINT(0), INVALID }, [BRW_REGISTER_TYPE_UB] = { GFX12_HW_REG_TYPE_UINT(0), INVALID }, [BRW_REGISTER_TYPE_V] = { INVALID, GFX12_HW_REG_TYPE_SINT(0) }, [BRW_REGISTER_TYPE_UV] = { INVALID, GFX12_HW_REG_TYPE_UINT(0) }, }, gfx125_hw_type[] = { [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID }, [BRW_REGISTER_TYPE_DF] = { GFX12_HW_REG_TYPE_FLOAT(3), GFX12_HW_REG_TYPE_FLOAT(3) }, [BRW_REGISTER_TYPE_F] = { GFX12_HW_REG_TYPE_FLOAT(2), GFX12_HW_REG_TYPE_FLOAT(2) }, [BRW_REGISTER_TYPE_HF] = { GFX12_HW_REG_TYPE_FLOAT(1), GFX12_HW_REG_TYPE_FLOAT(1) }, [BRW_REGISTER_TYPE_VF] = { INVALID, GFX12_HW_REG_TYPE_FLOAT(0) }, [BRW_REGISTER_TYPE_Q] = { GFX12_HW_REG_TYPE_SINT(3), GFX12_HW_REG_TYPE_SINT(3) }, [BRW_REGISTER_TYPE_UQ] = { GFX12_HW_REG_TYPE_UINT(3), GFX12_HW_REG_TYPE_UINT(3) }, [BRW_REGISTER_TYPE_D] = { GFX12_HW_REG_TYPE_SINT(2), GFX12_HW_REG_TYPE_SINT(2) }, [BRW_REGISTER_TYPE_UD] = { GFX12_HW_REG_TYPE_UINT(2), GFX12_HW_REG_TYPE_UINT(2) }, [BRW_REGISTER_TYPE_W] = { GFX12_HW_REG_TYPE_SINT(1), GFX12_HW_REG_TYPE_SINT(1) }, [BRW_REGISTER_TYPE_UW] = { GFX12_HW_REG_TYPE_UINT(1), GFX12_HW_REG_TYPE_UINT(1) }, [BRW_REGISTER_TYPE_B] = { GFX12_HW_REG_TYPE_SINT(0), INVALID }, [BRW_REGISTER_TYPE_UB] = { GFX12_HW_REG_TYPE_UINT(0), INVALID }, [BRW_REGISTER_TYPE_V] = { INVALID, GFX12_HW_REG_TYPE_SINT(0) }, [BRW_REGISTER_TYPE_UV] = { INVALID, GFX12_HW_REG_TYPE_UINT(0) }, }; /* SNB adds 3-src instructions (MAD and LRP) that only operate on floats, so * the types were implied. IVB adds BFE and BFI2 that operate on doublewords * and unsigned doublewords, so a new field is also available in the da3src * struct (part of struct brw_instruction.bits1 in brw_structs.h) to select * dst and shared-src types. * * CNL adds support for 3-src instructions in align1 mode, and with it support * for most register types. */ enum hw_3src_reg_type { GFX7_3SRC_TYPE_F = 0, GFX7_3SRC_TYPE_D = 1, GFX7_3SRC_TYPE_UD = 2, GFX7_3SRC_TYPE_DF = 3, GFX8_3SRC_TYPE_HF = 4, /** When ExecutionDatatype is 1: @{ */ GFX10_ALIGN1_3SRC_REG_TYPE_HF = 0b000, GFX10_ALIGN1_3SRC_REG_TYPE_F = 0b001, GFX10_ALIGN1_3SRC_REG_TYPE_DF = 0b010, GFX11_ALIGN1_3SRC_REG_TYPE_NF = 0b011, /** @} */ /** When ExecutionDatatype is 0: @{ */ GFX10_ALIGN1_3SRC_REG_TYPE_UD = 0b000, GFX10_ALIGN1_3SRC_REG_TYPE_D = 0b001, GFX10_ALIGN1_3SRC_REG_TYPE_UW = 0b010, GFX10_ALIGN1_3SRC_REG_TYPE_W = 0b011, GFX10_ALIGN1_3SRC_REG_TYPE_UB = 0b100, GFX10_ALIGN1_3SRC_REG_TYPE_B = 0b101, /** @} */ }; static const struct hw_3src_type { enum hw_3src_reg_type reg_type; enum gfx10_align1_3src_exec_type exec_type; } gfx6_hw_3src_type[] = { [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID }, [BRW_REGISTER_TYPE_F] = { GFX7_3SRC_TYPE_F }, }, gfx7_hw_3src_type[] = { [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID }, [BRW_REGISTER_TYPE_F] = { GFX7_3SRC_TYPE_F }, [BRW_REGISTER_TYPE_D] = { GFX7_3SRC_TYPE_D }, [BRW_REGISTER_TYPE_UD] = { GFX7_3SRC_TYPE_UD }, [BRW_REGISTER_TYPE_DF] = { GFX7_3SRC_TYPE_DF }, }, gfx8_hw_3src_type[] = { [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID }, [BRW_REGISTER_TYPE_F] = { GFX7_3SRC_TYPE_F }, [BRW_REGISTER_TYPE_D] = { GFX7_3SRC_TYPE_D }, [BRW_REGISTER_TYPE_UD] = { GFX7_3SRC_TYPE_UD }, [BRW_REGISTER_TYPE_DF] = { GFX7_3SRC_TYPE_DF }, [BRW_REGISTER_TYPE_HF] = { GFX8_3SRC_TYPE_HF }, }, gfx10_hw_3src_align1_type[] = { #define E(x) BRW_ALIGN1_3SRC_EXEC_TYPE_##x [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID }, [BRW_REGISTER_TYPE_DF] = { GFX10_ALIGN1_3SRC_REG_TYPE_DF, E(FLOAT) }, [BRW_REGISTER_TYPE_F] = { GFX10_ALIGN1_3SRC_REG_TYPE_F, E(FLOAT) }, [BRW_REGISTER_TYPE_HF] = { GFX10_ALIGN1_3SRC_REG_TYPE_HF, E(FLOAT) }, [BRW_REGISTER_TYPE_D] = { GFX10_ALIGN1_3SRC_REG_TYPE_D, E(INT) }, [BRW_REGISTER_TYPE_UD] = { GFX10_ALIGN1_3SRC_REG_TYPE_UD, E(INT) }, [BRW_REGISTER_TYPE_W] = { GFX10_ALIGN1_3SRC_REG_TYPE_W, E(INT) }, [BRW_REGISTER_TYPE_UW] = { GFX10_ALIGN1_3SRC_REG_TYPE_UW, E(INT) }, [BRW_REGISTER_TYPE_B] = { GFX10_ALIGN1_3SRC_REG_TYPE_B, E(INT) }, [BRW_REGISTER_TYPE_UB] = { GFX10_ALIGN1_3SRC_REG_TYPE_UB, E(INT) }, }, gfx11_hw_3src_type[] = { [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID }, [BRW_REGISTER_TYPE_NF] = { GFX11_ALIGN1_3SRC_REG_TYPE_NF, E(FLOAT) }, [BRW_REGISTER_TYPE_F] = { GFX10_ALIGN1_3SRC_REG_TYPE_F, E(FLOAT) }, [BRW_REGISTER_TYPE_HF] = { GFX10_ALIGN1_3SRC_REG_TYPE_HF, E(FLOAT) }, [BRW_REGISTER_TYPE_D] = { GFX10_ALIGN1_3SRC_REG_TYPE_D, E(INT) }, [BRW_REGISTER_TYPE_UD] = { GFX10_ALIGN1_3SRC_REG_TYPE_UD, E(INT) }, [BRW_REGISTER_TYPE_W] = { GFX10_ALIGN1_3SRC_REG_TYPE_W, E(INT) }, [BRW_REGISTER_TYPE_UW] = { GFX10_ALIGN1_3SRC_REG_TYPE_UW, E(INT) }, [BRW_REGISTER_TYPE_B] = { GFX10_ALIGN1_3SRC_REG_TYPE_B, E(INT) }, [BRW_REGISTER_TYPE_UB] = { GFX10_ALIGN1_3SRC_REG_TYPE_UB, E(INT) }, }, gfx12_hw_3src_type[] = { [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID }, [BRW_REGISTER_TYPE_F] = { GFX12_HW_REG_TYPE_UINT(2), E(FLOAT), }, [BRW_REGISTER_TYPE_HF] = { GFX12_HW_REG_TYPE_UINT(1), E(FLOAT), }, [BRW_REGISTER_TYPE_D] = { GFX12_HW_REG_TYPE_SINT(2), E(INT), }, [BRW_REGISTER_TYPE_UD] = { GFX12_HW_REG_TYPE_UINT(2), E(INT), }, [BRW_REGISTER_TYPE_W] = { GFX12_HW_REG_TYPE_SINT(1), E(INT), }, [BRW_REGISTER_TYPE_UW] = { GFX12_HW_REG_TYPE_UINT(1), E(INT), }, [BRW_REGISTER_TYPE_B] = { GFX12_HW_REG_TYPE_SINT(0), E(INT), }, [BRW_REGISTER_TYPE_UB] = { GFX12_HW_REG_TYPE_UINT(0), E(INT), }, }, gfx125_hw_3src_type[] = { [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID }, [BRW_REGISTER_TYPE_DF] = { GFX12_HW_REG_TYPE_UINT(3), E(FLOAT), }, [BRW_REGISTER_TYPE_F] = { GFX12_HW_REG_TYPE_UINT(2), E(FLOAT), }, [BRW_REGISTER_TYPE_HF] = { GFX12_HW_REG_TYPE_UINT(1), E(FLOAT), }, [BRW_REGISTER_TYPE_Q] = { GFX12_HW_REG_TYPE_SINT(3), E(INT), }, [BRW_REGISTER_TYPE_UQ] = { GFX12_HW_REG_TYPE_UINT(3), E(INT), }, [BRW_REGISTER_TYPE_D] = { GFX12_HW_REG_TYPE_SINT(2), E(INT), }, [BRW_REGISTER_TYPE_UD] = { GFX12_HW_REG_TYPE_UINT(2), E(INT), }, [BRW_REGISTER_TYPE_W] = { GFX12_HW_REG_TYPE_SINT(1), E(INT), }, [BRW_REGISTER_TYPE_UW] = { GFX12_HW_REG_TYPE_UINT(1), E(INT), }, [BRW_REGISTER_TYPE_B] = { GFX12_HW_REG_TYPE_SINT(0), E(INT), }, [BRW_REGISTER_TYPE_UB] = { GFX12_HW_REG_TYPE_UINT(0), E(INT), }, #undef E }; /** * Convert a brw_reg_type enumeration value into the hardware representation. * * The hardware encoding may depend on whether the value is an immediate. */ unsigned brw_reg_type_to_hw_type(const struct intel_device_info *devinfo, enum brw_reg_file file, enum brw_reg_type type) { const struct hw_type *table; if (devinfo->verx10 >= 125) { assert(type < ARRAY_SIZE(gfx125_hw_type)); table = gfx125_hw_type; } else if (devinfo->ver >= 12) { assert(type < ARRAY_SIZE(gfx12_hw_type)); table = gfx12_hw_type; } else if (devinfo->ver >= 11) { assert(type < ARRAY_SIZE(gfx11_hw_type)); table = gfx11_hw_type; } else if (devinfo->ver >= 8) { assert(type < ARRAY_SIZE(gfx8_hw_type)); table = gfx8_hw_type; } else if (devinfo->ver >= 7) { assert(type < ARRAY_SIZE(gfx7_hw_type)); table = gfx7_hw_type; } else if (devinfo->ver >= 6) { assert(type < ARRAY_SIZE(gfx6_hw_type)); table = gfx6_hw_type; } else { assert(type < ARRAY_SIZE(gfx4_hw_type)); table = gfx4_hw_type; } if (file == BRW_IMMEDIATE_VALUE) { assert(table[type].imm_type != (enum hw_imm_type)INVALID); return table[type].imm_type; } else { assert(table[type].reg_type != (enum hw_reg_type)INVALID); return table[type].reg_type; } } /** * Convert the hardware representation into a brw_reg_type enumeration value. * * The hardware encoding may depend on whether the value is an immediate. */ enum brw_reg_type brw_hw_type_to_reg_type(const struct intel_device_info *devinfo, enum brw_reg_file file, unsigned hw_type) { const struct hw_type *table; if (devinfo->verx10 >= 125) { table = gfx125_hw_type; } else if (devinfo->ver >= 12) { table = gfx12_hw_type; } else if (devinfo->ver >= 11) { table = gfx11_hw_type; } else if (devinfo->ver >= 8) { table = gfx8_hw_type; } else if (devinfo->ver >= 7) { table = gfx7_hw_type; } else if (devinfo->ver >= 6) { table = gfx6_hw_type; } else { table = gfx4_hw_type; } if (file == BRW_IMMEDIATE_VALUE) { for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) { if (table[i].imm_type == (enum hw_imm_type)hw_type) { return i; } } } else { for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) { if (table[i].reg_type == (enum hw_reg_type)hw_type) { return i; } } } return INVALID_REG_TYPE; } /** * Convert a brw_reg_type enumeration value into the hardware representation * for a 3-src align16 instruction */ unsigned brw_reg_type_to_a16_hw_3src_type(const struct intel_device_info *devinfo, enum brw_reg_type type) { const struct hw_3src_type *table; if (devinfo->ver >= 8) { assert(type < ARRAY_SIZE(gfx8_hw_3src_type)); table = gfx8_hw_3src_type; } else if (devinfo->ver >= 7) { assert(type < ARRAY_SIZE(gfx7_hw_3src_type)); table = gfx7_hw_3src_type; } else { assert(type < ARRAY_SIZE(gfx6_hw_3src_type)); table = gfx6_hw_3src_type; } assert(table[type].reg_type != (enum hw_3src_reg_type)INVALID); return table[type].reg_type; } /** * Convert a brw_reg_type enumeration value into the hardware representation * for a 3-src align1 instruction */ unsigned brw_reg_type_to_a1_hw_3src_type(const struct intel_device_info *devinfo, enum brw_reg_type type) { if (devinfo->verx10 >= 125) { assert(type < ARRAY_SIZE(gfx125_hw_3src_type)); return gfx125_hw_3src_type[type].reg_type; } else if (devinfo->ver >= 12) { assert(type < ARRAY_SIZE(gfx12_hw_3src_type)); return gfx12_hw_3src_type[type].reg_type; } else if (devinfo->ver >= 11) { assert(type < ARRAY_SIZE(gfx11_hw_3src_type)); return gfx11_hw_3src_type[type].reg_type; } else { assert(type < ARRAY_SIZE(gfx10_hw_3src_align1_type)); return gfx10_hw_3src_align1_type[type].reg_type; } } /** * Convert the hardware representation for a 3-src align16 instruction into a * brw_reg_type enumeration value. */ enum brw_reg_type brw_a16_hw_3src_type_to_reg_type(const struct intel_device_info *devinfo, unsigned hw_type) { const struct hw_3src_type *table = NULL; if (devinfo->ver >= 8) { table = gfx8_hw_3src_type; } else if (devinfo->ver >= 7) { table = gfx7_hw_3src_type; } else if (devinfo->ver >= 6) { table = gfx6_hw_3src_type; } for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) { if (table[i].reg_type == hw_type) { return i; } } return INVALID_REG_TYPE; } /** * Convert the hardware representation for a 3-src align1 instruction into a * brw_reg_type enumeration value. */ enum brw_reg_type brw_a1_hw_3src_type_to_reg_type(const struct intel_device_info *devinfo, unsigned hw_type, unsigned exec_type) { const struct hw_3src_type *table = (devinfo->verx10 >= 125 ? gfx125_hw_3src_type : devinfo->ver >= 12 ? gfx12_hw_3src_type : devinfo->ver >= 11 ? gfx11_hw_3src_type : gfx10_hw_3src_align1_type); for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) { if (table[i].reg_type == hw_type && table[i].exec_type == exec_type) { return i; } } return INVALID_REG_TYPE; } /** * Return the element size given a register type. */ unsigned brw_reg_type_to_size(enum brw_reg_type type) { static const unsigned type_size[] = { [BRW_REGISTER_TYPE_NF] = 8, [BRW_REGISTER_TYPE_DF] = 8, [BRW_REGISTER_TYPE_F] = 4, [BRW_REGISTER_TYPE_HF] = 2, [BRW_REGISTER_TYPE_VF] = 4, [BRW_REGISTER_TYPE_Q] = 8, [BRW_REGISTER_TYPE_UQ] = 8, [BRW_REGISTER_TYPE_D] = 4, [BRW_REGISTER_TYPE_UD] = 4, [BRW_REGISTER_TYPE_W] = 2, [BRW_REGISTER_TYPE_UW] = 2, [BRW_REGISTER_TYPE_B] = 1, [BRW_REGISTER_TYPE_UB] = 1, [BRW_REGISTER_TYPE_V] = 2, [BRW_REGISTER_TYPE_UV] = 2, }; if (type >= ARRAY_SIZE(type_size)) return -1; return type_size[type]; } /** * Converts a BRW_REGISTER_TYPE_* enum to a short string (F, UD, and so on). * * This is different than reg_encoding from brw_disasm.c in that it operates * on the abstract enum values, rather than the generation-specific encoding. */ const char * brw_reg_type_to_letters(enum brw_reg_type type) { static const char letters[][3] = { [BRW_REGISTER_TYPE_NF] = "NF", [BRW_REGISTER_TYPE_DF] = "DF", [BRW_REGISTER_TYPE_F] = "F", [BRW_REGISTER_TYPE_HF] = "HF", [BRW_REGISTER_TYPE_VF] = "VF", [BRW_REGISTER_TYPE_Q] = "Q", [BRW_REGISTER_TYPE_UQ] = "UQ", [BRW_REGISTER_TYPE_D] = "D", [BRW_REGISTER_TYPE_UD] = "UD", [BRW_REGISTER_TYPE_W] = "W", [BRW_REGISTER_TYPE_UW] = "UW", [BRW_REGISTER_TYPE_B] = "B", [BRW_REGISTER_TYPE_UB] = "UB", [BRW_REGISTER_TYPE_V] = "V", [BRW_REGISTER_TYPE_UV] = "UV", }; if (type >= ARRAY_SIZE(letters)) return "INVALID"; assert(type < ARRAY_SIZE(letters)); return letters[type]; }