A89: Floating-point "imitation"


[Prev][Next][Index][Thread]

A89: Floating-point "imitation"




 > Code_Section_One:
 >     mulu.w    #60,d0
 >     divu.w    #100,d0

Division is *slow*.

 > ;-- With d0 being any arbitrary integer x, this
 > ; is the TI-BASIC equivalent of
 > ; iPart((60*y)/100))
 > ;-- I'm concerned about actually getting division
 > ; to WORK and the speed of it - last time I tried
 > ; divu I found that divu.l #7,d7 crashes the calc =(

It is because divu.l is a valid instruction for 68020 and up but 
it is *not* valid for the vanilla 68000 that the TI89 has.
The only valid one on the 68000 and 68010 is:

  divu.w <ea>,Dn
  
divides the 32 bit Dn by the 16 bit <ea> and puts the *16* bit
quotient to the lower 16 bits of Dn and the 16 bit remainder to 
the upper 16 bits of Dn. If the division causes overflow (i.e. the
quotient can not be represented on 16 bits) then Dn is not changed.
If <ea> is 0, then the DIV0 exception is activated.


 > Code_Section_Two:
 >     mulu.w    #77,d0
 >     clr.w     d3
 >     lsr.w     #7,d0    ;almost the same as divu.w #128,d0
 >     addx.w    d3,d0    ;but lets me use this line to round
 > ;-- This is equivalent to round((77*y)/128,0)
 > ;-- 77/128 is ROUGHLY equal to 60/100, and it
 > ; SHOULD be faster because of shifting rather
 > ; than dividing.  Plus, this one rounds properly

Yup, this is obviously quicker. Now there are other things you can do
to speed things up a little bit.
The 68000 does not have a barrel shifter, so shifting is a relative
slow thing (much quicker than division, though). Therefore:

   mulu.w #39322,d0
   swap   d0
   
The net effect is a multiply by 0.6000061, which is 0.001% off from 0.6.
If you are unhappy with truncation, then you can make it rounding 
instead of truncating:

   mulu.w #39322,d0
   add.l  #8000,d0
   swap   d0

What's 'Plain Jump' ?

Regards,

Zoltan


References: