From 2d6c1d5ab2c4f9d5c58d5e516cfe9c29e3686fff Mon Sep 17 00:00:00 2001 From: Sebastian Nickolls Date: Thu, 21 Mar 2024 13:14:37 +0000 Subject: [PATCH] Make the source encoding for groups IF_SVE_FZ_2A and IF_SVE_HG_2A consistent with other groups with similar operands --- src/coreclr/jit/codegenarm64test.cpp | 14 +++++++------- src/coreclr/jit/emitarm64.cpp | 19 +++++++++---------- src/coreclr/jit/emitarm64.h | 17 +++++++++++++++++ src/coreclr/jit/emitarm64sve.cpp | 15 +++++++++------ 4 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/coreclr/jit/codegenarm64test.cpp b/src/coreclr/jit/codegenarm64test.cpp index 3c02c968fe919d..946e38ff46707d 100644 --- a/src/coreclr/jit/codegenarm64test.cpp +++ b/src/coreclr/jit/codegenarm64test.cpp @@ -6329,16 +6329,16 @@ void CodeGen::genArm64EmitterUnitTestsSve() INS_OPTS_SCALABLE_S); // URSQRTE .S, /M, .S // IF_SVE_FZ_2A - theEmitter->emitIns_R_R(INS_sve_sqcvtn, EA_SCALABLE, REG_V0, REG_V1); // SQCVTN .H, {.S-.S } - theEmitter->emitIns_R_R(INS_sve_sqcvtun, EA_SCALABLE, REG_V6, REG_V7); // SQCVTUN .H, {.S-.S } - theEmitter->emitIns_R_R(INS_sve_uqcvtn, EA_SCALABLE, REG_V14, REG_V15); // UQCVTN .H, {.S-.S } + theEmitter->emitIns_R_R(INS_sve_sqcvtn, EA_SCALABLE, REG_V0, REG_V2); // SQCVTN .H, {.S-.S } + theEmitter->emitIns_R_R(INS_sve_sqcvtun, EA_SCALABLE, REG_V6, REG_V8); // SQCVTUN .H, {.S-.S } + theEmitter->emitIns_R_R(INS_sve_uqcvtn, EA_SCALABLE, REG_V14, REG_V16); // UQCVTN .H, {.S-.S } #ifdef ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_HG_2A - theEmitter->emitIns_R_R(INS_sve_bfcvtn, EA_SCALABLE, REG_V0, REG_V1); // BFCVTN .B, {.H-.H } - theEmitter->emitIns_R_R(INS_sve_fcvtn, EA_SCALABLE, REG_V2, REG_V3); // FCVTN .B, {.H-.H } - theEmitter->emitIns_R_R(INS_sve_fcvtnb, EA_SCALABLE, REG_V6, REG_V7); // FCVTNB .B, {.S-.S } - theEmitter->emitIns_R_R(INS_sve_fcvtnt, EA_SCALABLE, REG_V14, REG_V15); // FCVTNT .B, {.S-.S } + theEmitter->emitIns_R_R(INS_sve_bfcvtn, EA_SCALABLE, REG_V0, REG_V2); // BFCVTN .B, {.H-.H } + theEmitter->emitIns_R_R(INS_sve_fcvtn, EA_SCALABLE, REG_V2, REG_V4); // FCVTN .B, {.H-.H } + theEmitter->emitIns_R_R(INS_sve_fcvtnb, EA_SCALABLE, REG_V6, REG_V8); // FCVTNB .B, {.S-.S } + theEmitter->emitIns_R_R(INS_sve_fcvtnt, EA_SCALABLE, REG_V14, REG_V16); // FCVTNT .B, {.S-.S } #endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE_UNSUPPORTED // IF_SVE_GA_2A diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 2ba16a9b39c694..68770931df8ef9 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -1787,6 +1787,7 @@ void emitter::emitInsSanityCheck(instrDesc* id) assert(id->idInsOpt() == INS_OPTS_SCALABLE_H); assert(isVectorRegister(id->idReg1())); // nnnn assert(isVectorRegister(id->idReg2())); // ddddd + assert(isEvenRegister(id->idReg2())); assert(isScalableVectorSize(id->idOpSize())); break; @@ -1828,14 +1829,16 @@ void emitter::emitInsSanityCheck(instrDesc* id) case IF_SVE_FZ_2A: // ................ ......nnnn.ddddd -- SME2 multi-vec extract narrow assert(insOptsNone(id->idInsOpt())); - assert(isVectorRegister(id->idReg1())); // ddddd - assert(isLowVectorRegister(id->idReg2())); // nnnn + assert(isVectorRegister(id->idReg1())); // ddddd + assert(isVectorRegister(id->idReg2())); // nnnn + assert(isEvenRegister(id->idReg2())); break; case IF_SVE_HG_2A: // ................ ......nnnn.ddddd -- SVE2 FP8 downconverts assert(insOptsNone(id->idInsOpt())); - assert(isVectorRegister(id->idReg1())); // ddddd - assert(isLowVectorRegister(id->idReg2())); // nnnn + assert(isVectorRegister(id->idReg1())); // ddddd + assert(isVectorRegister(id->idReg2())); // nnnn + assert(isEvenRegister(id->idReg2())); break; case IF_SVE_GD_2A: // .........x.xx... ......nnnnnddddd -- SVE2 saturating extract narrow @@ -17276,9 +17279,7 @@ void emitter::emitDispInsHelp( case IF_SVE_FZ_2A: // ................ ......nnnn.ddddd -- SME2 multi-vec extract narrow { emitDispSveReg(id->idReg1(), INS_OPTS_SCALABLE_H, true); - const unsigned baseRegNum = id->idReg2() - REG_FP_FIRST; - const regNumber regNum = (regNumber)((baseRegNum * 2) + REG_FP_FIRST); - emitDispSveConsecutiveRegList(regNum, 2, INS_OPTS_SCALABLE_S, false); + emitDispSveConsecutiveRegList(id->idReg2(), 2, INS_OPTS_SCALABLE_S, false); break; } @@ -17286,9 +17287,7 @@ void emitter::emitDispInsHelp( case IF_SVE_HG_2A: // ................ ......nnnn.ddddd -- SVE2 FP8 downconverts { emitDispSveReg(id->idReg1(), INS_OPTS_SCALABLE_B, true); - const unsigned baseRegNum = id->idReg2() - REG_FP_FIRST; - const regNumber regNum = (regNumber)((baseRegNum * 2) + REG_FP_FIRST); - emitDispSveConsecutiveRegList(regNum, 2, INS_OPTS_SCALABLE_H, false); + emitDispSveConsecutiveRegList(id->idReg2(), 2, INS_OPTS_SCALABLE_H, false); break; } diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index 0ddf5a86c803c2..d19840c781b321 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -1187,6 +1187,23 @@ inline static bool isHighPredicateRegister(regNumber reg) return (reg >= REG_PREDICATE_HIGH_FIRST) && (reg <= REG_PREDICATE_HIGH_LAST); } +inline static bool isEvenRegister(regNumber reg) +{ + if (isGeneralRegister(reg)) + { + return ((reg - REG_INT_FIRST) % 2 == 0); + } + else if (isVectorRegister(reg)) + { + return ((reg - REG_FP_FIRST) % 2) == 0; + } + else + { + assert(isPredicateRegister(reg)); + return ((reg - REG_PREDICATE_FIRST) % 2) == 0; + } +} + inline static bool insOptsNone(insOpts opt) { return (opt == INS_OPTS_NONE); diff --git a/src/coreclr/jit/emitarm64sve.cpp b/src/coreclr/jit/emitarm64sve.cpp index 577d815379dbed..0a9a343cd7c0f2 100644 --- a/src/coreclr/jit/emitarm64sve.cpp +++ b/src/coreclr/jit/emitarm64sve.cpp @@ -2118,8 +2118,9 @@ void emitter::emitInsSve_R_R(instruction ins, case INS_sve_uqcvtn: case INS_sve_sqcvtun: assert(insOptsNone(opt)); - assert(isVectorRegister(reg1)); // ddddd - assert(isLowVectorRegister(reg2)); // nnnn + assert(isVectorRegister(reg1)); // ddddd + assert(isVectorRegister(reg2)); // nnnn + assert(isEvenRegister(reg2)); fmt = IF_SVE_FZ_2A; break; @@ -2129,8 +2130,9 @@ void emitter::emitInsSve_R_R(instruction ins, case INS_sve_fcvtnb: unreached(); // TODO-SVE: Not yet supported. assert(insOptsNone(opt)); - assert(isVectorRegister(reg1)); // ddddd - assert(isLowVectorRegister(reg2)); // nnnn + assert(isVectorRegister(reg1)); // ddddd + assert(isVectorRegister(reg2)); // nnnn + assert(isEvenRegister(reg2)); fmt = IF_SVE_HG_2A; break; @@ -2542,6 +2544,7 @@ void emitter::emitInsSve_R_R_I(instruction ins, isRightShift = emitInsIsVectorRightShift(ins); assert(isVectorRegister(reg1)); assert(isVectorRegister(reg2)); + assert(isEvenRegister(reg2)); assert(opt == INS_OPTS_SCALABLE_H); assert(isRightShift); // These are always right-shift. assert(isValidVectorShiftAmount(imm, EA_4BYTE, isRightShift)); @@ -10735,8 +10738,8 @@ BYTE* emitter::emitOutput_InstrSve(BYTE* dst, instrDesc* id) case IF_SVE_FZ_2A: // ................ ......nnnn.ddddd -- SME2 multi-vec extract narrow case IF_SVE_HG_2A: // ................ ......nnnn.ddddd -- SVE2 FP8 downconverts code = emitInsCodeSve(ins, fmt); - code |= insEncodeReg_V_4_to_0(id->idReg1()); // ddddd - code |= insEncodeReg_V_9_to_6(id->idReg2()); // nnnn + code |= insEncodeReg_V_4_to_0(id->idReg1()); // ddddd + code |= insEncodeReg_V_9_to_6_Times_Two(id->idReg2()); // nnnn dst += emitOutput_Instr(dst, code); break;