diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index ff65e2d883a25f..bde4d3b41c7eab 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -13335,137 +13335,233 @@ void emitter::emitDispIns( } case IF_RRD_RRD: + { + if (ins == INS_bt) + { + // INS_bt operands are reversed. Display them in the normal order. + printf("%s, %s", emitRegName(id->idReg2(), attr), emitRegName(id->idReg1(), attr)); + break; + } + + FALLTHROUGH; + } + case IF_RWR_RRD: + { + if ((ins == INS_rol) || (ins == INS_ror) || (ins == INS_rcl) || (ins == INS_rcr) || (ins == INS_shl) || + (ins == INS_shr) || (ins == INS_sar)) + { + // This is the APX NDD form of these instructions. + printf("%s", emitRegName(id->idReg1(), attr)); + printf(", %s", emitRegName(id->idReg2(), attr)); + emitDispShift(ins, (BYTE)0); + break; + } + + FALLTHROUGH; + } + case IF_RRW_RRD: case IF_RRW_RRW: { - switch (ins) - { - case INS_pmovmskb: - { - assert(!id->idIsEvexAaaContextSet()); - printf("%s, %s", emitRegName(id->idReg1(), EA_4BYTE), emitRegName(id->idReg2(), attr)); - break; - } + emitAttr tgtAttr = attr; + emitAttr srcAttr = attr; - case INS_cvtsi2ss32: - case INS_cvtsi2sd32: - case INS_cvtsi2ss64: - case INS_cvtsi2sd64: - { - assert(!id->idIsEvexAaaContextSet()); - printf("%s, %s", emitRegName(id->idReg1(), EA_16BYTE), emitRegName(id->idReg2(), attr)); - break; - } + insTupleType tt = insTupleTypeInfo(ins); - case INS_cvttsd2si32: - case INS_cvttsd2si64: - case INS_cvtsd2si32: - case INS_cvtsd2si64: - case INS_cvtss2si32: - case INS_cvtss2si64: - case INS_cvttss2si32: - case INS_cvttss2si64: - case INS_vcvtsd2usi32: - case INS_vcvtsd2usi64: - case INS_vcvtss2usi32: - case INS_vcvtss2usi64: - case INS_vcvttsd2usi32: - case INS_vcvttsd2usi64: - case INS_vcvttss2usi32: - case INS_vcvttss2usi64: - case INS_vcvttsd2sis32: - case INS_vcvttsd2sis64: - case INS_vcvttss2sis32: - case INS_vcvttss2sis64: - case INS_vcvttsd2usis32: - case INS_vcvttsd2usis64: - case INS_vcvttss2usis32: - case INS_vcvttss2usis64: + if (tt == INS_TT_NONE) + { + switch (ins) { - assert(!id->idIsEvexAaaContextSet()); - printf("%s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), EA_16BYTE)); - break; - } + case INS_pmovmskb: + { + assert(!id->idIsEvexAaaContextSet()); + tgtAttr = EA_4BYTE; + break; + } #ifdef TARGET_AMD64 - case INS_movsxd: - { - printf("%s, %s", emitRegName(id->idReg1(), EA_8BYTE), emitRegName(id->idReg2(), EA_4BYTE)); - break; - } + case INS_movsxd: + { + tgtAttr = EA_8BYTE; + srcAttr = EA_4BYTE; + break; + } #endif // TARGET_AMD64 - case INS_movsx: - case INS_movzx: - { - printf("%s, %s", emitRegName(id->idReg1(), EA_PTRSIZE), emitRegName(id->idReg2(), attr)); - break; - } + case INS_movsx: + case INS_movzx: + { + tgtAttr = EA_PTRSIZE; + break; + } - case INS_bt: - { - // INS_bt operands are reversed. Display them in the normal order. - printf("%s, %s", emitRegName(id->idReg2(), attr), emitRegName(id->idReg1(), attr)); - break; + case INS_crc32: + { + tgtAttr = std::max(EA_4BYTE, EA_SIZE(attr)); + break; + } + + default: + break; } - case INS_crc32: + printf("%s", emitRegName(id->idReg1(), tgtAttr)); + printf(", %s", emitRegName(id->idReg2(), srcAttr)); + break; + } + + unsigned inputSize = static_cast(GetInputSizeInBytes(id)); + + switch (tt) + { + case INS_TT_HALF: + case INS_TT_HALF_MEM: { - if (attr != EA_8BYTE) + unsigned maskElemSize = XMM_REGSIZE_BYTES / CodeGenInterface::instKMaskBaseSize(ins); + emitAttr halfSize = std::max(EA_16BYTE, EA_ATTR(EA_SIZE_IN_BYTES(attr) / 2)); + + if (inputSize < maskElemSize) { - // The idReg1 is always 4 bytes, but the size of idReg2 can vary. - // This logic ensures that we print `crc32 eax, bx` instead of `crc32 ax, bx` - printf("%s, %s", emitRegName(id->idReg1(), EA_4BYTE), emitRegName(id->idReg2(), attr)); + assert(inputSize == (maskElemSize / 2)); + srcAttr = halfSize; } else { - printf("%s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr)); + tgtAttr = halfSize; } break; } - case INS_vpbroadcastb_gpr: - case INS_vpbroadcastd_gpr: - case INS_vpbroadcastw_gpr: + case INS_TT_QUARTER_MEM: { - printf("%s", emitRegName(id->idReg1(), attr)); - emitDispEmbMasking(id); - printf(", %s", emitRegName(id->idReg2(), EA_4BYTE)); - break; - } + unsigned maskElemSize = XMM_REGSIZE_BYTES / CodeGenInterface::instKMaskBaseSize(ins); + emitAttr quarterSize = std::max(EA_16BYTE, EA_ATTR(EA_SIZE_IN_BYTES(attr) / 4)); - case INS_vpbroadcastq_gpr: - { - printf("%s", emitRegName(id->idReg1(), attr)); - emitDispEmbMasking(id); - printf(", %s", emitRegName(id->idReg2(), EA_8BYTE)); + if (inputSize < maskElemSize) + { + assert(inputSize == (maskElemSize / 4)); + srcAttr = quarterSize; + } + else + { + tgtAttr = quarterSize; + } break; } - case INS_rol: - case INS_ror: - case INS_rcl: - case INS_rcr: - case INS_shl: - case INS_shr: - case INS_sar: + case INS_TT_EIGHTH_MEM: { - printf("%s", emitRegName(id->idReg1(), attr)); - printf(", %s", emitRegName(id->idReg2(), attr)); - emitDispShift(ins, (BYTE)0); + unsigned maskElemSize = XMM_REGSIZE_BYTES / CodeGenInterface::instKMaskBaseSize(ins); + emitAttr eighthSize = std::max(EA_16BYTE, EA_ATTR(EA_SIZE_IN_BYTES(attr) / 8)); + + if (inputSize < maskElemSize) + { + assert(inputSize == (maskElemSize / 8)); + srcAttr = eighthSize; + } + else + { + tgtAttr = eighthSize; + } break; } default: { - printf("%s", emitRegName(id->idReg1(), attr)); - emitDispEmbMasking(id); - printf(", %s", emitRegName(id->idReg2(), attr)); - emitDispEmbRounding(id); + switch (ins) + { + case INS_cvtsi2ss32: + case INS_cvtsi2sd32: + case INS_cvtsi2ss64: + case INS_cvtsi2sd64: + { + assert(!id->idIsEvexAaaContextSet()); + tgtAttr = EA_16BYTE; + break; + } + + case INS_cvttsd2si32: + case INS_cvttsd2si64: + case INS_cvtsd2si32: + case INS_cvtsd2si64: + case INS_cvtss2si32: + case INS_cvtss2si64: + case INS_cvttss2si32: + case INS_cvttss2si64: + case INS_vcvtsd2usi32: + case INS_vcvtsd2usi64: + case INS_vcvtss2usi32: + case INS_vcvtss2usi64: + case INS_vcvttsd2usi32: + case INS_vcvttsd2usi64: + case INS_vcvttss2usi32: + case INS_vcvttss2usi64: + case INS_vcvttsd2sis32: + case INS_vcvttsd2sis64: + case INS_vcvttss2sis32: + case INS_vcvttss2sis64: + case INS_vcvttsd2usis32: + case INS_vcvttsd2usis64: + case INS_vcvttss2usis32: + case INS_vcvttss2usis64: + { + assert(!id->idIsEvexAaaContextSet()); + srcAttr = EA_16BYTE; + break; + } + + case INS_vpbroadcastb_gpr: + case INS_vpbroadcastd_gpr: + case INS_vpbroadcastw_gpr: + { + srcAttr = EA_4BYTE; + break; + } + + case INS_vpbroadcastq_gpr: + { + srcAttr = EA_8BYTE; + break; + } + + case INS_cvtpd2dq: + case INS_cvtpd2ps: + case INS_cvttpd2dq: + case INS_vcvtdq2ph: + case INS_vcvtneps2bf16: + case INS_vcvtpd2udq: + case INS_vcvtps2phx: + case INS_vcvtqq2ps: + case INS_vcvttpd2dqs: + case INS_vcvttpd2udq: + case INS_vcvttpd2udqs: + case INS_vcvtudq2ph: + case INS_vcvtuqq2ps: + { + tgtAttr = std::max(EA_16BYTE, EA_ATTR(EA_SIZE_IN_BYTES(attr) / 2)); + break; + } + + case INS_vcvtpd2ph: + case INS_vcvtqq2ph: + case INS_vcvtuqq2ph: + { + tgtAttr = std::max(EA_16BYTE, EA_ATTR(EA_SIZE_IN_BYTES(attr) / 4)); + break; + } + + default: + break; + } break; } } + + printf("%s", emitRegName(id->idReg1(), tgtAttr)); + emitDispEmbMasking(id); + printf(", %s", emitRegName(id->idReg2(), srcAttr)); + emitDispEmbRounding(id); break; } @@ -13636,6 +13732,12 @@ void emitter::emitDispIns( break; } + case INS_vcvtps2ph: + { + tgtAttr = std::max(EA_16BYTE, EA_ATTR(EA_SIZE_IN_BYTES(attr) / 2)); + break; + } + default: { break;