diff --git a/src/coreclr/jit/codegenarm64test.cpp b/src/coreclr/jit/codegenarm64test.cpp index ca3557b84b2df..95d18fad59f3e 100644 --- a/src/coreclr/jit/codegenarm64test.cpp +++ b/src/coreclr/jit/codegenarm64test.cpp @@ -5173,6 +5173,90 @@ void CodeGen::genArm64EmitterUnitTestsSve() theEmitter->emitIns_R_R_R(INS_sve_bfsub, EA_SCALABLE, REG_V12, REG_P6, REG_V13, INS_OPTS_SCALABLE_H); // BFSUB .H, /M, .H, .H + // IF_SVE_HO_3A + theEmitter->emitIns_R_R_R(INS_sve_bfcvt, EA_SCALABLE, REG_V3, REG_P2, REG_V9, + INS_OPTS_S_TO_H); // BFCVT .H, /M, .S + + // IF_SVE_HO_3B + theEmitter->emitIns_R_R_R(INS_sve_fcvt, EA_SCALABLE, REG_V7, REG_P7, REG_V1, + INS_OPTS_S_TO_D); // FCVT .D, /M, .S + theEmitter->emitIns_R_R_R(INS_sve_fcvt, EA_SCALABLE, REG_V29, REG_P3, REG_V12, + INS_OPTS_D_TO_S); // FCVT .S, /M, .D + theEmitter->emitIns_R_R_R(INS_sve_fcvt, EA_SCALABLE, REG_V0, REG_P4, REG_V13, + INS_OPTS_D_TO_H); // FCVT .H, /M, .D + theEmitter->emitIns_R_R_R(INS_sve_fcvt, EA_SCALABLE, REG_V1, REG_P5, REG_V14, + INS_OPTS_H_TO_D); // FCVT .D, /M, .H + theEmitter->emitIns_R_R_R(INS_sve_fcvt, EA_SCALABLE, REG_V2, REG_P6, REG_V15, + INS_OPTS_S_TO_H); // FCVT .H, /M, .S + theEmitter->emitIns_R_R_R(INS_sve_fcvt, EA_SCALABLE, REG_V3, REG_P7, REG_V16, + INS_OPTS_H_TO_S); // FCVT .S, /M, .H + + // IF_SVE_HO_3C + theEmitter->emitIns_R_R_R(INS_sve_fcvtx, EA_SCALABLE, REG_V2, REG_P0, REG_V6, + INS_OPTS_D_TO_S); // FCVTX .S, /M, .D + + // IF_SVE_HP_3B + theEmitter->emitIns_R_R_R(INS_sve_fcvtzs, EA_SCALABLE, REG_V9, REG_P1, REG_V3, + INS_OPTS_SCALABLE_S); // FCVTZS .S, /M, .S + theEmitter->emitIns_R_R_R(INS_sve_fcvtzs, EA_SCALABLE, REG_V5, REG_P0, REG_V24, + INS_OPTS_S_TO_D); // FCVTZS .D, /M, .S + theEmitter->emitIns_R_R_R(INS_sve_fcvtzs, EA_SCALABLE, REG_V12, REG_P3, REG_V6, + INS_OPTS_D_TO_S); // FCVTZS .S, /M, .D + theEmitter->emitIns_R_R_R(INS_sve_fcvtzs, EA_SCALABLE, REG_V2, REG_P1, REG_V17, + INS_OPTS_SCALABLE_D); // FCVTZS .D, /M, .D + theEmitter->emitIns_R_R_R(INS_sve_fcvtzs, EA_SCALABLE, REG_V3, REG_P2, REG_V18, + INS_OPTS_SCALABLE_H); // FCVTZS .H, /M, .H + theEmitter->emitIns_R_R_R(INS_sve_fcvtzs, EA_SCALABLE, REG_V4, REG_P3, REG_V19, + INS_OPTS_H_TO_S); // FCVTZS .S, /M, .H + theEmitter->emitIns_R_R_R(INS_sve_fcvtzs, EA_SCALABLE, REG_V5, REG_P4, REG_V20, + INS_OPTS_H_TO_D); // FCVTZS .D, /M, .H + + theEmitter->emitIns_R_R_R(INS_sve_fcvtzu, EA_SCALABLE, REG_V3, REG_P2, REG_V10, + INS_OPTS_SCALABLE_S); // FCVTZU .S, /M, .S + theEmitter->emitIns_R_R_R(INS_sve_fcvtzu, EA_SCALABLE, REG_V10, REG_P7, REG_V1, + INS_OPTS_S_TO_D); // FCVTZU .D, /M, .S + theEmitter->emitIns_R_R_R(INS_sve_fcvtzu, EA_SCALABLE, REG_V4, REG_P3, REG_V13, + INS_OPTS_D_TO_S); // FCVTZU .S, /M, .D + theEmitter->emitIns_R_R_R(INS_sve_fcvtzu, EA_SCALABLE, REG_V22, REG_P6, REG_V4, + INS_OPTS_SCALABLE_D); // FCVTZU .D, /M, .D + theEmitter->emitIns_R_R_R(INS_sve_fcvtzu, EA_SCALABLE, REG_V23, REG_P7, REG_V5, + INS_OPTS_SCALABLE_H); // FCVTZU .H, /M, .H + theEmitter->emitIns_R_R_R(INS_sve_fcvtzu, EA_SCALABLE, REG_V24, REG_P0, REG_V6, + INS_OPTS_H_TO_S); // FCVTZU .S, /M, .H + theEmitter->emitIns_R_R_R(INS_sve_fcvtzu, EA_SCALABLE, REG_V25, REG_P1, REG_V7, + INS_OPTS_H_TO_D); // FCVTZU .D, /M, .H + + // IF_SVE_HS_3A + theEmitter->emitIns_R_R_R(INS_sve_scvtf, EA_SCALABLE, REG_V19, REG_P2, REG_V8, + INS_OPTS_SCALABLE_S); // SCVTF .S, /M, .S + theEmitter->emitIns_R_R_R(INS_sve_scvtf, EA_SCALABLE, REG_V1, REG_P5, REG_V19, + INS_OPTS_S_TO_D); // SCVTF .D, /M, .S + theEmitter->emitIns_R_R_R(INS_sve_scvtf, EA_SCALABLE, REG_V4, REG_P0, REG_V14, + INS_OPTS_D_TO_S); // SCVTF .S, /M, .D + theEmitter->emitIns_R_R_R(INS_sve_scvtf, EA_SCALABLE, REG_V0, REG_P0, REG_V0, + INS_OPTS_SCALABLE_D); // SCVTF .D, /M, .D + theEmitter->emitIns_R_R_R(INS_sve_scvtf, EA_SCALABLE, REG_V12, REG_P5, REG_V14, + INS_OPTS_SCALABLE_H); // SCVTF .H, /M, .H + theEmitter->emitIns_R_R_R(INS_sve_scvtf, EA_SCALABLE, REG_V14, REG_P7, REG_V16, + INS_OPTS_S_TO_H); // SCVTF .H, /M, .S + theEmitter->emitIns_R_R_R(INS_sve_scvtf, EA_SCALABLE, REG_V16, REG_P1, REG_V18, + INS_OPTS_D_TO_H); // SCVTF .H, /M, .D + + theEmitter->emitIns_R_R_R(INS_sve_ucvtf, EA_SCALABLE, REG_V17, REG_P6, REG_V11, + INS_OPTS_SCALABLE_S); // UCVTF .S, /M, .S + theEmitter->emitIns_R_R_R(INS_sve_ucvtf, EA_SCALABLE, REG_V3, REG_P3, REG_V20, + INS_OPTS_S_TO_D); // UCVTF .D, /M, .S + theEmitter->emitIns_R_R_R(INS_sve_ucvtf, EA_SCALABLE, REG_V8, REG_P1, REG_V7, + INS_OPTS_D_TO_S); // UCVTF .S, /M, .D + theEmitter->emitIns_R_R_R(INS_sve_ucvtf, EA_SCALABLE, REG_V8, REG_P4, REG_V9, + INS_OPTS_SCALABLE_D); // UCVTF .D, /M, .D + theEmitter->emitIns_R_R_R(INS_sve_ucvtf, EA_SCALABLE, REG_V13, REG_P6, REG_V15, + INS_OPTS_SCALABLE_H); // UCVTF .H, /M, .H + theEmitter->emitIns_R_R_R(INS_sve_ucvtf, EA_SCALABLE, REG_V15, REG_P0, REG_V17, + INS_OPTS_S_TO_H); // UCVTF .H, /M, .S + theEmitter->emitIns_R_R_R(INS_sve_ucvtf, EA_SCALABLE, REG_V17, REG_P2, REG_V19, + INS_OPTS_D_TO_H); // UCVTF .H, /M, .D + // IF_SVE_HT_4A theEmitter->emitIns_R_R_R_R(INS_sve_facge, EA_SCALABLE, REG_P0, REG_P0, REG_V10, REG_V31, INS_OPTS_SCALABLE_H); // FACGE ., /Z, ., . diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 8161214e10028..bc5394a34767a 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -1548,6 +1548,45 @@ void emitter::emitInsSanityCheck(instrDesc* id) } break; + case IF_SVE_HO_3A: // ................ ...gggnnnnnddddd -- SVE floating-point convert precision + assert(id->idInsOpt() == INS_OPTS_S_TO_H); + assert(isVectorRegister(id->idReg1())); // ddddd + assert(isLowPredicateRegister(id->idReg2())); // ggg + assert(isVectorRegister(id->idReg3())); // nnnnn + break; + + case IF_SVE_HO_3B: + assert(insOptsConvertFloatToFloat(id->idInsOpt())); + assert(isVectorRegister(id->idReg1())); // ddddd + assert(isLowPredicateRegister(id->idReg2())); // ggg + assert(isVectorRegister(id->idReg3())); // nnnnn + break; + + case IF_SVE_HO_3C: + assert(id->idInsOpt() == INS_OPTS_D_TO_S); + assert(isVectorRegister(id->idReg1())); // ddddd + assert(isLowPredicateRegister(id->idReg2())); // ggg + assert(isVectorRegister(id->idReg3())); // nnnnn + break; + + case IF_SVE_HP_3B: // ................ ...gggnnnnnddddd -- SVE floating-point convert to integer + assert(insOptsScalableFloat(id->idInsOpt()) || id->idInsOpt() == INS_OPTS_H_TO_S || + id->idInsOpt() == INS_OPTS_H_TO_D || id->idInsOpt() == INS_OPTS_S_TO_D || + id->idInsOpt() == INS_OPTS_D_TO_S); + assert(isVectorRegister(id->idReg1())); // ddddd + assert(isLowPredicateRegister(id->idReg2())); // ggg + assert(isVectorRegister(id->idReg3())); // nnnnn + break; + + case IF_SVE_HS_3A: // ................ ...gggnnnnnddddd -- SVE integer convert to floating-point + assert(insOptsScalableAtLeastHalf(id->idInsOpt()) || id->idInsOpt() == INS_OPTS_S_TO_H || + id->idInsOpt() == INS_OPTS_S_TO_D || id->idInsOpt() == INS_OPTS_D_TO_H || + id->idInsOpt() == INS_OPTS_D_TO_S); + assert(isVectorRegister(id->idReg1())); // ddddd + assert(isLowPredicateRegister(id->idReg2())); // ggg + assert(isVectorRegister(id->idReg3())); // nnnnn + break; + case IF_SVE_HT_4A: // ........xx.mmmmm ...gggnnnnn.DDDD -- SVE floating-point compare vectors elemsize = id->idOpSize(); assert(isScalableVectorSize(elemsize)); @@ -4610,8 +4649,6 @@ emitter::code_t emitter::emitInsCodeSve(instruction ins, insFormat fmt) IF_SVE_IG_4A_E}; const static insFormat formatEncode4A[4] = {IF_SVE_AA_3A, IF_SVE_AU_3A, IF_SVE_BS_1A, IF_SVE_CZ_4A}; const static insFormat formatEncode4B[4] = {IF_SVE_BU_2A, IF_SVE_BV_2B, IF_SVE_EA_1A, IF_SVE_EB_1B}; - const static insFormat formatEncode4C[4] = {IF_SVE_HS_3A, IF_SVE_HS_3A_H, IF_SVE_HS_3A_I, IF_SVE_HS_3A_J}; - const static insFormat formatEncode4D[4] = {IF_SVE_HP_3B, IF_SVE_HP_3B_H, IF_SVE_HP_3B_I, IF_SVE_HP_3B_J}; const static insFormat formatEncode4E[4] = {IF_SVE_BE_3A, IF_SVE_FI_3A, IF_SVE_FI_3B, IF_SVE_FI_3C}; const static insFormat formatEncode4F[4] = {IF_SVE_EM_3A, IF_SVE_FK_3A, IF_SVE_FK_3B, IF_SVE_FK_3C}; const static insFormat formatEncode4G[4] = {IF_SVE_AR_4A, IF_SVE_FF_3A, IF_SVE_FF_3B, IF_SVE_FF_3C}; @@ -4660,7 +4697,6 @@ emitter::code_t emitter::emitInsCodeSve(instruction ins, insFormat fmt) const static insFormat formatEncode2AP[2] = {IF_SVE_GY_3B, IF_SVE_HA_3A}; const static insFormat formatEncode2AQ[2] = {IF_SVE_GO_3A, IF_SVE_HC_3A}; const static insFormat formatEncode2AR[2] = {IF_SVE_AP_3A, IF_SVE_CZ_4A}; - const static insFormat formatEncode2AS[2] = {IF_SVE_HO_3A, IF_SVE_HO_3A_B}; const static insFormat formatEncode2AT[2] = {IF_SVE_AB_3A, IF_SVE_EC_1A}; const static insFormat formatEncode2AU[2] = {IF_SVE_AH_3A, IF_SVE_BI_2A}; const static insFormat formatEncode2AV[2] = {IF_SVE_BM_1A, IF_SVE_BN_1A}; @@ -4955,26 +4991,6 @@ emitter::code_t emitter::emitInsCodeSve(instruction ins, insFormat fmt) } } break; - case IF_SVE_4C: - for (index = 0; index < 4; index++) - { - if (fmt == formatEncode4C[index]) - { - encoding_found = true; - break; - } - } - break; - case IF_SVE_4D: - for (index = 0; index < 4; index++) - { - if (fmt == formatEncode4D[index]) - { - encoding_found = true; - break; - } - } - break; case IF_SVE_4E: for (index = 0; index < 4; index++) { @@ -5455,16 +5471,6 @@ emitter::code_t emitter::emitInsCodeSve(instruction ins, insFormat fmt) } } break; - case IF_SVE_2AS: - for (index = 0; index < 2; index++) - { - if (fmt == formatEncode2AS[index]) - { - encoding_found = true; - break; - } - } - break; case IF_SVE_2AT: for (index = 0; index < 2; index++) { @@ -7194,6 +7200,18 @@ emitter::code_t emitter::emitInsCodeSve(instruction ins, insFormat fmt) dst = INS_OPTS_SCALABLE_H; src = INS_OPTS_SCALABLE_D; break; + case INS_OPTS_SCALABLE_H: + dst = INS_OPTS_SCALABLE_H; + src = INS_OPTS_SCALABLE_H; + break; + case INS_OPTS_SCALABLE_S: + dst = INS_OPTS_SCALABLE_S; + src = INS_OPTS_SCALABLE_S; + break; + case INS_OPTS_SCALABLE_D: + dst = INS_OPTS_SCALABLE_D; + src = INS_OPTS_SCALABLE_D; + break; default: noway_assert(!"unreachable"); break; @@ -12685,6 +12703,47 @@ void emitter::emitIns_R_R_R(instruction ins, fmt = IF_SVE_HQ_3A; break; + case INS_sve_bfcvt: + assert(isVectorRegister(reg1)); // ddddd + assert(isLowPredicateRegister(reg2)); // ggg + assert(isVectorRegister(reg3)); // nnnnn + fmt = IF_SVE_HO_3A; + break; + + case INS_sve_fcvt: + assert(isVectorRegister(reg1)); // ddddd + assert(isLowPredicateRegister(reg2)); // ggg + assert(isVectorRegister(reg3)); // nnnnn + fmt = IF_SVE_HO_3B; + break; + + case INS_sve_fcvtx: + assert(isVectorRegister(reg1)); // ddddd + assert(isLowPredicateRegister(reg2)); // ggg + assert(isVectorRegister(reg3)); // nnnnn + fmt = IF_SVE_HO_3C; + break; + + case INS_sve_fcvtzs: + case INS_sve_fcvtzu: + assert(insOptsScalableFloat(opt) || opt == INS_OPTS_H_TO_S || opt == INS_OPTS_H_TO_D || + opt == INS_OPTS_S_TO_D || opt == INS_OPTS_D_TO_S); + assert(isVectorRegister(reg1)); // ddddd + assert(isLowPredicateRegister(reg2)); // ggg + assert(isVectorRegister(reg3)); // nnnnn + fmt = IF_SVE_HP_3B; + break; + + case INS_sve_scvtf: + case INS_sve_ucvtf: + assert(insOptsScalableAtLeastHalf(opt) || opt == INS_OPTS_S_TO_H || opt == INS_OPTS_S_TO_D || + opt == INS_OPTS_D_TO_H || opt == INS_OPTS_D_TO_S); + assert(isVectorRegister(reg1)); // ddddd + assert(isLowPredicateRegister(reg2)); // ggg + assert(isVectorRegister(reg3)); // nnnnn + fmt = IF_SVE_HS_3A; + break; + case INS_sve_frecpx: case INS_sve_fsqrt: assert(isVectorRegister(reg1)); @@ -20175,13 +20234,8 @@ void emitter::emitIns_Call(EmitCallType callType, case IF_SVE_BU_2A: case IF_SVE_BV_2B: case IF_SVE_HS_3A: - case IF_SVE_HS_3A_H: - case IF_SVE_HS_3A_I: - case IF_SVE_HS_3A_J: + case IF_SVE_HP_3A: case IF_SVE_HP_3B: - case IF_SVE_HP_3B_H: - case IF_SVE_HP_3B_I: - case IF_SVE_HP_3B_J: case IF_SVE_AR_4A: case IF_SVE_BV_2A_A: case IF_SVE_AB_3A: @@ -20195,7 +20249,8 @@ void emitter::emitIns_Call(EmitCallType callType, case IF_SVE_GT_4A: case IF_SVE_AP_3A: case IF_SVE_HO_3A: - case IF_SVE_HO_3A_B: + case IF_SVE_HO_3B: + case IF_SVE_HO_3C: case IF_SVE_GQ_3A: case IF_SVE_HU_4B: case IF_SVE_AQ_3A: @@ -20211,7 +20266,6 @@ void emitter::emitIns_Call(EmitCallType callType, case IF_SVE_HQ_3A: case IF_SVE_AS_4A: case IF_SVE_CT_3A: - case IF_SVE_HP_3A: case IF_SVE_HV_4A: return PREDICATE_MERGE; @@ -25425,6 +25479,126 @@ BYTE* emitter::emitOutput_InstrSve(BYTE* dst, instrDesc* id) dst += emitOutput_Instr(dst, code); break; + case IF_SVE_HO_3A: // ................ ...gggnnnnnddddd -- SVE floating-point convert precision + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_V_4_to_0(id->idReg1()); // ddddd + code |= insEncodeReg_P_12_to_10(id->idReg2()); // ggg + code |= insEncodeReg_V_9_to_5(id->idReg3()); // nnnnn + dst += emitOutput_Instr(dst, code); + break; + + case IF_SVE_HO_3B: // ................ ...gggnnnnnddddd -- SVE floating-point convert precision + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_V_4_to_0(id->idReg1()); // ddddd + code |= insEncodeReg_P_12_to_10(id->idReg2()); // ggg + code |= insEncodeReg_V_9_to_5(id->idReg3()); // nnnnn + switch (id->idInsOpt()) + { + case INS_OPTS_H_TO_S: + code |= (1 << 16); + break; + case INS_OPTS_H_TO_D: + code |= (1 << 22) | (1 << 16); + break; + case INS_OPTS_S_TO_H: + break; + case INS_OPTS_S_TO_D: + code |= (1 << 22) | (3 << 16); + break; + case INS_OPTS_D_TO_H: + code |= (1 << 22); + break; + case INS_OPTS_D_TO_S: + code |= (1 << 22) | (1 << 17); + break; + default: + unreached(); + } + dst += emitOutput_Instr(dst, code); + break; + + case IF_SVE_HO_3C: // ................ ...gggnnnnnddddd -- SVE floating-point convert precision + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_V_4_to_0(id->idReg1()); // ddddd + code |= insEncodeReg_P_12_to_10(id->idReg2()); // ggg + code |= insEncodeReg_V_9_to_5(id->idReg3()); // nnnnn + dst += emitOutput_Instr(dst, code); + break; + + case IF_SVE_HP_3B: // ................ ...gggnnnnnddddd -- SVE floating-point convert to integer + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_V_4_to_0(id->idReg1()); // ddddd + code |= insEncodeReg_P_12_to_10(id->idReg2()); // ggg + code |= insEncodeReg_V_9_to_5(id->idReg3()); // nnnnn + + switch (id->idInsOpt()) + { + case INS_OPTS_SCALABLE_H: + code |= (1 << 22) | (1 << 17); + break; + case INS_OPTS_H_TO_S: + code |= (1 << 22) | (1 << 18); + break; + case INS_OPTS_H_TO_D: + code |= (1 << 22) | (3 << 17); + break; + case INS_OPTS_SCALABLE_S: + code |= (1 << 23) | (1 << 18); + break; + case INS_OPTS_S_TO_D: + code |= (3 << 22) | (1 << 18); + break; + case INS_OPTS_D_TO_S: + code |= (3 << 22); + break; + case INS_OPTS_SCALABLE_D: + code |= (3 << 22) | (3 << 17); + break; + default: + unreached(); + break; + } + + dst += emitOutput_Instr(dst, code); + break; + + case IF_SVE_HS_3A: // ................ ...gggnnnnnddddd -- SVE integer convert to floating-point + code = emitInsCodeSve(ins, fmt); + code |= insEncodeReg_V_4_to_0(id->idReg1()); // ddddd + code |= insEncodeReg_P_12_to_10(id->idReg2()); // ggg + code |= insEncodeReg_V_9_to_5(id->idReg3()); // nnnnn + + switch (id->idInsOpt()) + { + case INS_OPTS_SCALABLE_H: + code |= (1 << 22) | (1 << 17); + break; + case INS_OPTS_S_TO_H: + code |= (1 << 22) | (1 << 18); + break; + case INS_OPTS_SCALABLE_S: + code |= (1 << 23) | (1 << 18); + break; + case INS_OPTS_S_TO_D: + code |= (1 << 23) | (1 << 22); + break; + case INS_OPTS_D_TO_H: + code |= (1 << 22) | (3 << 17); + break; + case INS_OPTS_D_TO_S: + code |= (3 << 22) | (1 << 18); + break; + case INS_OPTS_SCALABLE_D: + code |= (3 << 22) | (3 << 17); + break; + default: + unreached(); + break; + } + + dst += emitOutput_Instr(dst, code); + break; + case IF_SVE_IH_3A: // ............iiii ...gggnnnnnttttt -- SVE contiguous load (quadwords, scalar plus // immediate) case IF_SVE_IH_3A_A: // ............iiii ...gggnnnnnttttt -- SVE contiguous load (quadwords, scalar plus @@ -29775,7 +29949,18 @@ void emitter::emitDispInsHelp( // .S, /M, .D // .D, /M, .S // .S, /M, .H + // .D, /M, .D + // .S, /M, .S + // .D, /M, .H + // .H, /M, .H + // .H, /M, .D + // .H, /M, .S case IF_SVE_GQ_3A: // ................ ...gggnnnnnddddd -- SVE floating-point convert precision odd elements + case IF_SVE_HO_3A: // ................ ...gggnnnnnddddd -- SVE floating-point convert precision + case IF_SVE_HO_3B: // ................ ...gggnnnnnddddd -- SVE floating-point convert precision + case IF_SVE_HO_3C: // ................ ...gggnnnnnddddd -- SVE floating-point convert precision + case IF_SVE_HP_3B: // ................ ...gggnnnnnddddd -- SVE floating-point convert to integer + case IF_SVE_HS_3A: // ................ ...gggnnnnnddddd -- SVE integer convert to floating-point { insOpts opt = id->idInsOpt(); @@ -29788,6 +29973,12 @@ void emitter::emitDispInsHelp( case INS_sve_bfcvtnt: opt = INS_OPTS_S_TO_H; break; + case INS_sve_fcvtx: + opt = INS_OPTS_D_TO_S; + break; + case INS_sve_bfcvt: + opt = INS_OPTS_S_TO_H; + break; default: break; } @@ -33394,6 +33585,14 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins } break; + case IF_SVE_HO_3A: // ................ ...gggnnnnnddddd -- SVE floating-point convert precision + case IF_SVE_HO_3B: + case IF_SVE_HO_3C: + case IF_SVE_HP_3B: // ................ ...gggnnnnnddddd -- SVE floating-point convert to integer + result.insThroughput = PERFSCORE_THROUGHPUT_1C; + result.insLatency = PERFSCORE_LATENCY_3C; + break; + // Floating point round to integral, F64. (Note: Worse for F32 and F16) case IF_SVE_HQ_3A: // ........xx...... ...gggnnnnnddddd -- SVE floating-point round to integral value result.insLatency = PERFSCORE_LATENCY_3C; @@ -33422,6 +33621,11 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins } break; + case IF_SVE_HS_3A: // ................ ...gggnnnnnddddd -- SVE integer convert to floating-point + result.insThroughput = PERFSCORE_THROUGHPUT_4X; + result.insLatency = PERFSCORE_LATENCY_6C; + break; + case IF_SVE_DL_2A: // ........xx...... .....l.NNNNddddd -- SVE predicate count (predicate-as-counter) result.insThroughput = PERFSCORE_THROUGHPUT_2C; result.insLatency = PERFSCORE_LATENCY_2C; diff --git a/src/coreclr/jit/emitfmtsarm64sve.h b/src/coreclr/jit/emitfmtsarm64sve.h index 13137166b7d72..cd27f567478cf 100644 --- a/src/coreclr/jit/emitfmtsarm64sve.h +++ b/src/coreclr/jit/emitfmtsarm64sve.h @@ -395,18 +395,13 @@ IF_DEF(SVE_HL_3B, IS_NONE, NONE) // SVE_HL_3B ................ ...gggmmmmmddd IF_DEF(SVE_HM_2A, IS_NONE, NONE) // SVE_HM_2A ........xx...... ...ggg....iddddd -- SVE floating-point arithmetic with immediate (predicated) IF_DEF(SVE_HN_2A, IS_NONE, NONE) // SVE_HN_2A ........xx...iii ......mmmmmddddd -- SVE floating-point trig multiply-add coefficient IF_DEF(SVE_HO_3A, IS_NONE, NONE) // SVE_HO_3A ................ ...gggnnnnnddddd -- SVE floating-point convert precision -IF_DEF(SVE_HO_3A_B, IS_NONE, NONE) // SVE_HO_3A_B ................ ...gggnnnnnddddd -- +IF_DEF(SVE_HO_3B, IS_NONE, NONE) // SVE_HO_3B ................ ...gggnnnnnddddd -- +IF_DEF(SVE_HO_3C, IS_NONE, NONE) // SVE_HO_3C ................ ...gggnnnnnddddd -- IF_DEF(SVE_HP_3A, IS_NONE, NONE) // SVE_HP_3A .............xx. ...gggnnnnnddddd -- SVE floating-point convert to integer -IF_DEF(SVE_HP_3B, IS_NONE, NONE) // SVE_HP_3B ................ ...gggnnnnnddddd -- SVE floating-point convert to integer -IF_DEF(SVE_HP_3B_H, IS_NONE, NONE) // SVE_HP_3B_H ................ ...gggnnnnnddddd -- -IF_DEF(SVE_HP_3B_I, IS_NONE, NONE) // SVE_HP_3B_I ................ ...gggnnnnnddddd -- -IF_DEF(SVE_HP_3B_J, IS_NONE, NONE) // SVE_HP_3B_J ................ ...gggnnnnnddddd -- +IF_DEF(SVE_HP_3B, IS_NONE, NONE) // SVE_HP_3B .............xx. ...gggnnnnnddddd -- SVE floating-point convert to integer IF_DEF(SVE_HQ_3A, IS_NONE, NONE) // SVE_HQ_3A ........xx...... ...gggnnnnnddddd -- SVE floating-point round to integral value IF_DEF(SVE_HR_3A, IS_NONE, NONE) // SVE_HR_3A ........xx...... ...gggnnnnnddddd -- SVE floating-point unary operations IF_DEF(SVE_HS_3A, IS_NONE, NONE) // SVE_HS_3A ................ ...gggnnnnnddddd -- SVE integer convert to floating-point -IF_DEF(SVE_HS_3A_H, IS_NONE, NONE) // SVE_HS_3A_H ................ ...gggnnnnnddddd -- -IF_DEF(SVE_HS_3A_I, IS_NONE, NONE) // SVE_HS_3A_I ................ ...gggnnnnnddddd -- -IF_DEF(SVE_HS_3A_J, IS_NONE, NONE) // SVE_HS_3A_J ................ ...gggnnnnnddddd -- IF_DEF(SVE_HT_4A, IS_NONE, NONE) // SVE_HT_4A ........xx.mmmmm ...gggnnnnn.DDDD -- SVE floating-point compare vectors IF_DEF(SVE_HU_4A, IS_NONE, NONE) // SVE_HU_4A ........xx.mmmmm ...gggnnnnnddddd -- SVE floating-point multiply-accumulate writing addend IF_DEF(SVE_HU_4B, IS_NONE, NONE) // SVE_HU_4B ...........mmmmm ...gggnnnnnddddd -- SVE floating-point multiply-accumulate writing addend diff --git a/src/coreclr/jit/instrsarm64sve.h b/src/coreclr/jit/instrsarm64sve.h index 9e385bca8d7db..f7209c6df98a5 100644 --- a/src/coreclr/jit/instrsarm64sve.h +++ b/src/coreclr/jit/instrsarm64sve.h @@ -239,7 +239,6 @@ INST7(ld1sw, "ld1sw", 0, IF_SV // LD1SW {.D }, /Z, [, .D] SVE_IU_4B_B 11000101010mmmmm 100gggnnnnnttttt C540 8000 // LD1SW {.D }, /Z, [.D{, #}] SVE_IV_3A 11000101001iiiii 100gggnnnnnttttt C520 8000 - // enum name info SVE_AE_3A SVE_BD_3A SVE_EE_1A SVE_FD_3A SVE_FD_3B SVE_FD_3C INST6(mul, "mul", 0, IF_SVE_6A, 0x04100000, 0x04206000, 0x2530C000, 0x4420F800, 0x44A0F800, 0x44E0F800 ) // MUL ., /M, ., . SVE_AE_3A 00000100xx010000 000gggmmmmmddddd 0410 0000 @@ -442,32 +441,6 @@ INST4(fmov, "fmov", 0, IF_SV // FMOV ., #0.0 SVE_EB_1B 00100101xx111000 11000000000ddddd 2538 C000 -// enum name info SVE_HS_3A SVE_HS_3A_H SVE_HS_3A_I SVE_HS_3A_J -INST4(scvtf, "scvtf", 0, IF_SVE_4C, 0x6594A000, 0x65D0A000, 0x65D4A000, 0x65D6A000 ) - // SCVTF .S, /M, .S SVE_HS_3A 0110010110010100 101gggnnnnnddddd 6594 A000 - // SCVTF .D, /M, .S SVE_HS_3A_H 0110010111010000 101gggnnnnnddddd 65D0 A000 - // SCVTF .S, /M, .D SVE_HS_3A_I 0110010111010100 101gggnnnnnddddd 65D4 A000 - // SCVTF .D, /M, .D SVE_HS_3A_J 0110010111010110 101gggnnnnnddddd 65D6 A000 - -INST4(ucvtf, "ucvtf", 0, IF_SVE_4C, 0x6595A000, 0x65D1A000, 0x65D5A000, 0x65D7A000 ) - // UCVTF .S, /M, .S SVE_HS_3A 0110010110010101 101gggnnnnnddddd 6595 A000 - // UCVTF .D, /M, .S SVE_HS_3A_H 0110010111010001 101gggnnnnnddddd 65D1 A000 - // UCVTF .S, /M, .D SVE_HS_3A_I 0110010111010101 101gggnnnnnddddd 65D5 A000 - // UCVTF .D, /M, .D SVE_HS_3A_J 0110010111010111 101gggnnnnnddddd 65D7 A000 - - -// enum name info SVE_HP_3B SVE_HP_3B_H SVE_HP_3B_I SVE_HP_3B_J -INST4(fcvtzs, "fcvtzs", 0, IF_SVE_4D, 0x659CA000, 0x65DCA000, 0x65D8A000, 0x65DEA000 ) - // FCVTZS .S, /M, .S SVE_HP_3B 0110010110011100 101gggnnnnnddddd 659C A000 - // FCVTZS .D, /M, .S SVE_HP_3B_H 0110010111011100 101gggnnnnnddddd 65DC A000 - // FCVTZS .S, /M, .D SVE_HP_3B_I 0110010111011000 101gggnnnnnddddd 65D8 A000 - // FCVTZS .D, /M, .D SVE_HP_3B_J 0110010111011110 101gggnnnnnddddd 65DE A000 - -INST4(fcvtzu, "fcvtzu", 0, IF_SVE_4D, 0x659DA000, 0x65DDA000, 0x65D9A000, 0x65DFA000 ) - // FCVTZU .S, /M, .S SVE_HP_3B 0110010110011101 101gggnnnnnddddd 659D A000 - // FCVTZU .D, /M, .S SVE_HP_3B_H 0110010111011101 101gggnnnnnddddd 65DD A000 - // FCVTZU .S, /M, .D SVE_HP_3B_I 0110010111011001 101gggnnnnnddddd 65D9 A000 - // FCVTZU .D, /M, .D SVE_HP_3B_J 0110010111011111 101gggnnnnnddddd 65DF A000 // enum name info SVE_BE_3A SVE_FI_3A SVE_FI_3B SVE_FI_3C @@ -1121,12 +1094,6 @@ INST2(not, "not", 0, IF_SV // NOT .B, /Z, .B SVE_CZ_4A 001001010000MMMM 01gggg1NNNN0DDDD 2500 4200 -// enum name info SVE_HO_3A SVE_HO_3A_B -INST2(fcvt, "fcvt", 0, IF_SVE_2AS, 0x65CBA000, 0x65CAA000 ) - // FCVT .D, /M, .S SVE_HO_3A 0110010111001011 101gggnnnnnddddd 65CB A000 - // FCVT .S, /M, .D SVE_HO_3A_B 0110010111001010 101gggnnnnnddddd 65CA A000 - - // enum name info SVE_AB_3A SVE_EC_1A INST2(subr, "subr", 0, IF_SVE_2AT, 0x04030000, 0x2523C000 ) // SUBR ., /M, ., . SVE_AB_3A 00000100xx000011 000gggmmmmmddddd 0403 0000 @@ -1823,7 +1790,6 @@ INST1(frsqrts, "frsqrts", 0, IF_SV INST1(ftsmul, "ftsmul", 0, IF_SVE_HK_3A, 0x65000C00 ) // FTSMUL ., ., . SVE_HK_3A 01100101xx0mmmmm 000011nnnnnddddd 6500 0C00 - // enum name info SVE_HT_4A INST1(facge, "facge", 0, IF_SVE_HT_4A, 0x6500C010 ) // FACGE ., /Z, ., . SVE_HT_4A 01100101xx0mmmmm 110gggnnnnn1DDDD 6500 C010 @@ -2057,14 +2023,6 @@ INST1(xar, "xar", 0, IF_SV // XAR ., ., ., # SVE_AW_2A 00000100xx1xxiii 001101mmmmmddddd 0420 3400 -// enum name info SVE_HO_3A -INST1(bfcvt, "bfcvt", 0, IF_SVE_HO_3A, 0x658AA000 ) - // BFCVT .H, /M, .S SVE_HO_3A 0110010110001010 101gggnnnnnddddd 658A A000 - -INST1(fcvtx, "fcvtx", 0, IF_SVE_HO_3A, 0x650AA000 ) - // FCVTX .S, /M, .D SVE_HO_3A 0110010100001010 101gggnnnnnddddd 650A A000 - - // enum name info SVE_AF_3A INST1(andv, "andv", 0, IF_SVE_AF_3A, 0x041A2000 ) // ANDV , , . SVE_AF_3A 00000100xx011010 001gggnnnnnddddd 041A 2000 @@ -2758,10 +2716,35 @@ INST1(ftmad, "ftmad", 0, IF_SV // FTMAD ., ., ., # SVE_HN_2A 01100101xx010iii 100000mmmmmddddd 6510 8000 +// enum name info SVE_HO_3A +INST1(bfcvt, "bfcvt", 0, IF_SVE_HO_3A, 0x658AA000 ) + // BFCVT .H, /M, .S SVE_HO_3A 0110010110001010 101gggnnnnnddddd 658A A000 + +// enum name info SVE_HO_3B +INST1(fcvt, "fcvt", 0, IF_SVE_HO_3B, 0x6588A000) + // FCVT .D, /M, .S SVE_HO_3B 0110010110001000 101gggnnnnnddddd 6588 A000 + +// enum name info SVE_HO_3C +INST1(fcvtx, "fcvtx", 0, IF_SVE_HO_3C, 0x650AA000 ) + // FCVTX .S, /M, .D SVE_HO_3C 0110010100001010 101gggnnnnnddddd 650A A000 + // enum name info SVE_HP_3A INST1(flogb, "flogb", 0, IF_SVE_HP_3A, 0x6518A000 ) // FLOGB ., /M, . SVE_HP_3A 0110010100011xx0 101gggnnnnnddddd 6518 A000 +// enum name info SVE_HP_3B +INST1(fcvtzs, "fcvtzs", 0, IF_SVE_HP_3B, 0x6518A000) + // FCVTZS ., /M, . SVE_HP_3B 0110010100011000 101gggnnnnnddddd 6518 A000 + +INST1(fcvtzu, "fcvtzu", 0, IF_SVE_HP_3B, 0x6519A000) + // FCVTZU ., /M, . SVE_HP_3B 0110010100011001 101gggnnnnnddddd 6519 A000 + +// enum name info SVE_HS_3A +INST1(scvtf, "scvtf", 0, IF_SVE_HS_3A, 0x6510A000) + // SCVTF ., /M, . SVE_HS_3A 0110010100010000 101gggnnnnnddddd 6594 A000 + +INST1(ucvtf, "ucvtf", 0, IF_SVE_HS_3A, 0x6511A000) + // UCVTF ., /M, . SVE_HS_3A 0110010100010001 101gggnnnnnddddd 6595 A000 // enum name info SVE_HU_4A INST1(fnmla, "fnmla", 0, IF_SVE_HU_4A, 0x65204000 )