Skip to content
Closed
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
28 changes: 18 additions & 10 deletions docs/design/coreclr/botr/readytorun-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -810,8 +810,8 @@ enum ReadyToRunHelper
READYTORUN_HELPER_LLsh = 0xC7,
READYTORUN_HELPER_LRsh = 0xC8,
READYTORUN_HELPER_LRsz = 0xC9,
READYTORUN_HELPER_Lng2Dbl = 0xCA,
READYTORUN_HELPER_ULng2Dbl = 0xCB,
READYTORUN_HELPER_Int64ToDouble = 0xCA,
READYTORUN_HELPER_UInt64ToDouble = 0xCB,

// 32-bit division helpers
READYTORUN_HELPER_Div = 0xCC,
Expand All @@ -820,14 +820,22 @@ enum ReadyToRunHelper
READYTORUN_HELPER_UMod = 0xCF,

// Floating point conversions
READYTORUN_HELPER_Dbl2Int = 0xD0,
READYTORUN_HELPER_Dbl2IntOvf = 0xD1,
READYTORUN_HELPER_Dbl2Lng = 0xD2,
READYTORUN_HELPER_Dbl2LngOvf = 0xD3,
READYTORUN_HELPER_Dbl2UInt = 0xD4,
READYTORUN_HELPER_Dbl2UIntOvf = 0xD5,
READYTORUN_HELPER_Dbl2ULng = 0xD6,
READYTORUN_HELPER_Dbl2ULngOvf = 0xD7,
READYTORUN_HELPER_DoubleToInt32 = 0xD0,
READYTORUN_HELPER_DoubleToInt32Ovf = 0xD1,
READYTORUN_HELPER_DoubleToInt64 = 0xD2,
READYTORUN_HELPER_DoubleToInt64Ovf = 0xD3,
READYTORUN_HELPER_DoubleToUInt32 = 0xD4,
READYTORUN_HELPER_DoubleToUInt32Ovf = 0xD5,
READYTORUN_HELPER_DoubleToUInt64 = 0xD6,
READYTORUN_HELPER_DoubleToUInt64Ovf = 0xD7,
READYTORUN_HELPER_DoubleToInt8 = 0xD8,
READYTORUN_HELPER_DoubleToInt8Ovf = 0xD9,
READYTORUN_HELPER_DoubleToInt16 = 0xDA,
READYTORUN_HELPER_DoubleToInt16Ovf = 0xDB,
READYTORUN_HELPER_DoubleToUInt8 = 0xDC,
READYTORUN_HELPER_DoubleToUInt8Ovf = 0xDD,
READYTORUN_HELPER_DoubleToUInt16 = 0xDE,
READYTORUN_HELPER_DoubleToUInt16Ovf = 0xDF,

// Floating point ops
READYTORUN_HELPER_DblRem = 0xE0,
Expand Down
28 changes: 18 additions & 10 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,16 +385,24 @@ enum CorInfoHelpFunc
CORINFO_HELP_LMOD,
CORINFO_HELP_ULDIV,
CORINFO_HELP_ULMOD,
CORINFO_HELP_LNG2DBL, // Convert a signed int64 to a double
CORINFO_HELP_ULNG2DBL, // Convert a unsigned int64 to a double
CORINFO_HELP_DBL2INT,
CORINFO_HELP_DBL2INT_OVF,
CORINFO_HELP_DBL2LNG,
CORINFO_HELP_DBL2LNG_OVF,
CORINFO_HELP_DBL2UINT,
CORINFO_HELP_DBL2UINT_OVF,
CORINFO_HELP_DBL2ULNG,
CORINFO_HELP_DBL2ULNG_OVF,
CORINFO_HELP_Int64ToDouble,
CORINFO_HELP_UInt64ToDouble,
CORINFO_HELP_DoubleToInt8,
CORINFO_HELP_DoubleToInt8_OVF,
CORINFO_HELP_DoubleToInt16,
CORINFO_HELP_DoubleToInt16_OVF,
CORINFO_HELP_DoubleToInt32,
CORINFO_HELP_DoubleToInt32_OVF,
CORINFO_HELP_DoubleToInt64,
CORINFO_HELP_DoubleToInt64_OVF,
CORINFO_HELP_DoubleToUInt8,
CORINFO_HELP_DoubleToUInt8_OVF,
CORINFO_HELP_DoubleToUInt16,
CORINFO_HELP_DoubleToUInt16_OVF,
CORINFO_HELP_DoubleToUInt32,
CORINFO_HELP_DoubleToUInt32_OVF,
CORINFO_HELP_DoubleToUInt64,
CORINFO_HELP_DoubleToUInt64_OVF,
CORINFO_HELP_FLTREM,
CORINFO_HELP_DBLREM,
CORINFO_HELP_FLTROUND,
Expand Down
30 changes: 18 additions & 12 deletions src/coreclr/inc/jithelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
JITHELPER(CORINFO_HELP_UDIV, JIT_UDiv, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_UMOD, JIT_UMod, CORINFO_HELP_SIG_8_STACK)

// CORINFO_HELP_DBL2INT, CORINFO_HELP_DBL2UINT, and CORINFO_HELP_DBL2LONG get
// patched for CPUs that support SSE2 (P4 and above).
#ifndef TARGET_64BIT
JITHELPER(CORINFO_HELP_LLSH, JIT_LLsh, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_LRSH, JIT_LRsh, CORINFO_HELP_SIG_REG_ONLY)
Expand All @@ -53,16 +51,24 @@
JITHELPER(CORINFO_HELP_LMOD, JIT_LMod, CORINFO_HELP_SIG_16_STACK)
JITHELPER(CORINFO_HELP_ULDIV, JIT_ULDiv, CORINFO_HELP_SIG_16_STACK)
JITHELPER(CORINFO_HELP_ULMOD, JIT_ULMod, CORINFO_HELP_SIG_16_STACK)
JITHELPER(CORINFO_HELP_LNG2DBL, JIT_Lng2Dbl, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_ULNG2DBL, JIT_ULng2Dbl, CORINFO_HELP_SIG_8_STACK)
DYNAMICJITHELPER(CORINFO_HELP_DBL2INT, JIT_Dbl2Lng, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DBL2INT_OVF, JIT_Dbl2IntOvf, CORINFO_HELP_SIG_8_STACK)
DYNAMICJITHELPER(CORINFO_HELP_DBL2LNG, JIT_Dbl2Lng, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DBL2LNG_OVF, JIT_Dbl2LngOvf, CORINFO_HELP_SIG_8_STACK)
DYNAMICJITHELPER(CORINFO_HELP_DBL2UINT, JIT_Dbl2Lng, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DBL2UINT_OVF, JIT_Dbl2UIntOvf, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DBL2ULNG, JIT_Dbl2ULng, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DBL2ULNG_OVF, JIT_Dbl2ULngOvf, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_Int64ToDouble, JIT_Int64ToDouble, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_UInt64ToDouble, JIT_UInt64ToDouble, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToInt8, JIT_DoubleToInt8, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToInt8_OVF, JIT_DoubleToInt8Ovf, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToInt16, JIT_DoubleToInt16, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToInt16_OVF, JIT_DoubleToInt16Ovf, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToInt32, JIT_DoubleToInt32, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToInt32_OVF, JIT_DoubleToInt32Ovf, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToInt64, JIT_DoubleToInt64, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToInt64_OVF, JIT_DoubleToInt64Ovf, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToUInt8, JIT_DoubleToUInt8, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToUInt8_OVF, JIT_DoubleToUInt8Ovf, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToUInt16, JIT_DoubleToUInt16, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToUInt16_OVF, JIT_DoubleToUInt16Ovf, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToUInt32, JIT_DoubleToUInt32, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToUInt32_OVF, JIT_DoubleToUInt32Ovf, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToUInt64, JIT_DoubleToUInt64, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DoubleToUInt64_OVF, JIT_DoubleToUInt64Ovf, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_FLTREM, JIT_FltRem, CORINFO_HELP_SIG_8_STACK)
JITHELPER(CORINFO_HELP_DBLREM, JIT_DblRem, CORINFO_HELP_SIG_16_STACK)
JITHELPER(CORINFO_HELP_FLTROUND, JIT_FloatRound, CORINFO_HELP_SIG_8_STACK)
Expand Down
28 changes: 18 additions & 10 deletions src/coreclr/inc/readytorun.h
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,8 @@ enum ReadyToRunHelper
READYTORUN_HELPER_LLsh = 0xC7,
READYTORUN_HELPER_LRsh = 0xC8,
READYTORUN_HELPER_LRsz = 0xC9,
READYTORUN_HELPER_Lng2Dbl = 0xCA,
READYTORUN_HELPER_ULng2Dbl = 0xCB,
READYTORUN_HELPER_Int64ToDouble = 0xCA,
READYTORUN_HELPER_UInt64ToDouble = 0xCB,

// 32-bit division helpers
READYTORUN_HELPER_Div = 0xCC,
Expand All @@ -357,14 +357,22 @@ enum ReadyToRunHelper
READYTORUN_HELPER_UMod = 0xCF,

// Floating point conversions
READYTORUN_HELPER_Dbl2Int = 0xD0,
READYTORUN_HELPER_Dbl2IntOvf = 0xD1,
READYTORUN_HELPER_Dbl2Lng = 0xD2,
READYTORUN_HELPER_Dbl2LngOvf = 0xD3,
READYTORUN_HELPER_Dbl2UInt = 0xD4,
READYTORUN_HELPER_Dbl2UIntOvf = 0xD5,
READYTORUN_HELPER_Dbl2ULng = 0xD6,
READYTORUN_HELPER_Dbl2ULngOvf = 0xD7,
READYTORUN_HELPER_DoubleToInt32 = 0xD0,
READYTORUN_HELPER_DoubleToInt32Ovf = 0xD1,
READYTORUN_HELPER_DoubleToInt64 = 0xD2,
READYTORUN_HELPER_DoubleToInt64Ovf = 0xD3,
READYTORUN_HELPER_DoubleToUInt32 = 0xD4,
READYTORUN_HELPER_DoubleToUInt32Ovf = 0xD5,
READYTORUN_HELPER_DoubleToUInt64 = 0xD6,
READYTORUN_HELPER_DoubleToUInt64Ovf = 0xD7,
READYTORUN_HELPER_DoubleToInt8 = 0xD8,
READYTORUN_HELPER_DoubleToInt8Ovf = 0xD9,
READYTORUN_HELPER_DoubleToInt16 = 0xDA,
READYTORUN_HELPER_DoubleToInt16Ovf = 0xDB,
READYTORUN_HELPER_DoubleToUInt8 = 0xDC,
READYTORUN_HELPER_DoubleToUInt8Ovf = 0xDD,
READYTORUN_HELPER_DoubleToUInt16 = 0xDE,
READYTORUN_HELPER_DoubleToUInt16Ovf = 0xDF,

// Floating point ops
READYTORUN_HELPER_DblRem = 0xE0,
Expand Down
28 changes: 18 additions & 10 deletions src/coreclr/inc/readytorunhelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,30 @@ HELPER(READYTORUN_HELPER_ULMod, CORINFO_HELP_ULMOD,
HELPER(READYTORUN_HELPER_LLsh, CORINFO_HELP_LLSH, )
HELPER(READYTORUN_HELPER_LRsh, CORINFO_HELP_LRSH, )
HELPER(READYTORUN_HELPER_LRsz, CORINFO_HELP_LRSZ, )
HELPER(READYTORUN_HELPER_Lng2Dbl, CORINFO_HELP_LNG2DBL, )
HELPER(READYTORUN_HELPER_ULng2Dbl, CORINFO_HELP_ULNG2DBL, )
HELPER(READYTORUN_HELPER_Int64ToDouble, CORINFO_HELP_Int64ToDouble, )
HELPER(READYTORUN_HELPER_UInt64ToDouble, CORINFO_HELP_UInt64ToDouble, )

HELPER(READYTORUN_HELPER_Div, CORINFO_HELP_DIV, )
HELPER(READYTORUN_HELPER_Mod, CORINFO_HELP_MOD, )
HELPER(READYTORUN_HELPER_UDiv, CORINFO_HELP_UDIV, )
HELPER(READYTORUN_HELPER_UMod, CORINFO_HELP_UMOD, )

HELPER(READYTORUN_HELPER_Dbl2Int, CORINFO_HELP_DBL2INT, )
HELPER(READYTORUN_HELPER_Dbl2IntOvf, CORINFO_HELP_DBL2INT_OVF, )
HELPER(READYTORUN_HELPER_Dbl2Lng, CORINFO_HELP_DBL2LNG, )
HELPER(READYTORUN_HELPER_Dbl2LngOvf, CORINFO_HELP_DBL2LNG_OVF, )
HELPER(READYTORUN_HELPER_Dbl2UInt, CORINFO_HELP_DBL2UINT, )
HELPER(READYTORUN_HELPER_Dbl2UIntOvf, CORINFO_HELP_DBL2UINT_OVF, )
HELPER(READYTORUN_HELPER_Dbl2ULng, CORINFO_HELP_DBL2ULNG, )
HELPER(READYTORUN_HELPER_Dbl2ULngOvf, CORINFO_HELP_DBL2ULNG_OVF, )
HELPER(READYTORUN_HELPER_DoubleToInt32, CORINFO_HELP_DoubleToInt32, )
HELPER(READYTORUN_HELPER_DoubleToInt32Ovf, CORINFO_HELP_DoubleToInt32_OVF, )
HELPER(READYTORUN_HELPER_DoubleToInt64, CORINFO_HELP_DoubleToInt64, )
HELPER(READYTORUN_HELPER_DoubleToInt64Ovf, CORINFO_HELP_DoubleToInt64_OVF, )
HELPER(READYTORUN_HELPER_DoubleToUInt32, CORINFO_HELP_DoubleToUInt32, )
HELPER(READYTORUN_HELPER_DoubleToUInt32Ovf, CORINFO_HELP_DoubleToUInt32_OVF, )
HELPER(READYTORUN_HELPER_DoubleToUInt64, CORINFO_HELP_DoubleToUInt64, )
HELPER(READYTORUN_HELPER_DoubleToUInt64Ovf, CORINFO_HELP_DoubleToUInt64_OVF, )
HELPER(READYTORUN_HELPER_DoubleToInt8, CORINFO_HELP_DoubleToInt8, )
HELPER(READYTORUN_HELPER_DoubleToInt8Ovf, CORINFO_HELP_DoubleToInt8_OVF, )
HELPER(READYTORUN_HELPER_DoubleToInt16, CORINFO_HELP_DoubleToInt16, )
HELPER(READYTORUN_HELPER_DoubleToInt16Ovf, CORINFO_HELP_DoubleToInt16_OVF, )
HELPER(READYTORUN_HELPER_DoubleToUInt8, CORINFO_HELP_DoubleToUInt8, )
HELPER(READYTORUN_HELPER_DoubleToUInt8Ovf, CORINFO_HELP_DoubleToUInt8_OVF, )
HELPER(READYTORUN_HELPER_DoubleToUInt16, CORINFO_HELP_DoubleToUInt16, )
HELPER(READYTORUN_HELPER_DoubleToUInt16Ovf, CORINFO_HELP_DoubleToUInt16_OVF, )

HELPER(READYTORUN_HELPER_FltRem, CORINFO_HELP_FLTREM, )
HELPER(READYTORUN_HELPER_DblRem, CORINFO_HELP_DBLREM, )
Expand Down
96 changes: 42 additions & 54 deletions src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7167,11 +7167,6 @@ void CodeGen::genIntToFloatCast(GenTree* treeNode)
var_types srcType = op1->TypeGet();
assert(!varTypeIsFloating(srcType) && varTypeIsFloating(dstType));

#if !defined(TARGET_64BIT)
// We expect morph to replace long to float/double casts with helper calls
noway_assert(!varTypeIsLong(srcType));
#endif // !defined(TARGET_64BIT)

// Since xarch emitter doesn't handle reporting gc-info correctly while casting away gc-ness we
// ensure srcType of a cast is non gc-type. Codegen should never see BYREF as source type except
// for GT_LCL_VAR_ADDR and GT_LCL_FLD_ADDR that represent stack addresses and can be considered
Expand Down Expand Up @@ -7200,10 +7195,18 @@ void CodeGen::genIntToFloatCast(GenTree* treeNode)
emitAttr srcSize = EA_ATTR(genTypeSize(srcType));
noway_assert((srcSize == EA_ATTR(genTypeSize(TYP_INT))) || (srcSize == EA_ATTR(genTypeSize(TYP_LONG))));

// Also we don't expect to see uint32 -> float/double and uint64 -> float conversions
// here since they should have been lowered appropriately.
#if defined(TARGET_X86)
// x86 doesn't expect to see int64/uint32/uint64 -> float/double here since they should have been
// replaced with helper calls by the front end.
noway_assert(!varTypeIsLong(srcType));
noway_assert(srcType != TYP_UINT);
noway_assert((srcType != TYP_ULONG) || (dstType != TYP_FLOAT));
#endif // TARGET_X86

#if defined(TARGET_AMD64)
// x64 shouldn't see a uint64 -> float/double as it should have been lowered to an alternative
// sequence -or- converted to a helper call by the front end.
noway_assert(srcType != TYP_ULONG);
#endif // TARGET_AMD64

// To convert int to a float/double, cvtsi2ss/sd SSE2 instruction is used
// which does a partial write to lower 4/8 bytes of xmm register keeping the other
Expand All @@ -7219,46 +7222,27 @@ void CodeGen::genIntToFloatCast(GenTree* treeNode)

// Note that here we need to specify srcType that will determine
// the size of source reg/mem operand and rex.w prefix.
instruction ins = ins_FloatConv(dstType, TYP_INT, emitTypeSize(srcType));
GetEmitter()->emitInsBinary(ins, emitTypeSize(srcType), treeNode, op1);

// Handle the case of srcType = TYP_ULONG. SSE2 conversion instruction
// will interpret ULONG value as LONG. Hence we need to adjust the
// result if sign-bit of srcType is set.
if (srcType == TYP_ULONG)
{
// The instruction sequence below is less accurate than what clang
// and gcc generate. However, we keep the current sequence for backward compatibility.
// If we change the instructions below, FloatingPointUtils::convertUInt64ToDobule
// should be also updated for consistent conversion result.
assert(dstType == TYP_DOUBLE);
assert(op1->isUsedFromReg());
var_types fromType = srcType;

// Set the flags without modifying op1.
// test op1Reg, op1Reg
inst_RV_RV(INS_test, op1->GetRegNum(), op1->GetRegNum(), srcType);
#if defined(TARGET_AMD64)
if (fromType == TYP_UINT)
{
// There isn't an instruction that directly allows conversion from TYP_UINT
// so we convert from TYP_LONG instead.

// No need to adjust result if op1 >= 0 i.e. positive
// Jge label
BasicBlock* label = genCreateTempLabel();
inst_JMP(EJ_jge, label);
fromType = TYP_LONG;

// Adjust the result
// result = result + 0x43f00000 00000000
// addsd resultReg, 0x43f00000 00000000
CORINFO_FIELD_HANDLE* cns = &u8ToDblBitmask;
if (*cns == nullptr)
{
double d;
static_assert_no_msg(sizeof(double) == sizeof(__int64));
*((__int64*)&d) = 0x43f0000000000000LL;
// We require the value to come from a register so the upper bits here
// will be zero and we can know we'll get a correct result.
assert(op1->isUsedFromReg());
}
#endif // TARGET_AMD64

*cns = GetEmitter()->emitFltOrDblConst(d, EA_8BYTE);
}
GetEmitter()->emitIns_R_C(INS_addsd, EA_8BYTE, treeNode->GetRegNum(), *cns, 0);
assert(!varTypeIsUnsigned(fromType));

genDefineTempLabel(label);
}
emitAttr attr = emitTypeSize(fromType);
instruction ins = ins_FloatConv(dstType, fromType, attr);
GetEmitter()->emitInsBinary(ins, attr, treeNode, op1);

genProduceReg(treeNode);
}
Expand All @@ -7277,8 +7261,6 @@ void CodeGen::genIntToFloatCast(GenTree* treeNode)
// The treeNode must have an assigned register.
// SrcType=float/double and DstType= int32/uint32/int64/uint64
//
// TODO-XArch-CQ: (Low-pri) - generate in-line code when DstType = uint64
//
void CodeGen::genFloatToIntCast(GenTree* treeNode)
{
// we don't expect to see overflow detecting float/double --> int type conversions here
Expand All @@ -7297,9 +7279,9 @@ void CodeGen::genFloatToIntCast(GenTree* treeNode)
}
#endif

var_types srcType = treeNode->CastFromType();
var_types dstType = treeNode->CastToType();
var_types srcType = op1->TypeGet();
assert(varTypeIsFloating(srcType) && !varTypeIsFloating(dstType));
assert(varTypeIsFloating(srcType) && varTypeIsIntegral(dstType));

// We should never be seeing dstType whose size is neither sizeof(TYP_INT) nor sizeof(TYP_LONG).
// For conversions to byte/sbyte/int16/uint16 from float/double, we would expect the
Expand All @@ -7309,17 +7291,23 @@ void CodeGen::genFloatToIntCast(GenTree* treeNode)
emitAttr dstSize = EA_ATTR(genTypeSize(dstType));
noway_assert((dstSize == EA_ATTR(genTypeSize(TYP_INT))) || (dstSize == EA_ATTR(genTypeSize(TYP_LONG))));

// We shouldn't be seeing uint64 here as it should have been converted
// into a helper call by either front-end or lowering phase.
noway_assert(!varTypeIsUnsigned(dstType) || (dstSize != EA_ATTR(genTypeSize(TYP_LONG))));
#if defined(TARGET_X86)
// x86 shouldn't see casts to int64/uint32/uint64 as they should have been convered into
// helper calls by the front-end.

noway_assert(dstType != TYP_UINT);
noway_assert(!varTypeIsLong(dstType));
#else
// x64 shouldn't see casts to uint64 as they should have been lowered into an alternative sequence
noway_assert(dstType != TYP_ULONG);

// If the dstType is TYP_UINT, we have 32-bits to encode the
// float number. Any of 33rd or above bits can be the sign bit.
// To achieve it we pretend as if we are converting it to a long.
if (varTypeIsUnsigned(dstType) && (dstSize == EA_ATTR(genTypeSize(TYP_INT))))
// If the dstType is TYP_UINT, we can convert to TYP_LONG and implicitly take
// the lower 32-bits as the result.
if ((dstType == TYP_UINT) && (dstSize == EA_ATTR(genTypeSize(TYP_INT))))
{
dstType = TYP_LONG;
}
#endif // TARGET_X86

// Note that we need to specify dstType here so that it will determine
// the size of destination integer register and also the rex.w prefix.
Expand Down
Loading