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

Code before:
}

unsigned emitter::emitGetAlignHintLog2(const instrDesc* id)
{
    // FIXME
    return 0;
}

unsigned emitter::SizeOfULEB128(uint64_t value)
{
    // bits_to_encode = (data != 0) ? 64 - CLZ(x) : 1 = 64 - CLZ(data | 1)
    // bytes = ceil(bits_to_encode / 7.0);            = (6 + bits_to_encode) / 7
    unsigned x = 6 + 64 - (unsigned)BitOperations::LeadingZeroCount(value | 1UL);
    // Division by 7 is done by (x * 37) >> 8 where 37 = ceil(256 / 7).
    // This works for 0 <= x < 256 / (7 * 37 - 256), i.e. 0 <= x <= 85.
    return (x * 37) >> 8;
}

unsigned emitter::SizeOfSLEB128(int64_t value)
{
    // The same as SizeOfULEB128 calculation but we have to account for the sign bit.
    unsigned x = 1 + 6 + 64 - (unsigned)BitOperations::LeadingZeroCount((uint64_t)(value ^ (value >> 63)) | 1UL);
    return (x * 37) >> 8;
}

static uint8_t getWasmValueTypeCode(WasmValueType type)
{
    // clang-format off
    static const uint8_t typecode_mapping[] = {
        0x00, // WasmValueType::Invalid = 0,
        0x7C, // WasmValueType::F64 = 1,
        0x7D, // WasmValueType::F32 = 2,
        0x7E, // WasmValueType::I64 = 3,
        0x7F, // WasmValueType::I32 = 4,
    };
    static const int WASM_TYP_COUNT = ArrLen(typecode_mapping);
    static_assert(ArrLen(typecode_mapping) == (int)WasmValueType::Count);
    // clang-format on

    return typecode_mapping[static_cast<unsigned>(type)];
}

unsigned emitter::instrDesc::idCodeSize() const
{
#ifdef TARGET_WASM32
    static const unsigned PADDED_RELOC_SIZE = 5;
#else
#error WASM64
#endif

    // Currently, all our instructions have 1 byte opcode.

Review comment (suggestion):
```suggestion
static uint8_t GetWasmValueTypeCode(WasmValueType type)
```
https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/clr-jit-coding-conventions.md#89-functions-including-member-functions

Code after:
    };

    assert(ins < ArrLen(insOpcodes));
    return insOpcodes[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);
    }

    if (id->idIsLclVarDecl())
    {
        return sizeof(instrDescLclVarDecl);
    }

    return sizeof(instrDesc);
}

unsigned emitter::emitGetAlignHintLog2(const instrDesc* id)
{
    // FIXME
    return 0;
}

unsigned emitter::SizeOfULEB128(uint64_t value)
{
    // bits_to_encode = (data != 0) ? 64 - CLZ(x) : 1 = 64 - CLZ(data | 1)
    // bytes = ceil(bits_to_encode / 7.0);            = (6 + bits_to_encode) / 7
    unsigned x = 6 + 64 - (unsigned)BitOperations::LeadingZeroCount(value | 1UL);
    // Division by 7 is done by (x * 37) >> 8 where 37 = ceil(256 / 7).
    // This works for 0 <= x < 256 / (7 * 37 - 256), i.e. 0 <= x <= 85.
    return (x * 37) >> 8;
}

unsigned emitter::SizeOfSLEB128(int64_t value)
{
    // The same as SizeOfULEB128 calculation but we have to account for the sign bit.
    unsigned x = 1 + 6 + 64 - (unsigned)BitOperations::LeadingZeroCount((uint64_t)(value ^ (value >> 63)) | 1UL);
    return (x * 37) >> 8;
}