3 This file is part of the Free Pascal run time library.
4 Copyright (c) 1999-2000 by Carl-Eric Codere,
5 member of the Free Pascal development team
7 See the file COPYING.FPC, included in this distribution,
8 for details about the copyright.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 **********************************************************************}
15 {*************************************************************************}
17 { Ported to FPK-Pascal by Carl Eric Codere }
18 { Terms of use: This source code is freeware. }
19 {*************************************************************************}
20 { This inc. implements low-level mathemtical routines for the motorola }
21 { 68000 family of processors. }
22 {*************************************************************************}
23 { single floating point routines taken from GCC 2.5.2 Atari compiler }
26 { written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet). }
27 { Based on a 80x86 floating point packet from comp.os.minix, }
28 { written by P.Housel }
29 { Patched by Olaf Flebbe (flebbe@tat.physik.uni-tuebingen.de) }
30 { Revision by michal 05-93 (ntomczak@vm.ucs.ualberta.ca) }
31 {*************************************************************************}
32 {--------------------------------------------------------------------}
34 { o Add support for FPU if present. }
35 { o Verify if single comparison works in all cases. }
36 { o Add support for NANs in SINGLE_CMP }
37 { o Add comp (80-bit) multiplication,addition,substract,division, }
39 { o Add stack checking for the routines which use the stack. }
40 { (This will probably have to be done in the code generator). }
41 {--------------------------------------------------------------------}
45 Procedure Single_Norm;[alias : 'FPC_SINGLE_NORM'];Assembler;
46 {--------------------------------------------}
47 { Low-level routine to normalize single e }
48 { IEEE floating point values. Never called }
52 { Registers destroyed: d0,d1 }
53 {--------------------------------------------}
55 tst.l d4 { rounding and u.mant == 0 ? }
60 clr.b d2 { "sticky byte" }
64 tst.w d0 { divide (shift) }
65 ble @normlab2 { denormalized number }
67 and.l d5,d3 { or until no bits above 23 }
70 addq.w #1,d0 { increment exponent }
72 or.b d1,d2 { set "sticky" }
73 roxr.b #1,d1 { shift into rounding bits }
77 or.b d2,d1 { make least sig bit "sticky" }
78 asr.l #1,d5 { #0xff800000 -> d5 }
80 move.l d4,d3 { multiply (shift) until }
81 and.l d5,d3 { one in "implied" position }
83 subq.w #1,d0 { decrement exponent }
84 beq @normlab7 { too small. store as denormalized number }
85 add.b d1,d1 { some doubt about this one * }
89 tst.b d1 { check rounding bits }
90 bge @normlab9 { round down - no action neccessary }
92 bvc @normlab8 { round up }
93 move.w d4,d1 { tie case - round to even }
94 { dont need rounding bits any more }
95 and.w #1,d1 { check if even }
96 beq @normlab9 { mantissa is even - no action necessary }
99 clr.w d1 { zero rounding bits }
102 bne @normlab10 { renormalize if number was denormalized }
103 add.w #1,d0 { correct exponent for denormalized numbers }
106 move.l d4,d3 { check for rounding overflow }
107 asl.l #1,d5 { #0xff000000 -> d5 }
109 bne @normlab4 { go back and renormalize }
111 tst.l d4 { check if normalization caused an underflow }
113 tst.w d0 { check for exponent overflow or underflow }
118 lsl.w #8,d0 { re-position exponent - one bit too high }
119 lsl.w #1,d2 { get X bit }
120 roxr.w #1,d0 { shift it into sign position }
121 swap d0 { map to upper word }
123 and.l #$7fffff,d4 { top mantissa bits }
124 or.l d4,d0 { insert exponent and sign }
129 { handling underflow should be done here... }
130 { by default simply return 0 as retzok... }
134 roxr.l #1,d0 { sign of 0 is the same as of d2 }
139 move.l #$7f800000,d0 { +infinity as proposed by IEEE }
141 tst.w d2 { transfer sign }
142 bge @ofl_clear { (mjr++) }
145 or.b #2,ccr { set overflow flag. }
151 Procedure Single_AddSub; Assembler;
152 {--------------------------------------------}
153 { Low-level routine to add/subtract single }
154 { IEEE floating point values. Never called }
157 { d0 = result -- from normalize routine }
158 { Flags : V set if overflow. }
159 { on underflow d0 = 0 }
160 { Registers destroyed: d0,d1 }
161 {--------------------------------------------}
163 {--------------------------------------------}
165 { d1-d0 = single values to subtract. }
166 {--------------------------------------------}
168 eor.l #$80000000,d0 { reverse sign of v }
169 {--------------------------------------------}
171 { d0, d1 = single values to add. }
172 {--------------------------------------------}
174 movem.l d2-d5,-(sp) { save registers }
175 move.l d0,d4 { d4 = d0 = v }
176 move.l d1,d5 { d5 = d1 = u }
179 move.l d5,d0 { d0 = u.exp }
180 move.l d5,d2 { d2.h = u.sign }
182 move.w d0,d2 { d2 = u.sign }
183 and.l d3,d5 { remove exponent from u.mantissa }
185 move.l d4,d1 { d1 = v.exp }
186 and.l d3,d4 { remove exponent from v.mantissa }
188 eor.w d1,d2 { d2 = u.sign ^ v.sign (in bit 15)}
189 clr.b d2 { we will use the lowest byte as a flag }
191 bclr d3,d1 { kill sign bit u.exp }
192 bclr d3,d0 { kill sign bit u.exp }
193 btst d3,d2 { same sign for u and v? }
195 cmp.l d0,d1 { different signs - maybe x - x ? }
196 seq d2 { set 'cancellation' flag }
198 lsr.w #7,d0 { keep here exponents only }
200 {--------------------------------------------------------------------}
201 { Now perform testing of NaN and infinities }
202 {--------------------------------------------------------------------}
209 {--------------------------------------------------------------------}
211 {--------------------------------------------------------------------}
214 bne @retnan { cancellation of specials -> NaN }
216 bne @retnan { arith with Nan gives always NaN }
218 addq.w #4,a0 { here is an infinity }
220 bne @alabel3 { skip check for NaN if v not special }
221 {--------------------------------------------------------------------}
223 {--------------------------------------------------------------------}
230 {--------------------------------------------------------------------}
231 { Return a quiet nan }
232 {--------------------------------------------------------------------}
235 lsr.l #1,d0 { 0x7fffffff -> d0 }
237 { Ok, no inifinty or NaN involved.. }
241 moveq.l #0,d0 { x - x hence we always return +0 }
248 bset d3,d5 { restore implied leading "1" }
249 tst.w d0 { check for zero exponent - no leading "1" }
251 bclr d3,d5 { remove it }
252 addq.w #1,d0 { "normalize" exponent }
254 bset d3,d4 { restore implied leading "1" }
255 tst.w d1 { check for zero exponent - no leading "1" }
257 bclr d3,d4 { remove it }
258 addq.w #1,d1 { "normalize" exponent }
260 moveq.l #0,d3 { (put initial zero rounding bits in d3) }
261 neg.w d1 { d1 = u.exp - v.exp }
263 beq @alabel8 { exponents are equal - no shifting neccessary }
264 bgt @alabel7 { not equal but no exchange neccessary }
265 exg d4,d5 { exchange u and v }
266 sub.w d1,d0 { d0 = u.exp - (u.exp - v.exp) = v.exp }
268 tst.w d2 { d2.h = u.sign ^ (u.sign ^ v.sign) = v.sign }
272 cmp.w #26,d1 { is u so much bigger that v is not }
273 bge @alabel9 { significant ? }
274 {--------------------------------------------------------------------}
275 { shift mantissa left two digits, to allow cancellation of }
276 { most significant digit, while gaining an additional digit for }
278 {--------------------------------------------------------------------}
282 subq.w #1,d0 { decrement exponent }
283 subq.w #1,d1 { done shifting altogether ? }
284 dbeq d3,@alabel10 { loop if still can shift u.mant more }
287 cmp.w #16,d1 { see if fast rotate possible }
289 or.w d4,d3 { set rounding bits }
300 lsr.l #1,d4 { shift v.mant right the rest of the way }
302 dbra d1,@alabel12 { loop }
305 tst.w d2 { are the signs equal ? }
306 bpl @alabel13 { yes, no negate necessary }
309 tst.w d3 { negate rounding bits and v.mant }
316 add.l d4,d5 { u.mant = u.mant + v.mant }
317 bcs @alabel9 { needn not negate }
318 tst.w d2 { opposite signs ? }
319 bpl @alabel9 { do not need to negate result }
322 not.l d2 { switch sign }
324 move.l d5,d4 { move result for normalization }
330 swap d2 { put sign into d2 (exponent is in d0) }
331 jmp FPC_SINGLE_NORM { leave registers on stack for norm_sf }
335 Procedure Single_Mul;Assembler;
336 {--------------------------------------------}
337 { Low-level routine to multiply two single }
338 { IEEE floating point values. Never called }
341 { d0,d1 = values to multiply }
344 { Registers destroyed: d0,d1 }
345 { stack space used (and restored): 8 bytes. }
346 {--------------------------------------------}
350 move.l d0,d4 { d4 = v }
351 move.l d1,d5 { d5 = u }
354 move.l d5,d0 { d0 = u.exp }
355 and.l d3,d5 { remove exponent from u.mantissa }
357 move.w d0,d2 { d2 = u.sign }
359 move.l d4,d1 { d1 = v.exp }
360 and.l d3,d4 { remove exponent from v.mantissa }
362 eor.w d1,d2 { d2 = u.sign ^ v.sign (in bit 15)}
365 bclr d3,d0 { kill sign bit }
366 bclr d3,d1 { kill sign bit }
367 tst.l d0 { test if one of factors is 0 }
371 seq d2 { 'one of factors is 0' flag in the lowest byte }
372 lsr.w #7,d0 { keep here exponents only }
375 {--------------------------------------------------------------------}
376 { Now perform testing of NaN and infinities }
377 {--------------------------------------------------------------------}
384 {--------------------------------------------------------------------}
385 { first operand is special }
386 {--------------------------------------------------------------------}
388 tst.l d5 { is it NaN? }
391 tst.b d2 { 0 times special or special times 0 ? }
392 bne @mretnan { yes -> NaN }
393 cmp.b d3,d1 { is the other special ? }
394 beq @mlabel4 { maybe it is NaN }
395 {--------------------------------------------------------------------}
396 { Return infiny with correct sign }
397 {--------------------------------------------------------------------}
399 move.l #$ff000000,d0 { we will return #0xff800000 or #0x7f800000 }
401 roxr.l #1,d0 { shift in high bit as given by d2 }
406 {--------------------------------------------------------------------}
408 {--------------------------------------------------------------------}
410 tst.l d4 { is this NaN? }
411 beq @mretinf { we know that the other is not zero }
414 lsr.l #1,d0 { 0x7fffffff -> d0 }
416 {--------------------------------------------------------------------}
417 { End of NaN and Inf }
418 {--------------------------------------------------------------------}
420 tst.b d2 { not needed - but we can waste two instr. }
421 bne @mretzz { return signed 0 if one of factors is 0 }
423 bset d3,d5 { restore implied leading "1" }
424 subq.w #8,sp { multiplication accumulator }
425 tst.w d0 { check for zero exponent - no leading "1" }
427 bclr d3,d5 { remove it }
428 addq.w #1,d0 { "normalize" exponent }
431 beq @mretz { multiplying zero }
434 bset d3,d4 { restore implied leading "1" }
435 tst.w d1 { check for zero exponent - no leading "1" }
437 bclr d3,d4 { remove it }
438 addq.w #1,d1 { "normalize" exponent }
441 beq @mretz { multiply by zero }
443 add.w d1,d0 { add exponents, }
444 sub.w #BIAS4+16-8,d0 { remove excess bias, acnt for repositioning }
446 clr.l (sp) { initialize 64-bit product to zero }
448 {--------------------------------------------------------------------}
449 { see Knuth, Seminumerical Algorithms, section 4.3. algorithm M }
450 {--------------------------------------------------------------------}
452 mulu.w d5,d3 { mulitply with bigit from multiplier }
453 move.l d3,4(sp) { store into result }
458 add.l d3,2(sp) { add to result }
460 swap d5 { [TOP 8 BITS SHOULD BE ZERO !] }
463 mulu.w d5,d3 { mulitply with bigit from multiplier }
464 add.l d3,2(sp) { store into result (no carry can occur here) }
469 add.l d3,(sp) { add to result }
470 { [TOP 16 BITS SHOULD BE ZERO !] }
471 movem.l 2(sp),d4-d5 { get the 48 valid mantissa bits }
472 clr.w d5 { (pad to 64) }
476 cmp.l d3,d4 { multiply (shift) until }
477 bhi @mlabel8 { 1 in upper 16 result bits }
478 cmp.w #9,d0 { give up for denormalized numbers }
480 swap d4 { (we''re getting here only when multiplying }
481 swap d5 { with a denormalized number; there''s an }
482 move.w d5,d4 { eventual loss of 4 bits in the rounding }
483 clr.w d5 { byte -- what a pity 8-) }
484 subq.w #8,d0 { decrement exponent }
488 move.l d5,d1 { get rounding bits }
490 move.l d1,d3 { see if sticky bit should be set }
493 or.b #1,d1 { set "sticky bit" if any low-order set }
495 addq.w #8,sp { remove accumulator from stack }
496 jmp FPC_SINGLE_NORM{ (result in d4) }
499 addq.w #8,sp { release accumulator space }
501 moveq.l #0,d0 { save zero as result }
502 lsl.w #1,d2 { and set it sign as for d2 }
505 rts { no normalizing neccessary }
509 Procedure Single_Div;Assembler;
510 {--------------------------------------------}
511 { Low-level routine to dividr two single }
512 { IEEE floating point values. Never called }
515 { d1/d0 = u/v = operation to perform. }
518 { Registers destroyed: d0,d1 }
519 { stack space used (and restored): 8 bytes. }
520 {--------------------------------------------}
523 { u = d1 = dividend }
525 tst.l d0 { check if divisor is 0 }
529 btst #31,d1 { transfer sign of dividend }
536 move.l d1,d4 { d4 = u, d5 = v }
538 movem.l d2-d5,-(sp) { save registers }
541 move.l d4,d0 { d0 = u.exp }
542 and.l d3,d4 { remove exponent from u.mantissa }
544 move.w d0,d2 { d2 = u.sign }
546 move.l d5,d1 { d1 = v.exp }
547 and.l d3,d5 { remove exponent from v.mantissa }
549 eor.w d1,d2 { d2 = u.sign ^ v.sign (in bit 15) }
552 bclr d3,d0 { kill sign bit }
553 bclr d3,d1 { kill sign bit }
558 cmp.b d3,d0 { comparison with #0xff }
559 beq @dlabel1 { u == NaN ;; u== Inf }
561 beq @dlabel2 { v == NaN ;; v == Inf }
563 bne @dlabel4 { u not zero nor denorm }
565 beq @dlabel3 { 0/ ? }
573 bra @dretinf { x/0 -> +/- Inf }
576 tst.l d4 { u == NaN ? }
577 bne @dretnan { NaN/ x }
579 beq @dretnan { Inf/Inf or Inf/NaN }
580 { bra dretinf ; Inf/x ; x != Inf && x != NaN }
581 {--------------------------------------------------------------------}
582 { Return infinity with correct sign. }
583 {--------------------------------------------------------------------}
587 roxr.l #1,d0 { shift in high bit as given by d2 }
594 bne @dretnan { x/NaN }
595 { bra dretzero ; x/Inf -> +/- 0 }
596 {--------------------------------------------------------------------}
597 { Return correct signed zero. }
598 {--------------------------------------------------------------------}
600 moveq.l #0,d0 { zero destination }
601 lsl.w #1,d2 { set X bit accordingly }
607 bne @dretzero { 0/x ->+/- 0 }
609 bne @dretzero { 0/x }
611 {--------------------------------------------------------------------}
612 { Return NotANumber }
613 {--------------------------------------------------------------------}
615 move.l d3,d0 { d3 contains 0xffffffff }
618 {--------------------------------------------------------------------}
619 { End of Special Handling }
620 {--------------------------------------------------------------------}
623 bset d3,d4 { restore implied leading "1" }
624 tst.w d0 { check for zero exponent - no leading "1" }
626 bclr d3,d4 { remove it }
627 add.w #1,d0 { "normalize" exponent }
630 beq @dretzero { dividing zero }
632 bset d3,d5 { restore implied leading "1" }
633 tst.w d1 { check for zero exponent - no leading "1"}
635 bclr d3,d5 { remove it }
636 add.w #1,d1 { "normalize" exponent }
639 sub.w d1,d0 { subtract exponents, }
640 add.w #BIAS4-8+1,d0 { add bias back in, account for shift }
641 add.w #34,d0 { add loop offset, +2 for extra rounding bits}
642 { for denormalized numbers (2 implied by dbra)}
643 move.w #27,d1 { bit number for "implied" pos (+4 for rounding)}
644 moveq.l #-1,d3 { zero quotient (for speed a one''s complement) }
645 sub.l d5,d4 { initial subtraction, u = u - v }
647 btst d1,d3 { divide until 1 in implied position }
651 bcs @dlabel8 { if carry is set, add, else subtract }
653 addx.l d3,d3 { shift quotient and set bit zero }
654 sub.l d5,d4 { subtract, u = u - v }
655 dbra d0,@dlabel7 { give up if result is denormalized }
658 addx.l d3,d3 { shift quotient and clear bit zero }
659 add.l d5,d4 { add (restore), u = u + v }
660 dbra d0,@dlabel7 { give up if result is denormalized }
662 subq.w #2,d0 { remove rounding offset for denormalized nums }
663 not.l d3 { invert quotient to get it right }
665 clr.l d1 { zero rounding bits }
666 tst.l d4 { check for exact result }
668 moveq.l #-1,d1 { prevent tie case }
670 move.l d3,d4 { save quotient mantissa }
671 jmp FPC_SINGLE_NORM{ (registers on stack removed by norm_sf) }
675 Procedure Single_Cmp; Assembler;
676 {--------------------------------------------}
677 { Low-level routine to compare single two }
678 { single point values.. }
679 { Never called directly. }
681 { d1 and d0 Values to compare }
682 { d0 = first operand }
684 { Flags according to result }
685 { Registers destroyed: d0,d1 }
686 {--------------------------------------------}
689 tst.l d0 { check sign bit }
692 bchg #31,d0 { toggle sign bit }
694 tst.l d1 { check sign bit }
697 bchg #31,d1 { toggle sign bit }
699 cmp.l d0,d1 { compare... }
705 Procedure LongMul;Assembler;
706 {--------------------------------------------}
707 { Low-level routine to multiply two signed }
708 { 32-bit values. Never called directly. }
709 { On entry: d1,d0 = 32-bit signed values to }
713 { Registers destroyed: d0,d1 }
714 { stack space used and restored: 10 bytes }
715 {--------------------------------------------}
718 cmp.b #2,Test68000 { Are we on a 68020+ cpu }
720 muls.l d1,d0 { yes, then directly mul... }
721 rts { return... result in d0 }
723 move.l d2,a0 { save registers }
729 movem.w (sp)+,d0-d3 { u = d0-d1, v = d2-d3 }
731 move.w d0,-(sp) { sign flag }
732 bpl @LMul1 { is u negative ? }
733 neg.w d1 { yes, force it positive }
736 tst.w d2 { is v negative ? }
738 neg.w d3 { yes, force it positive ... }
740 not.w (sp) { ... and modify flag word }
742 ext.l d0 { u.h <> 0 ? }
744 mulu.w d3,d0 { r = v.l * u.h }
746 tst.w d2 { v.h <> 0 ? }
748 mulu.w d1,d2 { r += v.h * u.l }
753 mulu.w d3,d1 { r += v.l * u.l }
757 tst.w (sp)+ { should the result be negated ? }
758 bpl @LMul5 { no, just return }
759 neg.l d0 { else r = -r }
766 Procedure Long2Single;Assembler;
767 {--------------------------------------------}
768 { Low-level routine to convert a longint }
769 { to a single floating point value. }
770 { On entry: d0 = longint value to convert. }
772 { d0 = single IEEE value }
773 { Registers destroyed: d0,d1 }
774 { stack space used and restored: 8 bytes }
775 {--------------------------------------------}
778 movem.l d2-d5,-(sp) { save registers to make norm_sf happy}
780 move.l d0,d4 { prepare result mantissa }
781 move.w #BIAS4+32-8,d0 { radix point after 32 bits }
782 move.l d4,d2 { set sign flag }
783 bge @l2slabel1 { nonnegative }
784 neg.l d4 { take absolute value }
786 swap d2 { follow SINGLE_NORM conventions }
787 clr.w d1 { set rounding = 0 }
792 Procedure LongDiv; [alias : 'FPC_LONGDIV'];Assembler;
793 {--------------------------------------------}
794 { Low-level routine to do signed long }
796 { On entry: d0/d1 operation to perform }
800 { Registers destroyed: d0,d1,d6 }
801 { stack space used and restored: 10 bytes }
802 {--------------------------------------------}
805 cmp.b #2,Test68000 { can we use divs ? }
811 tst.l d0 { check sign of d0 }
813 move.l #$ffffffff,d1{ sign extend into d1 }
819 move.l d2,a0 { save registers }
821 move.l d4,-(sp) { divisor = d1 = d4 }
822 move.l d5,-(sp) { divident = d0 = d5 }
824 move.l d1,d4 { save divisor }
825 move.l d0,d5 { save dividend }
827 clr.w -(sp) { sign flag }
829 clr.l d0 { prepare result }
830 move.l d4,d2 { get divisor }
831 beq @zerodiv { divisor = 0 ? }
832 bpl @LDiv1 { divisor < 0 ? }
833 neg.l d2 { negate it }
834 not.w (sp) { remember sign }
836 move.l d5,d1 { get dividend }
837 bpl @LDiv2 { dividend < 0 ? }
838 neg.l d1 { negate it }
839 not.w (sp) { remember sign }
841 {;== case 1) divident < divisor}
842 cmp.l d2,d1 { is divident smaller then divisor ? }
843 bcs @LDiv7 { yes, return immediately }
844 {;== case 2) divisor has <= 16 significant bits}
845 move.l d4,d6 { put divisor in d6 register }
846 lsr.l #8,d6 { rotate into low word }
849 bne @LDiv3 { divisor has only 16 bits }
850 move.w d1,d3 { save dividend }
851 clr.w d1 { divide dvd.h by dvs }
853 beq @LDiv4 { (no division necessary if dividend zero)}
856 move.w d1,d0 { save quotient.h }
858 move.w d3,d1 { (d0.h = remainder of prev divu) }
859 divu d2,d1 { divide dvd.l by dvs }
860 move.w d1,d0 { save quotient.l }
861 clr.w d1 { get remainder }
863 bra @LDiv7 { and return }
864 {;== case 3) divisor > 16 bits (corollary is dividend > 16 bits, see case 1)}
866 moveq.l #31,d3 { loop count }
868 add.l d1,d1 { shift divident ... }
869 addx.l d0,d0 { ... into d0 }
870 cmp.l d2,d0 { compare with divisor }
872 sub.l d2,d0 { big enough, subtract }
873 addq.w #1,d1 { and note bit into result }
876 exg d0,d1 { put quotient and remainder in their registers}
878 tst.l d5 { must the remainder be corrected ? }
880 neg.l d1 { yes, apply sign }
881 { the following line would be correct if modulus is defined as in algebra}
882 {; add.l sp@(6),d1 ; algebraic correction: modulus can only be >= 0}
884 tst.w (sp)+ { result should be negative ? }
886 neg.l d0 { yes, negate it }
892 rts { en exit : remainder = d1, quotient = d0 }
894 move.l a1,d3 { restore stack... }
896 move.w (sp)+,d1 { remove sign word }
901 jsr FPC_HALT_ERROR { RunError(200) }
902 rts { this should never occur... }
906 Procedure LongMod;[alias : 'FPC_LONGMOD'];Assembler;
907 { see longdiv for info on calling convention }
911 move.l d1,d0 { return the remainder in d0 }
917 Revision 1.1 2002/02/19 08:25:41 sasu
920 Revision 1.1 2000/07/13 06:30:55 michael
923 Revision 1.6 2000/01/07 16:41:42 daniel
926 Revision 1.5 2000/01/07 16:32:28 daniel
927 * copyright 2000 added
929 Revision 1.4 1998/10/13 08:00:04 pierre
930 * some bugs related to FPC_ prefix fixed
931 * problems with pbyte sometimes defined and sometimes not for rttip.inc solved
933 Revision 1.3 1998/07/01 14:28:32 carl
934 * LONGDIV bugfixed with signed and modulo
935 * LONGDIV bugfix when divisor is less then 16 bits
937 Revision 1.1.1.1 1998/03/25 11:18:44 root
940 Revision 1.5 1998/01/26 12:01:47 michael
941 + Added log at the end
945 Working file: rtl/m68k/lowmath.inc
947 ----------------------------
949 date: 1998/01/05 00:33:30; author: carl; state: Exp; lines: +144 -156
950 * Several minor bugfixes
951 ----------------------------
953 date: 1997/12/14 19:03:36; author: carl; state: Exp; lines: +11 -12
954 + uses now correct register conventions
955 ----------------------------
957 date: 1997/12/01 12:37:20; author: michael; state: Exp; lines: +14 -0
958 + added copyright reference in header.
959 ----------------------------
961 date: 1997/11/27 13:55:47; author: carl; state: Exp;
962 Internal RTL math functions for m68k.
963 =============================================================================