From 0bca3b99ca19a22c4722652df1ce74a8cdf82f34 Mon Sep 17 00:00:00 2001 From: Anthony Canino Date: Tue, 26 Oct 2021 06:06:29 -0400 Subject: [PATCH 1/6] Add 'w' and 's' bit to xarch instruction flags. Change encodes 'w' and 's' in the insFlags struct and INS_FLAG entry for xarch instruction table. In addition, `HasWBit` and `HasSBit` check if this flag is set for an instruction, which allows to start simplifying some of the various ad-hoc checks for these bits that were previously done per-instruction throughout emitxarch.cpp. --- src/coreclr/jit/emitxarch.cpp | 47 ++++++++--- src/coreclr/jit/emitxarch.h | 3 + src/coreclr/jit/instr.h | 4 + src/coreclr/jit/instrsxarch.h | 150 ++++++++++++++++------------------ 4 files changed, 115 insertions(+), 89 deletions(-) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index d472b1393518fb..389f5c4190bc6e 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -149,6 +149,33 @@ bool emitter::IsDstSrcSrcAVXInstruction(instruction ins) return ((CodeGenInterface::instInfo[ins] & INS_Flags_IsDstSrcSrcAVXInstruction) != 0) && IsAVXInstruction(ins); } +//------------------------------------------------------------------------ +// HasSBit: check if the instruction has the 's' (sign extend) bit. +// +// Arguments: +// ins - instruction to test +// +// Return Value: +// true if instruction has the 's' bit, false otherwise +bool emitter::HasSBit(instruction ins) +{ + return ((CodeGenInterface::instInfo[ins] & INS_FLAGS_Has_Sbit) != 0) ; +} + +//------------------------------------------------------------------------ +// HasSBit: check if the instruction has the 'w' bit required to use the +// full operand size. +// +// Arguments: +// ins - instruction to test +// +// Return Value: +// true if instruction has the 'w' bit, false otherwise +bool emitter::HasWBit(instruction ins) +{ + return ((CodeGenInterface::instInfo[ins] & INS_FLAGS_Has_Wbit) != 0) ; +} + //------------------------------------------------------------------------ // DoesWriteZeroFlag: check if the instruction write the // ZF flag. @@ -10336,10 +10363,9 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) // Use the large version if this is not a byte. This trick will not // work in case of SSE2 and AVX instructions. - if ((size != EA_1BYTE) && (ins != INS_imul) && (ins != INS_bsf) && (ins != INS_bsr) && !IsSSEInstruction(ins) && - !IsAVXInstruction(ins)) + if ((size != EA_1BYTE) && HasWBit(ins)) { - code++; + code |= 0x1; } } else if (CodeGen::instIsFP(ins)) @@ -11104,8 +11130,9 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) // Use the large version if this is not a byte // TODO-XArch-Cleanup Can the need for the 'w' size bit be encoded in the instruction flags? - if ((size != EA_1BYTE) && (ins != INS_imul) && (ins != INS_bsf) && (ins != INS_bsr) && (!insIsCMOV(ins)) && - !IsSSEInstruction(ins) && !IsAVXInstruction(ins)) + // Anthony: I believe we may remove !insIsCMOV check, but leaving for comparison purposes with another + // similar check below + if ((size != EA_1BYTE) && HasWBit(ins) && !insIsCMOV(ins)) { code |= 0x1; } @@ -11568,12 +11595,12 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) code &= 0x0000FFFF; } - if ((ins == INS_movsx || ins == INS_movzx || ins == INS_cmpxchg || ins == INS_xchg || ins == INS_xadd || - insIsCMOV(ins)) && - size != EA_1BYTE) + // Anthony: Per L10986, why is this insIsCMOV (which does not have a w bit) + // and above is !insIsCMOV + if (size != EA_1BYTE && (HasWBit(ins) || insIsCMOV(ins))) { // movsx and movzx are 'big' opcodes but also have the 'w' bit - code++; + code |= 0x1; } } else if (CodeGen::instIsFP(ins)) @@ -12740,7 +12767,7 @@ BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id) } // "test" has no 's' bit - if (ins == INS_test) + if (!HasSBit(ins)) { useSigned = false; } diff --git a/src/coreclr/jit/emitxarch.h b/src/coreclr/jit/emitxarch.h index 54575044f13867..538cf574aa3367 100644 --- a/src/coreclr/jit/emitxarch.h +++ b/src/coreclr/jit/emitxarch.h @@ -89,6 +89,7 @@ static bool IsAVXOnlyInstruction(instruction ins); static bool IsFMAInstruction(instruction ins); static bool IsAVXVNNIInstruction(instruction ins); static bool IsBMIInstruction(instruction ins); + static regNumber getBmiRegNumber(instruction ins); static regNumber getSseShiftRegNumber(instruction ins); bool IsAVXInstruction(instruction ins) const; @@ -190,6 +191,8 @@ void SetContains256bitAVX(bool value) bool IsDstDstSrcAVXInstruction(instruction ins); bool IsDstSrcSrcAVXInstruction(instruction ins); +bool HasWBit(instruction ins); +bool HasSBit(instruction ins); bool DoesWriteZeroFlag(instruction ins); bool DoesWriteSignFlag(instruction ins); bool DoesResetOverflowAndCarryFlags(instruction ins); diff --git a/src/coreclr/jit/instr.h b/src/coreclr/jit/instr.h index 1e9302cf503e89..1b613b77eb446f 100644 --- a/src/coreclr/jit/instr.h +++ b/src/coreclr/jit/instr.h @@ -131,6 +131,10 @@ enum insFlags : uint32_t // Avx INS_Flags_IsDstDstSrcAVXInstruction = 1 << 25, INS_Flags_IsDstSrcSrcAVXInstruction = 1 << 26, + + // w and s bits + INS_FLAGS_Has_Wbit = 1 << 27, + INS_FLAGS_Has_Sbit = 1 << 28, // TODO-Cleanup: Remove this flag and its usage from TARGET_XARCH INS_FLAGS_DONT_CARE = 0x00, diff --git a/src/coreclr/jit/instrsxarch.h b/src/coreclr/jit/instrsxarch.h index 17b94fc81d779e..458f919fe27935 100644 --- a/src/coreclr/jit/instrsxarch.h +++ b/src/coreclr/jit/instrsxarch.h @@ -57,9 +57,9 @@ INST5(pop, "pop", IUM_WR, 0x00008E, BAD_CODE, INST5(push_hide, "push", IUM_RD, 0x0030FE, 0x000068, BAD_CODE, BAD_CODE, 0x000050, INS_FLAGS_None ) INST5(pop_hide, "pop", IUM_WR, 0x00008E, BAD_CODE, BAD_CODE, BAD_CODE, 0x000058, INS_FLAGS_None ) -INST5(inc, "inc", IUM_RW, 0x0000FE, BAD_CODE, BAD_CODE, BAD_CODE, 0x000040, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF ) +INST5(inc, "inc", IUM_RW, 0x0000FE, BAD_CODE, BAD_CODE, BAD_CODE, 0x000040, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | INS_FLAGS_Has_Wbit ) INST5(inc_l, "inc", IUM_RW, 0x0000FE, BAD_CODE, BAD_CODE, BAD_CODE, 0x00C0FE, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF ) -INST5(dec, "dec", IUM_RW, 0x0008FE, BAD_CODE, BAD_CODE, BAD_CODE, 0x000048, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF ) +INST5(dec, "dec", IUM_RW, 0x0008FE, BAD_CODE, BAD_CODE, BAD_CODE, 0x000048, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | INS_FLAGS_Has_Wbit ) INST5(dec_l, "dec", IUM_RW, 0x0008FE, BAD_CODE, BAD_CODE, BAD_CODE, 0x00C8FE, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF ) // Multi-byte opcodes without modrm are represented in mixed endian fashion. @@ -67,18 +67,16 @@ INST5(dec_l, "dec", IUM_RW, 0x0008FE, BAD_CODE, INST5(bswap, "bswap", IUM_RW, 0x0F00C8, BAD_CODE, BAD_CODE, BAD_CODE, 0x00C80F, INS_FLAGS_None ) // id nm um mr mi rm a4 flags -INST4(add, "add", IUM_RW, 0x000000, 0x000080, 0x000002, 0x000004, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF ) -INST4(or, "or", IUM_RW, 0x000008, 0x000880, 0x00000A, 0x00000C, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF ) -INST4(adc, "adc", IUM_RW, 0x000010, 0x001080, 0x000012, 0x000014, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF - | Reads_CF ) -INST4(sbb, "sbb", IUM_RW, 0x000018, 0x001880, 0x00001A, 0x00001C, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF - | Reads_CF ) -INST4(and, "and", IUM_RW, 0x000020, 0x002080, 0x000022, 0x000024, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF ) -INST4(sub, "sub", IUM_RW, 0x000028, 0x002880, 0x00002A, 0x00002C, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF ) -INST4(xor, "xor", IUM_RW, 0x000030, 0x003080, 0x000032, 0x000034, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF ) -INST4(cmp, "cmp", IUM_RD, 0x000038, 0x003880, 0x00003A, 0x00003C, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF ) -INST4(test, "test", IUM_RD, 0x000084, 0x0000F6, 0x000084, 0x0000A8, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF ) -INST4(mov, "mov", IUM_WR, 0x000088, 0x0000C6, 0x00008A, 0x0000B0, INS_FLAGS_None ) +INST4(add, "add", IUM_RW, 0x000000, 0x000080, 0x000002, 0x000004, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(or, "or", IUM_RW, 0x000008, 0x000880, 0x00000A, 0x00000C, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(adc, "adc", IUM_RW, 0x000010, 0x001080, 0x000012, 0x000014, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | Reads_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(sbb, "sbb", IUM_RW, 0x000018, 0x001880, 0x00001A, 0x00001C, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | Reads_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(and, "and", IUM_RW, 0x000020, 0x002080, 0x000022, 0x000024, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(sub, "sub", IUM_RW, 0x000028, 0x002880, 0x00002A, 0x00002C, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(xor, "xor", IUM_RW, 0x000030, 0x003080, 0x000032, 0x000034, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(cmp, "cmp", IUM_RD, 0x000038, 0x003880, 0x00003A, 0x00003C, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Sbit | INS_FLAGS_Has_Wbit ) +INST4(test, "test", IUM_RD, 0x000084, 0x0000F6, 0x000084, 0x0000A8, Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Resets_CF | INS_FLAGS_Has_Wbit ) +INST4(mov, "mov", IUM_WR, 0x000088, 0x0000C6, 0x00008A, 0x0000B0, INS_FLAGS_Has_Wbit ) INST4(lea, "lea", IUM_WR, BAD_CODE, BAD_CODE, 0x00008D, BAD_CODE, INS_FLAGS_None ) @@ -91,11 +89,11 @@ INST3(bt, "bt", IUM_RD, 0x0F00A3, BAD_CODE, INST3(bsf, "bsf", IUM_WR, BAD_CODE, BAD_CODE, 0x0F00BC, Undefined_OF | Undefined_SF | Writes_ZF | Undefined_AF | Undefined_PF | Undefined_CF ) INST3(bsr, "bsr", IUM_WR, BAD_CODE, BAD_CODE, 0x0F00BD, Undefined_OF | Undefined_SF | Writes_ZF | Undefined_AF | Undefined_PF | Undefined_CF ) -INST3(movsx, "movsx", IUM_WR, BAD_CODE, BAD_CODE, 0x0F00BE, INS_FLAGS_None ) +INST3(movsx, "movsx", IUM_WR, BAD_CODE, BAD_CODE, 0x0F00BE, INS_FLAGS_Has_Wbit ) #ifdef TARGET_AMD64 -INST3(movsxd, "movsxd", IUM_WR, BAD_CODE, BAD_CODE, 0x4800000063, INS_FLAGS_None ) +INST3(movsxd, "movsxd", IUM_WR, BAD_CODE, BAD_CODE, 0x4800000063, INS_FLAGS_Has_Wbit ) #endif -INST3(movzx, "movzx", IUM_WR, BAD_CODE, BAD_CODE, 0x0F00B6, INS_FLAGS_None ) +INST3(movzx, "movzx", IUM_WR, BAD_CODE, BAD_CODE, 0x0F00B6, INS_FLAGS_Has_Wbit ) INST3(cmovo, "cmovo", IUM_WR, BAD_CODE, BAD_CODE, 0x0F0040, Reads_OF ) INST3(cmovno, "cmovno", IUM_WR, BAD_CODE, BAD_CODE, 0x0F0041, Reads_OF ) @@ -114,8 +112,8 @@ INST3(cmovge, "cmovge", IUM_WR, BAD_CODE, BAD_CODE, INST3(cmovle, "cmovle", IUM_WR, BAD_CODE, BAD_CODE, 0x0F004E, Reads_OF | Reads_SF | Reads_ZF ) INST3(cmovg, "cmovg", IUM_WR, BAD_CODE, BAD_CODE, 0x0F004F, Reads_OF | Reads_SF | Reads_ZF ) -INST3(xchg, "xchg", IUM_RW, 0x000086, BAD_CODE, 0x000086, INS_FLAGS_None ) -INST3(imul, "imul", IUM_RW, 0x0F00AC, BAD_CODE, 0x0F00AF, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) +INST3(xchg, "xchg", IUM_RW, 0x000086, BAD_CODE, 0x000086, INS_FLAGS_Has_Wbit ) +INST3(imul, "imul", IUM_RW, 0x0F00AC, BAD_CODE, 0x0F00AF, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) // id nm um mr mi rm flags @@ -123,25 +121,25 @@ INST3(imul, "imul", IUM_RW, 0x0F00AC, BAD_CODE, // as 2-operand instructions with the target register being implicit // implicit_reg = op1*op2_icon #define INSTMUL INST3 -INSTMUL(imul_AX, "imul", IUM_RD, BAD_CODE, 0x000068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_CX, "imul", IUM_RD, BAD_CODE, 0x000868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_DX, "imul", IUM_RD, BAD_CODE, 0x001068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_BX, "imul", IUM_RD, BAD_CODE, 0x001868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_SP, "imul", IUM_RD, BAD_CODE, BAD_CODE, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_BP, "imul", IUM_RD, BAD_CODE, 0x002868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_SI, "imul", IUM_RD, BAD_CODE, 0x003068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_DI, "imul", IUM_RD, BAD_CODE, 0x003868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) +INSTMUL(imul_AX, "imul", IUM_RD, BAD_CODE, 0x000068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_CX, "imul", IUM_RD, BAD_CODE, 0x000868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_DX, "imul", IUM_RD, BAD_CODE, 0x001068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_BX, "imul", IUM_RD, BAD_CODE, 0x001868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_SP, "imul", IUM_RD, BAD_CODE, BAD_CODE, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_BP, "imul", IUM_RD, BAD_CODE, 0x002868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_SI, "imul", IUM_RD, BAD_CODE, 0x003068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_DI, "imul", IUM_RD, BAD_CODE, 0x003868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) #ifdef TARGET_AMD64 -INSTMUL(imul_08, "imul", IUM_RD, BAD_CODE, 0x4400000068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_09, "imul", IUM_RD, BAD_CODE, 0x4400000868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_10, "imul", IUM_RD, BAD_CODE, 0x4400001068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_11, "imul", IUM_RD, BAD_CODE, 0x4400001868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_12, "imul", IUM_RD, BAD_CODE, 0x4400002068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_13, "imul", IUM_RD, BAD_CODE, 0x4400002868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_14, "imul", IUM_RD, BAD_CODE, 0x4400003068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INSTMUL(imul_15, "imul", IUM_RD, BAD_CODE, 0x4400003868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) +INSTMUL(imul_08, "imul", IUM_RD, BAD_CODE, 0x4400000068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_09, "imul", IUM_RD, BAD_CODE, 0x4400000868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_10, "imul", IUM_RD, BAD_CODE, 0x4400001068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_11, "imul", IUM_RD, BAD_CODE, 0x4400001868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_12, "imul", IUM_RD, BAD_CODE, 0x4400002068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_13, "imul", IUM_RD, BAD_CODE, 0x4400002868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_14, "imul", IUM_RD, BAD_CODE, 0x4400003068, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) +INSTMUL(imul_15, "imul", IUM_RD, BAD_CODE, 0x4400003868, BAD_CODE, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Sbit ) #endif // TARGET_AMD64 @@ -628,55 +626,49 @@ INST2(ret, "ret", IUM_RD, 0x0000C3, 0x0000C2, INST2(loop, "loop", IUM_RD, BAD_CODE, 0x0000E2, INS_FLAGS_None ) INST2(call, "call", IUM_RD, 0x0010FF, 0x0000E8, INS_FLAGS_None ) -INST2(rol, "rol", IUM_RW, 0x0000D2, BAD_CODE, Undefined_OF | Writes_CF ) -INST2(rol_1, "rol", IUM_RW, 0x0000D0, 0x0000D0, Writes_OF | Writes_CF ) -INST2(rol_N, "rol", IUM_RW, 0x0000C0, 0x0000C0, Undefined_OF | Writes_CF ) -INST2(ror, "ror", IUM_RW, 0x0008D2, BAD_CODE, Undefined_OF | Writes_CF ) -INST2(ror_1, "ror", IUM_RW, 0x0008D0, 0x0008D0, Writes_OF | Writes_CF ) -INST2(ror_N, "ror", IUM_RW, 0x0008C0, 0x0008C0, Undefined_OF | Writes_CF ) - -INST2(rcl, "rcl", IUM_RW, 0x0010D2, BAD_CODE, Undefined_OF | Writes_CF - | Reads_CF ) -INST2(rcl_1, "rcl", IUM_RW, 0x0010D0, 0x0010D0, Writes_OF | Writes_CF - | Reads_CF ) -INST2(rcl_N, "rcl", IUM_RW, 0x0010C0, 0x0010C0, Undefined_OF | Writes_CF - | Reads_CF ) -INST2(rcr, "rcr", IUM_RW, 0x0018D2, BAD_CODE, Undefined_OF | Writes_CF - | Reads_CF ) -INST2(rcr_1, "rcr", IUM_RW, 0x0018D0, 0x0018D0, Writes_OF | Writes_CF - | Reads_CF ) -INST2(rcr_N, "rcr", IUM_RW, 0x0018C0, 0x0018C0, Undefined_OF | Writes_CF - | Reads_CF ) -INST2(shl, "shl", IUM_RW, 0x0020D2, BAD_CODE, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(shl_1, "shl", IUM_RW, 0x0020D0, 0x0020D0, Writes_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(shl_N, "shl", IUM_RW, 0x0020C0, 0x0020C0, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(shr, "shr", IUM_RW, 0x0028D2, BAD_CODE, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(shr_1, "shr", IUM_RW, 0x0028D0, 0x0028D0, Writes_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(shr_N, "shr", IUM_RW, 0x0028C0, 0x0028C0, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(sar, "sar", IUM_RW, 0x0038D2, BAD_CODE, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(sar_1, "sar", IUM_RW, 0x0038D0, 0x0038D0, Writes_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) -INST2(sar_N, "sar", IUM_RW, 0x0038C0, 0x0038C0, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) +INST2(rol, "rol", IUM_RW, 0x0000D2, BAD_CODE, Undefined_OF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(rol_1, "rol", IUM_RW, 0x0000D0, 0x0000D0, Writes_OF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(rol_N, "rol", IUM_RW, 0x0000C0, 0x0000C0, Undefined_OF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(ror, "ror", IUM_RW, 0x0008D2, BAD_CODE, Undefined_OF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(ror_1, "ror", IUM_RW, 0x0008D0, 0x0008D0, Writes_OF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(ror_N, "ror", IUM_RW, 0x0008C0, 0x0008C0, Undefined_OF | Writes_CF | INS_FLAGS_Has_Wbit ) + +INST2(rcl, "rcl", IUM_RW, 0x0010D2, BAD_CODE, Undefined_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) +INST2(rcl_1, "rcl", IUM_RW, 0x0010D0, 0x0010D0, Writes_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) +INST2(rcl_N, "rcl", IUM_RW, 0x0010C0, 0x0010C0, Undefined_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) +INST2(rcr, "rcr", IUM_RW, 0x0018D2, BAD_CODE, Undefined_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) +INST2(rcr_1, "rcr", IUM_RW, 0x0018D0, 0x0018D0, Writes_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) +INST2(rcr_N, "rcr", IUM_RW, 0x0018C0, 0x0018C0, Undefined_OF | Writes_CF | Reads_CF | INS_FLAGS_Has_Wbit ) +INST2(shl, "shl", IUM_RW, 0x0020D2, BAD_CODE, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(shl_1, "shl", IUM_RW, 0x0020D0, 0x0020D0, Writes_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(shl_N, "shl", IUM_RW, 0x0020C0, 0x0020C0, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(shr, "shr", IUM_RW, 0x0028D2, BAD_CODE, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(shr_1, "shr", IUM_RW, 0x0028D0, 0x0028D0, Writes_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(shr_N, "shr", IUM_RW, 0x0028C0, 0x0028C0, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(sar, "sar", IUM_RW, 0x0038D2, BAD_CODE, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(sar_1, "sar", IUM_RW, 0x0038D0, 0x0038D0, Writes_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST2(sar_N, "sar", IUM_RW, 0x0038C0, 0x0038C0, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) // id nm um mr flags -INST1(r_movsb, "rep movsb", IUM_RD, 0x00A4F3, Reads_DF ) -INST1(r_movsd, "rep movsd", IUM_RD, 0x00A5F3, Reads_DF ) +INST1(r_movsb, "rep movsb", IUM_RD, 0x00A4F3, Reads_DF | INS_FLAGS_Has_Wbit ) +INST1(r_movsd, "rep movsd", IUM_RD, 0x00A5F3, Reads_DF | INS_FLAGS_Has_Wbit ) #if defined(TARGET_AMD64) INST1(r_movsq, "rep movsq", IUM_RD, 0xF3A548, Reads_DF ) #endif // defined(TARGET_AMD64) -INST1(movsb, "movsb", IUM_RD, 0x0000A4, Reads_DF ) -INST1(movsd, "movsd", IUM_RD, 0x0000A5, Reads_DF ) +INST1(movsb, "movsb", IUM_RD, 0x0000A4, Reads_DF | INS_FLAGS_Has_Wbit ) +INST1(movsd, "movsd", IUM_RD, 0x0000A5, Reads_DF | INS_FLAGS_Has_Wbit ) #if defined(TARGET_AMD64) INST1(movsq, "movsq", IUM_RD, 0x00A548, Reads_DF ) #endif // defined(TARGET_AMD64) -INST1(r_stosb, "rep stosb", IUM_RD, 0x00AAF3, Reads_DF ) -INST1(r_stosd, "rep stosd", IUM_RD, 0x00ABF3, Reads_DF ) +INST1(r_stosb, "rep stosb", IUM_RD, 0x00AAF3, Reads_DF | INS_FLAGS_Has_Wbit ) +INST1(r_stosd, "rep stosd", IUM_RD, 0x00ABF3, Reads_DF | INS_FLAGS_Has_Wbit ) #if defined(TARGET_AMD64) INST1(r_stosq, "rep stosq", IUM_RD, 0xF3AB48, Reads_DF ) #endif // defined(TARGET_AMD64) -INST1(stosb, "stosb", IUM_RD, 0x0000AA, Reads_DF ) -INST1(stosd, "stosd", IUM_RD, 0x0000AB, Reads_DF ) +INST1(stosb, "stosb", IUM_RD, 0x0000AA, Reads_DF | INS_FLAGS_Has_Wbit ) +INST1(stosd, "stosd", IUM_RD, 0x0000AB, Reads_DF | INS_FLAGS_Has_Wbit ) #if defined(TARGET_AMD64) INST1(stosq, "stosq", IUM_RD, 0x00AB48, Reads_DF ) #endif // defined(TARGET_AMD64) @@ -687,20 +679,20 @@ INST1(pause, "pause", IUM_RD, 0x0090F3, INST1(lock, "lock", IUM_RD, 0x0000F0, INS_FLAGS_None ) INST1(leave, "leave", IUM_RD, 0x0000C9, INS_FLAGS_None ) -INST1(neg, "neg", IUM_RW, 0x0018F6, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF ) -INST1(not, "not", IUM_RW, 0x0010F6, INS_FLAGS_None ) +INST1(neg, "neg", IUM_RW, 0x0018F6, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST1(not, "not", IUM_RW, 0x0010F6, INS_FLAGS_None | INS_FLAGS_Has_Wbit ) INST1(cwde, "cwde", IUM_RD, 0x000098, INS_FLAGS_None ) INST1(cdq, "cdq", IUM_RD, 0x000099, INS_FLAGS_None ) -INST1(idiv, "idiv", IUM_RD, 0x0038F6, Undefined_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Undefined_CF ) -INST1(imulEAX, "imul", IUM_RD, 0x0028F6, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) -INST1(div, "div", IUM_RD, 0x0030F6, Undefined_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Undefined_CF ) -INST1(mulEAX, "mul", IUM_RD, 0x0020F6, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF ) +INST1(idiv, "idiv", IUM_RD, 0x0038F6, Undefined_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Undefined_CF | INS_FLAGS_Has_Wbit ) +INST1(imulEAX, "imul", IUM_RD, 0x0028F6, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST1(div, "div", IUM_RD, 0x0030F6, Undefined_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Undefined_CF | INS_FLAGS_Has_Wbit ) +INST1(mulEAX, "mul", IUM_RD, 0x0020F6, Writes_OF | Undefined_SF | Undefined_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_FLAGS_Has_Wbit ) INST1(sahf, "sahf", IUM_RD, 0x00009E, Restore_SF_ZF_AF_PF_CF ) -INST1(xadd, "xadd", IUM_RW, 0x0F00C0, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF ) -INST1(cmpxchg, "cmpxchg", IUM_RW, 0x0F00B0, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF ) +INST1(xadd, "xadd", IUM_RW, 0x0F00C0, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) +INST1(cmpxchg, "cmpxchg", IUM_RW, 0x0F00B0, Writes_OF | Writes_SF | Writes_ZF | Writes_AF | Writes_PF | Writes_CF | INS_FLAGS_Has_Wbit ) INST1(shld, "shld", IUM_RW, 0x0F00A4, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) INST1(shrd, "shrd", IUM_RW, 0x0F00AC, Undefined_OF | Writes_SF | Writes_ZF | Undefined_AF | Writes_PF | Writes_CF ) From 2edfb44b1dceda747ed2ff0bd2ae28de94c7e655 Mon Sep 17 00:00:00 2001 From: Anthony Canino Date: Thu, 4 Nov 2021 17:34:44 -0400 Subject: [PATCH 2/6] Run jit-format to fix formatting errors. --- src/coreclr/jit/emitxarch.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 389f5c4190bc6e..ed9dad2cb08c73 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -159,7 +159,7 @@ bool emitter::IsDstSrcSrcAVXInstruction(instruction ins) // true if instruction has the 's' bit, false otherwise bool emitter::HasSBit(instruction ins) { - return ((CodeGenInterface::instInfo[ins] & INS_FLAGS_Has_Sbit) != 0) ; + return ((CodeGenInterface::instInfo[ins] & INS_FLAGS_Has_Sbit) != 0); } //------------------------------------------------------------------------ @@ -173,7 +173,7 @@ bool emitter::HasSBit(instruction ins) // true if instruction has the 'w' bit, false otherwise bool emitter::HasWBit(instruction ins) { - return ((CodeGenInterface::instInfo[ins] & INS_FLAGS_Has_Wbit) != 0) ; + return ((CodeGenInterface::instInfo[ins] & INS_FLAGS_Has_Wbit) != 0); } //------------------------------------------------------------------------ From c30663b4aa50650ab02b6a33f31ef05888786e40 Mon Sep 17 00:00:00 2001 From: anthonycanino Date: Wed, 10 Nov 2021 12:13:01 -0800 Subject: [PATCH 3/6] Update src/coreclr/jit/emitxarch.cpp Co-authored-by: Tanner Gooding --- src/coreclr/jit/emitxarch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index ed9dad2cb08c73..705b594c556a5d 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -163,7 +163,7 @@ bool emitter::HasSBit(instruction ins) } //------------------------------------------------------------------------ -// HasSBit: check if the instruction has the 'w' bit required to use the +// HasWBit: check if the instruction has the 'w' bit required to use the // full operand size. // // Arguments: From f38a7380361c71745f8bee3dad67ec492c82ead8 Mon Sep 17 00:00:00 2001 From: "Canino, Anthony" Date: Wed, 15 Dec 2021 09:22:56 -0800 Subject: [PATCH 4/6] Remove TODOs and insIsCMOV checks. --- src/coreclr/jit/emitxarch.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 705b594c556a5d..78707b34b8bcf8 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -11129,10 +11129,7 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) } // Use the large version if this is not a byte - // TODO-XArch-Cleanup Can the need for the 'w' size bit be encoded in the instruction flags? - // Anthony: I believe we may remove !insIsCMOV check, but leaving for comparison purposes with another - // similar check below - if ((size != EA_1BYTE) && HasWBit(ins) && !insIsCMOV(ins)) + if ((size != EA_1BYTE) && HasWBit(ins)) { code |= 0x1; } @@ -11595,11 +11592,8 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) code &= 0x0000FFFF; } - // Anthony: Per L10986, why is this insIsCMOV (which does not have a w bit) - // and above is !insIsCMOV - if (size != EA_1BYTE && (HasWBit(ins) || insIsCMOV(ins))) + if (size != EA_1BYTE && HasWBit(ins)) { - // movsx and movzx are 'big' opcodes but also have the 'w' bit code |= 0x1; } } From f8ed36080c8eb0262d3b09cbda3a16256a6b33ae Mon Sep 17 00:00:00 2001 From: "Canino, Anthony" Date: Thu, 16 Dec 2021 16:43:09 -0800 Subject: [PATCH 5/6] Rename HasWBit and HasSBit, added comments for clarity. --- src/coreclr/jit/emitxarch.cpp | 28 +++++++++++++++++----------- src/coreclr/jit/emitxarch.h | 4 ++-- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 78707b34b8bcf8..a523f99971c918 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -150,28 +150,34 @@ bool emitter::IsDstSrcSrcAVXInstruction(instruction ins) } //------------------------------------------------------------------------ -// HasSBit: check if the instruction has the 's' (sign extend) bit. +// HasRegularWideImmediateForm: check if the instruction has a regular wide immediate +// form where the 's' bit needs to be set to sign extend the immediate. See Section B.2 +// of Volume 2 of Intel Architecture Software Developer Manual to cross reference +// instruction form with 's' bit requirements. // // Arguments: // ins - instruction to test // // Return Value: -// true if instruction has the 's' bit, false otherwise -bool emitter::HasSBit(instruction ins) +// true if instruction has a regular wide immediate form where the 's' bit needs to set. +bool emitter::HasRegularWideImmediateForm(instruction ins) { return ((CodeGenInterface::instInfo[ins] & INS_FLAGS_Has_Sbit) != 0); } //------------------------------------------------------------------------ -// HasWBit: check if the instruction has the 'w' bit required to use the -// full operand size. +// HasRegularWideForm: check if the instruction has a regular wide form where the 'w' +// bit needs to be set to use the full operand size. See Section B.2 +// of Volume 2 of Intel Architecture Software Developer Manual to cross reference +// instruction form with 'w' bit requirements. +// // // Arguments: // ins - instruction to test // // Return Value: -// true if instruction has the 'w' bit, false otherwise -bool emitter::HasWBit(instruction ins) +// true if instruction has a regular wide form where the 'w' bit needs to be set. +bool emitter::HasRegularWideForm(instruction ins) { return ((CodeGenInterface::instInfo[ins] & INS_FLAGS_Has_Wbit) != 0); } @@ -10363,7 +10369,7 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) // Use the large version if this is not a byte. This trick will not // work in case of SSE2 and AVX instructions. - if ((size != EA_1BYTE) && HasWBit(ins)) + if ((size != EA_1BYTE) && HasRegularWideForm(ins)) { code |= 0x1; } @@ -11129,7 +11135,7 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) } // Use the large version if this is not a byte - if ((size != EA_1BYTE) && HasWBit(ins)) + if ((size != EA_1BYTE) && HasRegularWideForm(ins)) { code |= 0x1; } @@ -11592,7 +11598,7 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) code &= 0x0000FFFF; } - if (size != EA_1BYTE && HasWBit(ins)) + if (size != EA_1BYTE && HasRegularWideForm(ins)) { code |= 0x1; } @@ -12761,7 +12767,7 @@ BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id) } // "test" has no 's' bit - if (!HasSBit(ins)) + if (!HasRegularWideImmediateForm(ins)) { useSigned = false; } diff --git a/src/coreclr/jit/emitxarch.h b/src/coreclr/jit/emitxarch.h index 538cf574aa3367..d6ed324deb242a 100644 --- a/src/coreclr/jit/emitxarch.h +++ b/src/coreclr/jit/emitxarch.h @@ -191,8 +191,8 @@ void SetContains256bitAVX(bool value) bool IsDstDstSrcAVXInstruction(instruction ins); bool IsDstSrcSrcAVXInstruction(instruction ins); -bool HasWBit(instruction ins); -bool HasSBit(instruction ins); +bool HasRegularWideForm(instruction ins); +bool HasRegularWideImmediateForm(instruction ins); bool DoesWriteZeroFlag(instruction ins); bool DoesWriteSignFlag(instruction ins); bool DoesResetOverflowAndCarryFlags(instruction ins); From 9fdd08a3461251f50c7d08c6d57d4488e73c9b70 Mon Sep 17 00:00:00 2001 From: "Canino, Anthony" Date: Fri, 17 Dec 2021 08:52:46 -0800 Subject: [PATCH 6/6] Updated HasRegularWideForm / HasRegularWideImmediateForm comments. --- src/coreclr/jit/emitxarch.cpp | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index a523f99971c918..8b0ba91a873aa2 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -150,36 +150,42 @@ bool emitter::IsDstSrcSrcAVXInstruction(instruction ins) } //------------------------------------------------------------------------ -// HasRegularWideImmediateForm: check if the instruction has a regular wide immediate -// form where the 's' bit needs to be set to sign extend the immediate. See Section B.2 -// of Volume 2 of Intel Architecture Software Developer Manual to cross reference -// instruction form with 's' bit requirements. +// HasRegularWideForm: Many x86/x64 instructions follow a regular encoding scheme where the +// byte-sized version of an instruction has the lowest bit of the opcode cleared +// while the 32-bit version of the instruction (taking potential prefixes to +// override operand size) has the lowest bit set. This function returns true if +// the instruction follows this format. +// +// Note that this bit is called `w` in the encoding table in Section B.2 of +// Volume 2 of the Intel Architecture Software Developer Manual. // // Arguments: // ins - instruction to test // // Return Value: -// true if instruction has a regular wide immediate form where the 's' bit needs to set. -bool emitter::HasRegularWideImmediateForm(instruction ins) +// true if instruction has a regular form where the 'w' bit needs to be set. +bool emitter::HasRegularWideForm(instruction ins) { - return ((CodeGenInterface::instInfo[ins] & INS_FLAGS_Has_Sbit) != 0); + return ((CodeGenInterface::instInfo[ins] & INS_FLAGS_Has_Wbit) != 0); } //------------------------------------------------------------------------ -// HasRegularWideForm: check if the instruction has a regular wide form where the 'w' -// bit needs to be set to use the full operand size. See Section B.2 -// of Volume 2 of Intel Architecture Software Developer Manual to cross reference -// instruction form with 'w' bit requirements. +// HasRegularWideImmediateForm: As above in HasRegularWideForm, many instructions taking +// immediates have a regular form used to encode whether the instruction takes a sign-extended +// 1-byte immediate or a (in 64-bit sign-extended) 4-byte immediate, by respectively setting and +// clearing the second lowest bit. // +// Note that this bit is called `s` in the encoding table in Section B.2 of +// Volume 2 of the Intel Architecture Software Developer Manual. // // Arguments: // ins - instruction to test // // Return Value: -// true if instruction has a regular wide form where the 'w' bit needs to be set. -bool emitter::HasRegularWideForm(instruction ins) +// true if instruction has a regular wide immediate form where the 's' bit needs to set. +bool emitter::HasRegularWideImmediateForm(instruction ins) { - return ((CodeGenInterface::instInfo[ins] & INS_FLAGS_Has_Wbit) != 0); + return ((CodeGenInterface::instInfo[ins] & INS_FLAGS_Has_Sbit) != 0); } //------------------------------------------------------------------------