Repository: dotnet/runtime
File: src/coreclr/jit/codegenwasm.cpp (C++)

Code before:
    genProduceReg(tree);
}

//------------------------------------------------------------------------
// genIntToFloatCast: Generate code for an integer to floating point cast
//
// Arguments:
//    tree - The GT_CAST node for the int-to-float cast operation
//
// Notes:
//    Handles casts from TYP_INT/TYP_LONG to TYP_FLOAT/TYP_DOUBLE.
//    Currently not implemented (NYI_WASM).
//
void CodeGen::genIntToFloatCast(GenTree* tree)
{
    NYI_WASM("genIntToFloatCast");
}

//------------------------------------------------------------------------
// genFloatToFloatCast: Generate code for a float to float cast
//
// Arguments:
//    tree - The GT_CAST node for the float-to-float cast operation
//
void CodeGen::genFloatToFloatCast(GenTree* tree)
{
    var_types   toType   = tree->TypeGet();
    var_types   fromType = tree->AsCast()->CastOp()->TypeGet();
    instruction ins      = INS_none;

    genConsumeOperands(tree->AsCast());

    switch (PackTypes(toType, fromType))
    {
        case PackTypes(TYP_FLOAT, TYP_DOUBLE):
            ins = INS_f32_demote_f64;
            break;
        case PackTypes(TYP_DOUBLE, TYP_FLOAT):
            ins = INS_f64_promote_f32;
            break;
        case PackTypes(TYP_FLOAT, TYP_FLOAT):
        case PackTypes(TYP_DOUBLE, TYP_DOUBLE):
            ins = INS_none;
            break;
        default:
            unreached();
    }

    if (ins != INS_none)
    {
        GetEmitter()->emitIns(ins);

Review comment (bug):
Need an NYI for checked (`gtOverflow`) casts. Also applies to `genFloatToIntCast`.

Code after:

//------------------------------------------------------------------------
// genIntToIntCast: Generate code for an integer to integer cast
//
// Arguments:
//    cast - The GT_CAST node for the integer cast operation
//
// Notes:
//    Handles casts to and from small int, int, and long types
//    including proper sign extension and truncation as needed.
//
void CodeGen::genIntToIntCast(GenTreeCast* cast)
{
    if (cast->gtOverflow())
    {
        NYI_WASM("Overflow checks");
    }

    GenIntCastDesc desc(cast);
    var_types      toType     = genActualType(cast->CastToType());
    var_types      fromType   = genActualType(cast->CastOp());
    int            extendSize = desc.ExtendSrcSize();
    instruction    ins        = INS_none;
    assert(fromType == TYP_INT || fromType == TYP_LONG);

    genConsumeOperands(cast);

    // TODO-WASM: Handle load containment GenIntCastDesc::LOAD_* cases once we mark containment for loads
    switch (desc.ExtendKind())
    {
        case GenIntCastDesc::COPY:
        {
            if (toType == TYP_INT && fromType == TYP_LONG)
            {
                ins = INS_i32_wrap_i64;
            }
            else
            {
                assert(toType == fromType);
                ins = INS_none;
            }
            break;
        }
        case GenIntCastDesc::ZERO_EXTEND_SMALL_INT:
        {
            int andAmount = extendSize == 1 ? 255 : 65535;
            if (fromType == TYP_LONG)
            {
                GetEmitter()->emitIns(INS_i32_wrap_i64);
            }
            GetEmitter()->emitIns_I(INS_i32_const, EA_4BYTE, andAmount);