Skip to content
44 changes: 38 additions & 6 deletions src/coreclr/jit/codegenwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,33 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
}
}

//------------------------------------------------------------------------
// OperAndType: Pack a genTreeOps and var_types into a switch value
//
// Arguments:
// oper - a genTreeOps to pack
// type - a var_types to pack
//
// Return Value:
// oper and type packed into a uint64_t that can be used as a switch value/case
//
constexpr uint64_t OperAndType (genTreeOps oper, var_types type) {
return ((uint64_t)oper) | ((uint64_t)type << 32);
}

//------------------------------------------------------------------------
// OperAndType: Pack a GenTreeOp* into a switch value
//
// Arguments:
// treeNode - a GenTreeOp to extract oper and type from
//
// Return Value:
// the node's oper and type packed into a uint64_t that can be used as a switch value/case
//
constexpr uint64_t OperAndType (GenTreeOp* treeNode) {
return OperAndType(treeNode->OperGet(), treeNode->TypeGet());
}

//------------------------------------------------------------------------
// genCodeForBinary: Generate code for a binary arithmetic operator
//
Expand All @@ -116,15 +143,20 @@ void CodeGen::genCodeForBinary(GenTreeOp* treeNode)
genConsumeOperands(treeNode);

instruction ins;
switch (treeNode->OperGet())
switch (OperAndType(treeNode))
{
case GT_ADD:
if (!treeNode->TypeIs(TYP_INT))
{
NYI_WASM("genCodeForBinary: non-INT GT_ADD");
}
case OperAndType(GT_ADD, TYP_INT):
ins = INS_i32_add;
break;
case OperAndType(GT_ADD, TYP_LONG):
ins = INS_i64_add;
break;
case OperAndType(GT_ADD, TYP_FLOAT):
ins = INS_f32_add;
break;
case OperAndType(GT_ADD, TYP_DOUBLE):
ins = INS_f64_add;
break;
default:
ins = INS_none;
NYI_WASM("genCodeForBinary");
Expand Down
14 changes: 14 additions & 0 deletions src/coreclr/jit/instr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2185,6 +2185,9 @@ instruction CodeGenInterface::ins_Load(var_types srcType, bool aligned /*=false*
case TYP_INT:
ins = INS_i32_load;
break;
case TYP_LONG:
ins = INS_i64_load;
break;
default:
NYI_WASM("ins_Load");
}
Expand Down Expand Up @@ -2259,6 +2262,17 @@ instruction CodeGenInterface::ins_Load(var_types srcType, bool aligned /*=false*
assert(srcType == TYP_FLOAT);
return INS_flw;
}
#elif defined(TARGET_WASM)
switch (srcType)
{
case TYP_FLOAT:
return INS_f32_load;
case TYP_DOUBLE:
return INS_f64_load;
default:
NYI_WASM("ins_Load");
return INS_none;
}
#else
NYI("ins_Load");
return INS_none;
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/jit/instrswasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ INST(nop, "nop", 0, IF_OPCODE, 0x01)
INST(br, "br", 0, IF_ULEB128, 0x0C)
INST(local_get, "local.get", 0, IF_ULEB128, 0x20)
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_add, "i32.add", 0, IF_OPCODE, 0x6a)
INST(i64_add, "i64.add", 0, IF_OPCODE, 0x7c)
INST(f32_add, "f32.add", 0, IF_OPCODE, 0x92)
INST(f64_add, "f64.add", 0, IF_OPCODE, 0xa0)
// clang-format on

#undef INST
17 changes: 10 additions & 7 deletions src/coreclr/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1613,15 +1613,18 @@ void Lowering::LowerArg(GenTreeCall* call, CallArg* callArg)
else
{
assert(abiInfo.NumSegments == 1);
const ABIPassingSegment& stackSeg = abiInfo.Segment(0);
const bool putInIncomingArgArea = call->IsFastTailCall();
// FIXME: Workaround for NumSegments being 0 on Wasm and causing crashes
if (abiInfo.NumSegments > 0) {
const ABIPassingSegment& stackSeg = abiInfo.Segment(0);
const bool putInIncomingArgArea = call->IsFastTailCall();

GenTree* putArg =
new (comp, GT_PUTARG_STK) GenTreePutArgStk(GT_PUTARG_STK, TYP_VOID, arg, stackSeg.GetStackOffset(),
stackSeg.GetStackSize(), call, putInIncomingArgArea);
GenTree* putArg =
new (comp, GT_PUTARG_STK) GenTreePutArgStk(GT_PUTARG_STK, TYP_VOID, arg, stackSeg.GetStackOffset(),
stackSeg.GetStackSize(), call, putInIncomingArgArea);

BlockRange().InsertAfter(arg, putArg);
*ppArg = arg = putArg;
BlockRange().InsertAfter(arg, putArg);
*ppArg = arg = putArg;
}
}
}

Expand Down
19 changes: 9 additions & 10 deletions src/coreclr/jit/targetwasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,30 +266,29 @@

inline bool genIsValidIntReg(regNumber reg)
{
NYI_WASM("genIsValidIntReg");
return false;
WasmValueType type;
UnpackWasmReg(reg, &type);
return (type == WasmValueType::I32) || (type == WasmValueType::I64);
}

inline bool genIsValidIntOrFakeReg(regNumber reg)
{
NYI_WASM("genIsValidIntOrFakeReg");
return false;
return genIsValidIntReg(reg);
}

inline bool genIsValidFloatReg(regNumber reg)
{
NYI_WASM("genIsValidFloatReg");
return false;
WasmValueType type;
UnpackWasmReg(reg, &type);
return (type == WasmValueType::F32) || (type == WasmValueType::F64);
}

inline bool isValidIntArgReg(regNumber reg, CorInfoCallConvExtension callConv)
{
NYI_WASM("isValidIntArgReg");
return false;
return genIsValidIntReg(reg);
}

inline bool isValidFloatArgReg(regNumber reg)
{
NYI_WASM("isValidFloatArgReg");
return false;
return genIsValidFloatReg(reg);
}
Loading