mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-21 09:50:36 +02:00
pvr: Add support for validating modifier combos
Signed-off-by: Simon Perretta <simon.perretta@imgtec.com> Acked-by: Frank Binns <frank.binns@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21474>
This commit is contained in:
parent
8ef839374e
commit
bdbd69edb8
5 changed files with 191 additions and 42 deletions
|
|
@ -251,6 +251,7 @@ ForEachMacros: [
|
|||
'rogue_foreach_instr_in_shader_safe',
|
||||
'rogue_foreach_instr_in_shader_rev',
|
||||
'rogue_foreach_instr_in_shader_safe_rev',
|
||||
'rogue_foreach_mod_in_set',
|
||||
'rogue_foreach_reg',
|
||||
'rogue_foreach_reg_safe',
|
||||
'rogue_foreach_reg_use',
|
||||
|
|
|
|||
|
|
@ -348,15 +348,16 @@ enum rogue_instr_phase {
|
|||
ROGUE_INSTR_PHASE_INVALID = ~0,
|
||||
};
|
||||
|
||||
#define rogue_foreach_phase_in_set(p, phases) \
|
||||
for (uint64_t __phases = (phases), p; \
|
||||
((p) = ffsll(__phases) - 1, __phases); \
|
||||
__phases &= ~(1ull << (p)))
|
||||
/* TODO: put into bitscan.h */
|
||||
#define u_foreach_bit64_rev(b, dword) \
|
||||
for (uint64_t __dword = (dword), b; \
|
||||
((b) = util_last_bit64(__dword) - 1, __dword); \
|
||||
__dword &= ~(1ull << (b)))
|
||||
|
||||
#define rogue_foreach_phase_in_set_rev(p, phases) \
|
||||
for (uint64_t __phases = (phases), p; \
|
||||
((p) = util_last_bit64(__phases) - 1, __phases); \
|
||||
__phases &= ~(1ull << (p)))
|
||||
#define rogue_foreach_phase_in_set(p, phases) u_foreach_bit64(p, phases)
|
||||
#define rogue_foreach_phase_in_set_rev(p, phases) u_foreach_bit64_rev(p, phases)
|
||||
|
||||
#define rogue_foreach_mod_in_set(m, mods) u_foreach_bit64(m, mods)
|
||||
|
||||
/** Rogue basic block. */
|
||||
typedef struct rogue_block {
|
||||
|
|
@ -1046,6 +1047,8 @@ enum rogue_alu_op_mod {
|
|||
|
||||
typedef struct rogue_alu_op_mod_info {
|
||||
const char *str;
|
||||
uint64_t exclude; /* Can't use this op mod with any of these. */
|
||||
uint64_t require; /* Required op mods for this to be used (OR). */
|
||||
} rogue_alu_op_mod_info;
|
||||
|
||||
extern const rogue_alu_op_mod_info
|
||||
|
|
@ -1113,6 +1116,8 @@ enum rogue_ctrl_op_mod {
|
|||
|
||||
typedef struct rogue_ctrl_op_mod_info {
|
||||
const char *str;
|
||||
uint64_t exclude; /* Can't use this op mod with any of these. */
|
||||
uint64_t require; /* Required op mods for this to be used (OR). */
|
||||
} rogue_ctrl_op_mod_info;
|
||||
|
||||
extern const rogue_ctrl_op_mod_info
|
||||
|
|
@ -1383,7 +1388,6 @@ typedef struct rogue_backend_op_info {
|
|||
extern const rogue_backend_op_info
|
||||
rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT];
|
||||
|
||||
/* TODO: Some of these may not be used together; express that in op mod info. */
|
||||
enum rogue_backend_op_mod {
|
||||
/* In order of priority */
|
||||
ROGUE_BACKEND_OP_MOD_PROJ, /* Projection (send T co-ordinate). */
|
||||
|
|
@ -1440,6 +1444,8 @@ enum rogue_backend_op_mod {
|
|||
|
||||
typedef struct rogue_backend_op_mod_info {
|
||||
const char *str;
|
||||
uint64_t exclude; /* Can't use this op mod with any of these. */
|
||||
uint64_t require; /* Required op mods for this to be used (OR). */
|
||||
} rogue_backend_op_mod_info;
|
||||
|
||||
extern const rogue_backend_op_mod_info
|
||||
|
|
@ -1531,6 +1537,25 @@ enum rogue_bitwise_op {
|
|||
ROGUE_BITWISE_OP_COUNT,
|
||||
};
|
||||
|
||||
enum rogue_bitwise_op_mod {
|
||||
/* In order of priority */
|
||||
ROGUE_BITWISE_OP_MOD_TWB, /* Top word break. */
|
||||
ROGUE_BITWISE_OP_MOD_PWB, /* Partial word break. */
|
||||
ROGUE_BITWISE_OP_MOD_MTB, /* Mask top break. */
|
||||
ROGUE_BITWISE_OP_MOD_FTB, /* Find top break. */
|
||||
|
||||
ROGUE_BITWISE_OP_MOD_COUNT,
|
||||
};
|
||||
|
||||
typedef struct rogue_bitwise_op_mod_info {
|
||||
const char *str;
|
||||
uint64_t exclude; /* Can't use this op mod with any of these. */
|
||||
uint64_t require; /* Required op mods for this to be used (OR). */
|
||||
} rogue_bitwise_op_mod_info;
|
||||
|
||||
extern const rogue_bitwise_op_mod_info
|
||||
rogue_bitwise_op_mod_infos[ROGUE_BITWISE_OP_MOD_COUNT];
|
||||
|
||||
#define ROGUE_BITWISE_OP_MAX_SRCS 7
|
||||
#define ROGUE_BITWISE_OP_MAX_DSTS 2
|
||||
|
||||
|
|
@ -1586,21 +1611,18 @@ typedef struct rogue_bitwise_instr {
|
|||
rogue_src_use src_use[ROGUE_BITWISE_OP_MAX_SRCS];
|
||||
} rogue_bitwise_instr;
|
||||
|
||||
#if 0
|
||||
static inline
|
||||
void
|
||||
rogue_set_bitwise_op_mod(rogue_bitwise_instr *bitwise, enum rogue_bitwise_op_mod mod)
|
||||
static inline void rogue_set_bitwise_op_mod(rogue_bitwise_instr *bitwise,
|
||||
enum rogue_bitwise_op_mod mod)
|
||||
{
|
||||
bitwise->mod |= BITFIELD64_BIT(mod);
|
||||
bitwise->mod |= BITFIELD64_BIT(mod);
|
||||
}
|
||||
|
||||
static inline
|
||||
bool
|
||||
rogue_bitwise_op_mod_is_set(const rogue_bitwise_instr *bitwise, enum rogue_bitwise_op_mod mod)
|
||||
static inline bool
|
||||
rogue_bitwise_op_mod_is_set(const rogue_bitwise_instr *bitwise,
|
||||
enum rogue_bitwise_op_mod mod)
|
||||
{
|
||||
return !!(bitwise->mod & BITFIELD64_BIT(mod));
|
||||
return !!(bitwise->mod & BITFIELD64_BIT(mod));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Allocates and initializes a new bitwise instruction.
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ static void rogue_encode_alu_instr(const rogue_alu_instr *alu,
|
|||
#undef DM
|
||||
#undef SM
|
||||
|
||||
#define OM(op_mod) BITFIELD64_BIT(ROGUE_BACKEND_OP_MOD_##op_mod)
|
||||
#define OM(op_mod) ROGUE_BACKEND_OP_MOD_##op_mod
|
||||
static void rogue_encode_backend_instr(const rogue_backend_instr *backend,
|
||||
unsigned instr_size,
|
||||
rogue_instr_encoding *instr_encoding)
|
||||
|
|
@ -471,7 +471,7 @@ static void rogue_encode_backend_instr(const rogue_backend_instr *backend,
|
|||
rogue_backend_op_mod_is_set(backend, OM(PPLOD));
|
||||
}
|
||||
|
||||
if (instr_size >= 3) {
|
||||
if (instr_size > 3) {
|
||||
instr_encoding->backend.dma.smp.extb = 1;
|
||||
|
||||
instr_encoding->backend.dma.smp.w =
|
||||
|
|
|
|||
|
|
@ -282,8 +282,11 @@ const rogue_backend_op_info rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT] = {
|
|||
[1] = T(REGARRAY),
|
||||
[2] = T(VAL),
|
||||
},
|
||||
.dst_stride = {
|
||||
[0] = ~0U,
|
||||
},
|
||||
.src_stride = {
|
||||
[1] = 3,
|
||||
[1] = ~0U,
|
||||
},
|
||||
},
|
||||
[ROGUE_BACKEND_OP_FITRP_PIXEL] = { .str = "fitrp.pixel", .num_dsts = 1, .num_srcs = 4,
|
||||
|
|
@ -318,6 +321,15 @@ const rogue_backend_op_info rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT] = {
|
|||
[4] = T(REG) | T(IO),
|
||||
[5] = T(VAL),
|
||||
},
|
||||
/* TODO: This may depend on the other options set. */
|
||||
.src_stride = {
|
||||
[1] = 3,
|
||||
[2] = ~0U,
|
||||
[3] = 3,
|
||||
},
|
||||
.dst_stride = {
|
||||
[0] = ~0U,
|
||||
},
|
||||
},
|
||||
[ROGUE_BACKEND_OP_SMP2D] = { .str = "smp2d", .num_dsts = 1, .num_srcs = 6,
|
||||
.phase_io = { .dst[0] = IO(S4), .src[1] = IO(S0), .src[2] = IO(S1), .src[3] = IO(S2), },
|
||||
|
|
@ -336,6 +348,15 @@ const rogue_backend_op_info rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT] = {
|
|||
[4] = T(REG) | T(IO),
|
||||
[5] = T(VAL),
|
||||
},
|
||||
/* TODO: This may depend on the other options set. */
|
||||
.src_stride = {
|
||||
[1] = 3,
|
||||
[2] = ~0U,
|
||||
[3] = 3,
|
||||
},
|
||||
.dst_stride = {
|
||||
[0] = ~0U,
|
||||
},
|
||||
},
|
||||
[ROGUE_BACKEND_OP_SMP3D] = { .str = "smp3d", .num_dsts = 1, .num_srcs = 6,
|
||||
.phase_io = { .dst[0] = IO(S4), .src[1] = IO(S0), .src[2] = IO(S1), .src[3] = IO(S2), },
|
||||
|
|
@ -354,6 +375,15 @@ const rogue_backend_op_info rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT] = {
|
|||
[4] = T(REG) | T(IO),
|
||||
[5] = T(VAL),
|
||||
},
|
||||
/* TODO: This may depend on the other options set. */
|
||||
.src_stride = {
|
||||
[1] = 3,
|
||||
[2] = ~0U,
|
||||
[3] = 3,
|
||||
},
|
||||
.dst_stride = {
|
||||
[0] = ~0U,
|
||||
},
|
||||
},
|
||||
};
|
||||
#undef B
|
||||
|
|
@ -361,36 +391,37 @@ const rogue_backend_op_info rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT] = {
|
|||
#undef OM
|
||||
#undef IO
|
||||
|
||||
#define OM(op_mod) BITFIELD64_BIT(ROGUE_BACKEND_OP_MOD_##op_mod)
|
||||
const rogue_backend_op_mod_info rogue_backend_op_mod_infos[ROGUE_BACKEND_OP_MOD_COUNT] = {
|
||||
[ROGUE_BACKEND_OP_MOD_PROJ] = { .str = "proj", },
|
||||
[ROGUE_BACKEND_OP_MOD_FCNORM] = { .str = "fcnorm", },
|
||||
[ROGUE_BACKEND_OP_MOD_NNCOORDS] = { .str = "nncoords", },
|
||||
|
||||
[ROGUE_BACKEND_OP_MOD_BIAS] = { .str = "bias", },
|
||||
[ROGUE_BACKEND_OP_MOD_REPLACE] = { .str = "replace", },
|
||||
[ROGUE_BACKEND_OP_MOD_GRADIENT] = { .str = "gradient", },
|
||||
[ROGUE_BACKEND_OP_MOD_BIAS] = { .str = "bias", .exclude = OM(REPLACE) | OM(GRADIENT) },
|
||||
[ROGUE_BACKEND_OP_MOD_REPLACE] = { .str = "replace", .exclude = OM(BIAS) | OM(GRADIENT) },
|
||||
[ROGUE_BACKEND_OP_MOD_GRADIENT] = { .str = "gradient", .exclude = OM(BIAS) | OM(REPLACE) },
|
||||
|
||||
[ROGUE_BACKEND_OP_MOD_PPLOD] = { .str = "pplod", },
|
||||
[ROGUE_BACKEND_OP_MOD_PPLOD] = { .str = "pplod", .require = OM(BIAS) | OM(REPLACE) },
|
||||
[ROGUE_BACKEND_OP_MOD_TAO] = { .str = "tao", },
|
||||
[ROGUE_BACKEND_OP_MOD_SOO] = { .str = "soo", },
|
||||
[ROGUE_BACKEND_OP_MOD_SNO] = { .str = "sno", },
|
||||
[ROGUE_BACKEND_OP_MOD_WRT] = { .str = "wrt", },
|
||||
|
||||
[ROGUE_BACKEND_OP_MOD_DATA] = { .str = "data", },
|
||||
[ROGUE_BACKEND_OP_MOD_INFO] = { .str = "info", },
|
||||
[ROGUE_BACKEND_OP_MOD_BOTH] = { .str = "both", },
|
||||
[ROGUE_BACKEND_OP_MOD_DATA] = { .str = "data", .exclude = OM(INFO) | OM(BOTH) },
|
||||
[ROGUE_BACKEND_OP_MOD_INFO] = { .str = "info", .exclude = OM(DATA) | OM(BOTH) },
|
||||
[ROGUE_BACKEND_OP_MOD_BOTH] = { .str = "both", .exclude = OM(DATA) | OM(INFO) },
|
||||
|
||||
[ROGUE_BACKEND_OP_MOD_BYPASS] = { .str = "bypass", },
|
||||
[ROGUE_BACKEND_OP_MOD_FORCELINEFILL] = { .str = "forcelinefill", },
|
||||
[ROGUE_BACKEND_OP_MOD_BYPASS] = { .str = "bypass", .exclude = OM(FORCELINEFILL) | OM(WRITETHROUGH) | OM(WRITEBACK) | OM(LAZYWRITEBACK) },
|
||||
[ROGUE_BACKEND_OP_MOD_FORCELINEFILL] = { .str = "forcelinefill", .exclude = OM(BYPASS) | OM(WRITETHROUGH) | OM(WRITEBACK) | OM(LAZYWRITEBACK) },
|
||||
|
||||
[ROGUE_BACKEND_OP_MOD_WRITETHROUGH] = { .str = "writethrough", },
|
||||
[ROGUE_BACKEND_OP_MOD_WRITEBACK] = { .str = "writeback", },
|
||||
[ROGUE_BACKEND_OP_MOD_LAZYWRITEBACK] = { .str = "lazywriteback", },
|
||||
[ROGUE_BACKEND_OP_MOD_WRITETHROUGH] = { .str = "writethrough", .exclude = OM(BYPASS) | OM(FORCELINEFILL) | OM(WRITEBACK) | OM(LAZYWRITEBACK) },
|
||||
[ROGUE_BACKEND_OP_MOD_WRITEBACK] = { .str = "writeback", .exclude = OM(BYPASS) | OM(FORCELINEFILL) | OM(WRITETHROUGH) | OM(LAZYWRITEBACK) },
|
||||
[ROGUE_BACKEND_OP_MOD_LAZYWRITEBACK] = { .str = "lazywriteback", .exclude = OM(BYPASS) | OM(FORCELINEFILL) | OM(WRITETHROUGH) | OM(WRITEBACK) },
|
||||
|
||||
[ROGUE_BACKEND_OP_MOD_SLCBYPASS] = { .str = "slcbypass", },
|
||||
[ROGUE_BACKEND_OP_MOD_SLCWRITEBACK] = { .str = "slcwriteback", },
|
||||
[ROGUE_BACKEND_OP_MOD_SLCWRITETHROUGH] = { .str = "slcwritethrough", },
|
||||
[ROGUE_BACKEND_OP_MOD_SLCNOALLOC] = { .str = "slcnoalloc", },
|
||||
[ROGUE_BACKEND_OP_MOD_SLCBYPASS] = { .str = "slcbypass", .exclude = OM(SLCWRITEBACK) | OM(SLCWRITETHROUGH) | OM(SLCNOALLOC) },
|
||||
[ROGUE_BACKEND_OP_MOD_SLCWRITEBACK] = { .str = "slcwriteback", .exclude = OM(SLCBYPASS) | OM(SLCWRITETHROUGH) | OM(SLCNOALLOC) },
|
||||
[ROGUE_BACKEND_OP_MOD_SLCWRITETHROUGH] = { .str = "slcwritethrough", .exclude = OM(SLCBYPASS) | OM(SLCWRITEBACK) | OM(SLCNOALLOC) },
|
||||
[ROGUE_BACKEND_OP_MOD_SLCNOALLOC] = { .str = "slcnoalloc", .exclude = OM(SLCBYPASS) | OM(SLCWRITEBACK) | OM(SLCWRITETHROUGH) },
|
||||
|
||||
[ROGUE_BACKEND_OP_MOD_ARRAY] = { .str = "array", },
|
||||
[ROGUE_BACKEND_OP_MOD_INTEGER] = { .str = "integer", },
|
||||
|
|
@ -400,6 +431,21 @@ const rogue_backend_op_mod_info rogue_backend_op_mod_infos[ROGUE_BACKEND_OP_MOD_
|
|||
|
||||
[ROGUE_BACKEND_OP_MOD_SAT] = { .str = "sat", },
|
||||
};
|
||||
#undef OM
|
||||
|
||||
#define OM(op_mod) BITFIELD64_BIT(ROGUE_BITWISE_OP_MOD_##op_mod)
|
||||
const rogue_bitwise_op_mod_info
|
||||
rogue_bitwise_op_mod_infos[ROGUE_BITWISE_OP_MOD_COUNT] = {
|
||||
[ROGUE_BITWISE_OP_MOD_TWB] = { .str = "twb",
|
||||
.exclude = OM(PWB) | OM(MTB) | OM(FTB) },
|
||||
[ROGUE_BITWISE_OP_MOD_PWB] = { .str = "pwb",
|
||||
.exclude = OM(TWB) | OM(MTB) | OM(FTB) },
|
||||
[ROGUE_BITWISE_OP_MOD_MTB] = { .str = "mtb",
|
||||
.exclude = OM(TWB) | OM(PWB) | OM(FTB) },
|
||||
[ROGUE_BITWISE_OP_MOD_FTB] = { .str = "ftb",
|
||||
.exclude = OM(TWB) | OM(PWB) | OM(MTB) },
|
||||
};
|
||||
#undef OM
|
||||
|
||||
#define P(type) BITFIELD64_BIT(ROGUE_INSTR_PHASE_##type)
|
||||
#define PH(type) ROGUE_INSTR_PHASE_##type
|
||||
|
|
|
|||
|
|
@ -224,6 +224,23 @@ static void validate_src(rogue_validation_state *state,
|
|||
state->ctx.ref = NULL;
|
||||
}
|
||||
|
||||
static bool validate_alu_op_mod_combo(uint64_t mods)
|
||||
{
|
||||
rogue_foreach_mod_in_set (mod, mods) {
|
||||
const rogue_alu_op_mod_info *info = &rogue_alu_op_mod_infos[mod];
|
||||
|
||||
/* Check if any excluded op mods have been included. */
|
||||
if (info->exclude & mods)
|
||||
return false;
|
||||
|
||||
/* Check if any required op mods have been missed. */
|
||||
if (info->require && !(info->require & mods))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void validate_alu_instr(rogue_validation_state *state,
|
||||
const rogue_alu_instr *alu)
|
||||
{
|
||||
|
|
@ -238,10 +255,13 @@ static void validate_alu_instr(rogue_validation_state *state,
|
|||
if (rogue_alu_comp_is_none(alu) && alu->op == ROGUE_ALU_OP_TST)
|
||||
validate_log(state, "ALU comparison not set for test op.");
|
||||
|
||||
/* Initial check if instruction modifiers are valid. */
|
||||
/* Check if instruction modifiers are valid. */
|
||||
if (!rogue_mods_supported(alu->mod, info->supported_op_mods))
|
||||
validate_log(state, "Unsupported ALU op modifiers.");
|
||||
|
||||
if (!validate_alu_op_mod_combo(alu->mod))
|
||||
validate_log(state, "Unsupported ALU op modifier combination.");
|
||||
|
||||
/* Instruction repeat checks. */
|
||||
if (alu->instr.repeat > 1 && !info->dst_repeat_mask &&
|
||||
!info->src_repeat_mask) {
|
||||
|
|
@ -270,6 +290,23 @@ static void validate_alu_instr(rogue_validation_state *state,
|
|||
}
|
||||
}
|
||||
|
||||
static bool validate_backend_op_mod_combo(uint64_t mods)
|
||||
{
|
||||
rogue_foreach_mod_in_set (mod, mods) {
|
||||
const rogue_backend_op_mod_info *info = &rogue_backend_op_mod_infos[mod];
|
||||
|
||||
/* Check if any excluded op mods have been included. */
|
||||
if (info->exclude & mods)
|
||||
return false;
|
||||
|
||||
/* Check if any required op mods have been missed. */
|
||||
if (info->require && !(info->require & mods))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void validate_backend_instr(rogue_validation_state *state,
|
||||
const rogue_backend_instr *backend)
|
||||
{
|
||||
|
|
@ -279,10 +316,13 @@ static void validate_backend_instr(rogue_validation_state *state,
|
|||
|
||||
const rogue_backend_op_info *info = &rogue_backend_op_infos[backend->op];
|
||||
|
||||
/* Initial check if instruction modifiers are valid. */
|
||||
/* Check if instruction modifiers are valid. */
|
||||
if (!rogue_mods_supported(backend->mod, info->supported_op_mods))
|
||||
validate_log(state, "Unsupported backend op modifiers.");
|
||||
|
||||
if (!validate_backend_op_mod_combo(backend->mod))
|
||||
validate_log(state, "Unsupported backend op modifier combination.");
|
||||
|
||||
/* Instruction repeat checks. */
|
||||
if (backend->instr.repeat > 1 && !info->dst_repeat_mask &&
|
||||
!info->src_repeat_mask) {
|
||||
|
|
@ -311,6 +351,23 @@ static void validate_backend_instr(rogue_validation_state *state,
|
|||
}
|
||||
}
|
||||
|
||||
static bool validate_ctrl_op_mod_combo(uint64_t mods)
|
||||
{
|
||||
rogue_foreach_mod_in_set (mod, mods) {
|
||||
const rogue_ctrl_op_mod_info *info = &rogue_ctrl_op_mod_infos[mod];
|
||||
|
||||
/* Check if any excluded op mods have been included. */
|
||||
if (info->exclude & mods)
|
||||
return false;
|
||||
|
||||
/* Check if any required op mods have been missed. */
|
||||
if (info->require && !(info->require & mods))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returns true if instruction can end block. */
|
||||
static bool validate_ctrl_instr(rogue_validation_state *state,
|
||||
const rogue_ctrl_instr *ctrl)
|
||||
|
|
@ -327,10 +384,13 @@ static bool validate_ctrl_instr(rogue_validation_state *state,
|
|||
validate_log(state,
|
||||
"Ctrl op did not expect target block, but one provided.");
|
||||
|
||||
/* Initial check if instruction modifiers are valid. */
|
||||
/* Check if instruction modifiers are valid. */
|
||||
if (!rogue_mods_supported(ctrl->mod, info->supported_op_mods))
|
||||
validate_log(state, "Unsupported CTRL op modifiers.");
|
||||
|
||||
if (!validate_ctrl_op_mod_combo(ctrl->mod))
|
||||
validate_log(state, "Unsupported CTRL op modifier combination.");
|
||||
|
||||
/* Instruction repeat checks. */
|
||||
if (ctrl->instr.repeat > 1 && !info->dst_repeat_mask &&
|
||||
!info->src_repeat_mask) {
|
||||
|
|
@ -369,6 +429,23 @@ static bool validate_ctrl_instr(rogue_validation_state *state,
|
|||
return info->ends_block;
|
||||
}
|
||||
|
||||
static bool validate_bitwise_op_mod_combo(uint64_t mods)
|
||||
{
|
||||
rogue_foreach_mod_in_set (mod, mods) {
|
||||
const rogue_bitwise_op_mod_info *info = &rogue_bitwise_op_mod_infos[mod];
|
||||
|
||||
/* Check if any excluded op mods have been included. */
|
||||
if (info->exclude & mods)
|
||||
return false;
|
||||
|
||||
/* Check if any required op mods have been missed. */
|
||||
if (info->require && !(info->require & mods))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void validate_bitwise_instr(rogue_validation_state *state,
|
||||
const rogue_bitwise_instr *bitwise)
|
||||
{
|
||||
|
|
@ -378,10 +455,13 @@ static void validate_bitwise_instr(rogue_validation_state *state,
|
|||
|
||||
const rogue_bitwise_op_info *info = &rogue_bitwise_op_infos[bitwise->op];
|
||||
|
||||
/* Initial check if instruction modifiers are valid. */
|
||||
/* Check if instruction modifiers are valid. */
|
||||
if (!rogue_mods_supported(bitwise->mod, info->supported_op_mods))
|
||||
validate_log(state, "Unsupported bitwise op modifiers.");
|
||||
|
||||
if (!validate_bitwise_op_mod_combo(bitwise->mod))
|
||||
validate_log(state, "Unsupported bitwise op modifier combination.");
|
||||
|
||||
/* Instruction repeat checks. */
|
||||
if (bitwise->instr.repeat > 1 && !info->dst_repeat_mask &&
|
||||
!info->src_repeat_mask) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue