mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
shader: decode and translate V_FRACT_F16 (VOP1 0x5f) and V_CMPX_LT_U16 (VOPC 0xb9) (#582)
shader: support V_FRACT_F16 and V_CMPX_LT_U16 Decode compact, SDWA, and VOP3 forms using the existing arithmetic and comparison paths. Preserve EXEC masking and VCC for the integer compare, and reject unsupported DPP encoding. Add captured-instruction, operand-selection, floating-point edge, and execution-mask regression coverage. Co-authored-by: nmzik <Nmzik@mail.ru>
This commit is contained in:
@@ -190,6 +190,7 @@ enum class Opcode {
|
||||
V_CEIL_F16,
|
||||
V_TRUNC_F16,
|
||||
V_RNDNE_F16,
|
||||
V_FRACT_F16,
|
||||
V_SIN_F16,
|
||||
V_COS_F16,
|
||||
V_SIN_F32,
|
||||
@@ -395,6 +396,7 @@ enum class Opcode {
|
||||
V_CMP_EQ_U16,
|
||||
V_CMP_LE_U16,
|
||||
V_CMP_GT_U16,
|
||||
V_CMPX_LT_U16,
|
||||
V_CMPX_GT_U16,
|
||||
V_CMP_NE_U16,
|
||||
V_CMP_GE_U16,
|
||||
|
||||
@@ -139,6 +139,7 @@ constexpr OpcodeMap VOP1_OPCODE_LIST[] = {
|
||||
{0x5cu, Opcode::V_CEIL_F16},
|
||||
{0x5du, Opcode::V_TRUNC_F16},
|
||||
{0x5eu, Opcode::V_RNDNE_F16},
|
||||
{0x5fu, Opcode::V_FRACT_F16},
|
||||
{0x60u, Opcode::V_SIN_F16},
|
||||
{0x61u, Opcode::V_COS_F16},
|
||||
};
|
||||
@@ -192,6 +193,7 @@ constexpr OpcodeMap VOP3_ENCODED_VOP1_OPCODE_LIST[] = {
|
||||
{0x5cu, Opcode::V_CEIL_F16},
|
||||
{0x5du, Opcode::V_TRUNC_F16},
|
||||
{0x5eu, Opcode::V_RNDNE_F16},
|
||||
{0x5fu, Opcode::V_FRACT_F16},
|
||||
{0x60u, Opcode::V_SIN_F16},
|
||||
{0x61u, Opcode::V_COS_F16},
|
||||
};
|
||||
@@ -233,6 +235,7 @@ constexpr VopcOpcodeInfo VOPC_OPCODE_LIST[] = {
|
||||
{0xa9u, Opcode::V_CMP_LT_U16}, {0xaau, Opcode::V_CMP_EQ_U16},
|
||||
{0xabu, Opcode::V_CMP_LE_U16}, {0xacu, Opcode::V_CMP_GT_U16},
|
||||
{0xadu, Opcode::V_CMP_NE_U16}, {0xaeu, Opcode::V_CMP_GE_U16},
|
||||
{0xb9u, Opcode::V_CMPX_LT_U16, false},
|
||||
{0xbcu, Opcode::V_CMPX_GT_U16}, {0xc0u, Opcode::V_CMP_F_U32},
|
||||
{0xc1u, Opcode::V_CMP_LT_U32}, {0xc2u, Opcode::V_CMP_EQ_U32},
|
||||
{0xc3u, Opcode::V_CMP_LE_U32}, {0xc4u, Opcode::V_CMP_GT_U32},
|
||||
@@ -479,6 +482,7 @@ bool IsVop1FloatSourceOpcode(Opcode opcode) {
|
||||
case Opcode::V_CEIL_F16:
|
||||
case Opcode::V_TRUNC_F16:
|
||||
case Opcode::V_RNDNE_F16:
|
||||
case Opcode::V_FRACT_F16:
|
||||
case Opcode::V_SIN_F16:
|
||||
case Opcode::V_COS_F16:
|
||||
case Opcode::V_SIN_F32:
|
||||
@@ -548,6 +552,8 @@ constexpr Vop1SdwaRule VOP1_SDWA_RULES[] = {
|
||||
SdwaSelWords() | SdwaSelFull(), true},
|
||||
{Opcode::V_RNDNE_F16, SdwaSelWords() | SdwaSelFull(), SdwaSelWords(),
|
||||
SdwaSelWords() | SdwaSelFull(), true},
|
||||
{Opcode::V_FRACT_F16, SdwaSelWords() | SdwaSelFull(), SdwaSelWords(),
|
||||
SdwaSelWords() | SdwaSelFull(), true},
|
||||
{Opcode::V_SIN_F16, SdwaSelWords() | SdwaSelFull(), SdwaSelWords(),
|
||||
SdwaSelWords() | SdwaSelFull(), true},
|
||||
{Opcode::V_COS_F16, SdwaSelWords() | SdwaSelFull(), SdwaSelWords(),
|
||||
@@ -773,6 +779,7 @@ bool IsVop1FloatResultOpcode(Opcode opcode) {
|
||||
case Opcode::V_CEIL_F16:
|
||||
case Opcode::V_TRUNC_F16:
|
||||
case Opcode::V_RNDNE_F16:
|
||||
case Opcode::V_FRACT_F16:
|
||||
case Opcode::V_SIN_F16:
|
||||
case Opcode::V_COS_F16:
|
||||
case Opcode::V_SIN_F32:
|
||||
@@ -1434,6 +1441,7 @@ bool IsVopcCompareExec(Opcode opcode) {
|
||||
case Opcode::V_CMPX_GE_U32:
|
||||
case Opcode::V_CMPX_NE_I64:
|
||||
case Opcode::V_CMPX_NE_U64:
|
||||
case Opcode::V_CMPX_LT_U16:
|
||||
case Opcode::V_CMPX_GT_U16:
|
||||
case Opcode::V_CMPX_LT_F16:
|
||||
case Opcode::V_CMPX_EQ_F16:
|
||||
|
||||
@@ -138,6 +138,9 @@ bool Translator::EmitVector(const Decoder::Instruction& inst) {
|
||||
case O::V_CMP_LT_U16:
|
||||
EmitInteger16Compare(inst, IR::ValueOpcode::ULessThan32, false, false);
|
||||
return true;
|
||||
case O::V_CMPX_LT_U16:
|
||||
EmitInteger16Compare(inst, IR::ValueOpcode::ULessThan32, false, true);
|
||||
return true;
|
||||
case O::V_CMP_LE_U16:
|
||||
EmitInteger16Compare(inst, IR::ValueOpcode::ULessThanEqual32, false, false);
|
||||
return true;
|
||||
@@ -370,6 +373,7 @@ bool Translator::EmitVector(const Decoder::Instruction& inst) {
|
||||
case O::V_CEIL_F16: return Float16Unary(inst, IR::ValueOpcode::FPCeil32, false);
|
||||
case O::V_TRUNC_F16: return Float16Unary(inst, IR::ValueOpcode::FPTrunc32, false);
|
||||
case O::V_RNDNE_F16: return Float16Unary(inst, IR::ValueOpcode::FPRoundEven32, false);
|
||||
case O::V_FRACT_F16: return Float16Unary(inst, IR::ValueOpcode::FPFract32, false);
|
||||
case O::V_SIN_F16: return Float16Trig(inst, IR::ValueOpcode::FPSin);
|
||||
case O::V_COS_F16: return Float16Trig(inst, IR::ValueOpcode::FPCos);
|
||||
case O::V_MIN3_F16: return Float16Ternary(inst, IR::ValueOpcode::FPMinTri32, false, false);
|
||||
|
||||
Reference in New Issue
Block a user