Shop OBEX P1 Docs P2 Docs Learn Events
32bit assembler math — Parallax Forums

32bit assembler math

JavalinJavalin Posts: 892
edited 2010-04-15 18:29 in Propeller 1
Hiya

Sure i've seen a link to some working code for 32bit assembler math, multiplication & division.

Can't see it in the links.

Can somebody point me a link?

James

Comments

  • JavalinJavalin Posts: 892
    edited 2010-04-15 11:41
    Looks like this might do it - from the propeller wiki:

                    mov   r,#0
    loop
                    shr   y,#1   wc
            if_c    add   r,x    wc
                    shl   x,#1
            if_nc   tjnz  y,#loop
    

    Assuming the the input is X·* Y

    James
  • JavalinJavalin Posts: 892
    edited 2010-04-15 15:03
    In fact that works - bar the typo.

                    mov   r,#0
    loop
                    shr   y,#1   wc
            if_c    add   r,x    wc
                    shl   x,#1
            if_nc   tjnz  y,#loop
    

    should be:

                    mov   x,#10
                    mov   y,#10
                    mov   r,#0
    loop
                    shr   y,#1   wc
            if_c    add   r,x    wc
                    shl   [b]r[/b],#1
            if_nc   tjnz  y,#loop
     
                    ' result left in R
    


    A worked example·looks like:

    -> R = 10 * 10
    Loop    Y             R (dec)       X (dec)
    1       5 ( %101)     10 (%1010)    10 (%1010)
    2       2 ( %10)      30 (%11110)   10
    3       1 ( %1)       40 (%101000)  10
    4       0 ( %0)       100(%1100100) 10
    END
    
    

    Sorted!

    James
  • lonesocklonesock Posts: 917
    edited 2010-04-15 15:25
    If you make y the lesser of the 2 values, it will need fewer passes to get to the final 1 bit. Here's my code, sorry that the variable names are different. ('lo' is the output...so named in case I want to add a 'hi' for 64 bit results.)

    {===== Peasant Multiplication =====}
    ' Stops on 0, works as long as the
    ' product fits in 32 bits. (So this
    ' is good for e.g. 24-bit x 5-bit.)
    ' All values treated as unsigned.
    peasant_multiply
                  ' put the smallest op in op1
                  mov       lo, op1
                  max       op1, op2
                  min       op2, lo
                  ' clear the accumulator
                  mov       lo,#0
                  ' do the multiplication
    :loop         shr       op1,#1 wc,wz            ' move the least significant bit of op1 into C         
            if_c  add       lo,op2                  ' if the bit was a 1, add op2 to the accumulator
                  shl       op2,#1                  ' adjust op2 up by a power of 2 
            if_nz jmp       #:loop                  ' continue if op1 is non-zero
                  ' done...return the result in lo
    peasant_multiply_ret
                  ret
    


    Jonathan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • lonesocklonesock Posts: 917
    edited 2010-04-15 15:29
    Oops, forgot to add, if you go to [noparse][[/noparse]Help]=>[noparse][[/noparse]Propeller Help] in the Propeller Tool, there is a section called "Math Resources"=>"Math Examples". Also, I believe DeSilva's PASM tutorial has some examples.

    edit: and Chip came up with this uber-fast sqrt:
    ''      'mask' is a register containing $40000000 which gets used directly and rotated all the way back to its original value
            mov     root,#0         'reset root
     :loop  or      root,mask       'set trial bit
            cmpsub  input,root  wc  'subtract root from input if fits
            sumnc   root,mask       'cancel trial bit, set root bit if fit
            shr     root,#1         'shift root down
            ror     mask,#2     wc  'shift mask down (wraps on last iteration)
     if_nc  jmp     #:loop          'loop until mask restored
    


    Jonathan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.

    Post Edited (lonesock) : 4/15/2010 3:49:40 PM GMT
  • JavalinJavalin Posts: 892
    edited 2010-04-15 16:49
    Hiya lonesock,

    Cool - thanks for that. Yours works - mine didn't!

    Do you have a 32bit divide too?

    Thanks,

    James
  • JavalinJavalin Posts: 892
    edited 2010-04-15 18:29
    ah, found the bit in the spin intepreter (and in another thread here)·:

    asmdivide32bit          mov     t1,#0                   ' no idea
                            mov     t2,#32                  ' multiply/divide
                            
    :mdiv                   shr     y,#1            wc,wz   ' divide
                            rcr     t1,#1
                if_nz       djnz    t2,#:mdiv
    :mdiv2                  cmpsub  x,t1            wc
                            rcl     y,#1
                            shr     t1,#1
                            djnz    t2,#:mdiv2
    asmdivide32bit_ret      ret
    

    put values in X and Y, and quotiant result is left in Y

    James
Sign In or Register to comment.