diff --git a/src/coreclr/jit/codegenwasm.cpp b/src/coreclr/jit/codegenwasm.cpp index cd7886b11ba30a..f06b5d193bfcde 100644 --- a/src/coreclr/jit/codegenwasm.cpp +++ b/src/coreclr/jit/codegenwasm.cpp @@ -265,6 +265,10 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) genCodeForLclVar(treeNode->AsLclVar()); break; + case GT_STORE_LCL_VAR: + genCodeForStoreLclVar(treeNode->AsLclVar()); + break; + case GT_JTRUE: genCodeForJTrue(treeNode->AsOp()); break; @@ -707,6 +711,39 @@ void CodeGen::genCodeForLclVar(GenTreeLclVar* tree) } } +//------------------------------------------------------------------------ +// genCodeForStoreLclVar: Produce code for a GT_STORE_LCL_VAR node. +// +// Arguments: +// tree - the GT_STORE_LCL_VAR node +// +void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree) +{ + assert(tree->OperIs(GT_STORE_LCL_VAR)); + + GenTree* const op1 = tree->gtGetOp1(); + assert(!op1->IsMultiRegNode()); + genConsumeRegs(op1); + + LclVarDsc* varDsc = compiler->lvaGetDesc(tree); + regNumber targetReg = varDsc->GetRegNum(); + + if (!varDsc->lvIsRegCandidate()) + { + // TODO-WASM: handle these cases in lower/ra. + // Emit drop for now to simulate the store effect on the wasm stack. + GetEmitter()->emitIns(INS_drop); + genUpdateLife(tree); + } + else + { + assert(genIsValidReg(targetReg)); + unsigned wasmLclIndex = UnpackWasmReg(targetReg); + GetEmitter()->emitIns_I(INS_local_set, emitTypeSize(tree), wasmLclIndex); + genUpdateLifeStore(tree, targetReg, varDsc); + } +} + //------------------------------------------------------------------------ // genCodeForCompare: Produce code for a GT_EQ/GT_NE/GT_LT/GT_LE/GT_GE/GT_GT node. // diff --git a/src/coreclr/jit/instr.cpp b/src/coreclr/jit/instr.cpp index fcd1c51dff590a..476980e9a7dbe1 100644 --- a/src/coreclr/jit/instr.cpp +++ b/src/coreclr/jit/instr.cpp @@ -2497,6 +2497,24 @@ instruction CodeGen::ins_Copy(regNumber srcReg, var_types dstType) instruction CodeGenInterface::ins_Store(var_types dstType, bool aligned /*=false*/) { // TODO-Cleanup: split this function across target-specific files (e. g. emit.cpp). + +#if defined(TARGET_WASM) + switch (dstType) + { + case TYP_INT: + return INS_i32_store; + case TYP_LONG: + return INS_i64_store; + case TYP_FLOAT: + return INS_f32_store; + case TYP_DOUBLE: + return INS_f64_store; + default: + NYI_WASM("ins_Store"); + return INS_none; + } +#endif // defined(TARGET_WASM) + if (varTypeUsesIntReg(dstType)) { instruction ins = INS_invalid; diff --git a/src/coreclr/jit/instrswasm.h b/src/coreclr/jit/instrswasm.h index 5264fdf0817d16..d5616cbd0d4636 100644 --- a/src/coreclr/jit/instrswasm.h +++ b/src/coreclr/jit/instrswasm.h @@ -37,12 +37,19 @@ INST(br, "br", 0, IF_ULEB128, 0x0C) INST(br_if, "br_if", 0, IF_ULEB128, 0x0D) INST(br_table, "br_table", 0, IF_ULEB128, 0x0E) INST(return, "return", 0, IF_OPCODE, 0x0F) +INST(drop, "drop", 0, IF_OPCODE, 0x1A) INST(local_get, "local.get", 0, IF_ULEB128, 0x20) +INST(local_set, "local.set", 0, IF_ULEB128, 0x21) INST(i32_load, "i32.load", 0, IF_MEMARG, 0x28) INST(i64_load, "i64.load", 0, IF_MEMARG, 0x29) INST(f32_load, "f32.load", 0, IF_MEMARG, 0x2A) INST(f64_load, "f64.load", 0, IF_MEMARG, 0x2B) +INST(i32_store, "i32.store", 0, IF_MEMARG, 0x36) +INST(i64_store, "i64.store", 0, IF_MEMARG, 0x37) +INST(f32_store, "f32.store", 0, IF_MEMARG, 0x38) +INST(f64_store, "f64.store", 0, IF_MEMARG, 0x39) + // 5.4.7 Numeric Instructions // Constants INST(i32_const, "i32.const", 0, IF_SLEB128, 0x41)