blob: a401291a3ab32bb4b245e06b5930a914eafccd4f [file] [log] [blame]
/*
* 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 */