native-v86-core 0.1.6

Native Rust x86 CPU interpreter core ported from v86
Documentation
#include <stdint.h>

#if defined(_MSC_VER)
static uint_fast8_t softfloat_clz64_impl(uint64_t value)
{
    uint_fast8_t count = 0;
    if (value == 0) return 64;
    while ((value & UINT64_C(0x8000000000000000)) == 0) {
        value <<= 1;
        ++count;
    }
    return count;
}
uint_fast8_t softfloat_countLeadingZeros64(uint64_t value)
{
    return softfloat_clz64_impl(value);
}
#endif

struct uint128 { uint64_t v0, v64; };
struct uint128_extra { uint64_t extra; struct uint128 v; };

struct uint128_extra
softfloat_shiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint_fast32_t dist)
{
    struct uint128_extra z;
    if (dist < 64) {
        z.v.v64 = a64 >> dist;
        z.v.v0 = (a64 << ((-dist) & 63)) | (a0 >> dist);
        z.extra = a0 << ((-dist) & 63);
    } else {
        z.v.v64 = 0;
        if (dist == 64) {
            z.v.v0 = a64;
            z.extra = a0;
        } else {
            extra |= a0;
            if (dist < 128) {
                z.v.v0 = a64 >> (dist & 63);
                z.extra = a64 << ((-dist) & 63);
            } else {
                z.v.v0 = 0;
                z.extra = (dist == 128) ? a64 : (a64 != 0);
            }
        }
    }
    z.extra |= (extra != 0);
    return z;
}

void
softfloat_shiftRightJam256M(const uint64_t *aPtr, uint_fast32_t dist, uint64_t *zPtr)
{
    uint64_t value[4] = { aPtr[0], aPtr[1], aPtr[2], aPtr[3] };
    uint_fast32_t word_dist = dist >> 6;
    uint_fast32_t bit_dist = dist & 63;
    uint64_t jam = 0;

    for (unsigned i = 0; i < 4; ++i) zPtr[i] = 0;
    if (word_dist >= 4) {
        for (unsigned i = 0; i < 4; ++i) jam |= value[i];
        zPtr[0] = jam != 0;
        return;
    }
    for (unsigned out = 0; out < 4 - word_dist; ++out) {
        unsigned src = out + word_dist;
        uint64_t word = value[src] >> bit_dist;
        if (bit_dist && src + 1 < 4) word |= value[src + 1] << (64 - bit_dist);
        zPtr[out] = word;
    }
    for (unsigned i = 4 - word_dist; i < 4; ++i) jam |= value[i];
    if (bit_dist && word_dist < 4) jam |= value[3 - word_dist] & ((((uint64_t)1) << bit_dist) - 1);
    zPtr[0] |= (jam != 0);
}