diff --git a/src/base/SMPInstr.cpp b/src/base/SMPInstr.cpp index 6535dff39d2939e66d89caa5447d74b4219cbeb3..df8331ba816771f99e64b913b120a03c32adb777 100644 --- a/src/base/SMPInstr.cpp +++ b/src/base/SMPInstr.cpp @@ -10221,11 +10221,13 @@ void SMPInstr::MDFixupDefUseLists(void) { // operands: imul ebx means EDX:EAX <-- EAX*EBX, but imul ebx,edx means that // EBX*EDX gets truncated and the result placed in EBX (no hidden operands). bool HasEDXDEF = true; + bool HasHiddenOperand = false; for (OpNum = 0; OpNum < STARS_UA_MAXOP; ++OpNum) { STARSOpndTypePtr TempUse = this->STARSInstPtr->GetOpnd(OpNum); if ((nullptr == TempUse) || TempUse->IsVoidOp()) // finished processing operands break; if (!TempUse->IsVisible()) { // hidden operand + HasHiddenOperand = true; if (TempUse->MatchesReg(STARS_x86_R_ax)) { // not STARS_x86_R_al, so it is not 8 bits if ((STARS_NN_div == opcode) || (STARS_NN_idiv == opcode)) { this->MDAddRegUse(STARS_x86_R_dx, false); @@ -10233,10 +10235,15 @@ void SMPInstr::MDFixupDefUseLists(void) { this->MDAddRegDef(STARS_x86_R_ax, false); } } - else if ((1 == TempUse->GetByteWidth()) && (STARS_NN_mul == opcode)) { + else if (1 == TempUse->GetByteWidth()) { HasEDXDEF = false; } } + if (!HasHiddenOperand && (STARS_NN_imul == opcode)) { + // Two-operand and three-operand imul instructions have no hidden operands + // and truncate the result, storing in visible DEF operand and not using EDX:EAX. + HasEDXDEF = false; + } if (HasEDXDEF) { this->MDAddRegDef(STARS_x86_R_dx, false); }