From 2173f7d39bcd439626c3286ca9e0765d90fc0f76 Mon Sep 17 00:00:00 2001 From: TIHan Date: Wed, 6 Dec 2023 13:09:53 -0800 Subject: [PATCH 1/4] Added SVE_GK_2A and SVE_GL_1A arm64 encodings --- src/coreclr/jit/codegenarm64.cpp | 12 +++++ src/coreclr/jit/emitarm64.cpp | 79 +++++++++++++++++++++++++++++++- src/coreclr/jit/emitarm64.h | 2 +- 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 0ffcecddb0214..47f094e447be1 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -10533,6 +10533,18 @@ void CodeGen::genArm64EmitterUnitTests() theEmitter->emitIns_R_R_I(INS_sve_uqrshrn, EA_SCALABLE, REG_V15, REG_V12, 1, INS_OPTS_SCALABLE_H); // UQRSHRN .H, {.S-.S }, # + // IF_SVE_GK_2A + theEmitter->emitIns_R_R(INS_sve_aesd, EA_SCALABLE, REG_V0, REG_V0, INS_OPTS_SCALABLE_B); // AESD .B, + // .B, .B + theEmitter->emitIns_R_R(INS_sve_aese, EA_SCALABLE, REG_V1, REG_V2, INS_OPTS_SCALABLE_B); // AESE .B, + // .B, .B + theEmitter->emitIns_R_R(INS_sve_sm4e, EA_SCALABLE, REG_V3, REG_V5, INS_OPTS_SCALABLE_B); // SM4E .S, + // .S, .S + + // IF_SVE_GL_1A + theEmitter->emitIns_R(INS_sve_aesimc, EA_SCALABLE, REG_V0, INS_OPTS_SCALABLE_B); // AESIMC .B, .B + theEmitter->emitIns_R(INS_sve_aesmc, EA_SCALABLE, REG_V5, INS_OPTS_SCALABLE_B); // AESMC .B, .B + #endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE #ifdef ALL_ARM64_EMITTER_UNIT_TESTS diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index dfdd84461cc01..7dffe58602947 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -1124,6 +1124,22 @@ void emitter::emitInsSanityCheck(instrDesc* id) assert(id->idInsOpt() == INS_OPTS_SCALABLE_H); break; + case IF_SVE_GK_2A: // ................ ......mmmmmddddd -- SVE2 crypto destructive binary operations + elemsize = id->idOpSize(); + assert(insOptsScalable(id->idInsOpt())); + assert(isVectorRegister(id->idReg1())); // mmmmm + assert(isVectorRegister(id->idReg2())); // ddddd + assert(id->idInsOpt() == INS_OPTS_SCALABLE_B); + assert(isScalableVectorSize(elemsize)); + break; + + case IF_SVE_GL_1A: // ................ ...........ddddd -- SVE2 crypto unary operations + elemsize = id->idOpSize(); + assert(insOptsScalable(id->idInsOpt())); + assert(isVectorRegister(id->idReg1())); // ddddd + assert(isScalableVectorSize(elemsize)); + break; + default: printf("unexpected format %s\n", emitIfName(id->idInsFmt())); assert(!"Unexpected format"); @@ -5468,7 +5484,7 @@ void emitter::emitIns_I(instruction ins, emitAttr attr, ssize_t imm) * Add an instruction referencing a single register. */ -void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg) +void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg, insOpts opt /* = INS_OPTS_NONE */) { insFormat fmt = IF_NONE; instrDesc* id = nullptr; @@ -5478,6 +5494,7 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg) { case INS_br: case INS_ret: + assert(opt == INS_OPTS_NONE); assert(isGeneralRegister(reg)); id = emitNewInstrSmall(attr); id->idReg1(reg); @@ -5485,6 +5502,7 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg) break; case INS_dczva: + assert(opt == INS_OPTS_NONE); assert(isGeneralRegister(reg)); assert(attr == EA_8BYTE); id = emitNewInstrSmall(attr); @@ -5493,11 +5511,24 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg) break; case INS_mrs_tpid0: + assert(opt == INS_OPTS_NONE); id = emitNewInstrSmall(attr); id->idReg1(reg); fmt = IF_SR_1A; break; + case INS_sve_aesmc: + case INS_sve_aesimc: + assert(opt == INS_OPTS_SCALABLE_B); + id = emitNewInstrSmall(attr); + id->idInsOpt(opt); + id->idReg1(reg); + assert(insOptsScalable(id->idInsOpt())); + assert(isVectorRegister(reg)); // ddddd + assert(isScalableVectorSize(attr)); + fmt = IF_SVE_GL_1A; + break; + default: unreached(); } @@ -6688,6 +6719,16 @@ void emitter::emitIns_R_R( } break; + case INS_sve_aese: + case INS_sve_aesd: + case INS_sve_sm4e: + assert(insOptsScalable(opt)); + assert(isVectorRegister(reg1)); + assert(isVectorRegister(reg2)); + assert(opt == INS_OPTS_SCALABLE_B); + fmt = IF_SVE_GK_2A; + break; + default: unreached(); break; @@ -14355,6 +14396,19 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) dst += emitOutput_Instr(dst, code); break; + case IF_SVE_GK_2A: // ................ ......mmmmmddddd -- SVE2 crypto destructive binary operations + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_V_4_to_0(id->idReg1()); // ddddd + code |= insEncodeReg_V_9_to_5(id->idReg2()); // mmmmm + dst += emitOutput_Instr(dst, code); + break; + + case IF_SVE_GL_1A: // ................ ...........ddddd -- SVE2 crypto unary operations + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_V_4_to_0(id->idReg1()); // ddddd + dst += emitOutput_Instr(dst, code); + break; + default: assert(!"Unexpected format"); break; @@ -16695,6 +16749,19 @@ void emitter::emitDispInsHelp( emitDispImm(emitGetInsSC(id), false); // iiii break; + // .B, .B, .B + case IF_SVE_GK_2A: // ................ ......mmmmmddddd -- SVE2 crypto destructive binary operations + emitDispSveReg(id->idReg1(), id->idInsOpt(), true); // ddddd + emitDispSveReg(id->idReg1(), id->idInsOpt(), true); // ddddd + emitDispSveReg(id->idReg2(), id->idInsOpt(), false); // mmmmm + break; + + // .B, .B + case IF_SVE_GL_1A: // ................ ...........ddddd -- SVE2 crypto unary operations + emitDispSveReg(id->idReg1(), id->idInsOpt(), true); // ddddd + emitDispSveReg(id->idReg1(), id->idInsOpt(), false); // ddddd + break; + default: printf("unexpected format %s", emitIfName(id->idInsFmt())); assert(!"unexpectedFormat"); @@ -19121,6 +19188,16 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins } break; + case IF_SVE_GK_2A: // ................ ......mmmmmddddd -- SVE2 crypto destructive binary operations + result.insThroughput = PERFSCORE_THROUGHPUT_2C; + result.insLatency = PERFSCORE_LATENCY_2C; + break; + + case IF_SVE_GL_1A: // ................ ...........ddddd -- SVE2 crypto unary operations + result.insThroughput = PERFSCORE_THROUGHPUT_2C; + result.insLatency = PERFSCORE_LATENCY_2C; + break; + default: // all other instructions perfScoreUnhandledInstruction(id, &result); diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index 064906cb9d0c9..6352481904438 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -963,7 +963,7 @@ void emitIns(instruction ins); void emitIns_I(instruction ins, emitAttr attr, ssize_t imm); -void emitIns_R(instruction ins, emitAttr attr, regNumber reg); +void emitIns_R(instruction ins, emitAttr attr, regNumber reg, insOpts opt = INS_OPTS_NONE); void emitIns_R_I(instruction ins, emitAttr attr, From 5b26c63ea0e65b67e3b0815928d0c647cfcec444 Mon Sep 17 00:00:00 2001 From: TIHan Date: Wed, 6 Dec 2023 13:39:47 -0800 Subject: [PATCH 2/4] Use SCALABLE_S for sm4e --- src/coreclr/jit/codegenarm64.cpp | 2 +- src/coreclr/jit/emitarm64.cpp | 27 +++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 47f094e447be1..dc41f3fe80557 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -10538,7 +10538,7 @@ void CodeGen::genArm64EmitterUnitTests() // .B, .B theEmitter->emitIns_R_R(INS_sve_aese, EA_SCALABLE, REG_V1, REG_V2, INS_OPTS_SCALABLE_B); // AESE .B, // .B, .B - theEmitter->emitIns_R_R(INS_sve_sm4e, EA_SCALABLE, REG_V3, REG_V5, INS_OPTS_SCALABLE_B); // SM4E .S, + theEmitter->emitIns_R_R(INS_sve_sm4e, EA_SCALABLE, REG_V3, REG_V5, INS_OPTS_SCALABLE_S); // SM4E .S, // .S, .S // IF_SVE_GL_1A diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 7dffe58602947..5b691ef64c9b7 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -1127,9 +1127,18 @@ void emitter::emitInsSanityCheck(instrDesc* id) case IF_SVE_GK_2A: // ................ ......mmmmmddddd -- SVE2 crypto destructive binary operations elemsize = id->idOpSize(); assert(insOptsScalable(id->idInsOpt())); - assert(isVectorRegister(id->idReg1())); // mmmmm - assert(isVectorRegister(id->idReg2())); // ddddd - assert(id->idInsOpt() == INS_OPTS_SCALABLE_B); + assert(isVectorRegister(id->idReg1())); // ddddd + assert(isVectorRegister(id->idReg2())); // mmmmm +#ifdef DEBUG + if (id->idInsOpt() == INS_OPTS_SCALABLE_S) + { + assert(id->idIns() == INS_sve_sm4e); + } + else + { + assert(id->idInsOpt() == INS_OPTS_SCALABLE_B); + } +#endif // DEBUG assert(isScalableVectorSize(elemsize)); break; @@ -6725,7 +6734,16 @@ void emitter::emitIns_R_R( assert(insOptsScalable(opt)); assert(isVectorRegister(reg1)); assert(isVectorRegister(reg2)); - assert(opt == INS_OPTS_SCALABLE_B); +#ifdef DEBUG + if (opt == INS_OPTS_SCALABLE_S) + { + assert(ins == INS_sve_sm4e); + } + else + { + assert(opt == INS_OPTS_SCALABLE_B); + } +#endif // DEBUG fmt = IF_SVE_GK_2A; break; @@ -16750,6 +16768,7 @@ void emitter::emitDispInsHelp( break; // .B, .B, .B + // .S, .S, .S case IF_SVE_GK_2A: // ................ ......mmmmmddddd -- SVE2 crypto destructive binary operations emitDispSveReg(id->idReg1(), id->idInsOpt(), true); // ddddd emitDispSveReg(id->idReg1(), id->idInsOpt(), true); // ddddd From 7d64a6738c0a8bb5edff6a9dbb4a835b1fd80482 Mon Sep 17 00:00:00 2001 From: TIHan Date: Wed, 6 Dec 2023 14:12:30 -0800 Subject: [PATCH 3/4] Formatting --- src/coreclr/jit/emitarm64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 5b691ef64c9b7..b3020f90a85e1 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -16777,7 +16777,7 @@ void emitter::emitDispInsHelp( // .B, .B case IF_SVE_GL_1A: // ................ ...........ddddd -- SVE2 crypto unary operations - emitDispSveReg(id->idReg1(), id->idInsOpt(), true); // ddddd + emitDispSveReg(id->idReg1(), id->idInsOpt(), true); // ddddd emitDispSveReg(id->idReg1(), id->idInsOpt(), false); // ddddd break; From 815257d02fad4c8e20a480f7fb749830898a3e70 Mon Sep 17 00:00:00 2001 From: TIHan Date: Thu, 7 Dec 2023 10:51:03 -0800 Subject: [PATCH 4/4] Removing `insOpts opt` from emitIns_R --- src/coreclr/jit/codegenarm64.cpp | 4 ++-- src/coreclr/jit/emitarm64.cpp | 9 ++------- src/coreclr/jit/emitarm64.h | 2 +- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index dc41f3fe80557..0b5f462e12c89 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -10542,8 +10542,8 @@ void CodeGen::genArm64EmitterUnitTests() // .S, .S // IF_SVE_GL_1A - theEmitter->emitIns_R(INS_sve_aesimc, EA_SCALABLE, REG_V0, INS_OPTS_SCALABLE_B); // AESIMC .B, .B - theEmitter->emitIns_R(INS_sve_aesmc, EA_SCALABLE, REG_V5, INS_OPTS_SCALABLE_B); // AESMC .B, .B + theEmitter->emitIns_R(INS_sve_aesimc, EA_SCALABLE, REG_V0); // AESIMC .B, .B + theEmitter->emitIns_R(INS_sve_aesmc, EA_SCALABLE, REG_V5); // AESMC .B, .B #endif // ALL_ARM64_EMITTER_UNIT_TESTS_SVE diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index b3020f90a85e1..ac41408f3bd4e 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -5493,7 +5493,7 @@ void emitter::emitIns_I(instruction ins, emitAttr attr, ssize_t imm) * Add an instruction referencing a single register. */ -void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg, insOpts opt /* = INS_OPTS_NONE */) +void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg) { insFormat fmt = IF_NONE; instrDesc* id = nullptr; @@ -5503,7 +5503,6 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg, insOpts o { case INS_br: case INS_ret: - assert(opt == INS_OPTS_NONE); assert(isGeneralRegister(reg)); id = emitNewInstrSmall(attr); id->idReg1(reg); @@ -5511,7 +5510,6 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg, insOpts o break; case INS_dczva: - assert(opt == INS_OPTS_NONE); assert(isGeneralRegister(reg)); assert(attr == EA_8BYTE); id = emitNewInstrSmall(attr); @@ -5520,7 +5518,6 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg, insOpts o break; case INS_mrs_tpid0: - assert(opt == INS_OPTS_NONE); id = emitNewInstrSmall(attr); id->idReg1(reg); fmt = IF_SR_1A; @@ -5528,11 +5525,9 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg, insOpts o case INS_sve_aesmc: case INS_sve_aesimc: - assert(opt == INS_OPTS_SCALABLE_B); id = emitNewInstrSmall(attr); - id->idInsOpt(opt); + id->idInsOpt(INS_OPTS_SCALABLE_B); id->idReg1(reg); - assert(insOptsScalable(id->idInsOpt())); assert(isVectorRegister(reg)); // ddddd assert(isScalableVectorSize(attr)); fmt = IF_SVE_GL_1A; diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index 6352481904438..064906cb9d0c9 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -963,7 +963,7 @@ void emitIns(instruction ins); void emitIns_I(instruction ins, emitAttr attr, ssize_t imm); -void emitIns_R(instruction ins, emitAttr attr, regNumber reg, insOpts opt = INS_OPTS_NONE); +void emitIns_R(instruction ins, emitAttr attr, regNumber reg); void emitIns_R_I(instruction ins, emitAttr attr,