diff --git a/src/coreclr/jit/codegenarm64test.cpp b/src/coreclr/jit/codegenarm64test.cpp index 47cc0fb6bfd194..6fc86ba66c5c37 100644 --- a/src/coreclr/jit/codegenarm64test.cpp +++ b/src/coreclr/jit/codegenarm64test.cpp @@ -7599,6 +7599,117 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R_I(INS_sve_str, EA_SCALABLE, REG_V2, REG_R3, 255, INS_OPTS_NONE, INS_SCALABLE_OPTS_UNPREDICATED); + // IF_SVE_HY_3A + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_UXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfd, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P6, REG_R5, REG_V4, + INS_OPTS_SCALABLE_S_UXTW, + INS_SCALABLE_OPTS_MOD_N); // PRFD , , [, .S, #3] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfh, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P7, REG_R8, REG_V9, + INS_OPTS_SCALABLE_S_SXTW, + INS_SCALABLE_OPTS_MOD_N); // PRFH , , [, .S, #1] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfw, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P0, REG_R2, REG_V1, + INS_OPTS_SCALABLE_S_UXTW, + INS_SCALABLE_OPTS_MOD_N); // PRFW , , [, .S, #2] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PLDL1STRM, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_UXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PLDL2KEEP, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_UXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PLDL2STRM, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_UXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PLDL3KEEP, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_UXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PLDL3STRM, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_UXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PSTL1KEEP, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_UXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PSTL1STRM, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_UXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PSTL2KEEP, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_UXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PSTL2STRM, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_UXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PSTL3KEEP, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_UXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PSTL3STRM, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_UXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_CONST6, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_SXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_CONST7, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_SXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_CONST14, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_UXTW); // PRFB , , [, .S, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_CONST15, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_S_UXTW); // PRFB , , [, .S, ] + + // IF_SVE_HY_3A_A + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P1, REG_R2, REG_V3, + INS_OPTS_SCALABLE_D_UXTW); // PRFB , , [, .D, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfd, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P6, REG_R5, REG_V4, + INS_OPTS_SCALABLE_D_UXTW, + INS_SCALABLE_OPTS_MOD_N); // PRFD , , [, .D, #3] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfh, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P7, REG_R8, REG_V9, + INS_OPTS_SCALABLE_D_SXTW, + INS_SCALABLE_OPTS_MOD_N); // PRFH , , [, .D, #1] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfw, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P0, REG_R2, REG_V1, + INS_OPTS_SCALABLE_D_UXTW, + INS_SCALABLE_OPTS_MOD_N); // PRFW , , [, .D, #2] + + // IF_SVE_HY_3B + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P0, REG_R1, REG_V2, + INS_OPTS_SCALABLE_D); // PRFB , , [, .D] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfd, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P7, REG_R4, REG_V3, + INS_OPTS_SCALABLE_D, + INS_SCALABLE_OPTS_LSL_N); // PRFD , , [, .D, LSL #3] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfh, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P6, REG_R5, REG_V4, + INS_OPTS_SCALABLE_D, + INS_SCALABLE_OPTS_LSL_N); // PRFH , , [, .D, LSL #1] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfw, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P3, REG_R2, REG_V1, + INS_OPTS_SCALABLE_D, + INS_SCALABLE_OPTS_LSL_N); // PRFW , , [, .D, LSL #2] + + // IF_SVE_HZ_2A_B + theEmitter->emitIns_PRFOP_R_R_I(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P1, REG_V2, 0, + INS_OPTS_SCALABLE_S); // PRFB , , [.S{, #}] + theEmitter->emitIns_PRFOP_R_R_I(INS_sve_prfd, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P4, REG_V3, 248, + INS_OPTS_SCALABLE_S); // PRFD , , [.S{, #}] + theEmitter->emitIns_PRFOP_R_R_I(INS_sve_prfh, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P0, REG_V4, 62, + INS_OPTS_SCALABLE_S); // PRFH , , [.S{, #}] + theEmitter->emitIns_PRFOP_R_R_I(INS_sve_prfw, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P7, REG_V5, 124, + INS_OPTS_SCALABLE_S); // PRFW , , [.S{, #}] + theEmitter->emitIns_PRFOP_R_R_I(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P1, REG_V2, 31, + INS_OPTS_SCALABLE_D); // PRFB , , [.D{, #}] + theEmitter->emitIns_PRFOP_R_R_I(INS_sve_prfd, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P4, REG_V3, 248, + INS_OPTS_SCALABLE_D); // PRFD , , [.D{, #}] + theEmitter->emitIns_PRFOP_R_R_I(INS_sve_prfh, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P0, REG_V4, 62, + INS_OPTS_SCALABLE_D); // PRFH , , [.D{, #}] + theEmitter->emitIns_PRFOP_R_R_I(INS_sve_prfw, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P7, REG_V5, 124, + INS_OPTS_SCALABLE_D); // PRFW , , [.D{, #}] + + // IF_SVE_IA_2A + theEmitter->emitIns_PRFOP_R_R_I(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P2, REG_R3, + -32); // PRFB , , [{, #, MUL VL}] + theEmitter->emitIns_PRFOP_R_R_I(INS_sve_prfd, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P7, REG_R4, + 31); // PRFD , , [{, #, MUL VL}] + theEmitter->emitIns_PRFOP_R_R_I(INS_sve_prfh, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P1, REG_R2, + 0); // PRFH , , [{, #, MUL VL}] + theEmitter->emitIns_PRFOP_R_R_I(INS_sve_prfw, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P0, REG_R5, + -32); // PRFW , , [{, #, MUL VL}] + theEmitter->emitIns_PRFOP_R_R_I(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P2, REG_R3, + 17); // PRFB , , [{, #, MUL VL}] + + // IF_SVE_IB_3A + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfb, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P0, REG_R1, + REG_R2); // PRFB , , [, ] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfd, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P5, REG_R4, REG_R3, + INS_OPTS_NONE, + INS_SCALABLE_OPTS_LSL_N); // PRFD , , [, , LSL #3] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfh, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P6, REG_R7, REG_R8, + INS_OPTS_NONE, + INS_SCALABLE_OPTS_LSL_N); // PRFH , , [, , LSL #1] + theEmitter->emitIns_PRFOP_R_R_R(INS_sve_prfw, EA_SCALABLE, SVE_PRFOP_PLDL1KEEP, REG_P7, REG_R1, REG_R9, + INS_OPTS_NONE, + INS_SCALABLE_OPTS_LSL_N); // PRFW , , [, , LSL #2] // IF_SVE_HX_3A_B theEmitter->emitIns_R_R_R_I(INS_sve_ld1b, EA_SCALABLE, REG_V0, REG_P0, REG_V1, 0, INS_OPTS_SCALABLE_S); // LD1B {.S }, /Z, [.S{, #}] diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 45be55272f661f..8ef49e0d5215c6 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -1478,6 +1478,16 @@ class emitter assert(!idIsSmallDsc()); idAddr()->_idSvePattern = idSvePattern; } + insSvePrfop idSvePrfop() const + { + assert(!idIsSmallDsc()); + return (insSvePrfop)(idAddr()->_idReg4); + } + void idSvePrfop(insSvePrfop idSvePrfop) + { + assert(!idIsSmallDsc()); + idAddr()->_idReg4 = (regNumber)idSvePrfop; + } #endif // TARGET_ARM64 #endif // TARGET_ARMARCH diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index dea80c05e6b8be..e09952558df63a 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -2355,6 +2355,53 @@ void emitter::emitInsSanityCheck(instrDesc* id) // iiiiii break; + case IF_SVE_HY_3A: // .........h.mmmmm ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (scalar plus 32-bit scaled + // offsets) + case IF_SVE_HY_3A_A: // .........h.mmmmm ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (scalar plus 32-bit + // scaled offsets) + elemsize = id->idOpSize(); + assert(insOptsScalable32bitExtends(id->idInsOpt())); + assert(isLowPredicateRegister(id->idReg1())); + assert(isGeneralRegister(id->idReg2())); + assert(isVectorRegister(id->idReg3())); + assert(isScalableVectorSize(elemsize)); + break; + + case IF_SVE_HY_3B: // ...........mmmmm ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (scalar plus 32-bit scaled + // offsets) + elemsize = id->idOpSize(); + assert(id->idInsOpt() == INS_OPTS_SCALABLE_D); + assert(isLowPredicateRegister(id->idReg1())); + assert(isGeneralRegister(id->idReg2())); + assert(isVectorRegister(id->idReg3())); + assert(isScalableVectorSize(elemsize)); + break; + + case IF_SVE_IB_3A: // ...........mmmmm ...gggnnnnn.oooo -- SVE contiguous prefetch (scalar plus scalar) + elemsize = id->idOpSize(); + assert(insOptsNone(id->idInsOpt())); + assert(isLowPredicateRegister(id->idReg1())); + assert(isGeneralRegister(id->idReg2())); + assert(isGeneralRegister(id->idReg3())); + assert(isScalableVectorSize(elemsize)); + break; + + case IF_SVE_HZ_2A_B: // ...........iiiii ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (vector plus immediate) + elemsize = id->idOpSize(); + assert(insOptsScalableWords(id->idInsOpt())); + assert(isLowPredicateRegister(id->idReg1())); + assert(isVectorRegister(id->idReg2())); + assert(isScalableVectorSize(elemsize)); + break; + + case IF_SVE_IA_2A: // ..........iiiiii ...gggnnnnn.oooo -- SVE contiguous prefetch (scalar plus immediate) + elemsize = id->idOpSize(); + assert(insOptsNone(id->idInsOpt())); + assert(isLowPredicateRegister(id->idReg1())); + assert(isGeneralRegister(id->idReg2())); + assert(isScalableVectorSize(elemsize)); + break; + case IF_SVE_HX_3A_B: // ...........iiiii ...gggnnnnnttttt -- SVE 32-bit gather load (vector plus immediate) elemsize = id->idOpSize(); assert(insOptsScalableWords(id->idInsOpt())); @@ -15079,6 +15126,205 @@ void emitter::emitIns_R_PATTERN_I(instruction ins, emitAttr attr, regNumber reg1 appendToCurIG(id); } +/***************************************************************************** + * + * Add an instruction referencing three registers and a SVE 'prfop'. + */ + +void emitter::emitIns_PRFOP_R_R_R(instruction ins, + emitAttr attr, + insSvePrfop prfop, + regNumber reg1, + regNumber reg2, + regNumber reg3, + insOpts opt /* = INS_OPTS_NONE */, + insScalableOpts sopt /* = INS_SCALABLE_OPTS_NONE */) +{ + emitAttr size = EA_SIZE(attr); + emitAttr elemsize = EA_UNKNOWN; + insFormat fmt = IF_NONE; + + /* Figure out the encoding format of the instruction */ + switch (ins) + { + case INS_sve_prfb: + assert(insScalableOptsNone(sopt)); + assert(isLowPredicateRegister(reg1)); + assert(isGeneralRegister(reg2)); + assert(isScalableVectorSize(size)); + + if (insOptsScalable32bitExtends(opt)) + { + assert(isVectorRegister(reg3)); + + if (insOptsScalableSingleWord32bitExtends(opt)) + { + fmt = IF_SVE_HY_3A; + } + else + { + assert(insOptsScalableDoubleWord32bitExtends(opt)); + fmt = IF_SVE_HY_3A_A; + } + } + else if (isVectorRegister(reg3)) + { + assert(opt == INS_OPTS_SCALABLE_D); + fmt = IF_SVE_HY_3B; + } + else + { + assert(insOptsNone(opt)); + assert(isGeneralRegister(reg3)); + fmt = IF_SVE_IB_3A; + } + break; + + case INS_sve_prfh: + case INS_sve_prfw: + case INS_sve_prfd: + assert(isLowPredicateRegister(reg1)); + assert(isGeneralRegister(reg2)); + assert(isScalableVectorSize(size)); + + if (sopt == INS_SCALABLE_OPTS_MOD_N) + { + if (insOptsScalableSingleWord32bitExtends(opt)) + { + fmt = IF_SVE_HY_3A; + } + else + { + assert(insOptsScalableDoubleWord32bitExtends(opt)); + fmt = IF_SVE_HY_3A_A; + } + } + else + { + assert(sopt == INS_SCALABLE_OPTS_LSL_N); + if (isVectorRegister(reg3)) + { + assert(opt == INS_OPTS_SCALABLE_D); + fmt = IF_SVE_HY_3B; + } + else + { + assert(insOptsNone(opt)); + assert(isGeneralRegister(reg3)); + fmt = IF_SVE_IB_3A; + } + } + break; + + default: + unreached(); + break; + + } // end switch (ins) + assert(fmt != IF_NONE); + + instrDesc* id = emitNewInstr(attr); + + id->idIns(ins); + id->idInsOpt(opt); + id->idInsFmt(fmt); + + id->idReg1(reg1); + id->idReg2(reg2); + id->idReg3(reg3); + id->idSvePrfop(prfop); + + dispIns(id); + appendToCurIG(id); +} + +/***************************************************************************** + * + * Add an instruction referencing two registers, a SVE 'prfop' and an immediate. + */ + +void emitter::emitIns_PRFOP_R_R_I(instruction ins, + emitAttr attr, + insSvePrfop prfop, + regNumber reg1, + regNumber reg2, + int imm, + insOpts opt /* = INS_OPTS_NONE */) +{ + emitAttr size = EA_SIZE(attr); + emitAttr elemsize = EA_UNKNOWN; + insFormat fmt = IF_NONE; + + /* Figure out the encoding format of the instruction */ + switch (ins) + { + case INS_sve_prfb: + case INS_sve_prfh: + case INS_sve_prfw: + case INS_sve_prfd: + assert(isLowPredicateRegister(reg1)); + assert(isScalableVectorSize(size)); + + if (isVectorRegister(reg2)) + { + assert(insOptsScalableWords(opt)); + +#ifdef DEBUG + switch (ins) + { + case INS_sve_prfb: + assert(isValidUimm5(imm)); + break; + + case INS_sve_prfh: + assert(isValidUimm5_MultipleOf2(imm)); + break; + + case INS_sve_prfw: + assert(isValidUimm5_MultipleOf4(imm)); + break; + + case INS_sve_prfd: + assert(isValidUimm5_MultipleOf8(imm)); + break; + + default: + assert(!"Invalid instruction"); + break; + } +#endif // DEBUG + fmt = IF_SVE_HZ_2A_B; + } + else + { + assert(insOptsNone(opt)); + assert(isGeneralRegister(reg2)); + assert(isValidSimm6(imm)); + fmt = IF_SVE_IA_2A; + } + break; + + default: + unreached(); + break; + + } // end switch (ins) + assert(fmt != IF_NONE); + + instrDesc* id = emitNewInstrCns(attr, imm); + + id->idIns(ins); + id->idInsOpt(opt); + id->idInsFmt(fmt); + + id->idReg1(reg1); + id->idReg2(reg2); + id->idSvePrfop(prfop); + + dispIns(id); + appendToCurIG(id); +} + /***************************************************************************** * * Add a memory barrier instruction with a 'barrier' immediate @@ -18649,6 +18895,20 @@ void emitter::emitIns_Call(EmitCallType callType, } break; + case IF_SVE_HY_3B: + case IF_SVE_IB_3A: + switch (ins) + { + case INS_sve_prfh: + case INS_sve_prfw: + case INS_sve_prfd: + return true; + + default: + break; + } + break; + default: break; } @@ -18780,6 +19040,21 @@ void emitter::emitIns_Call(EmitCallType callType, } break; + case IF_SVE_HY_3A: + case IF_SVE_HY_3A_A: + switch (ins) + { + case INS_sve_prfb: + case INS_sve_prfh: + case INS_sve_prfw: + case INS_sve_prfd: + return true; + + default: + break; + } + break; + default: break; } @@ -19254,6 +19529,49 @@ void emitter::emitIns_Call(EmitCallType callType, } break; + case IF_SVE_HY_3A: + case IF_SVE_HY_3A_A: + assert(!insSveIsLslN(ins, fmt)); + assert(insSveIsModN(ins, fmt)); + switch (ins) + { + case INS_sve_prfb: + return 0; + + case INS_sve_prfh: + return 1; + + case INS_sve_prfw: + return 2; + + case INS_sve_prfd: + return 3; + + default: + break; + } + break; + + case IF_SVE_HY_3B: + case IF_SVE_IB_3A: + assert(insSveIsLslN(ins, fmt)); + assert(!insSveIsModN(ins, fmt)); + switch (ins) + { + case INS_sve_prfh: + return 1; + + case INS_sve_prfw: + return 2; + + case INS_sve_prfd: + return 3; + + default: + break; + } + break; + default: break; } @@ -19698,7 +20016,7 @@ void emitter::emitIns_Call(EmitCallType callType, /***************************************************************************** * - * // Returns the encoding for the immediate value that is a multiple of 2 as 5-bits at bit locations '20-16'. + * Returns the encoding for the immediate value that is a multiple of 2 as 5-bits at bit locations '20-16'. */ /*static*/ emitter::code_t emitter::insEncodeUimm5_MultipleOf2_20_to_16(ssize_t imm) @@ -19709,7 +20027,7 @@ void emitter::emitIns_Call(EmitCallType callType, /***************************************************************************** * - * // Returns the encoding for the immediate value that is a multiple of 4 as 5-bits at bit locations '20-16'. + * Returns the encoding for the immediate value that is a multiple of 4 as 5-bits at bit locations '20-16'. */ /*static*/ emitter::code_t emitter::insEncodeUimm5_MultipleOf4_20_to_16(ssize_t imm) @@ -19720,7 +20038,7 @@ void emitter::emitIns_Call(EmitCallType callType, /***************************************************************************** * - * // Returns the encoding for the immediate value that is a multiple of 8 as 5-bits at bit locations '20-16'. + * Returns the encoding for the immediate value that is a multiple of 8 as 5-bits at bit locations '20-16'. */ /*static*/ emitter::code_t emitter::insEncodeUimm5_MultipleOf8_20_to_16(ssize_t imm) @@ -19731,7 +20049,7 @@ void emitter::emitIns_Call(EmitCallType callType, /***************************************************************************** * - * // Returns the encoding for the immediate value that is a multiple of 2 as 6-bits at bit locations '21-16'. + * Returns the encoding for the immediate value that is a multiple of 2 as 6-bits at bit locations '21-16'. */ /*static*/ emitter::code_t emitter::insEncodeUimm6_MultipleOf2_21_to_16(ssize_t imm) @@ -19742,7 +20060,7 @@ void emitter::emitIns_Call(EmitCallType callType, /***************************************************************************** * - * // Returns the encoding for the immediate value that is a multiple of 4 as 6-bits at bit locations '21-16'. + * Returns the encoding for the immediate value that is a multiple of 4 as 6-bits at bit locations '21-16'. */ /*static*/ emitter::code_t emitter::insEncodeUimm6_MultipleOf4_21_to_16(ssize_t imm) @@ -19753,7 +20071,7 @@ void emitter::emitIns_Call(EmitCallType callType, /***************************************************************************** * - * // Returns the encoding for the immediate value that is a multiple of 8 as 6-bits at bit locations '21-16'. + * Returns the encoding for the immediate value that is a multiple of 8 as 6-bits at bit locations '21-16'. */ /*static*/ emitter::code_t emitter::insEncodeUimm6_MultipleOf8_21_to_16(ssize_t imm) @@ -19777,6 +20095,21 @@ void emitter::emitIns_Call(EmitCallType callType, return (code_t)imm << 16; } +/***************************************************************************** + * + * Returns the encoding for the immediate value as 6-bits at bit locations '20-16'. + */ + +/*static*/ emitter::code_t emitter::insEncodeSimm6_21_to_16(ssize_t imm) +{ + assert(isValidSimm6(imm)); + if (imm < 0) + { + imm = (imm & 0x3F); + } + return (code_t)imm << 16; +} + /***************************************************************************** * * Returns the encoding for the immediate value as 2-bits at bit locations '9-8'. @@ -23316,6 +23649,81 @@ BYTE* emitter::emitOutput_InstrSve(BYTE* dst, instrDesc* id) dst += emitOutput_Instr(dst, code); break; + case IF_SVE_HY_3A: // .........h.mmmmm ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (scalar plus 32-bit scaled + // offsets) + case IF_SVE_HY_3A_A: // .........h.mmmmm ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (scalar plus 32-bit + // scaled offsets) + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_P_12_to_10(id->idReg1()); // ggg + code |= insEncodeReg_R_9_to_5(id->idReg2()); // nnnnn + code |= insEncodeReg_V_20_to_16(id->idReg3()); // mmmmm + code |= id->idSvePrfop(); // oooo + + switch (id->idInsOpt()) + { + case INS_OPTS_SCALABLE_S_SXTW: + case INS_OPTS_SCALABLE_D_SXTW: + code |= (1 << 22); // h + break; + + default: + break; + } + + dst += emitOutput_Instr(dst, code); + break; + + case IF_SVE_HY_3B: // ...........mmmmm ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (scalar plus 32-bit scaled + // offsets) + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_P_12_to_10(id->idReg1()); // ggg + code |= insEncodeReg_R_9_to_5(id->idReg2()); // nnnnn + code |= insEncodeReg_V_20_to_16(id->idReg3()); // mmmmm + code |= id->idSvePrfop(); // oooo + dst += emitOutput_Instr(dst, code); + break; + + case IF_SVE_IB_3A: // ...........mmmmm ...gggnnnnn.oooo -- SVE contiguous prefetch (scalar plus scalar) + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_P_12_to_10(id->idReg1()); // ggg + code |= insEncodeReg_R_9_to_5(id->idReg2()); // nnnnn + code |= insEncodeReg_R_20_to_16(id->idReg3()); // mmmmm + code |= id->idSvePrfop(); // oooo + dst += emitOutput_Instr(dst, code); + break; + + case IF_SVE_HZ_2A_B: // ...........iiiii ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (vector plus immediate) + imm = emitGetInsSC(id); + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_P_12_to_10(id->idReg1()); // ggg + code |= insEncodeReg_V_9_to_5(id->idReg2()); // nnnnn + code |= id->idSvePrfop(); // oooo + + if (id->idInsOpt() == INS_OPTS_SCALABLE_D) + { + code |= (1 << 30); // set bit '30' to make it a double-word + } + + switch (ins) + { + case INS_sve_prfh: + code |= insEncodeUimm5_MultipleOf2_20_to_16(imm); // iiiii + break; + + case INS_sve_prfw: + code |= insEncodeUimm5_MultipleOf4_20_to_16(imm); // iiiii + break; + + case INS_sve_prfd: + code |= insEncodeUimm5_MultipleOf8_20_to_16(imm); // iiiii + break; + + default: + assert(ins == INS_sve_prfb); + } + dst += emitOutput_Instr(dst, code); + break; + case IF_SVE_HX_3A_B: // ...........iiiii ...gggnnnnnttttt -- SVE 32-bit gather load (vector plus immediate) imm = emitGetInsSC(id); code = emitInsCodeSve(ins, fmt); @@ -23395,6 +23803,16 @@ BYTE* emitter::emitOutput_InstrSve(BYTE* dst, instrDesc* id) dst += emitOutput_Instr(dst, code); break; + case IF_SVE_IA_2A: // ..........iiiiii ...gggnnnnn.oooo -- SVE contiguous prefetch (scalar plus immediate) + imm = emitGetInsSC(id); + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_P_12_to_10(id->idReg1()); // ggg + code |= insEncodeReg_R_9_to_5(id->idReg2()); // nnnnn + code |= id->idSvePrfop(); // oooo + code |= insEncodeSimm6_21_to_16(imm); // iiiiii + dst += emitOutput_Instr(dst, code); + break; + case IF_SVE_IC_3A: // ..........iiiiii ...gggnnnnnttttt -- SVE load and broadcast element imm = emitGetInsSC(id); code = emitInsCodeSve(ins, fmt); @@ -23844,6 +24262,24 @@ void emitter::emitDispSveModAddr(instruction ins, regNumber reg1, regNumber reg2 printf("]"); } +/***************************************************************************** + * + * Prints the encoding for format [.S{, #}] + */ +void emitter::emitDispSveImm(regNumber reg1, ssize_t imm, insOpts opt) +{ + printf("["); + emitDispSveReg(reg1, opt, imm != 0); + if (imm != 0) + { + // This does not have to be printed as hex. + // We only do it because the capstone disassembly displays this immediate as hex. + // We could not modify capstone without affecting other cases. + emitDispImm(imm, false, /* alwaysHex */ true); + } + printf("]"); +} + /***************************************************************************** * * Prints the encoding for format [{, #, MUL VL}] @@ -24413,6 +24849,89 @@ void emitter::emitDispSvePattern(insSvePattern pattern, bool addComma) } } +/***************************************************************************** + * + * Display an insSvePrfop + */ +void emitter::emitDispSvePrfop(insSvePrfop prfop, bool addComma) +{ + switch (prfop) + { + case SVE_PRFOP_PLDL1KEEP: + printf("pldl1keep"); + break; + + case SVE_PRFOP_PLDL1STRM: + printf("pldl1strm"); + break; + + case SVE_PRFOP_PLDL2KEEP: + printf("pldl2keep"); + break; + + case SVE_PRFOP_PLDL2STRM: + printf("pldl2strm"); + break; + + case SVE_PRFOP_PLDL3KEEP: + printf("pldl3keep"); + break; + + case SVE_PRFOP_PLDL3STRM: + printf("pldl3strm"); + break; + + case SVE_PRFOP_PSTL1KEEP: + printf("pstl1keep"); + break; + + case SVE_PRFOP_PSTL1STRM: + printf("pstl1strm"); + break; + + case SVE_PRFOP_PSTL2KEEP: + printf("pstl2keep"); + break; + + case SVE_PRFOP_PSTL2STRM: + printf("pstl2strm"); + break; + + case SVE_PRFOP_PSTL3KEEP: + printf("pstl3keep"); + break; + + case SVE_PRFOP_PSTL3STRM: + printf("pstl3strm"); + break; + + case SVE_PRFOP_CONST6: + printf("#6"); + break; + + case SVE_PRFOP_CONST7: + printf("#7"); + break; + + case SVE_PRFOP_CONST14: + printf("#0xE"); + break; + + case SVE_PRFOP_CONST15: + printf("#0xF"); + break; + + default: + assert(!"Invalid prfop"); + break; + } + + if (addComma) + { + emitDispComma(); + } +} + /***************************************************************************** * * Display (optionally) the instruction encoding in hex @@ -26981,6 +27500,51 @@ void emitter::emitDispInsHelp( emitDispSveReg(id->idReg4(), id->idInsOpt(), false); break; + // , , [, .S, ] + // , , [, .S, #1] + // , , [, .S, #2] + // , , [, .S, #3] + case IF_SVE_HY_3A: // .........h.mmmmm ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (scalar plus 32-bit scaled + // offsets) + // , , [, .D, ] + // , , [, .D, #1] + // , , [, .D, #2] + // , , [, .D, #3] + case IF_SVE_HY_3A_A: // .........h.mmmmm ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (scalar plus 32-bit + // scaled offsets) + // , , [, .D] + // , , [, .D, LSL #1] + // , , [, .D, LSL #2] + // , , [, .D, LSL #3] + case IF_SVE_HY_3B: // ...........mmmmm ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (scalar plus 32-bit scaled + // offsets) + // , , [, ] + // , , [, , LSL #1] + // , , [, , LSL #2] + // , , [, , LSL #3] + case IF_SVE_IB_3A: // ...........mmmmm ...gggnnnnn.oooo -- SVE contiguous prefetch (scalar plus scalar) + emitDispSvePrfop(id->idSvePrfop(), true); + emitDispPredicateReg(id->idReg1(), insGetPredicateType(fmt), id->idInsOpt(), true); + emitDispSveModAddr(ins, id->idReg2(), id->idReg3(), id->idInsOpt(), fmt); + break; + + // , , [.S{, #}] + // , , [.D{, #}] + case IF_SVE_HZ_2A_B: // ...........iiiii ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (vector plus immediate) + imm = emitGetInsSC(id); + emitDispSvePrfop(id->idSvePrfop(), true); + emitDispPredicateReg(id->idReg1(), insGetPredicateType(fmt), id->idInsOpt(), true); + emitDispSveImm(id->idReg2(), imm, id->idInsOpt()); + break; + + // , , [{, #, MUL VL}] + case IF_SVE_IA_2A: // ..........iiiiii ...gggnnnnn.oooo -- SVE contiguous prefetch (scalar plus immediate) + imm = emitGetInsSC(id); + emitDispSvePrfop(id->idSvePrfop(), true); + emitDispPredicateReg(id->idReg1(), insGetPredicateType(fmt), id->idInsOpt(), true); + emitDispSveImmMulVl(id->idReg2(), imm); + break; + // {.S }, /Z, [.S{, #}] // {.D }, /Z, [.D{, #}] case IF_SVE_HX_3A_B: // ...........iiiii ...gggnnnnnttttt -- SVE 32-bit gather load (vector plus immediate) @@ -30690,6 +31254,165 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins result.insLatency = PERFSCORE_LATENCY_2C; break; + case IF_SVE_HY_3A: // .........h.mmmmm ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (scalar plus 32-bit scaled + // offsets) + switch (ins) + { + case INS_sve_prfb: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfh: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfw: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfd: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + default: + // all other instructions + perfScoreUnhandledInstruction(id, &result); + break; + } + break; + + case IF_SVE_HY_3A_A: // .........h.mmmmm ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (scalar plus 32-bit + // scaled offsets) + switch (ins) + { + case INS_sve_prfb: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfh: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfw: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfd: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + default: + // all other instructions + perfScoreUnhandledInstruction(id, &result); + break; + } + break; + + case IF_SVE_HY_3B: // ...........mmmmm ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (scalar plus 32-bit scaled + // offsets) + switch (ins) + { + case INS_sve_prfb: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfh: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfw: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfd: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + default: + // all other instructions + perfScoreUnhandledInstruction(id, &result); + break; + } + break; + + case IF_SVE_IB_3A: // ...........mmmmm ...gggnnnnn.oooo -- SVE contiguous prefetch (scalar plus scalar) + switch (ins) + { + case INS_sve_prfb: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfh: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfw: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfd: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + default: + // all other instructions + perfScoreUnhandledInstruction(id, &result); + break; + } + break; + + case IF_SVE_HZ_2A_B: // ...........iiiii ...gggnnnnn.oooo -- SVE 32-bit gather prefetch (vector plus immediate) + switch (ins) + { + case INS_sve_prfb: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfh: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfw: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfd: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + default: + // all other instructions + perfScoreUnhandledInstruction(id, &result); + break; + } + break; + + case IF_SVE_IA_2A: // ..........iiiiii ...gggnnnnn.oooo -- SVE contiguous prefetch (scalar plus immediate) + switch (ins) + { + case INS_sve_prfb: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfh: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfw: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + case INS_sve_prfd: + result.insThroughput = PERFSCORE_THROUGHPUT_1C; // need to fix + result.insLatency = PERFSCORE_LATENCY_1C; // need to fix + break; + default: + // all other instructions + perfScoreUnhandledInstruction(id, &result); + break; + } + break; + case IF_SVE_HX_3A_B: // ...........iiiii ...gggnnnnnttttt -- SVE 32-bit gather load (vector plus immediate) case IF_SVE_HX_3A_E: // ...........iiiii ...gggnnnnnttttt -- SVE 32-bit gather load (vector plus immediate) case IF_SVE_IV_3A: // ...........iiiii ...gggnnnnnttttt -- SVE 64-bit gather load (vector plus immediate) diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index cd4b3bc9738198..3fa81419e96048 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -53,6 +53,7 @@ void emitDispExtendOpts(insOpts opt); void emitDispSveExtendOpts(insOpts opt); void emitDispSveExtendOptsModN(insOpts opt, int n); void emitDispSveModAddr(instruction ins, regNumber reg1, regNumber reg2, insOpts opt, insFormat fmt); +void emitDispSveImm(regNumber reg1, ssize_t imm, insOpts opt); void emitDispSveImmMulVl(regNumber reg1, ssize_t imm); void emitDispSveImmIndex(regNumber reg1, insOpts opt, ssize_t imm); void emitDispLSExtendOpts(insOpts opt); @@ -75,6 +76,7 @@ void emitDispExtendReg(regNumber reg, insOpts opt, ssize_t imm); void emitDispAddrRI(regNumber reg, insOpts opt, ssize_t imm); void emitDispAddrRRExt(regNumber reg1, regNumber reg2, insOpts opt, bool isScaled, emitAttr size); void emitDispSvePattern(insSvePattern pattern, bool addComma); +void emitDispSvePrfop(insSvePrfop prfop, bool addComma); /************************************************************************/ /* Private members that deal with target-dependent instr. descriptors */ @@ -619,6 +621,9 @@ static code_t insEncodeUimm5_MultipleOf4_20_to_16(ssize_t imm); // Returns the encoding for the immediate value that is a multiple of 8 as 5-bits at bit locations '20-16'. static code_t insEncodeUimm5_MultipleOf8_20_to_16(ssize_t imm); +// Returns the encoding for the immediate value as 6-bits at bit locations '21-16'. +static code_t insEncodeSimm6_21_to_16(ssize_t imm); + // Returns the encoding for the immediate value that is a multiple of 2 as 6-bits at bit locations '21-16'. static code_t insEncodeUimm6_MultipleOf2_21_to_16(ssize_t imm); @@ -735,19 +740,19 @@ static bool isValidSimm4_MultipleOf32(ssize_t value) return (-256 <= value) && (value <= 224) && (value % 32 == 0); }; -// Returns true if 'value' is a legal signed multiple of 2 immediate 5 bit encoding (such as for LD1H). +// Returns true if 'value' is a legal unsigned multiple of 2 immediate 5 bit encoding (such as for LD1H). static bool isValidUimm5_MultipleOf2(ssize_t value) { return (0 <= value) && (value <= 62) && (value % 2 == 0); }; -// Returns true if 'value' is a legal signed multiple of 4 immediate 5 bit encoding (such as for LD1W). +// Returns true if 'value' is a legal unsigned multiple of 4 immediate 5 bit encoding (such as for LD1W). static bool isValidUimm5_MultipleOf4(ssize_t value) { return (0 <= value) && (value <= 124) && (value % 4 == 0); }; -// Returns true if 'value' is a legal signed multiple of 8 immediate 5 bit encoding (such as for LD1D). +// Returns true if 'value' is a legal unsigned multiple of 8 immediate 5 bit encoding (such as for LD1D). static bool isValidUimm5_MultipleOf8(ssize_t value) { return (0 <= value) && (value <= 248) && (value % 8 == 0); @@ -879,6 +884,12 @@ static bool isValidSimm5(ssize_t value) return (-0x10LL <= value) && (value <= 0xFLL); }; +// Returns true if 'value' is a legal signed immediate 6 bit encoding (such as for PRFB). +static bool isValidSimm6(ssize_t value) +{ + return (-32 <= value) && (value <= 31); +}; + // Returns true if 'value' is a legal rotation value (such as for CDOT, CMLA). static bool isValidRot(ssize_t value) { @@ -1508,6 +1519,23 @@ void emitIns_R_PATTERN( void emitIns_R_PATTERN_I(instruction ins, emitAttr attr, regNumber reg1, insSvePattern pattern, int imm); +void emitIns_PRFOP_R_R_R(instruction ins, + emitAttr attr, + insSvePrfop prfop, + regNumber reg1, + regNumber reg2, + regNumber reg3, + insOpts opt = INS_OPTS_NONE, + insScalableOpts sopt = INS_SCALABLE_OPTS_NONE); + +void emitIns_PRFOP_R_R_I(instruction ins, + emitAttr attr, + insSvePrfop prfop, + regNumber reg1, + regNumber reg2, + int imm, + insOpts opt = INS_OPTS_NONE); + void emitIns_BARR(instruction ins, insBarrier barrier); void emitIns_C(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE fdlHnd, int offs); diff --git a/src/coreclr/jit/instr.h b/src/coreclr/jit/instr.h index bdbddc60160cf0..3120b2ac87fc60 100644 --- a/src/coreclr/jit/instr.h +++ b/src/coreclr/jit/instr.h @@ -404,6 +404,28 @@ enum insSvePattern : unsigned SVE_PATTERN_ALL = 31 // All available (implicitly a multiple of two). }; +// Prefetch operation specifier for SVE instructions such as prfb. +enum insSvePrfop : unsigned +{ + SVE_PRFOP_PLDL1KEEP = 0b0000, + SVE_PRFOP_PLDL1STRM = 0b0001, + SVE_PRFOP_PLDL2KEEP = 0b0010, + SVE_PRFOP_PLDL2STRM = 0b0011, + SVE_PRFOP_PLDL3KEEP = 0b0100, + SVE_PRFOP_PLDL3STRM = 0b0101, + SVE_PRFOP_PSTL1KEEP = 0b1000, + SVE_PRFOP_PSTL1STRM = 0b1001, + SVE_PRFOP_PSTL2KEEP = 0b1010, + SVE_PRFOP_PSTL2STRM = 0b1011, + SVE_PRFOP_PSTL3KEEP = 0b1100, + SVE_PRFOP_PSTL3STRM = 0b1101, + + SVE_PRFOP_CONST6 = 0b0110, + SVE_PRFOP_CONST7 = 0b0111, + SVE_PRFOP_CONST14 = 0b1110, + SVE_PRFOP_CONST15 = 0b1111 +}; + enum insCond : unsigned { INS_COND_EQ, diff --git a/src/coreclr/jit/instrsarm64sve.h b/src/coreclr/jit/instrsarm64sve.h index 0c0a4019237149..9e385bca8d7db0 100644 --- a/src/coreclr/jit/instrsarm64sve.h +++ b/src/coreclr/jit/instrsarm64sve.h @@ -285,7 +285,7 @@ INST6(prfb, "prfb", 0, IF_SV // PRFB , , [, .S, ] SVE_HY_3A 100001000h1mmmmm 000gggnnnnn0oooo 8420 0000 // PRFB , , [, .D, ] SVE_HY_3A_A 110001000h1mmmmm 000gggnnnnn0oooo C420 0000 // PRFB , , [, .D] SVE_HY_3B 11000100011mmmmm 100gggnnnnn0oooo C460 8000 - // PRFB , , [.D{, #}] SVE_HZ_2A_B 10000100000iiiii 111gggnnnnn0oooo 8400 E000 + // PRFB , , [.S{, #}] SVE_HZ_2A_B 10000100000iiiii 111gggnnnnn0oooo 8400 E000 // PRFB , , [{, #, MUL VL}] SVE_IA_2A 1000010111iiiiii 000gggnnnnn0oooo 85C0 0000 // PRFB , , [, ] SVE_IB_3A 10000100000mmmmm 110gggnnnnn0oooo 8400 C000 @@ -293,7 +293,7 @@ INST6(prfd, "prfd", 0, IF_SV // PRFD , , [, .S, #3] SVE_HY_3A 100001000h1mmmmm 011gggnnnnn0oooo 8420 6000 // PRFD , , [, .D, #3] SVE_HY_3A_A 110001000h1mmmmm 011gggnnnnn0oooo C420 6000 // PRFD , , [, .D, LSL #3] SVE_HY_3B 11000100011mmmmm 111gggnnnnn0oooo C460 E000 - // PRFD , , [.D{, #}] SVE_HZ_2A_B 10000101100iiiii 111gggnnnnn0oooo 8580 E000 + // PRFD , , [.S{, #}] SVE_HZ_2A_B 10000101100iiiii 111gggnnnnn0oooo 8580 E000 // PRFD , , [{, #, MUL VL}] SVE_IA_2A 1000010111iiiiii 011gggnnnnn0oooo 85C0 6000 // PRFD , , [, , LSL #3] SVE_IB_3A 10000101100mmmmm 110gggnnnnn0oooo 8580 C000 @@ -301,7 +301,7 @@ INST6(prfh, "prfh", 0, IF_SV // PRFH , , [, .S, #1] SVE_HY_3A 100001000h1mmmmm 001gggnnnnn0oooo 8420 2000 // PRFH , , [, .D, #1] SVE_HY_3A_A 110001000h1mmmmm 001gggnnnnn0oooo C420 2000 // PRFH , , [, .D, LSL #1] SVE_HY_3B 11000100011mmmmm 101gggnnnnn0oooo C460 A000 - // PRFH , , [.D{, #}] SVE_HZ_2A_B 10000100100iiiii 111gggnnnnn0oooo 8480 E000 + // PRFH , , [.S{, #}] SVE_HZ_2A_B 10000100100iiiii 111gggnnnnn0oooo 8480 E000 // PRFH , , [{, #, MUL VL}] SVE_IA_2A 1000010111iiiiii 001gggnnnnn0oooo 85C0 2000 // PRFH , , [, , LSL #1] SVE_IB_3A 10000100100mmmmm 110gggnnnnn0oooo 8480 C000 @@ -309,7 +309,7 @@ INST6(prfw, "prfw", 0, IF_SV // PRFW , , [, .S, #2] SVE_HY_3A 100001000h1mmmmm 010gggnnnnn0oooo 8420 4000 // PRFW , , [, .D, #2] SVE_HY_3A_A 110001000h1mmmmm 010gggnnnnn0oooo C420 4000 // PRFW , , [, .D, LSL #2] SVE_HY_3B 11000100011mmmmm 110gggnnnnn0oooo C460 C000 - // PRFW , , [.D{, #}] SVE_HZ_2A_B 10000101000iiiii 111gggnnnnn0oooo 8500 E000 + // PRFW , , [.S{, #}] SVE_HZ_2A_B 10000101000iiiii 111gggnnnnn0oooo 8500 E000 // PRFW , , [{, #, MUL VL}] SVE_IA_2A 1000010111iiiiii 010gggnnnnn0oooo 85C0 4000 // PRFW , , [, , LSL #2] SVE_IB_3A 10000101000mmmmm 110gggnnnnn0oooo 8500 C000