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

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

    genConsumeRegs(cast->CastOp());

    switch (desc.ExtendKind())
    {
        case GenIntCastDesc::ExtendKind::COPY:
        {
            if (toType == TYP_INT && fromType == TYP_LONG)
            {
                ins = INS_i32_wrap_i64;
            }
            else
            {
                assert(toType == fromType);
                ins = INS_none;
            }
            break;
        }
        case GenIntCastDesc::ExtendKind::ZERO_EXTEND_SMALL_INT:
        {
            assert(extendSize <= 2);
            if (toType == TYP_LONG)
            {
                ins = INS_i64_extend_u_i32;
            }
            else
            {
                // We expect the underlying types to both be int here,
                // so we don't need to do anything more
                assert(toType == TYP_INT && fromType == TYP_INT);
                ins = INS_none;
            }
            break;
        }
        case GenIntCastDesc::ExtendKind::SIGN_EXTEND_SMALL_INT:
        {
            assert(extendSize <= 2);
            switch (extendSize)
            {
                case 1:
                    ins = INS_i32_extend8_s;
                    break;
                case 2:
                    ins = INS_i32_extend16_s;
                    break;
                default:

Review comment (suggestion):
This logic does not look correct to me. These kinds of casts are `long x; (byte)x` and `int x; (byte)x`.

It should be something like:
```
if (fromType == TYP_LONG) emit(INS_i32_wrap_i64);
int andValue = extendSize == 1 ? 255 : 65535;
emit(i32.const andValue; i32.and);
```
Nit: I would delete the asserts like `assert(extendSize <= 2);`, they seem of low value (validating that `GenIntCastDesc` logic is correct, but that logic is already exercised by all targets).

Code after:

        case GT_STOREIND:
            genCodeForStoreInd(treeNode->AsStoreInd());
            break;

        default:
#ifdef DEBUG
            NYIRAW(GenTree::OpName(treeNode->OperGet()));
#else
            NYI_WASM("Opcode not implemented");
#endif
            break;
    }
}

//------------------------------------------------------------------------
// genCodeForJTrue: emit Wasm br_if
//
// Arguments:
//    treeNode - predicate value
//
void CodeGen::genCodeForJTrue(GenTreeOp* jtrue)
{
    BasicBlock* const block = compiler->compCurBB;
    assert(block->KindIs(BBJ_COND));

    genConsumeOperands(jtrue);

    BasicBlock* const trueTarget  = block->GetTrueTarget();
    BasicBlock* const falseTarget = block->GetFalseTarget();

    // We don't expect degenerate BBJ_COND
    //
    assert(trueTarget != falseTarget);

    // We don't expect the true target to be the next block.
    //
    assert(trueTarget != block->Next());

    // br_if for true target
    //
    inst_JMP(EJ_jmpif, trueTarget);

    // br for false target, if not fallthrough
    //
    if (falseTarget != block->Next())
    {
        inst_JMP(EJ_jmp, falseTarget);
    }
}