home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / demos / baah / CakeHead2 / Cake2_Src / MathMacros < prev    next >
Encoding:
Text File  |  1995-10-21  |  5.3 KB  |  129 lines

  1. ;                                     \|/
  2. ;                                     O O
  3. ; --------------------------------oOO--U--OOo--------------------------------
  4. ; |                                                                         |
  5. ; |                         'Maths' Macros Library.                         |
  6. ; |                      By Alain BROBECKER. (aka Baah)                     |
  7. ; |                                                          September 1995 |
  8. ; ---------------------------------------------------------------------------
  9. ;
  10. ;   * This library was created in order to perform high precision fixed point
  11. ; calculi. I won' t explain what fixed point is in here.
  12. ;   * A 64 bits integer is symbolised by [a|b] where a represents the 32
  13. ; upperbits of the integer, and b represents the 32 lowerbits.
  14. ;   * Most of the routines are unsigned. (symbolised by 'u' being the first
  15. ; letter of the routine name) This was chosen because you often have operands
  16. ; which are always positive, so you can gain some cycles. Here is a small
  17. ; example to show you how to perform a signed multiplication of r0 by r1...
  18. ;     movS    r2,r0
  19. ;     rsbMI   r2,r2,#0              ; r2=Abs(r0).
  20. ;     movS    r3,r1
  21. ;     rsbMI   r3,r3,#0              ; r3=Abs(r1).
  22. ;     umul64(r2,r3,r2,r3,r4,r5,r6)  ; [r2|r3]=Abs(r0)*Abs(r1).
  23. ;     adjust64(r2,r2,r3,premul_cst) ; r2=Abs(r0)*Abs(r1).
  24. ;     teq     r0,r1                 ; Flags=r0 eor r1=Sgn(r0*r1).
  25. ;     rsbMI   r2,r2,#0              ; r2=Sgn(r0*r1)*Abs(r0)*Abs(r1)=r0*r1.
  26. ;   * The udiv64 routine performs a 64 by 32 bits division. But if
  27. ; [m1|m2]>m3*2^32, (so, if m1>m3), normally an overflow shall be generated.
  28. ; My routine does not handle this, so beware. (it does not happen very often)
  29. ; To understand the udiv64 rout in details, you must know that the CS
  30. ; condition is equivalent to an unsigned higher or same.
  31. ;   * Each macro has a header which contains...
  32. ; IN -----  Entry parameters and constants.
  33. ; OUT ----  Shows what is the result, and where it is stored.
  34. ; KILL ---  Lists all registers modified by the function.
  35. ; EXTRA --  Sometimes, some IN registers can be the same as some
  36. ;           temporary or OUT registers. This will tell it to you.
  37.  
  38.  
  39. ; ---------------------------------------------------------------------------
  40. ;     IN -----  m2. (positive)
  41. ;     OUT ----  [m0|m1]=sqr(m2).
  42. ;     KILL ---  [m0|m1],m3,m4,flags.
  43. ;     EXTRA --  m2=m0 or m3 or m4.
  44. macro usqr64 m0,m1,m2,m3,m4
  45. { mov       m1,m2,lsr #16           ; m1=up(m2).
  46.   sub       m3,m2,m1,lsl #16        ; m3=down(m2).
  47.   mul       m0,m1,m1                ; m0=up(m2)*up(m2).
  48.   mul       m4,m3,m1                ; m4=up(m2)*down(m2).
  49.   mul       m1,m3,m3                ; m1=down(m2)*down(m2).
  50.   addS      m1,m1,m4,lsl #17
  51.   adc       m0,m0,m4,lsr #15        ; [m0|m1]=64 bits result.
  52. }
  53.  
  54.  
  55. ; ---------------------------------------------------------------------------
  56. ;     IN -----  m2,m3. (positive)
  57. ;     OUT ----  [m0|m1]=m2*m3.
  58. ;     KILL ---  [m0|m1],m4,m5,m6,flags.
  59. ;     EXTRA --  [m2|m3]=[m0|m1].
  60. macro umul64 m0,m1,m2,m3,m4,m5,m6
  61. { mov       m4,m2,lsr #16           ; m4=up(m2).
  62.   sub       m5,m2,m4,lsl #16        ; m5=down(m2).
  63.   mov       m0,m3,lsr #16           ; m0=up(m3).
  64.   sub       m1,m3,m0,lsl #16        ; m1=down(m3).
  65.   mul       m6,m5,m0                ; m6=down(m2)*up(m3).
  66.   mul       m0,m4,m0                ; m0=up(m2)*up(m3).
  67.   mlaS      m6,m1,m4,m6             ; Carry+m6=up(m2)*down(m3)+down(m2)*up(m3).
  68.   adc       m0,m0,m6,lsr #16
  69.   mul       m1,m5,m1                ; m1=down(m2)*down(m3).
  70.   addS      m1,m1,m6,lsl #16
  71.   adc       m0,m0,#0                ; [m0|m1]=m2*m3.
  72. }
  73.  
  74.  
  75. ; ---------------------------------------------------------------------------
  76. ;     IN -----  [m1|m2],m3. (positive)
  77. ;     OUT ----  m0=[m1|m2]/m3.
  78. ;     KILL ---  m0,m4,m5.
  79. ;     EXTRA --  [m1|m2]=[m4|m5].
  80. macro udiv64 m0,m1,m2,m3,m4,m5
  81. { mov       m0,#0                   ; m0=0.
  82.   addS      m5,m2,m2                ; Perform a 'movS [m4|m5],[m1|m2],lsl #1'.
  83.   adcS      m4,m1,m1
  84. #set N=31
  85. #rept 31
  86.   cmpCC     m4,m3                   ; If CC, then flags=m4-m3.
  87.   subCS     m4,m4,m3                ; If m4+Carry>m3 then substract m3.
  88.   addCS     m0,m0,#1<<N             ; And quotient=quotient+1<<N.
  89.   addS      m5,m5,m5                ; Perform a 'movS [m4|m5],[m4|m5],lsl #1'.
  90.   adcS      m4,m4,m4
  91. #set N=N-1
  92. #endr
  93.   cmpCC     m4,m3                   ; If CC, then flags=m4-m3.
  94.   addCS     m0,m0,#1                ; If m4+Carry>m3 quotient+=1.
  95. }
  96.  
  97.  
  98. ; ---------------------------------------------------------------------------
  99. ;     IN -----  m1,m2. And c0=constant is the premultiplication factor.
  100. ;     OUT ----  m0=[m1|m2]>>c0.
  101. ;     KILL ---  m0.
  102. ;     EXTRA --  m1=m0.
  103. macro adjust64 m0,m1,m2,c0
  104. { mov       m0,m1,lsl #32-c0
  105.   add       m0,m0,m2,lsr #c0
  106. }
  107.  
  108.  
  109. ; ---------------------------------------------------------------------------
  110. ;     IN -----  [m2|m3],[m4|m5].
  111. ;     OUT ----  [m0|m1]=[m2|m3]+[m4|m5].
  112. ;     KILL ---  [m0|m1],flags.
  113. ;     EXTRA --  [m2|m3] or [m4|m5]=[m0|m1].
  114. macro add64 m0,m1,m2,m3,m4,m5
  115. { addS      m1,m3,m5
  116.   adc       m0,m2,m4
  117. }
  118.  
  119.  
  120. ; ---------------------------------------------------------------------------
  121. ;     IN -----  [m2|m3],[m4|m5].
  122. ;     OUT ----  [m0|m1]=[m2|m3]-[m4|m5].
  123. ;     KILL ---  [m0|m1],flags.
  124. ;     EXTRA --  [m2|m3] or [m4|m5]=[m0|m1].
  125. macro sub64 m0,m1,m2,m3,m4,m5
  126. { subS      m1,m3,m5
  127.   sbc       m0,m2,m4
  128. }
  129.