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

//------------------------------------------------------------------------
// PackOperAndType: Pack a genTreeOps and var_types into a uint32_t
//
// Arguments:
// oper - a genTreeOps to pack
// type - a var_types to pack
//
// Return Value:
// oper and type packed into an integer that can be used as a switch value/case
//
static constexpr uint32_t PackOperAndType(genTreeOps oper, var_types type)
{
if (type == TYP_BYREF)
{
type = TYP_I_IMPL;
}
return ((uint32_t)oper << (ConstLog2<GT_COUNT>::value + 1)) | ((uint32_t)type);
}

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

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

instruction ins;
switch (treeNode->OperGet())
switch (PackOperAndType(treeNode))
{
case GT_ADD:
if (!treeNode->TypeIs(TYP_INT))
{
NYI_WASM("genCodeForBinary: non-INT GT_ADD");
}
case PackOperAndType(GT_ADD, TYP_INT):
ins = INS_i32_add;
break;
case PackOperAndType(GT_ADD, TYP_LONG):
ins = INS_i64_add;
break;
case PackOperAndType(GT_ADD, TYP_FLOAT):
ins = INS_f32_add;
break;
case PackOperAndType(GT_ADD, TYP_DOUBLE):
ins = INS_f64_add;
break;
default:
ins = INS_none;
NYI_WASM("genCodeForBinary");
Expand Down
27 changes: 18 additions & 9 deletions src/coreclr/jit/instr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2097,6 +2097,24 @@ instruction CodeGen::ins_Move_Extend(var_types srcType, bool srcInReg)
instruction CodeGenInterface::ins_Load(var_types srcType, bool aligned /*=false*/)
{
// TODO-Cleanup: split this function across target-specific files (e. g. emit<target>.cpp).

#if defined(TARGET_WASM)
switch (srcType)
{
case TYP_INT:
return INS_i32_load;
case TYP_LONG:
return INS_i64_load;
case TYP_FLOAT:
return INS_f32_load;
case TYP_DOUBLE:
return INS_f64_load;
default:
NYI_WASM("ins_Load");
return INS_none;
}
#endif // defined(TARGET_WASM)

if (varTypeUsesIntReg(srcType))
{
instruction ins = INS_invalid;
Expand Down Expand Up @@ -2179,15 +2197,6 @@ instruction CodeGenInterface::ins_Load(var_types srcType, bool aligned /*=false*
{
ins = INS_ld; // default ld.
}
#elif defined(TARGET_WASM)
switch (srcType)
{
case TYP_INT:
ins = INS_i32_load;
break;
default:
NYI_WASM("ins_Load");
}
#else
NYI("ins_Load");
#endif
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
34 changes: 34 additions & 0 deletions src/coreclr/jit/registeropswasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,40 @@ bool genIsValidReg(regNumber reg)
return (WasmValueType::Invalid < wasmType) && (wasmType < WasmValueType::Count);
}

// TODO-WASM: implement the following functions in terms of a "locals registry" that would hold information
// about the registers.

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

bool genIsValidIntOrFakeReg(regNumber reg)
{
return genIsValidIntReg(reg);
}

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

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

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

const char* getRegName(regNumber reg)
{
if (reg == REG_NA)
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/jit/registeropswasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,8 @@ regNumber MakeWasmReg(unsigned index, var_types type);
unsigned UnpackWasmReg(regNumber reg, WasmValueType* pType = nullptr);
unsigned WasmRegToIndex(regNumber reg);
bool genIsValidReg(regNumber reg);
bool genIsValidIntReg(regNumber reg);
bool genIsValidIntOrFakeReg(regNumber reg);
bool genIsValidFloatReg(regNumber reg);
bool isValidIntArgReg(regNumber reg, CorInfoCallConvExtension callConv);
bool isValidFloatArgReg(regNumber reg);
33 changes: 0 additions & 33 deletions src/coreclr/jit/targetwasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,36 +260,3 @@
// clang-format on

#include "registeropswasm.h"

// TODO-WASM: implement the following functions in terms of a "locals registry" that would hold information
// about the registers.

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

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

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

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

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