| /* |
| * Copyright © 2022 Imagination Technologies Ltd. |
| * |
| * 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 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. |
| */ |
| |
| #ifndef ROGUE_ISA_H |
| #define ROGUE_ISA_H |
| |
| /** |
| * \file rogue_isa.h |
| * |
| * \brief Contains hardware ISA definitions and encodings. |
| */ |
| |
| /* Source/destination encodings. */ |
| |
| /* Internal source selector. */ |
| typedef struct rogue_iss_encoding { |
| unsigned is1 : 1; |
| unsigned is2 : 1; |
| unsigned is3 : 2; |
| unsigned is4 : 2; |
| unsigned is5 : 2; |
| } PACKED rogue_iss_encoding; |
| static_assert(sizeof(rogue_iss_encoding) == 1, |
| "sizeof(rogue_iss_encoding) != 1"); |
| |
| typedef struct rogue_dbN { |
| union { |
| struct { |
| unsigned _0 : 1; |
| unsigned _2_1 : 2; |
| unsigned : 5; |
| } PACKED; |
| |
| uint8_t _; |
| } PACKED; |
| } PACKED rogue_dbN; |
| static_assert(sizeof(rogue_dbN) == 1, "sizeof(rogue_dbN) != 1"); |
| |
| typedef struct rogue_dN { |
| union { |
| struct { |
| unsigned _5_0 : 6; |
| unsigned _7_6 : 2; |
| unsigned _10_8 : 3; |
| unsigned : 5; |
| } PACKED; |
| |
| uint8_t _; |
| } PACKED; |
| } PACKED rogue_dN; |
| static_assert(sizeof(rogue_dN) == 2, "sizeof(rogue_dN) != 2"); |
| |
| typedef struct rogue_db0 { |
| union { |
| struct { |
| unsigned _0 : 1; |
| unsigned _2_1 : 2; |
| unsigned : 5; |
| } PACKED; |
| |
| uint8_t _; |
| } PACKED; |
| } PACKED rogue_db0; |
| static_assert(sizeof(rogue_db0) == 1, "sizeof(rogue_db0) != 1"); |
| |
| typedef struct rogue_db1 { |
| union { |
| struct { |
| unsigned _0 : 1; |
| unsigned _2_1 : 2; |
| unsigned : 5; |
| } PACKED; |
| |
| uint8_t _; |
| } PACKED; |
| } PACKED rogue_db1; |
| static_assert(sizeof(rogue_db0) == 1, "sizeof(rogue_db0) != 1"); |
| |
| typedef struct rogue_d0 { |
| union { |
| struct { |
| unsigned _6_0 : 7; |
| unsigned _7 : 1; |
| unsigned _10_8 : 3; |
| unsigned : 5; |
| } PACKED; |
| |
| uint16_t _; |
| } PACKED; |
| } PACKED rogue_d0; |
| static_assert(sizeof(rogue_d0) == 2, "sizeof(rogue_d0) != 2"); |
| |
| typedef struct rogue_d1 { |
| union { |
| struct { |
| unsigned _5_0 : 6; |
| unsigned _7_6 : 2; |
| unsigned _10_8 : 3; |
| unsigned : 5; |
| } PACKED; |
| |
| uint16_t _; |
| } PACKED; |
| } PACKED rogue_d1; |
| static_assert(sizeof(rogue_d1) == 2, "sizeof(rogue_d1) != 2"); |
| |
| typedef struct rogue_dest_map_encoding { |
| /* Byte 0 */ |
| union { |
| struct { |
| unsigned dN_5_0 : 6; |
| unsigned dbN_0 : 1; |
| unsigned ext0 : 1; |
| } PACKED; |
| |
| struct { |
| unsigned d0_6_0 : 7; |
| unsigned db0_0 : 1; |
| } PACKED; |
| }; |
| |
| /* Byte 1 */ |
| union { |
| struct { |
| unsigned dN_7_6 : 2; |
| unsigned dbN_2_1 : 2; |
| unsigned dN_10_8 : 3; |
| unsigned rsvd1 : 1; |
| } PACKED; |
| |
| struct { |
| unsigned d1_5_0 : 6; |
| unsigned db1_0 : 1; |
| unsigned ext1 : 1; |
| } PACKED; |
| }; |
| |
| /* Byte 2 */ |
| struct { |
| unsigned d0_7 : 1; |
| unsigned db0_2_1 : 2; |
| unsigned d1_7_6 : 2; |
| unsigned db1_2_1 : 2; |
| unsigned ext2 : 1; |
| } PACKED; |
| |
| /* Byte 3 */ |
| struct { |
| unsigned d0_10_8 : 3; |
| unsigned d1_10_8 : 3; |
| unsigned rsvd3 : 2; |
| } PACKED; |
| } PACKED rogue_dest_map_encoding; |
| static_assert(sizeof(rogue_dest_map_encoding) == 4, |
| "sizeof(rogue_dest_map_encoding) != 4"); |
| |
| /****************/ |
| |
| typedef struct rogue_source_map_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned sA_5_0 : 6; |
| unsigned sbA_0 : 1; |
| unsigned ext0 : 1; |
| } PACKED; |
| |
| /* Byte 1 */ |
| union { |
| struct { |
| unsigned sA_7_6 : 2; |
| unsigned sbA_2_1 : 2; |
| unsigned mux_1_0 : 2; |
| unsigned : 2; |
| } PACKED sA_1; |
| |
| struct { |
| unsigned sB_4_0 : 5; |
| unsigned sbB_0 : 1; |
| unsigned ext1 : 1; |
| unsigned sel : 1; |
| } PACKED; |
| } PACKED; |
| |
| /* Byte 2 */ |
| union { |
| /* Common def. */ |
| struct sA_sC_10_8 { |
| unsigned sA_10_8 : 3; |
| unsigned sC_10_8 : 3; |
| unsigned rsvd5 : 2; |
| } PACKED sA_2; |
| |
| struct { |
| unsigned sB_6_5 : 2; |
| unsigned sA_6 : 1; |
| unsigned sbB_1 : 1; |
| unsigned sbA_1 : 1; |
| unsigned mux_1_0 : 2; |
| unsigned ext2 : 1; |
| } PACKED; |
| |
| struct { |
| unsigned : 3; |
| unsigned rsvd2 : 5; |
| } PACKED; |
| } PACKED; |
| |
| /* Byte 3 */ |
| union { |
| /* Common def. */ |
| struct sB_sC_mux2 { |
| union { |
| struct { |
| unsigned sB_7 : 1; |
| unsigned sA_7 : 1; |
| unsigned rsvd3 : 1; |
| unsigned sbA_2 : 1; |
| unsigned mux_2 : 1; |
| unsigned sA_10_8 : 3; |
| } PACKED; |
| |
| struct { |
| unsigned : 2; |
| unsigned ext4 : 1; |
| unsigned : 2; |
| unsigned sC_7_6 : 2; |
| unsigned sbC_2 : 1; |
| } PACKED; |
| } PACKED; |
| } PACKED sB_3; |
| |
| struct { |
| unsigned sC_5_0 : 6; |
| unsigned sbC_1_0 : 2; |
| } PACKED; |
| } PACKED; |
| |
| /* Byte 4 */ |
| struct sB_sC_mux2 sC_4; |
| |
| /* Byte 5 */ |
| struct sA_sC_10_8 sC_5; |
| } PACKED rogue_source_map_encoding; |
| static_assert(sizeof(rogue_source_map_encoding) == 6, |
| "sizeof(rogue_source_map_encoding) == 6"); |
| |
| typedef struct rogue_sbA { |
| union { |
| struct { |
| unsigned _0 : 1; |
| unsigned _2_1 : 2; |
| unsigned : 5; |
| } PACKED; |
| |
| struct { |
| unsigned : 1; |
| unsigned _1 : 1; |
| unsigned _2 : 1; |
| unsigned : 5; |
| } PACKED; |
| |
| uint8_t _; |
| } PACKED; |
| } PACKED rogue_sbA; |
| static_assert(sizeof(rogue_sbA) == 1, "sizeof(rogue_sbA) != 1"); |
| |
| typedef struct rogue_sA { |
| union { |
| struct { |
| unsigned _5_0 : 6; |
| unsigned _7_6 : 2; |
| unsigned _10_8 : 3; |
| unsigned : 5; |
| } PACKED; |
| |
| struct { |
| unsigned : 6; |
| unsigned _6 : 1; |
| unsigned _7 : 1; |
| unsigned : 8; |
| } PACKED; |
| |
| uint16_t _; |
| } PACKED; |
| } PACKED rogue_sA; |
| static_assert(sizeof(rogue_sA) == 2, "sizeof(rogue_sA) != 2"); |
| |
| typedef struct rogue_sbB { |
| union { |
| struct { |
| unsigned _0 : 1; |
| unsigned _1 : 1; |
| unsigned : 6; |
| } PACKED; |
| |
| uint8_t _; |
| } PACKED; |
| } PACKED rogue_sbB; |
| static_assert(sizeof(rogue_sbB) == 1, "sizeof(rogue_sbB) != 1"); |
| |
| typedef struct rogue_sB { |
| union { |
| struct { |
| unsigned _4_0 : 5; |
| unsigned _6_5 : 2; |
| unsigned _7 : 1; |
| unsigned : 8; |
| } PACKED; |
| |
| uint16_t _; |
| } PACKED; |
| } PACKED rogue_sB; |
| static_assert(sizeof(rogue_sB) == 2, "sizeof(rogue_sB) != 2"); |
| |
| typedef struct rogue_sbC { |
| union { |
| struct { |
| unsigned _1_0 : 2; |
| unsigned _2 : 1; |
| unsigned : 5; |
| } PACKED; |
| |
| uint8_t _; |
| } PACKED; |
| } PACKED rogue_sbC; |
| static_assert(sizeof(rogue_sbC) == 1, "sizeof(rogue_sbC) != 1"); |
| |
| typedef struct rogue_sC { |
| union { |
| struct { |
| unsigned _5_0 : 6; |
| unsigned _7_6 : 2; |
| unsigned _10_8 : 3; |
| unsigned : 5; |
| } PACKED; |
| |
| uint16_t _; |
| } PACKED; |
| } PACKED rogue_sC; |
| static_assert(sizeof(rogue_sC) == 2, "sizeof(rogue_sC) != 2"); |
| |
| typedef struct rogue_mux { |
| union { |
| struct { |
| unsigned _1_0 : 2; |
| unsigned _2 : 1; |
| unsigned : 5; |
| } PACKED; |
| |
| uint8_t _; |
| } PACKED; |
| } PACKED rogue_mux; |
| static_assert(sizeof(rogue_mux) == 1, "sizeof(rogue_mux) != 1"); |
| |
| typedef struct rogue_idx_offset { |
| union { |
| struct { |
| unsigned bank : 3; |
| unsigned offset : 8; |
| unsigned : 5; |
| } PACKED; |
| |
| uint16_t _; |
| } PACKED; |
| } PACKED rogue_idx_offset; |
| static_assert(sizeof(rogue_idx_offset) == 2, "sizeof(rogue_idx_offset) != 2"); |
| |
| typedef struct rogue_idx_dim_offset { |
| union { |
| struct { |
| unsigned bank : 3; |
| unsigned dim_offset : 5; |
| unsigned : 8; |
| } PACKED; |
| |
| uint16_t _; |
| } PACKED; |
| } PACKED rogue_idx_dim_offset; |
| static_assert(sizeof(rogue_idx_dim_offset) == 2, |
| "sizeof(rogue_idx_dim_offset) != 2"); |
| |
| enum reg_bank { |
| BANK_SPECIAL = 0b000, |
| BANK_TEMP = 0b001, |
| BANK_VTXIN = 0b010, |
| BANK_COEFF = 0b011, |
| BANK_SHARED = 0b100, |
| BANK_COEFF_ALT = 0b101, |
| BANK_IDX0 = 0b110, |
| BANK_IDX1 = 0b111, |
| }; |
| |
| enum idx_bank { |
| IDX_BANK_TEMP = 0b000, |
| IDX_BANK_VTXIN = 0b001, |
| IDX_BANK_COEFF = 0b010, |
| IDX_BANK_SHARED = 0b011, |
| IDX_BANK_DC = 0b100, |
| IDX_BANK_IDX = 0b101, |
| IDX_BANK_COEFF_ALT = 0b110, |
| IDX_BANK_PIXOUT = 0b111, |
| }; |
| |
| enum is0 { |
| IS0_S0 = 0b000, |
| IS0_S3 = 0b001, |
| IS0_S4 = 0b010, |
| IS0_S5 = 0b011, |
| IS0_S1 = 0b100, |
| IS0_S2 = 0b101, |
| }; |
| |
| enum is1 { |
| IS1_FT0 = 0b0, |
| IS1_FTE = 0b1, |
| }; |
| |
| enum is2 { |
| IS2_FT1 = 0b0, |
| IS2_FTE = 0b1, |
| }; |
| |
| enum is3 { |
| IS3_FT0 = 0b00, |
| IS3_FT1 = 0b01, |
| IS3_S2 = 0b10, |
| IS3_FTE = 0b11, |
| }; |
| |
| enum is4 { |
| IS4_FT0 = 0b00, |
| IS4_FT1 = 0b01, |
| IS4_FT2 = 0b10, |
| IS4_FTE = 0b11, |
| }; |
| |
| enum is5 { |
| IS5_FT0 = 0b00, |
| IS5_FT1 = 0b01, |
| IS5_FT2 = 0b10, |
| IS5_FTE = 0b11, |
| }; |
| |
| /* Single source instructions. */ |
| |
| typedef struct rogue_single_pck_encoding { |
| /* Byte 1 */ |
| union { |
| struct { |
| union { |
| struct { |
| unsigned format : 5; |
| unsigned scale : 1; |
| unsigned elem : 2; |
| } PACKED; |
| |
| struct { |
| unsigned : 5; |
| unsigned rtz : 1; |
| unsigned : 2; |
| } PACKED; |
| } PACKED; |
| } PACKED upck; |
| |
| struct { |
| unsigned format : 5; |
| unsigned scale : 1; |
| unsigned rtz : 1; |
| unsigned prog : 1; |
| } PACKED pck; |
| } PACKED; |
| } PACKED rogue_single_pck_encoding; |
| static_assert(sizeof(rogue_single_pck_encoding) == 1, |
| "sizeof(rogue_single_pck_encoding) != 1"); |
| |
| enum pck_fmt { |
| PCK_FMT_U8888 = 0b00000, |
| PCK_FMT_S8888 = 0b00001, |
| PCK_FMT_O8888 = 0b00010, |
| PCK_FMT_U1616 = 0b00011, |
| PCK_FMT_S1616 = 0b00100, |
| PCK_FMT_O1616 = 0b00101, |
| PCK_FMT_U32 = 0b00110, |
| PCK_FMT_S32 = 0b00111, |
| PCK_FMT_U1010102 = 0b01000, |
| PCK_FMT_S1010102 = 0b01001, |
| PCK_FMT_U111110 = 0b01010, |
| PCK_FMT_S111110 = 0b01011, |
| PCK_FMT_F111110 = 0b01100, |
| PCK_FMT_F16F16 = 0b01110, |
| PCK_FMT_F32 = 0b01111, |
| PCK_FMT_COV = 0b10000, |
| PCK_FMT_U565U565 = 0b10001, |
| PCK_FMT_D24S8 = 0b10010, |
| PCK_FMT_S8D24 = 0b10011, |
| PCK_FMT_F32_MASK = 0b10100, |
| PCK_FMT_2F10F10F10 = 0b10101, |
| PCK_FMT_S8888OGL = 0b10110, |
| PCK_FMT_S1616OGL = 0b10111, |
| PCK_FMT_ZERO = 0b11110, |
| PCK_FMT_ONE = 0b11111, |
| }; |
| |
| typedef struct rogue_single_mbyp_encoding { |
| /* Byte 1 */ |
| struct { |
| unsigned s0abs : 1; |
| unsigned s0neg : 1; |
| unsigned : 6; |
| } PACKED; |
| } PACKED rogue_single_mbyp_encoding; |
| static_assert(sizeof(rogue_single_mbyp_encoding) == 1, |
| "sizeof(rogue_single_mbyp_encoding) != 1"); |
| |
| enum snglop { |
| SNGLOP_RCP = 0b0000, |
| SNGLOP_RSQ = 0b0001, |
| SNGLOP_LOG = 0b0010, |
| SNGLOP_EXP = 0b0011, |
| SNGLOP_F16SOP = 0b0100, |
| SNGLOP_LOGCN = 0b0101, |
| SNGLOP_GAMMA = 0b0110, |
| SNGLOP_BYP = 0b0111, |
| SNGLOP_DSX = 0b1000, |
| SNGLOP_DSY = 0b1001, |
| SNGLOP_DSXF = 0b1010, |
| SNGLOP_DSYF = 0b1011, |
| SNGLOP_PCK = 0b1100, |
| SNGLOP_RED = 0b1101, |
| SNGLOP_SINC = 0b1110, |
| SNGLOP_ARCTANC = 0b1111, |
| }; |
| |
| typedef struct rogue_alu_single_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned snglop : 4; |
| unsigned ext0 : 1; |
| unsigned : 3; |
| } PACKED; |
| |
| /* Byte 1+ */ |
| union { |
| rogue_single_mbyp_encoding mbyp; |
| rogue_single_pck_encoding pck; |
| } PACKED; |
| } PACKED rogue_alu_single_encoding; |
| static_assert(sizeof(rogue_alu_single_encoding) == 2, |
| "sizeof(rogue_alu_single_encoding) != 2"); |
| |
| typedef struct rogue_alu_fmad_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned sat : 1; |
| unsigned s2neg : 1; |
| unsigned s0abs : 1; |
| unsigned s0neg : 1; |
| unsigned ext : 1; |
| unsigned : 3; |
| } PACKED; |
| |
| /* Byte 1 */ |
| struct { |
| unsigned s2abs : 1; |
| unsigned s2flr : 1; |
| unsigned s1neg : 1; |
| unsigned s1abs : 1; |
| unsigned lp : 1; |
| unsigned : 3; |
| } PACKED; |
| } PACKED rogue_alu_fmad_encoding; |
| static_assert(sizeof(rogue_alu_fmad_encoding) == 2, |
| "sizeof(rogue_alu_fmad_encoding) != 2"); |
| |
| typedef struct rogue_alu_fdual_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned s0flr : 1; |
| unsigned s1abs : 1; |
| unsigned s0abs : 1; |
| unsigned s0neg : 1; |
| unsigned sat : 1; |
| unsigned lp : 1; |
| unsigned : 2; |
| } PACKED; |
| } PACKED rogue_alu_fdual_encoding; |
| static_assert(sizeof(rogue_alu_fdual_encoding) == 1, |
| "sizeof(rogue_alu_fdual_encoding) != 1"); |
| |
| typedef struct rogue_alu_tst_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned pwen : 1; |
| unsigned tstop_2_0 : 3; |
| unsigned ext : 1; |
| unsigned : 3; |
| } PACKED; |
| |
| /* Byte 1 */ |
| struct { |
| unsigned tstop_3 : 1; |
| unsigned : 1; |
| unsigned elem : 2; |
| unsigned p2end : 1; |
| unsigned type : 3; |
| } PACKED; |
| } PACKED rogue_alu_tst_encoding; |
| static_assert(sizeof(rogue_alu_tst_encoding) == 2, |
| "sizeof(rogue_alu_tst_encoding) != 2"); |
| |
| typedef struct rogue_tstop { |
| union { |
| struct { |
| unsigned _2_0 : 3; |
| unsigned _3 : 1; |
| unsigned : 4; |
| } PACKED; |
| |
| uint8_t _; |
| } PACKED; |
| } PACKED rogue_tstop; |
| static_assert(sizeof(rogue_tstop) == 1, "sizeof(rogue_tstop) != 1"); |
| |
| enum tstop { |
| TSTOP_Z = 0b0000, |
| TSTOP_GZ = 0b0001, |
| TSTOP_GEZ = 0b0010, |
| TSTOP_C = 0b0011, |
| TSTOP_E = 0b0100, |
| TSTOP_G = 0b0101, |
| TSTOP_GE = 0b0110, |
| TSTOP_NE = 0b0111, |
| TSTOP_L = 0b1000, |
| TSTOP_LE = 0b1001, |
| }; |
| |
| enum tsttype { |
| TSTTYPE_F32 = 0b000, |
| TSTTYPE_U16 = 0b001, |
| TSTTYPE_S16 = 0b010, |
| TSTTYPE_U8 = 0b011, |
| TSTTYPE_S8 = 0b100, |
| TSTTYPE_U32 = 0b101, |
| TSTTYPE_S32 = 0b110, |
| }; |
| |
| enum tstelem { |
| TST_E0 = 0b00, |
| TST_E1 = 0b01, |
| TST_E2 = 0b10, |
| TST_E3 = 0b11, |
| }; |
| |
| typedef struct rogue_alu_movc_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned movw0 : 2; |
| unsigned movw1 : 2; |
| unsigned ext : 1; |
| unsigned : 3; |
| } PACKED; |
| |
| /* Byte 1 */ |
| struct { |
| unsigned p2end : 1; |
| unsigned aw : 1; |
| unsigned maskw0 : 4; |
| unsigned : 2; |
| } PACKED; |
| } PACKED rogue_alu_movc_encoding; |
| static_assert(sizeof(rogue_alu_movc_encoding) == 2, |
| "sizeof(rogue_alu_movc_encoding) != 2"); |
| |
| enum movw { |
| MOVW_FT0 = 0b00, |
| MOVW_FT1 = 0b01, |
| MOVW_FT2 = 0b10, |
| MOVW_FTE = 0b11, |
| }; |
| |
| enum maskw0 { |
| MASKW0_E0 = 0b0001, |
| MASKW0_E1 = 0b0010, |
| MASKW0_E2 = 0b0100, |
| MASKW0_E3 = 0b1000, |
| MASKW0_EALL = 0b1111, |
| }; |
| |
| typedef struct rogue_alu_int32_64_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned int32_64_op : 2; |
| unsigned s2neg : 1; |
| unsigned s : 1; |
| unsigned ext : 1; |
| unsigned : 3; |
| } PACKED; |
| |
| /* Byte 1 */ |
| struct { |
| unsigned s2abs : 1; |
| unsigned s1abs : 1; |
| unsigned s0abs : 1; |
| unsigned : 1; |
| unsigned s0neg : 1; |
| unsigned s1neg : 1; |
| unsigned cin : 1; |
| unsigned : 1; |
| } PACKED; |
| } PACKED rogue_alu_int32_64_encoding; |
| static_assert(sizeof(rogue_alu_int32_64_encoding) == 2, |
| "sizeof(rogue_alu_int32_64_encoding) != 2"); |
| |
| enum int32_64_op { |
| INT32_64_OP_ADD6432 = 0b00, |
| /* No multiply or extension, only valid when s=0. */ |
| INT32_64_OP_ADD64_NMX = 0b01, |
| INT32_64_OP_MADD32 = 0b10, |
| INT32_64_OP_MADD64 = 0b11, |
| }; |
| typedef struct rogue_alu_instr_encoding { |
| union { |
| /* Byte 0 */ |
| struct { |
| unsigned : 5; |
| unsigned op : 3; |
| } PACKED; |
| |
| /* Bytes 1+ */ |
| rogue_alu_single_encoding sngl; |
| rogue_alu_fdual_encoding fadd; |
| rogue_alu_fdual_encoding fmul; |
| rogue_alu_fmad_encoding fmad; |
| rogue_alu_tst_encoding tst; |
| rogue_alu_movc_encoding movc; |
| rogue_alu_int32_64_encoding int32_64; |
| } PACKED; |
| } PACKED rogue_alu_instr_encoding; |
| static_assert(sizeof(rogue_alu_instr_encoding) == 2, |
| "sizeof(rogue_alu_instr_encoding) != 2"); |
| |
| enum aluop { |
| ALUOP_FADD = 0b000, /** Phase 0, 1. */ |
| ALUOP_FMUL = 0b010, /** Phase 0, 1. */ |
| ALUOP_SNGL = 0b100, /** Phase 0, 1, 2. */ |
| ALUOP_INT8_16 = 0b101, /** Phase 0. */ |
| ALUOP_FMAD = 0b110, /** Phase 0, 1. */ |
| ALUOP_MOVC = 0b110, /** Phase 2. */ |
| ALUOP_INT32_64 = 0b111, /** Phase 0. */ |
| ALUOP_TST = 0b111, /** Phase 2. */ |
| }; |
| |
| /* Backend instructions. */ |
| |
| typedef struct rogue_backend_emitpix_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned : 1; |
| unsigned freep : 1; |
| unsigned : 6; |
| } PACKED; |
| } PACKED rogue_backend_emitpix_encoding; |
| static_assert(sizeof(rogue_backend_emitpix_encoding) == 1, |
| "sizeof(rogue_backend_emitpix_encoding) != 1"); |
| |
| typedef struct rogue_backend_fitr_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned mode : 2; |
| unsigned : 1; |
| unsigned drc : 1; |
| unsigned p : 1; |
| unsigned : 3; |
| } PACKED; |
| |
| /* Byte 1 */ |
| struct { |
| unsigned count : 4; |
| unsigned sat : 1; |
| unsigned : 3; |
| } PACKED; |
| } PACKED rogue_backend_fitr_encoding; |
| static_assert(sizeof(rogue_backend_fitr_encoding) == 2, |
| "sizeof(rogue_backend_fitr_encoding) != 2"); |
| |
| enum fitr_mode { |
| FITR_MODE_PIXEL = 0b00, |
| FITR_MODE_SAMPLE = 0b01, |
| FITR_MODE_CENTROID = 0b10, |
| }; |
| |
| typedef struct rogue_backend_uvsw_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned writeop : 3; |
| unsigned imm : 1; |
| unsigned dsel : 1; |
| unsigned : 3; |
| } PACKED; |
| |
| /* Byte 1 */ |
| union { |
| struct { |
| unsigned srcsel : 3; |
| unsigned : 5; |
| } PACKED src; |
| |
| struct { |
| unsigned imm_addr : 8; |
| } PACKED imm_src; |
| |
| struct { |
| unsigned streamid : 2; |
| unsigned : 6; |
| } PACKED stream_src; |
| } PACKED; |
| } PACKED rogue_backend_uvsw_encoding; |
| static_assert(sizeof(rogue_backend_uvsw_encoding) == 2, |
| "sizeof(rogue_backend_uvsw_encoding) != 2"); |
| |
| enum uvsw_writeop { |
| UVSW_WRITEOP_WRITE = 0b000, |
| UVSW_WRITEOP_EMIT = 0b001, |
| UVSW_WRITEOP_CUT = 0b010, |
| UVSW_WRITEOP_EMIT_CUT = 0b011, |
| UVSW_WRITEOP_END = 0b100, |
| UVSW_WRITEOP_EMIT_END = 0b101, |
| UVSW_WRITEOP_WRITE_EMIT_END = 0b110, |
| }; |
| |
| typedef struct rogue_burstlen { |
| union { |
| struct { |
| unsigned _2_0 : 3; |
| unsigned _3 : 1; |
| unsigned : 4; |
| } PACKED; |
| |
| uint8_t _; |
| } PACKED; |
| } PACKED rogue_burstlen; |
| static_assert(sizeof(rogue_burstlen) == 1, "sizeof(rogue_burstlen) != 1"); |
| |
| typedef struct rogue_backend_dma_ld_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned : 3; |
| unsigned drc : 1; |
| unsigned ext : 1; |
| unsigned : 3; |
| } PACKED; |
| |
| /* Byte 1 */ |
| union { |
| struct { |
| unsigned cachemode : 2; |
| unsigned burstlen_2_0 : 3; |
| unsigned srcseladd : 3; |
| } PACKED; |
| |
| struct { |
| unsigned : 2; |
| unsigned srcselbl : 3; |
| unsigned : 3; |
| } PACKED; |
| } PACKED; |
| |
| /* Byte 2 */ |
| struct { |
| unsigned burstlen_3 : 1; |
| unsigned slccachemode : 2; |
| unsigned notimmbl : 1; /* N.B. default is 1 if ext = 0. */ |
| unsigned : 4; |
| } PACKED; |
| } PACKED rogue_backend_dma_ld_encoding; |
| static_assert(sizeof(rogue_backend_dma_ld_encoding) == 3, |
| "sizeof(rogue_backend_dma_ld_encoding) != 3"); |
| |
| enum cachemode_ld { |
| CACHEMODE_LD_NORMAL = 0b00, |
| CACHEMODE_LD_BYPASS = 0b01, |
| CACHEMODE_LD_FORCE_LINE_FILL = 0b10, |
| }; |
| |
| typedef struct rogue_backend_dma_st_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned : 3; |
| unsigned drc : 1; |
| unsigned immbl : 1; |
| unsigned : 3; |
| } PACKED; |
| |
| /* Byte 1 */ |
| union { |
| struct { |
| unsigned cachemode : 2; |
| unsigned burstlen_2_0 : 3; |
| unsigned srcseladd : 3; |
| } PACKED; |
| |
| struct { |
| unsigned : 2; |
| unsigned srcselbl : 3; |
| unsigned : 3; |
| } PACKED; |
| } PACKED; |
| |
| /* Byte 2 */ |
| struct { |
| unsigned burstlen_3 : 1; |
| unsigned : 1; |
| unsigned dsize : 2; |
| unsigned srcseldata : 3; |
| unsigned ext : 1; |
| } PACKED; |
| |
| /* Byte 3 */ |
| struct { |
| unsigned srcmask : 3; |
| unsigned slccachemode : 2; |
| unsigned nottiled : 1; /* N.B. default is 1 if ext = 0. */ |
| unsigned : 2; |
| } PACKED; |
| } PACKED rogue_backend_dma_st_encoding; |
| static_assert(sizeof(rogue_backend_dma_st_encoding) == 4, |
| "sizeof(rogue_backend_dma_st_encoding) != 4"); |
| |
| enum dsize { |
| DSIZE_8 = 0b00, |
| DSIZE_16 = 0b01, |
| DSIZE_BURSTLEN = 0b10, |
| }; |
| |
| enum cachemode_st { |
| CACHEMODE_ST_WRITE_THROUGH = 0b00, |
| CACHEMODE_ST_WRITE_BACK = 0b01, |
| CACHEMODE_ST_WRITE_BACK_LAZY = 0b10, |
| }; |
| |
| enum slccachemode { |
| SLCCACHEMODE_BYPASS = 0b00, |
| SLCCACHEMODE_WRITE_BACK = 0b01, |
| SLCCACHEMODE_WRITE_THROUGH = 0b10, |
| SLCCACHEMODE_CACHED_READS = 0b11, |
| }; |
| |
| typedef struct rogue_backend_dma_smp_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned : 3; |
| unsigned drc : 1; |
| unsigned fcnorm : 1; |
| unsigned : 3; |
| } PACKED; |
| |
| /* Byte 1 */ |
| struct { |
| unsigned lodm : 2; |
| unsigned chan : 2; |
| unsigned exta : 1; |
| unsigned dmn : 2; |
| unsigned extb : 1; |
| } PACKED; |
| |
| /* Byte 2 */ |
| struct { |
| unsigned tao : 1; |
| unsigned soo : 1; |
| unsigned sno : 1; |
| unsigned nncoords : 1; |
| unsigned sbmode : 2; |
| unsigned proj : 1; |
| unsigned pplod : 1; |
| } PACKED; |
| |
| /* Byte 3 */ |
| struct { |
| unsigned w : 1; |
| unsigned cachemode : 2; |
| unsigned swap : 1; |
| unsigned f16 : 1; |
| unsigned slccachemode : 2; |
| unsigned extc : 1; |
| } PACKED; |
| |
| /* Byte 4 */ |
| struct { |
| unsigned array : 1; |
| unsigned : 7; |
| } PACKED; |
| } PACKED rogue_backend_dma_smp_encoding; |
| static_assert(sizeof(rogue_backend_dma_smp_encoding) == 5, |
| "sizeof(rogue_backend_dma_smp_encoding) != 5"); |
| |
| enum fcnorm { |
| FCNORM_INT_NOCONVFP = 0, |
| FCNORM_FIXED_CONVFP = 1, |
| }; |
| |
| enum lodm { |
| LODM_NORMAL = 0b00, |
| LODM_BIAS = 0b01, |
| LODM_REPLACE = 0b10, |
| LODM_GRADIENTS = 0b11, |
| }; |
| |
| enum smpchan { |
| SMPCHAN_1 = 0b00, |
| SMPCHAN_2 = 0b01, |
| SMPCHAN_3 = 0b10, |
| SMPCHAN_4 = 0b11, |
| }; |
| |
| enum dmn { |
| DMN_1D = 0b01, |
| DMN_2D = 0b10, |
| DMN_3D = 0b11, |
| }; |
| |
| enum sbmode { |
| SBMODE_NONE = 0b00, |
| SBMODE_DATA = 0b01, |
| SBMODE_INFO = 0b10, |
| SBMODE_BOTH = 0b11, |
| }; |
| |
| typedef struct rogue_backend_dma_idf_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned : 3; |
| unsigned drc : 1; |
| unsigned : 4; |
| } PACKED; |
| |
| /* Byte 1 */ |
| struct { |
| unsigned srcseladd : 3; |
| unsigned : 5; |
| } PACKED; |
| } PACKED rogue_backend_dma_idf_encoding; |
| static_assert(sizeof(rogue_backend_dma_idf_encoding) == 2, |
| "sizeof(rogue_backend_dma_idf_encoding) != 2"); |
| |
| typedef struct rogue_backend_dma_encoding { |
| union { |
| /* Byte 0 */ |
| struct { |
| unsigned dmaop : 3; |
| unsigned : 5; |
| } PACKED; |
| |
| rogue_backend_dma_smp_encoding smp; |
| rogue_backend_dma_idf_encoding idf; |
| rogue_backend_dma_ld_encoding ld; |
| rogue_backend_dma_st_encoding st; |
| } PACKED; |
| } PACKED rogue_backend_dma_encoding; |
| static_assert(sizeof(rogue_backend_dma_encoding) == 5, |
| "sizeof(rogue_backend_dma_encoding) != 5"); |
| |
| enum dmaop { |
| DMAOP_IDF = 0b000, |
| DMAOP_LD = 0b001, |
| DMAOP_ST = 0b010, |
| DMAOP_SMP = 0b100, |
| DMAOP_ATOMIC = 0b101, |
| }; |
| |
| typedef struct rogue_backend_instr_encoding { |
| union { |
| /* Byte 0 */ |
| struct { |
| unsigned : 5; |
| unsigned op : 3; |
| } PACKED; |
| |
| rogue_backend_uvsw_encoding uvsw; |
| rogue_backend_fitr_encoding fitr; |
| rogue_backend_emitpix_encoding emitpix; |
| rogue_backend_dma_encoding dma; |
| } PACKED; |
| } PACKED rogue_backend_instr_encoding; |
| static_assert(sizeof(rogue_backend_instr_encoding) == 5, |
| "sizeof(rogue_backend_instr_encoding) != 5"); |
| |
| enum backendop { |
| BACKENDOP_UVSW = 0b000, |
| BACKENDOP_MSK = 0b001, |
| BACKENDOP_PHAS = 0b010, |
| BACKENDOP_SETL = 0b011, |
| BACKENDOP_VISTEST = 0b100, |
| BACKENDOP_FITR = 0b101, |
| BACKENDOP_EMIT = 0b110, |
| BACKENDOP_DMA = 0b111, |
| }; |
| |
| /* Branch */ |
| typedef struct rogue_ctrl_ba_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned : 1; |
| unsigned abs : 1; |
| unsigned allp : 1; |
| unsigned anyp : 1; |
| unsigned link : 1; |
| unsigned : 3; |
| } PACKED; |
| |
| /* Byte 1 */ |
| struct { |
| unsigned : 1; |
| unsigned offset_7_1 : 7; |
| } PACKED; |
| |
| /* Byte 2 */ |
| struct { |
| unsigned offset_15_8 : 8; |
| } PACKED; |
| |
| /* Byte 3 */ |
| struct { |
| unsigned offset_23_16 : 8; |
| } PACKED; |
| |
| /* Byte 4 */ |
| struct { |
| unsigned offset_31_24 : 8; |
| } PACKED; |
| } PACKED rogue_ctrl_ba_encoding; |
| static_assert(sizeof(rogue_ctrl_ba_encoding) == 5, |
| "sizeof(rogue_ctrl_ba_encoding) != 5"); |
| |
| typedef struct rogue_offset32 { |
| union { |
| struct { |
| struct { |
| unsigned : 1; |
| unsigned _7_1 : 7; |
| } PACKED; |
| |
| struct { |
| unsigned _15_8 : 8; |
| } PACKED; |
| |
| struct { |
| unsigned _23_16 : 8; |
| } PACKED; |
| |
| struct { |
| unsigned _31_24 : 8; |
| } PACKED; |
| } PACKED; |
| |
| uint32_t _; |
| } PACKED; |
| } PACKED rogue_offset32; |
| static_assert(sizeof(rogue_offset32) == 4, "sizeof(rogue_offset32) != 4"); |
| |
| /* NOP */ |
| typedef struct rogue_ctrl_nop_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned : 8; |
| } PACKED; |
| } PACKED rogue_ctrl_nop_encoding; |
| static_assert(sizeof(rogue_ctrl_nop_encoding) == 1, |
| "sizeof(rogue_ctrl_nop_encoding) != 1"); |
| |
| /* Common for all control instructions. */ |
| typedef struct rogue_ctrl_instr_encoding { |
| union { |
| /* Bytes 0+ */ |
| rogue_ctrl_ba_encoding ba; |
| rogue_ctrl_nop_encoding nop; |
| } PACKED; |
| } PACKED rogue_ctrl_instr_encoding; |
| static_assert(sizeof(rogue_ctrl_instr_encoding) == 5, |
| "sizeof(rogue_ctrl_instr_encoding) != 5"); |
| |
| enum ctrlop { |
| CTRLOP_BA = 0b0000, |
| CTRLOP_LAPC = 0b0001, |
| CTRLOP_SAVL = 0b0010, |
| CTRLOP_CND = 0b0011, |
| CTRLOP_WOP = 0b0100, |
| CTRLOP_WDF = 0b0101, |
| CTRLOP_MUTEX = 0b0110, |
| CTRLOP_NOP = 0b0111, |
| CTRLOP_ITRSMP = 0b1000, |
| CTRLOP_UNIQ = 0b1001, |
| CTRLOP_FETCH = 0b1010, |
| CTRLOP_SBO = 0b1011, |
| }; |
| |
| /* Bitwise phase 0: logical */ |
| typedef struct rogue_bitwise_ph0_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned bm : 1; |
| unsigned cnt_byp : 1; |
| unsigned shft : 2; |
| unsigned ext : 1; |
| unsigned cnt : 1; |
| unsigned csrc : 1; |
| unsigned : 1; |
| } PACKED; |
| |
| /* Byte 1 */ |
| struct { |
| unsigned imm_7_0 : 8; |
| } PACKED; |
| |
| /* Byte 2 */ |
| struct { |
| unsigned imm_15_8 : 8; |
| } PACKED; |
| |
| /* Byte 3 */ |
| struct { |
| unsigned imm_23_16 : 8; |
| } PACKED; |
| |
| /* Byte 4 */ |
| struct { |
| unsigned imm_31_24 : 8; |
| } PACKED; |
| } PACKED rogue_bitwise_ph0_encoding; |
| static_assert(sizeof(rogue_bitwise_ph0_encoding) == 5, |
| "sizeof(rogue_bitwise_ph0_encoding) != 5"); |
| |
| enum shft1 { |
| SHFT1_BYP = 0b00, |
| SHFT1_SHFL = 0b01, |
| SHFT1_REV = 0b10, |
| SHFT1_LSL = 0b11, |
| }; |
| |
| enum cnt { |
| CNT_CBS = 0b0, |
| CNT_FTB = 0b1, |
| }; |
| |
| enum csrc { |
| CNT_S2 = 0b0, |
| CNT_FT2 = 0b1, |
| }; |
| |
| typedef struct rogue_imm32 { |
| union { |
| struct { |
| struct { |
| unsigned _7_0 : 8; |
| } PACKED; |
| |
| struct { |
| unsigned _15_8 : 8; |
| } PACKED; |
| |
| struct { |
| unsigned _23_16 : 8; |
| } PACKED; |
| |
| struct { |
| unsigned _31_24 : 8; |
| } PACKED; |
| } PACKED; |
| |
| uint32_t _; |
| } PACKED; |
| } PACKED rogue_imm32; |
| static_assert(sizeof(rogue_imm32) == 4, "sizeof(rogue_imm32) != 4"); |
| |
| /* Bitwise phase 1: logical */ |
| typedef struct rogue_bitwise_ph1_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned op : 3; |
| unsigned mska : 1; |
| unsigned : 1; |
| unsigned mskb : 1; |
| unsigned : 2; |
| } PACKED; |
| } PACKED rogue_bitwise_ph1_encoding; |
| static_assert(sizeof(rogue_bitwise_ph1_encoding) == 1, |
| "sizeof(rogue_bitwise_ph1_encoding) != 1"); |
| |
| enum ph1op { |
| PH1OP_OR = 0b000, |
| PH1OP_AND = 0b001, |
| PH1OP_XOR = 0b010, |
| PH1OP_NOR = 0b100, |
| PH1OP_NAND = 0b101, |
| PH1OP_XNOR = 0b110, |
| PH1OP_BYP = 0b111, |
| }; |
| |
| /* Bitwise phase 2: shift2/test */ |
| typedef struct rogue_bitwise_ph2_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned shft : 3; |
| unsigned top : 1; |
| unsigned tsrc : 1; |
| unsigned pwen : 1; |
| unsigned : 2; |
| } PACKED; |
| } PACKED rogue_bitwise_ph2_encoding; |
| static_assert(sizeof(rogue_bitwise_ph2_encoding) == 1, |
| "sizeof(rogue_bitwise_ph2_encoding) != 1"); |
| |
| enum shft2 { |
| SHFT2_LSL = 0b000, |
| SHFT2_SHR = 0b001, |
| SHFT2_ROL = 0b010, |
| SHFT2_CPS = 0b011, |
| SHFT2_ASR_TWB = 0b100, |
| SHFT2_ASR_PWB = 0b101, |
| SHFT2_ASR_MTB = 0b110, |
| SHFT2_ASR_FTB = 0b111, |
| }; |
| |
| enum top { |
| TOP_TZ = 0b0, |
| TOP_TNZ = 0b1, |
| }; |
| |
| enum tsrc { |
| TSRC_FT5 = 0b0, |
| TSRC_FT3 = 0b1, |
| }; |
| |
| /* Common for all bitwise instructions. */ |
| typedef struct rogue_bitwise_instr_encoding { |
| union { |
| /* Bytes 0+ */ |
| struct { |
| unsigned : 6; |
| unsigned phase1 : 1; |
| unsigned phase0 : 1; |
| } PACKED; |
| |
| rogue_bitwise_ph0_encoding ph0; |
| rogue_bitwise_ph1_encoding ph1; |
| rogue_bitwise_ph2_encoding ph2; |
| } PACKED; |
| } PACKED rogue_bitwise_instr_encoding; |
| static_assert(sizeof(rogue_bitwise_instr_encoding) == 5, |
| "sizeof(rogue_bitwise_instr_encoding) != 5"); |
| |
| typedef struct rogue_instr_group_header_encoding { |
| /* Byte 0 */ |
| struct { |
| unsigned length : 4; |
| unsigned da : 4; |
| } PACKED; |
| |
| /* Byte 1 */ |
| union { |
| struct { |
| unsigned cc : 1; |
| unsigned w0p : 1; |
| unsigned w1p : 1; |
| unsigned olchk : 1; |
| unsigned oporg : 3; |
| unsigned ext : 1; |
| } PACKED; |
| |
| struct { |
| unsigned : 4; |
| unsigned opcnt : 3; |
| unsigned : 1; |
| } PACKED; |
| } PACKED; |
| |
| /* Byte 2 */ |
| union { |
| struct { |
| unsigned ccext : 1; |
| unsigned rpt : 2; |
| unsigned atom : 1; |
| unsigned : 1; |
| unsigned alutype : 2; |
| unsigned end : 1; |
| } PACKED; |
| |
| struct { |
| unsigned : 1; |
| unsigned ctrlop : 4; |
| unsigned : 2; |
| unsigned miscctl : 1; |
| } PACKED; |
| } PACKED; |
| } PACKED rogue_instr_group_header_encoding; |
| static_assert(sizeof(rogue_instr_group_header_encoding) == 3, |
| "sizeof(rogue_instr_group_header_encoding) != 3"); |
| |
| enum oporg { |
| OPORG_P0 = 0b000, |
| OPORG_P2 = 0b001, |
| OPORG_BE = 0b010, |
| OPORG_P0_P1 = 0b011, |
| OPORG_P0_P2 = 0b100, |
| OPORG_P0_P1_P2 = 0b101, |
| OPORG_P0_P2_BE = 0b110, |
| OPORG_P0_P1_P2_BE = 0b111, |
| }; |
| |
| enum opcnt { |
| OPCNT_P0 = 0b001, |
| OPCNT_P1 = 0b010, |
| OPCNT_P2 = 0b100, |
| }; |
| |
| enum alutype { |
| ALUTYPE_MAIN = 0b00, |
| ALUTYPE_BITWISE = 0b10, |
| ALUTYPE_CONTROL = 0b11, |
| }; |
| |
| enum cc { |
| CC_PE_TRUE = 0b00, |
| CC_P0_TRUE = 0b01, |
| CC_PE_ANY = 0b10, |
| CC_P0_FALSE = 0b11, |
| }; |
| |
| typedef struct rogue_cc { |
| union { |
| struct { |
| unsigned cc : 1; |
| unsigned ccext : 1; |
| unsigned : 6; |
| } PACKED; |
| |
| uint8_t _; |
| } PACKED; |
| } PACKED rogue_cc; |
| static_assert(sizeof(rogue_cc) == 1, "sizeof(rogue_cc) != 1"); |
| |
| #endif /* ROGUE_ISA_H */ |