diff --git a/src/coreclr/jit/codegenarm64test.cpp b/src/coreclr/jit/codegenarm64test.cpp index f5752a90166a8..aa62749d94da8 100644 --- a/src/coreclr/jit/codegenarm64test.cpp +++ b/src/coreclr/jit/codegenarm64test.cpp @@ -6006,6 +6006,28 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R_F(INS_sve_fmov, EA_SCALABLE, REG_V10, REG_P11, 0.5, INS_OPTS_SCALABLE_D); // FMOV ., /M, # + // IF_SVE_CC_2A + theEmitter->emitIns_R_R(INS_sve_insr, EA_SCALABLE, REG_V0, REG_V13, + INS_OPTS_SCALABLE_B); // INSR ., + theEmitter->emitIns_R_R(INS_sve_insr, EA_SCALABLE, REG_V29, REG_V0, + INS_OPTS_SCALABLE_H); // INSR ., + theEmitter->emitIns_R_R(INS_sve_insr, EA_SCALABLE, REG_V4, REG_V15, + INS_OPTS_SCALABLE_S); // INSR ., + theEmitter->emitIns_R_R(INS_sve_insr, EA_SCALABLE, REG_V8, REG_V2, + INS_OPTS_SCALABLE_D); // INSR ., + + // IF_SVE_CD_2A + theEmitter->emitIns_R_R(INS_sve_insr, EA_SCALABLE, REG_V4, REG_R23, + INS_OPTS_SCALABLE_B); // INSR ., + theEmitter->emitIns_R_R(INS_sve_insr, EA_SCALABLE, REG_V11, REG_R1, + INS_OPTS_SCALABLE_H); // INSR ., + theEmitter->emitIns_R_R(INS_sve_insr, EA_SCALABLE, REG_V14, REG_R9, + INS_OPTS_SCALABLE_S); // INSR ., + theEmitter->emitIns_R_R(INS_sve_insr, EA_SCALABLE, REG_V19, REG_R0, + INS_OPTS_SCALABLE_D); // INSR ., + theEmitter->emitIns_R_R(INS_sve_insr, EA_SCALABLE, REG_V29, REG_ZR, + INS_OPTS_SCALABLE_D); // INSR ., + // IF_SVE_CI_3A theEmitter->emitIns_R_R_R(INS_sve_trn1, EA_SCALABLE, REG_P1, REG_P3, REG_P4, INS_OPTS_SCALABLE_B); // TRN1 ., ., . diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index da8f4d55c6649..a7e00cc2ea814 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -1240,6 +1240,18 @@ void emitter::emitInsSanityCheck(instrDesc* id) assert(isValidUimm<2>(emitGetInsSC(id))); // ii break; + case IF_SVE_CC_2A: // ........xx...... ......mmmmmddddd -- SVE insert SIMD&FP scalar register + assert(insOptsScalableStandard(id->idInsOpt())); + assert(isVectorRegister(id->idReg1())); // ddddd + assert(isVectorRegister(id->idReg2())); // mmmmm + break; + + case IF_SVE_CD_2A: // ........xx...... ......mmmmmddddd -- SVE insert general register + assert(insOptsScalableStandard(id->idInsOpt())); + assert(isVectorRegister(id->idReg1())); // ddddd + assert(isGeneralRegisterOrZR(id->idReg2())); // mmmmm + break; + case IF_SVE_CI_3A: // ........xx..MMMM .......NNNN.DDDD -- SVE permute predicate elements elemsize = id->idOpSize(); assert(insOptsScalableStandard(id->idInsOpt())); @@ -9034,6 +9046,23 @@ void emitter::emitIns_R_R(instruction ins, break; } + case INS_sve_insr: + assert(insOptsScalableStandard(opt)); + assert(isVectorRegister(reg1)); // ddddd + if (isVectorRegister(reg2)) + { + fmt = IF_SVE_CC_2A; + } + else if (isGeneralRegisterOrZR(reg2)) + { + fmt = IF_SVE_CD_2A; + } + else + { + unreached(); + } + break; + case INS_sve_pfirst: assert(opt == INS_OPTS_SCALABLE_B); assert(isPredicateRegister(reg1)); // DDDD @@ -24654,6 +24683,22 @@ BYTE* emitter::emitOutput_InstrSve(BYTE* dst, instrDesc* id) dst += emitOutput_Instr(dst, code); break; + case IF_SVE_CC_2A: // ........xx...... ......mmmmmddddd -- SVE insert SIMD&FP scalar register + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_V_4_to_0(id->idReg1()); // ddddd + code |= insEncodeReg_V_9_to_5(id->idReg2()); // mmmmm + code |= insEncodeSveElemsize(optGetSveElemsize(id->idInsOpt())); // xx + dst += emitOutput_Instr(dst, code); + break; + + case IF_SVE_CD_2A: // ........xx...... ......mmmmmddddd -- SVE insert general register + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_V_4_to_0(id->idReg1()); // ddddd + code |= insEncodeReg_R_9_to_5(id->idReg2()); // mmmmm + code |= insEncodeSveElemsize(optGetSveElemsize(id->idInsOpt())); // xx + dst += emitOutput_Instr(dst, code); + break; + case IF_SVE_CI_3A: // ........xx..MMMM .......NNNN.DDDD -- SVE permute predicate elements code = emitInsCodeSve(ins, fmt); code |= insEncodeReg_P_3_to_0(id->idReg1()); // DDDD @@ -28900,6 +28945,18 @@ void emitter::emitDispInsHelp( printf("]"); break; + // ., + case IF_SVE_CC_2A: // ........xx...... ......mmmmmddddd -- SVE insert SIMD&FP scalar register + emitDispSveReg(id->idReg1(), id->idInsOpt(), true); // ddddd + emitDispReg(id->idReg2(), optGetSveElemsize(id->idInsOpt()), false); // mmmmm + break; + + // ., + case IF_SVE_CD_2A: // ........xx...... ......mmmmmddddd -- SVE insert general register + emitDispSveReg(id->idReg1(), id->idInsOpt(), true); // ddddd + emitDispReg(id->idReg2(), id->idInsOpt() == INS_OPTS_SCALABLE_D ? EA_8BYTE : EA_4BYTE, false); // mmmmm + break; + // .H, .B case IF_SVE_CK_2A: // ................ .......NNNN.DDDD -- SVE unpack predicate elements emitDispPredicateReg(id->idReg1(), insGetPredicateType(fmt), INS_OPTS_SCALABLE_H, true); // DDDD @@ -32874,6 +32931,12 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins result.insLatency = PERFSCORE_LATENCY_140C; break; + case IF_SVE_CC_2A: // ........xx...... ......mmmmmddddd -- SVE insert SIMD&FP scalar register + case IF_SVE_CD_2A: // ........xx...... ......mmmmmddddd -- SVE insert general register + result.insThroughput = PERFSCORE_THROUGHPUT_1C; + result.insLatency = PERFSCORE_LATENCY_5C; + break; + case IF_SVE_CI_3A: // ........xx..MMMM .......NNNN.DDDD -- SVE permute predicate elements case IF_SVE_CJ_2A: // ........xx...... .......NNNN.DDDD -- SVE reverse predicate elements case IF_SVE_CK_2A: // ................ .......NNNN.DDDD -- SVE unpack predicate elements