Ponde divmod32
word
_udivide(dividend, divisor)
{
    word shift_n;

    if(divisor == 0) return -1;
    if(divisor > dividend) {
      divisor = -1;    //(*) shift_n+1 = (-1)+1 => 0
      return 0;
    }

    outp(DIV_LMBD0, divisor);
    __push__(inp(DIV_LMBD0));
    outp(DIV_LMBD0, dividend);
    shift_n = __pop__() - inp(DIV_LMBD0);

    if(shift_n)
      repeat(shift_n) divisor <<= 1;

    repeat(shift_n+1) {
    // unsigned comparison i.e. checking 'C' flag
    __push__(dividend);
    __push__(divisor);
    asm {
      sub
      exc
    }

    if(!__pop__())
      dividend = ((dividend - divisor) << 1) + 1;
    else
      dividend <<= 1;
    }

    // keeping the shift_n and the dividend
    divisor = shift_n;  //(*)

    outp(DIV_QMASK, shift_n);
    return dividend & inp(DIV_QMASK);
}

Note: The above code is for 32 bit positive divide only.
Note: The remainder can be obtained by right-shifting the dividend by (shift_n+1) times.
Note: //(*) lines are only necessary for piggy-backed modulo implementation shown later in this page
asm {
$dseg

_masktbl:
    .dd        000000001h    // 32'b0000_0000_0000_0000_0000_0000_0000_0001
    .dd        000000003h    // 32'b0000_0000_0000_0000_0000_0000_0000_0011
    .dd        000000007h    // 32'b0000_0000_0000_0000_0000_0000_0000_0111
    .dd        00000000Fh    // 32'b0000_0000_0000_0000_0000_0000_0000_1111
    .dd        00000001Fh    // 32'b0000_0000_0000_0000_0000_0000_0001_1111
    .dd        00000003Fh    // 32'b0000_0000_0000_0000_0000_0000_0011_1111
    .dd        00000007Fh    // 32'b0000_0000_0000_0000_0000_0000_0111_1111
    .dd        0000000FFh    // 32'b0000_0000_0000_0000_0000_0000_1111_1111
    .dd        0000001FFh    // 32'b0000_0000_0000_0000_0000_0001_1111_1111
    .dd        0000003FFh    // 32'b0000_0000_0000_0000_0000_0011_1111_1111
    .dd        0000007FFh    // 32'b0000_0000_0000_0000_0000_0111_1111_1111
    .dd        000000FFFh    // 32'b0000_0000_0000_0000_0000_1111_1111_1111
    .dd        000001FFFh    // 32'b0000_0000_0000_0000_0001_1111_1111_1111
    .dd        000003FFFh    // 32'b0000_0000_0000_0000_0011_1111_1111_1111
    .dd        000007FFFh    // 32'b0000_0000_0000_0000_0111_1111_1111_1111
    .dd        00000FFFFh    // 32'b0000_0000_0000_0000_1111_1111_1111_1111
    .dd        00001FFFFh    // 32'b0000_0000_0000_0001_1111_1111_1111_1111
    .dd        00003FFFFh    // 32'b0000_0000_0000_0011_1111_1111_1111_1111
    .dd        00007FFFFh    // 32'b0000_0000_0000_0111_1111_1111_1111_1111
    .dd        0000FFFFFh    // 32'b0000_0000_0000_1111_1111_1111_1111_1111
    .dd        0001FFFFFh    // 32'b0000_0000_0001_1111_1111_1111_1111_1111
    .dd        0003FFFFFh    // 32'b0000_0000_0011_1111_1111_1111_1111_1111
    .dd        0007FFFFFh    // 32'b0000_0000_0111_1111_1111_1111_1111_1111
    .dd        000FFFFFFh    // 32'b0000_0000_1111_1111_1111_1111_1111_1111
    .dd        001FFFFFFh    // 32'b0000_0001_1111_1111_1111_1111_1111_1111
    .dd        003FFFFFFh    // 32'b0000_0011_1111_1111_1111_1111_1111_1111
    .dd        007FFFFFFh    // 32'b0000_0111_1111_1111_1111_1111_1111_1111
    .dd        00FFFFFFFh    // 32'b0000_1111_1111_1111_1111_1111_1111_1111
    .dd        01FFFFFFFh    // 32'b0001_1111_1111_1111_1111_1111_1111_1111
    .dd        03FFFFFFFh    // 32'b0011_1111_1111_1111_1111_1111_1111_1111
    .dd        07FFFFFFFh    // 32'b0111_1111_1111_1111_1111_1111_1111_1111
    .dd        0FFFFFFFFh    // 32'b1111_1111_1111_1111_1111_1111_1111_1111

$ends
}

ptr masktbl;

//    outp(QMASK, shift_n);
//    return dividend & inp(QMASK);

    return dividend & masktbl[shift_n];
}
    parameter INH_QMASK =    -1;            // inhibiting the QMASK table

    // divide logic

    scc32_divmod #(DIV_LMBD0, INH_QMASK) i_scc32_divmod (
    ...
    )
word
_umodulo(dividend, divisor)
{
    word _dividend (r24);
    word _shift_n  (r25);

    _udivide(dividend, divisor);

    //    Note: The remainder can be obtained by right-shifting
    //    the dividend by (shift_n+1) times.
    repeat(_shift_n+1)
     _dividend >>= 1;

    return _dividend;
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License