Skip to content

Commit 4cc70c5

Browse files
Copilotkg
andcommitted
Add partial constant emitting support to WebAssembly RyuJIT backend
Co-authored-by: kg <198130+kg@users.noreply.github.com>
1 parent 052a469 commit 4cc70c5

File tree

5 files changed

+67
-5
lines changed

5 files changed

+67
-5
lines changed

src/coreclr/jit/codegenwasm.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,16 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
104104
genCodeForLclVar(treeNode->AsLclVar());
105105
break;
106106

107+
case GT_CNS_INT:
108+
case GT_CNS_DBL:
109+
{
110+
regNumber targetReg = treeNode->GetRegNum();
111+
var_types targetType = treeNode->TypeGet();
112+
genSetRegToConst(targetReg, targetType, treeNode);
113+
genProduceReg(treeNode);
114+
}
115+
break;
116+
107117
case GT_RETURN:
108118
genReturn(treeNode);
109119
break;
@@ -347,6 +357,41 @@ void CodeGen::genCodeForShiftOrRotate(GenTreeOp* treeNode)
347357
genProduceReg(treeNode);
348358
}
349359

360+
//------------------------------------------------------------------------
361+
// genSetRegToConst: Generate code to set a register to a constant value.
362+
//
363+
// Arguments:
364+
// targetReg - The target register
365+
// targetType - The type of the target register
366+
// tree - The constant tree node
367+
//
368+
void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTree* tree)
369+
{
370+
switch (tree->gtOper)
371+
{
372+
case GT_CNS_INT:
373+
{
374+
ssize_t constant = tree->AsIntCon()->IconValue();
375+
emitAttr encodedSize = (emitAttr)GetEmitter()->emitEncodeLEB64(nullptr, &constant, true);
376+
GetEmitter()->emitIns_R_I((targetType == TYP_INT) ? INS_i32_const : INS_i64_const,
377+
encodedSize, targetReg, constant);
378+
}
379+
break;
380+
381+
case GT_CNS_DBL:
382+
{
383+
double constant = tree->AsDblCon()->DconValue();
384+
emitAttr encodedSize = (targetType == TYP_FLOAT) ? EA_4BYTE : EA_8BYTE;
385+
GetEmitter()->emitIns_R_F((targetType == TYP_FLOAT) ? INS_f32_const : INS_f64_const,
386+
encodedSize, targetReg, constant);
387+
}
388+
break;
389+
390+
default:
391+
unreached();
392+
}
393+
}
394+
350395
//------------------------------------------------------------------------
351396
// genCodeForLclVar: Produce code for a GT_LCL_VAR node.
352397
//

src/coreclr/jit/emitfmtswasm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ enum ID_OPS
2929
IF_DEF(NONE, IS_NONE, NONE)
3030
IF_DEF(OPCODE, IS_NONE, NONE) // <opcode>
3131
IF_DEF(ULEB128, IS_NONE, NONE) // <opcode> <ULEB128 immediate>
32+
IF_DEF(LEB128, IS_NONE, NONE) // <opcode> <LEB128 immediate (signed)>
33+
IF_DEF(F32, IS_NONE, NONE) // <opcode> <f32 immediate>
34+
IF_DEF(F64, IS_NONE, NONE) // <opcode> <f64 immediate>
3235
IF_DEF(MEMARG, IS_NONE, NONE) // <opcode> <memarg> (<align> <offset>)
3336

3437
#undef IF_DEF

src/coreclr/jit/emitwasm.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ void emitter::emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t
7070
NYI_WASM("emitIns_R_I");
7171
}
7272

73+
void emitter::emitIns_R_F(instruction ins, emitAttr attr, regNumber reg, double immDbl)
74+
{
75+
NYI_WASM("emitIns_R_F");
76+
}
77+
7378
void emitter::emitIns_Mov(instruction ins, emitAttr attr, regNumber dstReg, regNumber srcReg, bool canSkip)
7479
{
7580
NYI_WASM("emitIns_Mov");
@@ -91,6 +96,12 @@ bool emitter::emitInsIsStore(instruction ins)
9196
return false;
9297
}
9398

99+
size_t emitter::emitEncodeLEB64(uint8_t* destination, const void* source, bool valueIsSigned)
100+
{
101+
NYI_WASM("emitEncodeLEB64");
102+
return 0;
103+
}
104+
94105
emitter::insFormat emitter::emitInsFormat(instruction ins)
95106
{
96107
// clang-format off

src/coreclr/jit/emitwasm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ void emitIns_S(instruction ins, emitAttr attr, int varx, int offs);
2222
void emitIns_R(instruction ins, emitAttr attr, regNumber reg);
2323

2424
void emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t imm);
25+
void emitIns_R_F(instruction ins, emitAttr attr, regNumber reg, double immDbl);
2526
void emitIns_Mov(instruction ins, emitAttr attr, regNumber dstReg, regNumber srcReg, bool canSkip);
2627
void emitIns_R_R(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2);
2728

@@ -51,3 +52,5 @@ instrDesc* emitNewInstrCallInd(int argCnt,
5152
bool emitInsIsStore(instruction ins);
5253

5354
insFormat emitInsFormat(instruction ins);
55+
56+
size_t emitEncodeLEB64(uint8_t* destination, const void* source, bool valueIsSigned);

src/coreclr/jit/instrswasm.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ INST(i64_load, "i64.load", 0, IF_MEMARG, 0x29)
3333
INST(f32_load, "f32.load", 0, IF_MEMARG, 0x2A)
3434
INST(f64_load, "f64.load", 0, IF_MEMARG, 0x2B)
3535
// 5.4.7 Numeric Instructions
36-
// TODO-WASM: Constants
37-
// INST(i32_const, "i32.const", 0, IF_LEB128, 0x41)
38-
// INST(i64_const, "i64.const", 0, IF_LEB128, 0x42)
39-
// INST(f32_const, "f32.const", 0, IF_F32, 0x43)
40-
// INST(f64_const, "f64.const", 0, IF_F64, 0x44)
36+
// Constants
37+
INST(i32_const, "i32.const", 0, IF_LEB128, 0x41)
38+
INST(i64_const, "i64.const", 0, IF_LEB128, 0x42)
39+
INST(f32_const, "f32.const", 0, IF_F32, 0x43)
40+
INST(f64_const, "f64.const", 0, IF_F64, 0x44)
4141
// Integer comparisons
4242
INST(i32_eqz, "i32.eqz", 0, IF_OPCODE, 0x45)
4343
INST(i32_eq, "i32.eq", 0, IF_OPCODE, 0x46)

0 commit comments

Comments
 (0)