diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index fe416738fa506e..74b5ff34d4ff4d 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -8672,6 +8672,14 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) } } +#ifdef TARGET_64BIT + if (m_pStackPointer->GetStackType() == StackTypeI) + { + // Emit a saturating conversion from U8 to U4 + EmitConv(m_pStackPointer, StackTypeI4, INTOP_CONV_U4_U8_SAT); + } +#endif // TARGET_64BIT + AddInsExplicit(INTOP_SWITCH, n + 3); m_pLastNewIns->data[0] = n; m_pLastNewIns->SetSVar(m_pStackPointer->var); diff --git a/src/coreclr/interpreter/inc/intops.def b/src/coreclr/interpreter/inc/intops.def index 6b8a382cb9ad9c..838739cd21b16e 100644 --- a/src/coreclr/interpreter/inc/intops.def +++ b/src/coreclr/interpreter/inc/intops.def @@ -163,6 +163,7 @@ OPDEF(INTOP_CONV_U2_R8, "conv.u2.r8", 3, 1, 1, InterpOpNoArgs) OPDEF(INTOP_CONV_I4_R4, "conv.i4.r4", 3, 1, 1, InterpOpNoArgs) OPDEF(INTOP_CONV_I4_R8, "conv.i4.r8", 3, 1, 1, InterpOpNoArgs) +OPDEF(INTOP_CONV_U4_U8_SAT, "conv.u4.u8.sat", 3, 1, 1, InterpOpNoArgs) OPDEF(INTOP_CONV_U4_R4, "conv.u4.r4", 3, 1, 1, InterpOpNoArgs) OPDEF(INTOP_CONV_U4_R8, "conv.u4.r8", 3, 1, 1, InterpOpNoArgs) diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index 9e26575fda40b7..caabc89fd8bdce 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -1385,7 +1385,16 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr ConvOvfHelper(stack, ip); ip += 3; break; - + case INTOP_CONV_U4_U8_SAT: + { + uint64_t val = LOCAL_VAR(ip[2], uint64_t); + if (val > UINT32_MAX) + LOCAL_VAR(ip[1], uint32_t) = UINT32_MAX; + else + LOCAL_VAR(ip[1], uint32_t) = (uint32_t)val; + ip += 3; + break; + } case INTOP_SWITCH: { uint32_t val = LOCAL_VAR(ip[1], uint32_t);