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

Code before:
    GenTree* const op1 = tree->gtGetOp1();
    assert(!op1->IsMultiRegNode());
    genConsumeRegs(op1);

    // We rewrite all stack stores to STOREIND because the address must be first on the operand stack, so here only
    // enregistered locals need to be handled.
    LclVarDsc* varDsc    = compiler->lvaGetDesc(tree);
    regNumber  targetReg = varDsc->GetRegNum();
    assert(genIsValidReg(targetReg) && varDsc->lvIsRegCandidate());

    unsigned wasmLclIndex = WasmRegToIndex(targetReg);
    GetEmitter()->emitIns_I(INS_local_set, emitTypeSize(tree), wasmLclIndex);
    genUpdateLifeStore(tree, targetReg, varDsc);
}

//------------------------------------------------------------------------
// genCodeForIndir: Produce code for a GT_IND node.
//
// Arguments:
//    tree - the GT_IND node
//
void CodeGen::genCodeForIndir(GenTreeIndir* tree)
{
    assert(tree->OperIs(GT_IND));

    var_types   type      = tree->TypeGet();
    instruction ins       = ins_Load(type);
    regNumber   targetReg = tree->GetRegNum();
    emitAttr    attr      = emitActualTypeSize(type);

    genConsumeAddress(tree->Addr());

    // TODO-WASM: Memory barriers
    /*
    if ((tree->gtFlags & GTF_IND_VOLATILE) != 0)
    {
        instGen_MemoryBarrier(BARRIER_FULL);
    }
    */

    GetEmitter()->emitIns_I(ins, emitActualTypeSize(type), 0);

    genProduceReg(tree);
}

//------------------------------------------------------------------------
// genCodeForCompare: Produce code for a GT_EQ/GT_NE/GT_LT/GT_LE/GT_GE/GT_GT node.
//
// Arguments:
//    tree - the node
//

Review comment (refactor):
This may be a good time to introduce the infrastructure for throw helpers, so that we can call `CORINFO_HELP_THROWNULLREF` here when necessary.

Code after:
void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree)
{
    assert(tree->OperIs(GT_STORE_LCL_VAR));

    GenTree* const op1 = tree->gtGetOp1();
    assert(!op1->IsMultiRegNode());
    genConsumeRegs(op1);

    // We rewrite all stack stores to STOREIND because the address must be first on the operand stack, so here only
    // enregistered locals need to be handled.
    LclVarDsc* varDsc    = compiler->lvaGetDesc(tree);
    regNumber  targetReg = varDsc->GetRegNum();
    assert(genIsValidReg(targetReg) && varDsc->lvIsRegCandidate());

    unsigned wasmLclIndex = WasmRegToIndex(targetReg);
    GetEmitter()->emitIns_I(INS_local_set, emitTypeSize(tree), wasmLclIndex);
    genUpdateLifeStore(tree, targetReg, varDsc);
}

//------------------------------------------------------------------------
// genCodeForIndir: Produce code for a GT_IND node.
//
// Arguments:
//    tree - the GT_IND node
//
void CodeGen::genCodeForIndir(GenTreeIndir* tree)
{
    assert(tree->OperIs(GT_IND));

    var_types   type = tree->TypeGet();
    instruction ins  = ins_Load(type);

    genConsumeAddress(tree->Addr());

    // TODO-WASM: Memory barriers

    GetEmitter()->emitIns_I(ins, emitActualTypeSize(type), 0);

    genProduceReg(tree);
}

//------------------------------------------------------------------------
// genCodeForStoreInd: Produce code for a GT_STOREIND node.
//
// Arguments:
//    tree - the GT_STOREIND node
//
void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree)
{
    GenTree* data = tree->Data();
    GenTree* addr = tree->Addr();