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

Code before:
    cnsval_ssize_t bits;
    static_assert(sizeof(cnsval_ssize_t) >= sizeof(double));

    switch (treeNode->TypeGet())
    {
        case TYP_INT:
        {
            ins                      = INS_i32_const;
            GenTreeIntConCommon* con = treeNode->AsIntConCommon();
            bits                     = con->IconValue();
            break;
        }
        case TYP_LONG:
        {
            ins                      = INS_i64_const;
            GenTreeIntConCommon* con = treeNode->AsIntConCommon();
            bits                     = con->IconValue();
            break;
        }
        case TYP_FLOAT:
        {
            ins                  = INS_f32_const;
            GenTreeDblCon* con   = treeNode->AsDblCon();
            double         value = con->DconValue();
            memcpy(&bits, &value, sizeof(double));
            break;
        }
        case TYP_DOUBLE:
        {
            ins                  = INS_f64_const;
            GenTreeDblCon* con   = treeNode->AsDblCon();
            double         value = con->DconValue();
            memcpy(&bits, &value, sizeof(double));
            break;
        }
        default:
            NYI_WASM("genCodeForConstant");
            return;
    }

    // The IF_ for the selected instruction, i.e. IF_F64, determines how these bits are emitted
    GetEmitter()->emitIns_I(ins, EA_8BYTE, bits);
    genProduceReg(treeNode);
}

//------------------------------------------------------------------------
// genCodeForShift: Generate code for a shift or rotate operator
//
// Arguments:
//    tree - The shift or rotate operation for which we are generating code.
//

Review comment (suggestion):
This contract that we transport the f32 value in a double and only convert it to an actual 32 bit value in `emitOutputInstr` seems weird, since this is the point where we convert float/double to raw bits.

Code after:
    cnsval_ssize_t bits;
    var_types      type = treeNode->TypeIs(TYP_REF, TYP_BYREF) ? TYP_I_IMPL : treeNode->TypeGet();
    static_assert(sizeof(cnsval_ssize_t) >= sizeof(double));

    switch (type)
    {
        case TYP_INT:
        {
            ins                      = INS_i32_const;
            GenTreeIntConCommon* con = treeNode->AsIntConCommon();
            bits                     = con->IntegralValue();
            break;
        }
        case TYP_LONG:
        {
            ins                      = INS_i64_const;
            GenTreeIntConCommon* con = treeNode->AsIntConCommon();
            bits                     = con->IntegralValue();
            break;
        }
        case TYP_FLOAT:
        {
            ins                  = INS_f32_const;
            GenTreeDblCon* con   = treeNode->AsDblCon();
            double         value = con->DconValue();
            memcpy(&bits, &value, sizeof(double));
            break;
        }
        case TYP_DOUBLE:
        {
            ins                  = INS_f64_const;
            GenTreeDblCon* con   = treeNode->AsDblCon();
            double         value = con->DconValue();
            memcpy(&bits, &value, sizeof(double));
            break;
        }
        default:
            unreached();
    }

    // The IF_ for the selected instruction, i.e. IF_F64, determines how these bits are emitted
    GetEmitter()->emitIns_I(ins, emitTypeSize(treeNode), bits);
    genProduceReg(treeNode);
}

//------------------------------------------------------------------------
// genCodeForShift: Generate code for a shift or rotate operator
//
// Arguments:
//    tree - The shift or rotate operation for which we are generating code.
//