| /* |
| * 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]; |
| } |