Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JIT ARM64/SVE2: Add increment/decrement from predicate register instructions #94811

Merged
merged 28 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6b9db26
Add incp/decp
amanasifkhalid Nov 15, 2023
f96fa21
Add saturating inc/dec instructions
amanasifkhalid Nov 15, 2023
91fc564
Add SVE_DO_2A format
amanasifkhalid Nov 15, 2023
fbfdc9b
Fix build
amanasifkhalid Nov 15, 2023
83bcb09
Merge from main; address feedback
amanasifkhalid Nov 22, 2023
13d8fb6
Merge branch 'main' into arm64-sve2
amanasifkhalid Nov 27, 2023
52f5a50
Fix unit tests
amanasifkhalid Nov 27, 2023
d000a17
Update PerfScores
amanasifkhalid Nov 27, 2023
36becce
Fix merge conflict
amanasifkhalid Dec 5, 2023
ebc6141
Fix encodings
amanasifkhalid Dec 11, 2023
158c71d
Clean up IF_SVE_DO_2A
amanasifkhalid Dec 11, 2023
46f2b67
Add comment
amanasifkhalid Dec 11, 2023
a8e634b
Merge from main
amanasifkhalid Dec 11, 2023
4fe7266
Style; comment ALL_ARM64_EMITTER_UNIT_TESTS
amanasifkhalid Dec 11, 2023
90c5bbe
Revert comment
amanasifkhalid Dec 11, 2023
3c3148a
Delete unused variables
amanasifkhalid Dec 11, 2023
b72b908
Formatting
amanasifkhalid Dec 11, 2023
953bb55
Add missing asserts
amanasifkhalid Dec 12, 2023
c15420a
Remove debug code
amanasifkhalid Dec 12, 2023
59ae6e2
Merge branch 'main' into arm64-sve2
amanasifkhalid Dec 12, 2023
9e14baa
Fix build
amanasifkhalid Dec 12, 2023
059b027
Merge
amanasifkhalid Dec 15, 2023
3361154
Add emitDispInsHelp comments
amanasifkhalid Dec 17, 2023
02c03ed
Merge from main; update emitDispPredicateReg to use PREDICATE_SIZED
amanasifkhalid Dec 18, 2023
538f524
Use INS_OPTS_SCALABLE_B_WITH_SCALAR
amanasifkhalid Dec 18, 2023
51d0b1c
Remove old code
amanasifkhalid Dec 18, 2023
0744ee9
Merge from main
amanasifkhalid Dec 18, 2023
dbe6add
Style
amanasifkhalid Dec 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions src/coreclr/jit/codegenarm64test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5120,6 +5120,138 @@ void CodeGen::genArm64EmitterUnitTestsSve()
theEmitter->emitIns_R_R_I(INS_sve_uqrshrn, EA_SCALABLE, REG_V15, REG_V12, 1,
INS_OPTS_SCALABLE_H); // UQRSHRN <Zd>.H, {<Zn1>.S-<Zn2>.S }, #<const>

// IF_SVE_DM_2A
theEmitter->emitIns_R_R(INS_sve_decp, EA_8BYTE, REG_R0, REG_P0,
INS_OPTS_SCALABLE_B_WITH_SCALAR); // DECP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_decp, EA_8BYTE, REG_R1, REG_P1,
INS_OPTS_SCALABLE_H_WITH_SCALAR); // DECP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_decp, EA_8BYTE, REG_R2, REG_P2,
INS_OPTS_SCALABLE_S_WITH_SCALAR); // DECP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_decp, EA_8BYTE, REG_R3, REG_P3,
INS_OPTS_SCALABLE_D_WITH_SCALAR); // DECP <Xdn>, <Pm>.<T>

theEmitter->emitIns_R_R(INS_sve_incp, EA_8BYTE, REG_R4, REG_P4,
INS_OPTS_SCALABLE_B_WITH_SCALAR); // INCP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_incp, EA_8BYTE, REG_R5, REG_P5,
INS_OPTS_SCALABLE_H_WITH_SCALAR); // INCP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_incp, EA_8BYTE, REG_R6, REG_P6,
INS_OPTS_SCALABLE_S_WITH_SCALAR); // INCP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_incp, EA_8BYTE, REG_R7, REG_P7,
INS_OPTS_SCALABLE_D_WITH_SCALAR); // INCP <Xdn>, <Pm>.<T>

// IF_SVE_DN_2A
// Note: B is reserved
theEmitter->emitIns_R_R(INS_sve_decp, EA_SCALABLE, REG_V0, REG_P0, INS_OPTS_SCALABLE_H); // DECP <Zdn>.<T>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_decp, EA_SCALABLE, REG_V1, REG_P1, INS_OPTS_SCALABLE_S); // DECP <Zdn>.<T>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_decp, EA_SCALABLE, REG_V2, REG_P2, INS_OPTS_SCALABLE_D); // DECP <Zdn>.<T>, <Pm>.<T>

theEmitter->emitIns_R_R(INS_sve_incp, EA_SCALABLE, REG_V3, REG_P3, INS_OPTS_SCALABLE_H); // INCP <Zdn>.<T>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_incp, EA_SCALABLE, REG_V4, REG_P4, INS_OPTS_SCALABLE_S); // INCP <Zdn>.<T>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_incp, EA_SCALABLE, REG_V5, REG_P5, INS_OPTS_SCALABLE_D); // INCP <Zdn>.<T>, <Pm>.<T>

// IF_SVE_DO_2A
theEmitter->emitIns_R_R(INS_sve_sqdecp, EA_4BYTE, REG_R0, REG_P0,
INS_OPTS_SCALABLE_B_WITH_SCALAR); // SQDECP <Xdn>, <Pm>.<T>, <Wdn>
theEmitter->emitIns_R_R(INS_sve_sqdecp, EA_4BYTE, REG_R1, REG_P1,
INS_OPTS_SCALABLE_H_WITH_SCALAR); // SQDECP <Xdn>, <Pm>.<T>, <Wdn>
theEmitter->emitIns_R_R(INS_sve_sqdecp, EA_4BYTE, REG_R2, REG_P2,
INS_OPTS_SCALABLE_S_WITH_SCALAR); // SQDECP <Xdn>, <Pm>.<T>, <Wdn>
theEmitter->emitIns_R_R(INS_sve_sqdecp, EA_4BYTE, REG_R3, REG_P3,
INS_OPTS_SCALABLE_D_WITH_SCALAR); // SQDECP <Xdn>, <Pm>.<T>, <Wdn>

theEmitter->emitIns_R_R(INS_sve_sqdecp, EA_8BYTE, REG_R4, REG_P4,
INS_OPTS_SCALABLE_B_WITH_SCALAR); // SQDECP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_sqdecp, EA_8BYTE, REG_R5, REG_P5,
INS_OPTS_SCALABLE_H_WITH_SCALAR); // SQDECP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_sqdecp, EA_8BYTE, REG_R6, REG_P6,
INS_OPTS_SCALABLE_S_WITH_SCALAR); // SQDECP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_sqdecp, EA_8BYTE, REG_R7, REG_P7,
INS_OPTS_SCALABLE_D_WITH_SCALAR); // SQDECP <Xdn>, <Pm>.<T>

theEmitter->emitIns_R_R(INS_sve_sqincp, EA_4BYTE, REG_R0, REG_P0,
INS_OPTS_SCALABLE_H_WITH_SCALAR); // SQINCP <Xdn>, <Pm>.<T>, <Wdn>
theEmitter->emitIns_R_R(INS_sve_sqincp, EA_4BYTE, REG_R1, REG_P1,
INS_OPTS_SCALABLE_S_WITH_SCALAR); // SQINCP <Xdn>, <Pm>.<T>, <Wdn>
theEmitter->emitIns_R_R(INS_sve_sqincp, EA_4BYTE, REG_R2, REG_P2,
INS_OPTS_SCALABLE_B_WITH_SCALAR); // SQINCP <Xdn>, <Pm>.<T>, <Wdn>
theEmitter->emitIns_R_R(INS_sve_sqincp, EA_4BYTE, REG_R3, REG_P3,
INS_OPTS_SCALABLE_D_WITH_SCALAR); // SQINCP <Xdn>, <Pm>.<T>, <Wdn>

theEmitter->emitIns_R_R(INS_sve_sqincp, EA_8BYTE, REG_R4, REG_P4,
INS_OPTS_SCALABLE_B_WITH_SCALAR); // SQINCP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_sqincp, EA_8BYTE, REG_R5, REG_P5,
INS_OPTS_SCALABLE_H_WITH_SCALAR); // SQINCP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_sqincp, EA_8BYTE, REG_R6, REG_P6,
INS_OPTS_SCALABLE_S_WITH_SCALAR); // SQINCP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_sqincp, EA_8BYTE, REG_R7, REG_P7,
INS_OPTS_SCALABLE_D_WITH_SCALAR); // SQINCP <Xdn>, <Pm>.<T>

theEmitter->emitIns_R_R(INS_sve_uqdecp, EA_4BYTE, REG_R0, REG_P0,
INS_OPTS_SCALABLE_B_WITH_SCALAR); // UQDECP <Wdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqdecp, EA_4BYTE, REG_R1, REG_P1,
INS_OPTS_SCALABLE_H_WITH_SCALAR); // UQDECP <Wdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqdecp, EA_4BYTE, REG_R2, REG_P2,
INS_OPTS_SCALABLE_S_WITH_SCALAR); // UQDECP <Wdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqdecp, EA_4BYTE, REG_R3, REG_P3,
INS_OPTS_SCALABLE_D_WITH_SCALAR); // UQDECP <Wdn>, <Pm>.<T>

theEmitter->emitIns_R_R(INS_sve_uqdecp, EA_8BYTE, REG_R4, REG_P4,
INS_OPTS_SCALABLE_B_WITH_SCALAR); // UQDECP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqdecp, EA_8BYTE, REG_R5, REG_P5,
INS_OPTS_SCALABLE_H_WITH_SCALAR); // UQDECP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqdecp, EA_8BYTE, REG_R6, REG_P6,
INS_OPTS_SCALABLE_S_WITH_SCALAR); // UQDECP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqdecp, EA_8BYTE, REG_R7, REG_P7,
INS_OPTS_SCALABLE_D_WITH_SCALAR); // UQDECP <Xdn>, <Pm>.<T>

theEmitter->emitIns_R_R(INS_sve_uqincp, EA_4BYTE, REG_R0, REG_P0,
INS_OPTS_SCALABLE_B_WITH_SCALAR); // UQINCP <Wdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqincp, EA_4BYTE, REG_R1, REG_P1,
INS_OPTS_SCALABLE_H_WITH_SCALAR); // UQINCP <Wdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqincp, EA_4BYTE, REG_R2, REG_P2,
INS_OPTS_SCALABLE_S_WITH_SCALAR); // UQINCP <Wdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqincp, EA_4BYTE, REG_R3, REG_P3,
INS_OPTS_SCALABLE_D_WITH_SCALAR); // UQINCP <Wdn>, <Pm>.<T>

theEmitter->emitIns_R_R(INS_sve_uqincp, EA_8BYTE, REG_R4, REG_P4,
INS_OPTS_SCALABLE_B_WITH_SCALAR); // UQINCP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqincp, EA_8BYTE, REG_R5, REG_P5,
INS_OPTS_SCALABLE_H_WITH_SCALAR); // UQINCP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqincp, EA_8BYTE, REG_R6, REG_P6,
INS_OPTS_SCALABLE_S_WITH_SCALAR); // UQINCP <Xdn>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqincp, EA_8BYTE, REG_R7, REG_P7,
INS_OPTS_SCALABLE_D_WITH_SCALAR); // UQINCP <Xdn>, <Pm>.<T>

// IF_SVE_DP_2A
// NOTE: B is reserved
theEmitter->emitIns_R_R(INS_sve_sqdecp, EA_SCALABLE, REG_V0, REG_P0,
INS_OPTS_SCALABLE_H); // SQDECP <Zdn>.<T>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_sqdecp, EA_SCALABLE, REG_V1, REG_P1,
INS_OPTS_SCALABLE_S); // SQDECP <Zdn>.<T>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_sqdecp, EA_SCALABLE, REG_V2, REG_P2,
INS_OPTS_SCALABLE_D); // SQDECP <Zdn>.<T>, <Pm>.<T>

theEmitter->emitIns_R_R(INS_sve_sqincp, EA_SCALABLE, REG_V3, REG_P3,
INS_OPTS_SCALABLE_H); // SQINCP <Zdn>.<T>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_sqincp, EA_SCALABLE, REG_V4, REG_P4,
INS_OPTS_SCALABLE_S); // SQINCP <Zdn>.<T>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_sqincp, EA_SCALABLE, REG_V5, REG_P5,
INS_OPTS_SCALABLE_D); // SQINCP <Zdn>.<T>, <Pm>.<T>

theEmitter->emitIns_R_R(INS_sve_uqdecp, EA_SCALABLE, REG_V6, REG_P6,
INS_OPTS_SCALABLE_H); // UQDECP <Zdn>.<T>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqdecp, EA_SCALABLE, REG_V7, REG_P7,
INS_OPTS_SCALABLE_S); // UQDECP <Zdn>.<T>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqdecp, EA_SCALABLE, REG_V8, REG_P0,
INS_OPTS_SCALABLE_D); // UQDECP <Zdn>.<T>, <Pm>.<T>

theEmitter->emitIns_R_R(INS_sve_uqincp, EA_SCALABLE, REG_V9, REG_P1,
INS_OPTS_SCALABLE_H); // UQINCP <Zdn>.<T>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqincp, EA_SCALABLE, REG_V10, REG_P2,
INS_OPTS_SCALABLE_S); // UQINCP <Zdn>.<T>, <Pm>.<T>
theEmitter->emitIns_R_R(INS_sve_uqincp, EA_SCALABLE, REG_V11, REG_P3,
INS_OPTS_SCALABLE_D); // UQINCP <Zdn>.<T>, <Pm>.<T>

// IF_SVE_DQ_0A
theEmitter->emitIns_I(INS_sve_setffr, EA_PTRSIZE, 0); // SETFFR

Expand Down
136 changes: 132 additions & 4 deletions src/coreclr/jit/emitarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1182,11 +1182,29 @@ void emitter::emitInsSanityCheck(instrDesc* id)
break;

case IF_SVE_GA_2A: // ............iiii ......nnnn.ddddd -- SME2 multi-vec shift narrow
elemsize = id->idOpSize();
assert(id->idInsOpt() == INS_OPTS_SCALABLE_H);
assert(isVectorRegister(id->idReg1())); // nnnn
assert(isVectorRegister(id->idReg2())); // ddddd
assert(id->idInsOpt() == INS_OPTS_SCALABLE_H);
assert(isScalableVectorSize(elemsize));
assert(isScalableVectorSize(id->idOpSize()));
break;

case IF_SVE_DO_2A: // ........xx...... .....X.MMMMddddd -- SVE saturating inc/dec register by predicate count
assert(isValidGeneralDatasize(id->idOpSize())); // X

FALLTHROUGH;
case IF_SVE_DM_2A: // ........xx...... .......MMMMddddd -- SVE inc/dec register by predicate count
assert(insOptsScalableWithScalar(id->idInsOpt())); // xx
assert(isGeneralRegister(id->idReg1())); // ddddd
assert(isPredicateRegister(id->idReg2())); // MMMM
assert(isValidGeneralDatasize(id->idOpSize()));
break;

case IF_SVE_DP_2A: // ........xx...... .......MMMMddddd -- SVE saturating inc/dec vector by predicate count
case IF_SVE_DN_2A: // ........xx...... .......MMMMddddd -- SVE inc/dec vector by predicate count
assert(insOptsScalableAtLeastHalf(id->idInsOpt())); // xx
assert(isPredicateRegister(id->idReg1())); // MMMM
assert(isVectorRegister(id->idReg2())); // ddddd
assert(isScalableVectorSize(id->idOpSize()));
break;

case IF_SVE_DQ_0A: // ................ ................ -- SVE FFR initialise
Expand All @@ -1205,7 +1223,6 @@ void emitter::emitInsSanityCheck(instrDesc* id)
break;

case IF_SVE_GD_2A: // .........x.xx... ......nnnnnddddd -- SVE2 saturating extract narrow
elemsize = id->idOpSize();
assert(insOptsScalableSimple(id->idInsOpt()));
assert(isVectorRegister(id->idReg1())); // nnnnn
assert(isVectorRegister(id->idReg2())); // ddddd
Expand Down Expand Up @@ -6884,6 +6901,46 @@ void emitter::emitIns_R_R(
}
break;

case INS_sve_incp:
case INS_sve_decp:
assert(isPredicateRegister(reg2)); // MMMM

if (isGeneralRegister(reg1)) // ddddd
{
assert(insOptsScalableWithScalar(opt)); // xx
assert(size == EA_8BYTE);
fmt = IF_SVE_DM_2A;
}
else
{
assert(insOptsScalableAtLeastHalf(opt)); // xx
assert(isVectorRegister(reg1)); // ddddd
assert(isScalableVectorSize(size));
fmt = IF_SVE_DN_2A;
}
break;

case INS_sve_sqincp:
case INS_sve_uqincp:
case INS_sve_sqdecp:
case INS_sve_uqdecp:
assert(isPredicateRegister(reg2)); // MMMM

if (isGeneralRegister(reg1)) // ddddd
{
assert(insOptsScalableWithScalar(opt)); // xx
assert(isValidGeneralDatasize(size));
fmt = IF_SVE_DO_2A;
}
else
{
assert(insOptsScalableAtLeastHalf(opt)); // xx
assert(isVectorRegister(reg1)); // ddddd
assert(isScalableVectorSize(size));
fmt = IF_SVE_DP_2A;
}
break;

case INS_sve_ctermeq:
case INS_sve_ctermne:
assert(insOptsNone(opt));
Expand Down Expand Up @@ -14849,6 +14906,32 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
dst += emitOutput_Instr(dst, code);
break;

case IF_SVE_DM_2A: // ........xx...... .......MMMMddddd -- SVE inc/dec register by predicate count
code = emitInsCodeSve(ins, fmt);
code |= insEncodeReg_R_4_to_0(id->idReg1()); // ddddd
code |= insEncodeReg_P_8_to_5(id->idReg2()); // MMMM
code |= insEncodeSveElemsize(optGetSveElemsize(id->idInsOpt())); // xx
dst += emitOutput_Instr(dst, code);
break;

case IF_SVE_DN_2A: // ........xx...... .......MMMMddddd -- SVE inc/dec vector by predicate count
case IF_SVE_DP_2A: // ........xx...... .......MMMMddddd -- SVE saturating inc/dec vector by predicate count
code = emitInsCodeSve(ins, fmt);
code |= insEncodeReg_V_4_to_0(id->idReg1()); // ddddd
code |= insEncodeReg_P_8_to_5(id->idReg2()); // MMMM
code |= insEncodeSveElemsize(optGetSveElemsize(id->idInsOpt())); // xx
dst += emitOutput_Instr(dst, code);
break;

case IF_SVE_DO_2A: // ........xx...... .....X.MMMMddddd -- SVE saturating inc/dec register by predicate count
code = emitInsCodeSve(ins, fmt);
code |= insEncodeReg_R_4_to_0(id->idReg1()); // ddddd
code |= insEncodeReg_P_8_to_5(id->idReg2()); // MMMM
code |= insEncodeVLSElemsize(id->idOpSize()); // X
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically, you could combine this with IF_SVE_DM_2A, but lets do it in cleanup phase.

case IF_SVE_DO_2A:
  code |= insEncodeVLSElemsize(id->idOpSize());                    // X
  FALLTHROUGH;

case IF_SVE_DM_2A:
  ...

code |= insEncodeSveElemsize(optGetSveElemsize(id->idInsOpt())); // xx
dst += emitOutput_Instr(dst, code);
break;

case IF_SVE_DQ_0A: // ................ ................ -- SVE FFR initialise
code = emitInsCodeSve(ins, fmt);
dst += emitOutput_Instr(dst, code);
Expand Down Expand Up @@ -17278,6 +17361,43 @@ void emitter::emitDispInsHelp(
emitDispImm(emitGetInsSC(id), false); // iiii
break;

// <Xdn>, <Pm>.<T>
case IF_SVE_DM_2A: // ........xx...... .......MMMMddddd -- SVE inc/dec register by predicate count
emitDispReg(id->idReg1(), id->idOpSize(), true); // ddddd
emitDispPredicateReg(id->idReg2(), PREDICATE_SIZED, id->idInsOpt(), false); // MMMM
break;

// <Zdn>.<T>, <Pm>.<T>
case IF_SVE_DN_2A: // ........xx...... .......MMMMddddd -- SVE inc/dec vector by predicate count
case IF_SVE_DP_2A: // ........xx...... .......MMMMddddd -- SVE saturating inc/dec vector by predicate count
emitDispSveReg(id->idReg1(), id->idInsOpt(), true); // ddddd
emitDispPredicateReg(id->idReg2(), PREDICATE_SIZED, id->idInsOpt(), false); // MMMM
break;

// <Xdn>, <Pm>.<T>, <Wdn>
// <Xdn>, <Pm>.<T>
case IF_SVE_DO_2A: // ........xx...... .....X.MMMMddddd -- SVE saturating inc/dec register by predicate count
if ((ins == INS_sve_sqdecp) || (ins == INS_sve_sqincp))
{
// 32-bit result: <Xdn>, <Pm>.<T>, <Wdn>
// 64-bit result: <Xdn>, <Pm>.<T>
const bool is32BitResult = (id->idOpSize() == EA_4BYTE); // X
emitDispReg(id->idReg1(), EA_8BYTE, true); // ddddd
emitDispPredicateReg(id->idReg2(), PREDICATE_SIZED, id->idInsOpt(), is32BitResult); // MMMM

if (is32BitResult)
{
emitDispReg(id->idReg1(), EA_4BYTE, false);
}
}
else
{
assert((ins == INS_sve_uqdecp) || (ins == INS_sve_uqincp));
emitDispReg(id->idReg1(), id->idOpSize(), true); // ddddd
emitDispPredicateReg(id->idReg2(), PREDICATE_SIZED, id->idInsOpt(), false); // MMMM
}
break;

// none
case IF_SVE_DQ_0A: // ................ ................ -- SVE FFR initialise
break;
Expand Down Expand Up @@ -19805,6 +19925,14 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins
}
break;

case IF_SVE_DM_2A: // ........xx...... .......MMMMddddd -- SVE inc/dec register by predicate count
case IF_SVE_DN_2A: // ........xx...... .......MMMMddddd -- SVE inc/dec vector by predicate count
case IF_SVE_DP_2A: // ........xx...... .......MMMMddddd -- SVE saturating inc/dec vector by predicate count
case IF_SVE_DO_2A: // ........xx...... .....X.MMMMddddd -- SVE saturating inc/dec register by predicate count
result.insThroughput = PERFSCORE_THROUGHPUT_1C;
result.insLatency = PERFSCORE_LATENCY_7C;
break;

case IF_SVE_DQ_0A: // ................ ................ -- SVE FFR initialise
case IF_SVE_DR_1A: // ................ .......NNNN..... -- SVE FFR write from predicate
result.insThroughput = PERFSCORE_THROUGHPUT_1C;
Expand Down