Skip to content

Commit 7416d91

Browse files
authored
Implement CONV_OVF_xxx in the Interpreter (#116356)
Implemented most possible forms of CONV_OVF_xxx opcodes in native C++ Moved the existing CONV_xxx opcodes that do float->int conversions into native C++ as well Refactored uses of INTERP_INDIRECT_HELPER_TAG to use a helper to strip the tag in one place instead of duplicating the tag logic everywhere Added new InterpOp type for possibly indirect helper pointers
1 parent bc6f4b0 commit 7416d91

File tree

5 files changed

+654
-48
lines changed

5 files changed

+654
-48
lines changed

src/coreclr/interpreter/compiler.cpp

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,6 +1287,8 @@ void InterpCompiler::EmitConv(StackInfo *sp, StackType type, InterpOpcode convOp
12871287
int32_t var = CreateVarExplicit(g_interpTypeFromStackType[type], NULL, INTERP_STACK_SLOT_SIZE);
12881288
sp->var = var;
12891289
newInst->SetDVar(var);
1290+
1291+
// NOTE: We rely on m_pLastNewIns == newInst upon return from this function. Make sure you preserve that if you change anything.
12901292
}
12911293

12921294
static InterpType GetInterpType(CorInfoType corInfoType)
@@ -2120,6 +2122,7 @@ int32_t InterpCompiler::GetMethodDataItemIndex(CORINFO_METHOD_HANDLE mHandle)
21202122

21212123
int32_t InterpCompiler::GetDataItemIndexForHelperFtn(CorInfoHelpFunc ftn)
21222124
{
2125+
// Interpreter-TODO: Find an existing data item index for this helper if possible and reuse it
21232126
void *indirect;
21242127
void *direct = m_compHnd->getHelperFtn(ftn, &indirect);
21252128
size_t data = !direct
@@ -3526,6 +3529,245 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
35263529
}
35273530
m_ip++;
35283531
break;
3532+
case CEE_CONV_OVF_I1:
3533+
CHECK_STACK(1);
3534+
switch (m_pStackPointer[-1].type)
3535+
{
3536+
case StackTypeR4:
3537+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I1_R4);
3538+
break;
3539+
case StackTypeR8:
3540+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I1_R8);
3541+
break;
3542+
case StackTypeI4:
3543+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I1_I4);
3544+
break;
3545+
case StackTypeI8:
3546+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I1_I8);
3547+
break;
3548+
default:
3549+
assert(0);
3550+
}
3551+
m_ip++;
3552+
break;
3553+
case CEE_CONV_OVF_U1:
3554+
CHECK_STACK(1);
3555+
switch (m_pStackPointer[-1].type)
3556+
{
3557+
case StackTypeR4:
3558+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U1_R4);
3559+
break;
3560+
case StackTypeR8:
3561+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U1_R8);
3562+
break;
3563+
case StackTypeI4:
3564+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U1_I4);
3565+
break;
3566+
case StackTypeI8:
3567+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U1_I8);
3568+
break;
3569+
default:
3570+
assert(0);
3571+
}
3572+
m_ip++;
3573+
break;
3574+
case CEE_CONV_OVF_I2:
3575+
CHECK_STACK(1);
3576+
switch (m_pStackPointer[-1].type)
3577+
{
3578+
case StackTypeR4:
3579+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I2_R4);
3580+
break;
3581+
case StackTypeR8:
3582+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I2_R8);
3583+
break;
3584+
case StackTypeI4:
3585+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I2_I4);
3586+
break;
3587+
case StackTypeI8:
3588+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I2_I8);
3589+
break;
3590+
default:
3591+
assert(0);
3592+
}
3593+
m_ip++;
3594+
break;
3595+
case CEE_CONV_OVF_U2:
3596+
CHECK_STACK(1);
3597+
switch (m_pStackPointer[-1].type)
3598+
{
3599+
case StackTypeR4:
3600+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U2_R4);
3601+
break;
3602+
case StackTypeR8:
3603+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U2_R8);
3604+
break;
3605+
case StackTypeI4:
3606+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U2_I4);
3607+
break;
3608+
case StackTypeI8:
3609+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U2_I8);
3610+
break;
3611+
default:
3612+
assert(0);
3613+
}
3614+
m_ip++;
3615+
break;
3616+
case CEE_CONV_OVF_I4:
3617+
CHECK_STACK(1);
3618+
switch (m_pStackPointer[-1].type)
3619+
{
3620+
case StackTypeR4:
3621+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I4_R4);
3622+
break;
3623+
case StackTypeR8:
3624+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I4_R8);
3625+
break;
3626+
case StackTypeI4:
3627+
break;
3628+
case StackTypeI8:
3629+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_I4_I8);
3630+
break;
3631+
default:
3632+
assert(0);
3633+
}
3634+
m_ip++;
3635+
break;
3636+
case CEE_CONV_OVF_U4:
3637+
CHECK_STACK(1);
3638+
switch (m_pStackPointer[-1].type)
3639+
{
3640+
case StackTypeR4:
3641+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U4_R4);
3642+
break;
3643+
case StackTypeR8:
3644+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U4_R8);
3645+
break;
3646+
case StackTypeI4:
3647+
break;
3648+
case StackTypeI8:
3649+
EmitConv(m_pStackPointer - 1, StackTypeI4, INTOP_CONV_OVF_U4_I8);
3650+
break;
3651+
default:
3652+
assert(0);
3653+
}
3654+
m_ip++;
3655+
break;
3656+
case CEE_CONV_OVF_I8:
3657+
CHECK_STACK(1);
3658+
switch (m_pStackPointer[-1].type)
3659+
{
3660+
case StackTypeR4:
3661+
EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_OVF_I8_R4);
3662+
break;
3663+
case StackTypeR8:
3664+
EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_OVF_I8_R8);
3665+
break;
3666+
case StackTypeI4:
3667+
EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_I8_I4);
3668+
break;
3669+
case StackTypeI8:
3670+
break;
3671+
default:
3672+
assert(0);
3673+
}
3674+
m_ip++;
3675+
break;
3676+
case CEE_CONV_OVF_U8:
3677+
CHECK_STACK(1);
3678+
switch (m_pStackPointer[-1].type)
3679+
{
3680+
case StackTypeR4:
3681+
EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_OVF_U8_R4);
3682+
break;
3683+
case StackTypeR8:
3684+
EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_OVF_U8_R8);
3685+
break;
3686+
case StackTypeI4:
3687+
EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_I8_U4);
3688+
break;
3689+
case StackTypeI8:
3690+
break;
3691+
default:
3692+
assert(0);
3693+
}
3694+
m_ip++;
3695+
break;
3696+
case CEE_CONV_OVF_I:
3697+
CHECK_STACK(1);
3698+
switch (m_pStackPointer[-1].type)
3699+
{
3700+
case StackTypeR4:
3701+
#ifdef TARGET_64BIT
3702+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_I8_R4);
3703+
#else
3704+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_I4_R4);
3705+
#endif
3706+
break;
3707+
case StackTypeR8:
3708+
#ifdef TARGET_64BIT
3709+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_I8_R8);
3710+
#else
3711+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_I4_R8);
3712+
#endif
3713+
break;
3714+
case StackTypeI4:
3715+
#ifdef TARGET_64BIT
3716+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_I8_I4);
3717+
#else
3718+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_MOV_4);
3719+
#endif
3720+
break;
3721+
case StackTypeI8:
3722+
#ifdef TARGET_64BIT
3723+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_MOV_8);
3724+
#else
3725+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_I4_I8);
3726+
#endif
3727+
break;
3728+
default:
3729+
assert(0);
3730+
}
3731+
m_ip++;
3732+
break;
3733+
case CEE_CONV_OVF_U:
3734+
CHECK_STACK(1);
3735+
switch (m_pStackPointer[-1].type)
3736+
{
3737+
case StackTypeR4:
3738+
#ifdef TARGET_64BIT
3739+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_U8_R4);
3740+
#else
3741+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_U4_R4);
3742+
#endif
3743+
break;
3744+
case StackTypeR8:
3745+
#ifdef TARGET_64BIT
3746+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_U8_R8);
3747+
#else
3748+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_U4_R8);
3749+
#endif
3750+
break;
3751+
case StackTypeI4:
3752+
#ifdef TARGET_64BIT
3753+
// FIXME: Is this the right conv opcode?
3754+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_I8_I4);
3755+
#else
3756+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_MOV_4);
3757+
#endif
3758+
break;
3759+
case StackTypeI8:
3760+
#ifdef TARGET_64BIT
3761+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_MOV_8);
3762+
#else
3763+
EmitConv(m_pStackPointer - 1, StackTypeI, INTOP_CONV_OVF_U4_I8);
3764+
#endif
3765+
break;
3766+
default:
3767+
assert(0);
3768+
}
3769+
m_ip++;
3770+
break;
35293771
case CEE_SWITCH:
35303772
{
35313773
m_ip++;
@@ -5009,6 +5251,15 @@ void InterpCompiler::PrintInsData(InterpInst *ins, int32_t insOffset, const int3
50095251
PrintClassName(ch);
50105252
break;
50115253
}
5254+
case InterpOpHelperFtn:
5255+
{
5256+
size_t helperDirectOrIndirect = (size_t)m_dataItems.Get(*pData);
5257+
if (helperDirectOrIndirect & INTERP_INDIRECT_HELPER_TAG)
5258+
printf(" (indirect) %p", (void*)(helperDirectOrIndirect & ~INTERP_INDIRECT_HELPER_TAG));
5259+
else
5260+
printf(" (direct) %p", (void*)helperDirectOrIndirect);
5261+
break;
5262+
}
50125263
default:
50135264
assert(0);
50145265
break;

src/coreclr/interpreter/intops.def

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,40 @@ OPDEF(INTOP_CONV_R8_R4, "conv.r8.r4", 3, 1, 1, InterpOpNoArgs)
171171
OPDEF(INTOP_CONV_U8_R4, "conv.u8.r4", 3, 1, 1, InterpOpNoArgs)
172172
OPDEF(INTOP_CONV_U8_R8, "conv.u8.r8", 3, 1, 1, InterpOpNoArgs)
173173

174+
OPDEF(INTOP_CONV_OVF_I1_I4, "conv.ovf.i1.i4", 3, 1, 1, InterpOpNoArgs)
175+
OPDEF(INTOP_CONV_OVF_I1_I8, "conv.ovf.i1.i8", 3, 1, 1, InterpOpNoArgs)
176+
OPDEF(INTOP_CONV_OVF_I1_R4, "conv.ovf.i1.r4", 3, 1, 1, InterpOpNoArgs)
177+
OPDEF(INTOP_CONV_OVF_I1_R8, "conv.ovf.i1.r8", 3, 1, 1, InterpOpNoArgs)
178+
179+
OPDEF(INTOP_CONV_OVF_U1_I4, "conv.ovf.u1.i4", 3, 1, 1, InterpOpNoArgs)
180+
OPDEF(INTOP_CONV_OVF_U1_I8, "conv.ovf.u1.i8", 3, 1, 1, InterpOpNoArgs)
181+
OPDEF(INTOP_CONV_OVF_U1_R4, "conv.ovf.u1.r4", 3, 1, 1, InterpOpNoArgs)
182+
OPDEF(INTOP_CONV_OVF_U1_R8, "conv.ovf.u1.r8", 3, 1, 1, InterpOpNoArgs)
183+
184+
OPDEF(INTOP_CONV_OVF_I2_I4, "conv.ovf.i2.i4", 3, 1, 1, InterpOpNoArgs)
185+
OPDEF(INTOP_CONV_OVF_I2_I8, "conv.ovf.i2.i8", 3, 1, 1, InterpOpNoArgs)
186+
OPDEF(INTOP_CONV_OVF_I2_R4, "conv.ovf.i2.r4", 3, 1, 1, InterpOpNoArgs)
187+
OPDEF(INTOP_CONV_OVF_I2_R8, "conv.ovf.i2.r8", 3, 1, 1, InterpOpNoArgs)
188+
189+
OPDEF(INTOP_CONV_OVF_U2_I4, "conv.ovf.u2.i4", 3, 1, 1, InterpOpNoArgs)
190+
OPDEF(INTOP_CONV_OVF_U2_I8, "conv.ovf.u2.i8", 3, 1, 1, InterpOpNoArgs)
191+
OPDEF(INTOP_CONV_OVF_U2_R4, "conv.ovf.u2.r4", 3, 1, 1, InterpOpNoArgs)
192+
OPDEF(INTOP_CONV_OVF_U2_R8, "conv.ovf.u2.r8", 3, 1, 1, InterpOpNoArgs)
193+
194+
OPDEF(INTOP_CONV_OVF_I4_I8, "conv.ovf.i4.i8", 3, 1, 1, InterpOpNoArgs)
195+
OPDEF(INTOP_CONV_OVF_I4_R4, "conv.ovf.i4.r4", 3, 1, 1, InterpOpNoArgs)
196+
OPDEF(INTOP_CONV_OVF_I4_R8, "conv.ovf.i4.r8", 3, 1, 1, InterpOpNoArgs)
197+
198+
OPDEF(INTOP_CONV_OVF_U4_I8, "conv.ovf.u4.i8", 3, 1, 1, InterpOpNoArgs)
199+
OPDEF(INTOP_CONV_OVF_U4_R4, "conv.ovf.u4.r4", 3, 1, 1, InterpOpNoArgs)
200+
OPDEF(INTOP_CONV_OVF_U4_R8, "conv.ovf.u4.r8", 3, 1, 1, InterpOpNoArgs)
201+
202+
OPDEF(INTOP_CONV_OVF_I8_R4, "conv.ovf.i8.r4", 3, 1, 1, InterpOpNoArgs)
203+
OPDEF(INTOP_CONV_OVF_I8_R8, "conv.ovf.i8.r8", 3, 1, 1, InterpOpNoArgs)
204+
205+
OPDEF(INTOP_CONV_OVF_U8_R4, "conv.ovf.u8.r4", 3, 1, 1, InterpOpNoArgs)
206+
OPDEF(INTOP_CONV_OVF_U8_R8, "conv.ovf.u8.r8", 3, 1, 1, InterpOpNoArgs)
207+
174208
OPDEF(INTOP_BOX, "box", 5, 1, 1, InterpOpClassHandle) // [class handle data item] [helper data item]
175209
OPDEF(INTOP_UNBOX, "unbox", 5, 1, 1, InterpOpClassHandle) // [class handle data item] [helper data item]
176210
OPDEF(INTOP_UNBOX_ANY, "unbox.any", 5, 1, 1, InterpOpClassHandle) // [class handle data item] [helper data item]
@@ -293,8 +327,8 @@ OPDEF(INTOP_NEWOBJ, "newobj", 5, 1, 1, InterpOpMethodHandle)
293327
OPDEF(INTOP_NEWOBJ_VAR, "newobj.var", 5, 1, 2, InterpOpMethodHandle)
294328
OPDEF(INTOP_NEWOBJ_VT, "newobj.vt", 5, 1, 1, InterpOpMethodHandle)
295329

296-
OPDEF(INTOP_CALL_HELPER_PP, "call.helper.pp", 4, 1, 0, InterpOpTwoInts)
297-
OPDEF(INTOP_CALL_HELPER_PP_2, "call.helper.pp.2", 5, 1, 1, InterpOpTwoInts)
330+
OPDEF(INTOP_CALL_HELPER_PP, "call.helper.pp", 4, 1, 0, InterpOpHelperFtn)
331+
OPDEF(INTOP_CALL_HELPER_PP_2, "call.helper.pp.2", 5, 1, 1, InterpOpHelperFtn)
298332

299333
OPDEF(INTOP_GENERICLOOKUP_METHOD, "generic.method", 4, 1, 1, InterpOpGenericLookup)
300334
OPDEF(INTOP_GENERICLOOKUP_CLASS, "generic.class", 4, 1, 1, InterpOpGenericLookup)

src/coreclr/interpreter/intops.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ typedef enum
2424
InterpOpClassHandle,
2525
InterpOpGenericLookup,
2626
InterpOpLdPtr,
27+
InterpOpHelperFtn,
2728
} InterpOpArgType;
2829

2930
extern const uint8_t g_interpOpLen[];

0 commit comments

Comments
 (0)