#include "game_types.h"

/* Math_Log2 @ 0x08015474 (real 146B) -- signed restoring division (log2/divide core). Mirrors src/matched/Math_Log2.c. */
/* Signed restoring division: normalizes both operands (nibble then bit
   loops from 1<<28), runs the unrolled subtract quartet per step, and
   re-applies the xor sign. Zero divisor calls the (empty) allocator stub
   and yields 0. The 890B ARM blob at 0x08012572 nearby is data, not code. */
extern void Mem_Alloc(void);

unsigned Math_Log2(unsigned a, unsigned b)
{
    unsigned x, y, q = 0, bit = 1, scale;
    int neg;
    if (b == 0) {
        Mem_Alloc();
        return 0;
    }
    neg = ((int)(a ^ b)) < 0;
    x = (int)a < 0 ? -a : a;
    y = (int)b < 0 ? -b : b;
    if (x < y)
        return 0;
    scale = 1u << 28;
    while (y < scale && y < x) {
        y <<= 4;
        bit <<= 4;
    }
    scale <<= 3;
    while (y < scale && y < x) {
        y <<= 1;
        bit <<= 1;
    }
    for (;;) {
        if (x >= y) {
            x -= y;
            q |= bit;
        }
        if (x >= (y >> 1)) {
            x -= y >> 1;
            q |= bit >> 1;
        }
        if (x >= (y >> 2)) {
            x -= y >> 2;
            q |= bit >> 2;
        }
        if (x >= (y >> 3)) {
            x -= y >> 3;
            q |= bit >> 3;
        }
        if (x == 0 || (bit >>= 4) == 0)
            break;
        y >>= 4;
    }
    return neg ? -q : q;
}
