Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions src/coreclr/jit/codegenwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@

void CodeGen::genMarkLabelsForCodegen()
{
// TODO-WASM: serialize fgWasmControlFlow results into codegen-level metadata/labels
// (or use them directly and leave this empty).
// We have alredy marked labels, so nothing to do here
Comment thread
AndyAyersMS marked this conversation as resolved.
Outdated
Comment thread
AndyAyersMS marked this conversation as resolved.
Outdated
}

void CodeGen::genFnEpilog(BasicBlock* block)
Expand Down Expand Up @@ -154,7 +153,13 @@ void CodeGen::genEmitStartBlock(BasicBlock* block)
while (!wasmControlFlowStack->Empty() && (wasmControlFlowStack->Top()->End() == cursor))
{
instGen(INS_end);
wasmControlFlowStack->Pop();
WasmInterval* interval = wasmControlFlowStack->Pop();

if (!interval->IsLoop() && !block->HasFlag(BBF_HAS_LABEL))
{
block->SetFlags(BBF_HAS_LABEL);
genDefineTempLabel(block);
}
}

// Push control flow for intervals that start here or earlier, and emit
Expand All @@ -179,6 +184,12 @@ void CodeGen::genEmitStartBlock(BasicBlock* block)
wasmCursor++;
wasmControlFlowStack->Push(interval);

if (interval->IsLoop() && !block->HasFlag(BBF_HAS_LABEL))
{
block->SetFlags(BBF_HAS_LABEL);
genDefineTempLabel(block);
}

if (wasmCursor >= compiler->fgWasmIntervals->size())
{
break;
Expand Down Expand Up @@ -349,7 +360,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode)
BasicBlock* const caseTarget = desc->GetCase(caseNum)->getDestinationBlock();
unsigned depth = findTargetDepth(caseTarget);

GetEmitter()->emitIns_I(INS_label, EA_4BYTE, depth);
GetEmitter()->emitIns_J(INS_label, EA_4BYTE, depth, caseTarget);
}
}

Expand Down Expand Up @@ -878,7 +889,7 @@ void CodeGen::inst_JMP(emitJumpKind jmp, BasicBlock* tgtBlock)
{
instruction instr = emitter::emitJumpKindToIns(jmp);
unsigned const depth = findTargetDepth(tgtBlock);
GetEmitter()->emitIns_I(instr, EA_4BYTE, depth);
GetEmitter()->emitIns_J(instr, EA_4BYTE, depth, tgtBlock);
}

void CodeGen::genCreateAndStoreGCInfo(unsigned codeSize, unsigned prologSize, unsigned epilogSize DEBUGARG(void* code))
Expand Down
19 changes: 17 additions & 2 deletions src/coreclr/jit/emit.h
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,10 @@ class emitter
insOpts _idInsOpt : 3; // options for Load/Store instructions
#endif

#ifdef TARGET_WASM
unsigned _idJump : 1; // jump descriptor
#endif

////////////////////////////////////////////////////////////////////////
// Space taken up to here:
// x86: 50 bits
Expand All @@ -900,7 +904,7 @@ class emitter
// arm64: 55 bits
// loongarch64: 46 bits
// risc-v: 46 bits
// wasm: 28 bits
// wasm: 29 bits

//
// How many bits have been used beyond the first 32?
Expand All @@ -918,7 +922,7 @@ class emitter
#elif defined(TARGET_AMD64)
#define ID_EXTRA_BITFIELD_BITS (20)
#elif defined(TARGET_WASM)
#define ID_EXTRA_BITFIELD_BITS (-4)
#define ID_EXTRA_BITFIELD_BITS (-3)
#else
#error Unsupported or unset target architecture
#endif
Expand Down Expand Up @@ -1935,6 +1939,17 @@ class emitter
}
#endif // TARGET_RISCV64

#ifdef TARGET_WASM
bool idIsJump() const
{
return _idJump != 0;
}
void idSetIsJump()
{
_idJump = 1;
}
#endif

bool idIsCnsReloc() const
{
return _idCnsReloc != 0;
Expand Down
43 changes: 42 additions & 1 deletion src/coreclr/jit/emitwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,23 @@ void emitter::emitIns_I(instruction ins, emitAttr attr, cnsval_ssize_t imm)
appendToCurIG(id);
}

//------------------------------------------------------------------------
// emitIns_J: Emit a jump instruction with an immediate operand.
//
void emitter::emitIns_J(instruction ins, emitAttr attr, cnsval_ssize_t imm, BasicBlock* tgtBlock)
{
instrDesc* id = emitNewInstrCns(attr, imm);
insFormat fmt = emitInsFormat(ins);

id->idIns(ins);
id->idInsFmt(fmt);
id->idAddr()->iiaBBlabel = tgtBlock;
Comment thread
AndyAyersMS marked this conversation as resolved.
Outdated
id->idSetIsJump();

dispIns(id);
appendToCurIG(id);
}

//------------------------------------------------------------------------
// emitIns_S: Emit a memory instruction with a stack-based address mode operand.
//
Expand Down Expand Up @@ -113,14 +130,17 @@ static unsigned GetInsOpcode(instruction ins)
size_t emitter::emitSizeOfInsDsc(instrDesc* id) const
{
if (emitIsSmallInsDsc(id))
{
return SMALL_IDSC_SIZE;
}

if (id->idIsLargeCns())
{
assert(!id->idIsLargeDsp());
assert(!id->idIsLargeCall());
return sizeof(instrDescCns);
}

return sizeof(instrDesc);
}

Expand Down Expand Up @@ -304,8 +324,11 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
break;
}
case IF_LABEL:
NYI_WASM("emitOutputInstr IF_LABEL");
{
cnsval_ssize_t constant = emitGetInsSC(id);
dst += emitOutputULEB128(dst, (uint64_t)constant);
break;
}
case IF_MEMARG:
{
dst += emitOutputByte(dst, opcode);
Expand Down Expand Up @@ -411,19 +434,37 @@ void emitter::emitDispIns(

emitDispInst(ins);

auto dispJumpTarget = [this, id]() {
BasicBlock* target = id->idAddr()->iiaBBlabel;
printf(" ;; ");
void* label = emitCodeGetCookie(target);
assert(label != nullptr);
insGroup* targetGroup = (insGroup*)label;
emitPrintLabel(targetGroup);
};

// The reference for the following style of display is wasm-objdump output.
//
switch (fmt)
{
case IF_OPCODE:
case IF_BLOCK:
if (id->idIsJump())
{
dispJumpTarget();
}
break;
Comment thread
AndyAyersMS marked this conversation as resolved.

case IF_LABEL:
case IF_ULEB128:
{
cnsval_ssize_t imm = emitGetInsSC(id);
printf(" %llu", (uint64_t)imm);

if (id->idIsJump())
{
dispJumpTarget();
}
}
break;

Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/emitwasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ void emitDispInst(instruction ins);
public:
void emitIns(instruction ins);
void emitIns_I(instruction ins, emitAttr attr, cnsval_ssize_t imm);
void emitIns_J(instruction ins, emitAttr attr, cnsval_ssize_t imm, BasicBlock* tgtBlock);
void emitIns_S(instruction ins, emitAttr attr, int varx, int offs);
void emitIns_R(instruction ins, emitAttr attr, regNumber reg);

Expand Down
Loading