Repository: dotnet/runtime
File: src/coreclr/jit/emitwasm.cpp (C++)

Code before:
    instruction ins    = id->idIns();
    insFormat   insFmt = id->idInsFmt();
    unsigned    opcode = GetInsOpcode(ins);

    switch (insFmt)
    {
        case IF_OPCODE:
            dst += emitOutputByte(dst, opcode);
            break;
        case IF_BLOCK:
            dst += emitOutputByte(dst, opcode);
            dst += emitOutputByte(dst, 0x40 /* block type of void */);
            break;
        case IF_ULEB128:
        case IF_LEB128:
        {
            dst += emitOutputByte(dst, opcode);
            cnsval_ssize_t constant = emitGetInsSC(id);
            dst += emitEncodeLEB64(dst, &constant, (insFmt == IF_LEB128));
            break;
        }
        case IF_F32:
        case IF_F64:
        {
            dst += emitOutputByte(dst, opcode);
            /* FIXME: How do I get the constant from inside the emitter? */
            NYI_WASM("emitOutputInstr get double constant value");
            break;
        }
        case IF_LABEL:
            NYI_WASM("emitOutputInstr IF_LABEL");
            break;
        case IF_MEMARG:
        {
            dst += emitOutputByte(dst, opcode);
            size_t align = 0; // FIXME
            assert(align <= UINT32_MAX); // spec says memarg alignment is u32
            dst += emitEncodeLEB64(dst, &align, false);
            size_t offset = 0 /* id->idAddr()->iiaAddr */; // FIXME
            dst += emitEncodeLEB64(dst, &offset, false);
            break;
        }
        default:
            NYI_WASM("emitOutputInstr");
            break;
    }

#ifdef DEBUG
    bool dspOffs = emitComp->opts.dspGCtbls;
    if (emitComp->opts.disAsm || emitComp->verbose)
    {

Review comment (suggestion):
Codegen for float/dbl constants should create an instrDesc (of suitable type, we may need a new kind) with room for the appropriate value, and then you can add an accessor to call here.

Code after:
        value >>= 7;
        bool isSignBitSet = (b & 0x40) != 0;
        if ((value == 0 && !isSignBitSet) || (value == -1 && isSignBitSet))
        {
            cont = false;
        }
        else
        {
            b |= 0x80;
        }
        buffer[pos++] = b;
    }
    return pos;
}

size_t emitter::emitRawBytes(uint8_t* destination, const void* source, size_t count)
{
    memcpy(destination + writeableOffset, source, count);
    return count;
}

size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
{
    BYTE*       dst    = *dp;
    size_t      sz     = emitSizeOfInsDsc(id);
    instruction ins    = id->idIns();
    insFormat   insFmt = id->idInsFmt();
    unsigned    opcode = GetInsOpcode(ins);

    switch (insFmt)
    {
        case IF_OPCODE:
            dst += emitOutputByte(dst, opcode);
            break;
        case IF_BLOCK:
            dst += emitOutputByte(dst, opcode);
            dst += emitOutputByte(dst, 0x40 /* block type of void */);
            break;
        case IF_ULEB128:
        {
            dst += emitOutputByte(dst, opcode);
            cnsval_ssize_t constant = emitGetInsSC(id);
            dst += emitOutputULEB128(dst, (uint64_t)constant);
            break;
        }
        case IF_SLEB128:
        {
            dst += emitOutputByte(dst, opcode);
            cnsval_ssize_t constant = emitGetInsSC(id);
            dst += emitOutputSLEB128(dst, (int64_t)constant);
            break;