Shop OBEX P1 Docs P2 Docs Learn Events
Where are the integer math functions implemented? — Parallax Forums

Where are the integer math functions implemented?

SRLMSRLM Posts: 5,045
edited 2013-11-06 07:22 in Propeller 1
Where are the integer math functions such as division, multiplication, and modulus implemented? I assume addition and subtraction is done by hardware, but we can't do that for */%.

I have a curious timing problem that seems to depend on the particular modulus values, and I think it has to do with the implementation. In my case, I *think* that it's taking less time to do i%550 than i%549 or i%551

Comments

  • David BetzDavid Betz Posts: 14,516
    edited 2013-11-05 14:09
    SRLM wrote: »
    Where are the integer math functions such as division, multiplication, and modulus implemented? I assume addition and subtraction is done by hardware, but we can't do that for */%.

    I have a curious timing problem that seems to depend on the particular modulus values, and I think it has to do with the implementation. In my case, I *think* that it's taking less time to do i%550 than i%549 or i%551
    Multiply and divide are done by code in the LMM kernel.
  • ersmithersmith Posts: 6,054
    edited 2013-11-06 07:22
    SRLM wrote: »
    Where are the integer math functions such as division, multiplication, and modulus implemented? I assume addition and subtraction is done by hardware, but we can't do that for */%.

    I have a curious timing problem that seems to depend on the particular modulus values, and I think it has to do with the implementation. In my case, I *think* that it's taking less time to do i%550 than i%549 or i%551

    In the current default branch the division functions are in gcc/gcc/config/propeller/kernel.ext (they used to be in the various kernels, like crt0_lmm.s). The multiplication routine is still in the kernel. The division and modulus routines try to estimate the number of iterations required by counting the leading 0's of both the dividend and divisor. I don't think i % 550 should take any different amount of time than i %549, since both 550 and 549 have the same number of bits.

    Here are the inner loops:
    __MULSI
            mov     __TMP0, r0
            min     __TMP0, r1
            max     r1, r0
            mov     r0, #0
    __MULSI_loop
            shr     r1, #1  wz, wc
     IF_C   add     r0, __TMP0
            add     __TMP0, __TMP0
     IF_NZ  jmp     #__MULSI_loop
    __MULSI_ret     ret
    
    __UDIVSI_impl
        mov    __DIVR, r0
        call    #__CLZSI_impl
        neg    __DIVCNT, r0
        mov    r0, r1 wz
     IF_Z   jmp    #__UDIV_BY_ZERO
        call    #__CLZSI_impl
        add    __DIVCNT, r0
        mov    r0, #0
        cmps    __DIVCNT, #0    wz, wc
     IF_C    jmp    #__UDIVSI_done
        shl    r1, __DIVCNT
        add    __DIVCNT, #1
    __UDIVSI_loop
        cmpsub    __DIVR, r1    wz, wc
        addx    r0, r0
        shr    r1, #1
        djnz    __DIVCNT, #__UDIVSI_loop
    __UDIVSI_done
        mov    r1, __DIVR
    __UDIVSI_impl_ret
        ret
    
Sign In or Register to comment.