Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion src/coreclr/interpreter/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
#include "interpreter.h"

#include <inttypes.h>

static const StackType g_stackTypeFromInterpType[] =
{
StackTypeI4, // I1
Expand Down Expand Up @@ -1871,13 +1873,58 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
m_pLastIns->SetDVar(m_pStackPointer[-1].var);
m_ip += 5;
break;
case CEE_LDC_I8:
{
int64_t val = getI8LittleEndian(m_ip + 1);
AddIns(INTOP_LDC_I8);
PushInterpType(InterpTypeI8, NULL);
m_pLastIns->SetDVar(m_pStackPointer[-1].var);
m_pLastIns->data[0] = (int32_t)val;
m_pLastIns->data[1] = (int32_t)(val >> 32);
m_ip += 9;
break;
}
case CEE_LDC_R4:
{
int32_t val = getI4LittleEndian(m_ip + 1);
AddIns(INTOP_LDC_R4);
PushInterpType(InterpTypeR4, NULL);
m_pLastIns->SetDVar(m_pStackPointer[-1].var);
m_pLastIns->data[0] = val;
m_ip += 5;
break;
}
case CEE_LDC_R8:
{
int64_t val = getI8LittleEndian(m_ip + 1);
AddIns(INTOP_LDC_R8);
PushInterpType(InterpTypeR8, NULL);
m_pLastIns->SetDVar(m_pStackPointer[-1].var);
m_pLastIns->data[0] = (int32_t)val;
m_pLastIns->data[1] = (int32_t)(val >> 32);
m_ip += 9;
break;
}
case CEE_LDNULL:
AddIns(INTOP_LDNULL);
PushStackType(StackTypeO, NULL);
m_pLastIns->SetDVar(m_pStackPointer[-1].var);
m_ip++;
break;

case CEE_LDSTR:
{
int32_t token = getI4LittleEndian(m_ip + 1);
void *str;
InfoAccessType accessType = m_compHnd->constructStringLiteral(m_compScopeHnd, token, &str);
assert(accessType == IAT_VALUE);
// str should be forever pinned, so we can include its ref inside interpreter code
AddIns(INTOP_LDPTR);
PushInterpType(InterpTypeO, m_compHnd->getBuiltinClass(CLASSID_STRING));
m_pLastIns->SetDVar(m_pStackPointer[-1].var);
m_pLastIns->data[0] = GetDataItemIndex(str);
m_ip += 5;
break;
}
case CEE_LDARG_S:
EmitLoadVar(m_ip[1]);
m_ip += 2;
Expand Down Expand Up @@ -3048,6 +3095,23 @@ void InterpCompiler::PrintInsData(InterpInst *ins, int32_t insOffset, const int3
case InterpOpInt:
printf(" %d", *pData);
break;
case InterpOpLongInt:
{
int64_t i64 = (int64_t)pData[0] + ((int64_t)pData[1] << 32);
printf(" %" PRId64, i64);
break;
}
case InterpOpFloat:
{
printf(" %g", *(float*)pData);
break;
}
case InterpOpDouble:
{
int64_t i64 = (int64_t)pData[0] + ((int64_t)pData[1] << 32);
printf(" %g", *(double*)&i64);
break;
}
case InterpOpTwoInts:
printf(" %d,%d", *pData, *(pData + 1));
break;
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/interpreter/intops.def
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ OPDEF(INTOP_MEMBAR, "membar", 1, 0, 0, InterpOpNoArgs)
OPDEF(INTOP_LDC_I4, "ldc.i4", 3, 1, 0, InterpOpInt)
OPDEF(INTOP_LDC_I4_0, "ldc.i4.0", 2, 1, 0, InterpOpNoArgs)
OPDEF(INTOP_LDC_I8_0, "ldc.i8.0", 2, 1, 0, InterpOpNoArgs)
OPDEF(INTOP_LDC_I8, "ldc.i8", 4, 1, 0, InterpOpLongInt)

OPDEF(INTOP_LDC_R4, "ldc.r4", 3, 1, 0, InterpOpFloat)
OPDEF(INTOP_LDC_R8, "ldc.r8", 4, 1, 0, InterpOpDouble)

OPDEF(INTOP_LDPTR, "ldptr", 3, 1, 0, InterpOpInt)

Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/interpreter/intops.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ typedef enum
{
InterpOpNoArgs,
InterpOpInt,
InterpOpLongInt,
InterpOpFloat,
InterpOpDouble,
InterpOpTwoInts,
InterpOpThreeInts,
InterpOpBranch,
Expand Down
12 changes: 12 additions & 0 deletions src/coreclr/vm/interpexec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr
LOCAL_VAR(ip[1], int64_t) = 0;
ip += 2;
break;
case INTOP_LDC_I8:
LOCAL_VAR(ip[1], int64_t) = (int64_t)ip[2] + ((int64_t)ip[3] << 32);
ip += 4;
break;
case INTOP_LDC_R4:
LOCAL_VAR(ip[1], int32_t) = ip[2];
ip += 3;
break;
case INTOP_LDC_R8:
LOCAL_VAR(ip[1], int64_t) = (int64_t)ip[2] + ((int64_t)ip[3] << 32);
ip += 4;
break;
case INTOP_LDPTR:
LOCAL_VAR(ip[1], void*) = pMethod->pDataItems[ip[2]];
ip += 3;
Expand Down
23 changes: 23 additions & 0 deletions src/tests/JIT/interpreter/Interpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ public static void RunInterpreterTests()
// Environment.FailFast(null);
// if (!TestSpecialFields())
// Environment.FailFast(null);
if (!TestFloat())
Environment.FailFast(null);
}

public static int Mul4(int a, int b, int c, int d)
Expand Down Expand Up @@ -186,4 +188,25 @@ public static bool TestSpecialFields()

return true;
}

public static bool TestFloat()
{
float f1 = 14554.9f;
float f2 = 12543.4f;

float sum = f1 + f2;

if ((sum - 27098.3) > 0.001 || (sum - 27098.3) < -0.001)
Copy link

Copilot AI Apr 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using an absolute difference check (e.g., if (fabs(sum - 27098.3) > 0.001)) for clearer and more robust floating point comparisons.

Suggested change
if ((sum - 27098.3) > 0.001 || (sum - 27098.3) < -0.001)
if (Math.Abs(sum - 27098.3) > 0.001)

Copilot uses AI. Check for mistakes.
return false;

double d1 = 14554.9;
double d2 = 12543.4;

double diff = d1 - d2;

if ((diff - 2011.5) > 0.001 || (diff - 2011.5) < -0.001)
return false;

return true;
}
}
Loading