From: Ian Lance Taylor Date: Fri, 19 Jul 1996 20:02:44 +0000 (+0000) Subject: Add MCF5200 support X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=686cada41d2970b45a29ebaeddb787f747295a07;p=gcc.git Add MCF5200 support From-SVN: r12534 --- diff --git a/gcc/config/m68k/lb1sf68.asm b/gcc/config/m68k/lb1sf68.asm index 23c1373d5e6..c290b56bce0 100644 --- a/gcc/config/m68k/lb1sf68.asm +++ b/gcc/config/m68k/lb1sf68.asm @@ -244,12 +244,22 @@ FPTRAP = 15 $_exception_handler: lea SYM (_fpCCR),a0 movew d7,a0@(EBITS) | set __exception_bits +#ifndef __mcf5200__ orw d7,a0@(STICK) | and __sticky_bits +#else + movew a0@(STICK),d4 + orl d7,d4 + movew d4,a0@(STICK) +#endif movew d6,a0@(FORMT) | and __format movew d5,a0@(LASTO) | and __last_operation | Now put the operands in place: +#ifndef __mcf5200__ cmpw IMM (SINGLE_FLOAT),d6 +#else + cmpl IMM (SINGLE_FLOAT),d6 +#endif beq 1f movel a6@(8),a0@(OPER1) movel a6@(12),a0@(OPER1+4) @@ -260,7 +270,13 @@ $_exception_handler: movel a6@(12),a0@(OPER2) 2: | And check whether the exception is trap-enabled: +#ifndef __mcf5200__ andw a0@(TRAPE),d7 | is exception trap-enabled? +#else + clrl d6 + movew a0@(TRAPE),d6 + andl d6,d7 +#endif beq 1f | no, exit pea SYM (_fpCCR) | yes, push address of _fpCCR trap IMM (FPTRAP) | and trap @@ -278,7 +294,11 @@ SYM (__mulsi3): muluw sp@(10), d0 /* x0*y1 */ movew sp@(6), d1 /* x1 -> d1 */ muluw sp@(8), d1 /* x1*y0 */ +#ifndef __mcf5200__ addw d1, d0 +#else + addl d1, d0 +#endif swap d0 clrw d0 movew sp@(6), d1 /* x1 -> d1 */ @@ -293,6 +313,7 @@ SYM (__mulsi3): .proc .globl SYM (__udivsi3) SYM (__udivsi3): +#ifndef __mcf5200__ movel d2, sp@- movel sp@(12), d1 /* d1 = divisor */ movel sp@(8), d0 /* d0 = dividend */ @@ -336,6 +357,31 @@ L5: subql IMM (1), d0 /* adjust quotient */ L6: movel sp@+, d2 rts + +#else /* __mcf5200__ */ + +/* Coldfire implementation of non-restoring division algorithm from + Hennessy & Patterson, Appendix A. */ + link a6,IMM (0) + moveml d2-d4,sp@- + movel a6@(8),d0 + movel a6@(12),d1 + clrl d2 | clear p + moveq IMM (31),d4 +L1: addl d0,d0 | shift reg pair (p,a) one bit left + addxl d2,d2 + movl d2,d3 | subtract b from p, store in tmp. + subl d1,d3 + jmi L2 | if the result is not is negative, set the + bset #0,d0 | low order bit of a to 1 and store tmp in p. + movl d3,d2 +L2: subql IMM (1),d4 + jcc L1 + moveml sp@+,d2-d4 | restore data registers + unlk a6 | and return + rts +#endif /* __mcf5200__ */ + #endif /* L_udivsi3 */ #ifdef L_divsi3 @@ -345,15 +391,23 @@ L6: movel sp@+, d2 SYM (__divsi3): movel d2, sp@- - moveb IMM (1), d2 /* sign of result stored in d2 (=1 or =-1) */ + moveq IMM (1), d2 /* sign of result stored in d2 (=1 or =-1) */ movel sp@(12), d1 /* d1 = divisor */ jpl L1 negl d1 +#ifndef __mcf5200__ negb d2 /* change sign because divisor <0 */ +#else + negl d2 /* change sign because divisor <0 */ +#endif L1: movel sp@(8), d0 /* d0 = dividend */ jpl L2 negl d0 +#ifndef __mcf5200__ negb d2 +#else + negl d2 +#endif L2: movel d1, sp@- movel d0, sp@- @@ -467,7 +521,7 @@ Ld$den: | Return and signal a denormalized number orl d7,d0 movew IMM (INEXACT_RESULT+UNDERFLOW),d7 - movew IMM (DOUBLE_FLOAT),d6 + moveq IMM (DOUBLE_FLOAT),d6 jmp $_exception_handler Ld$infty: @@ -477,7 +531,7 @@ Ld$overflow: movel IMM (0),d1 orl d7,d0 movew IMM (INEXACT_RESULT+OVERFLOW),d7 - movew IMM (DOUBLE_FLOAT),d6 + moveq IMM (DOUBLE_FLOAT),d6 jmp $_exception_handler Ld$underflow: @@ -485,7 +539,7 @@ Ld$underflow: movel IMM (0),d0 movel d0,d1 movew IMM (INEXACT_RESULT+UNDERFLOW),d7 - movew IMM (DOUBLE_FLOAT),d6 + moveq IMM (DOUBLE_FLOAT),d6 jmp $_exception_handler Ld$inop: @@ -493,7 +547,7 @@ Ld$inop: movel IMM (QUIET_NaN),d0 movel d0,d1 movew IMM (INEXACT_RESULT+INVALID_OPERATION),d7 - movew IMM (DOUBLE_FLOAT),d6 + moveq IMM (DOUBLE_FLOAT),d6 jmp $_exception_handler Ld$div$0: @@ -502,7 +556,7 @@ Ld$div$0: movel IMM (0),d1 orl d7,d0 movew IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7 - movew IMM (DOUBLE_FLOAT),d6 + moveq IMM (DOUBLE_FLOAT),d6 jmp $_exception_handler |============================================================================= @@ -558,10 +612,15 @@ SYM (__adddf3): andl IMM (0x80000000),d7 | isolate a's sign bit ' swap d6 | and also b's sign bit ' +#ifndef __mcf5200__ andw IMM (0x8000),d6 | orw d6,d7 | and combine them into d7, so that a's sign ' | bit is in the high word and b's is in the ' | low word, so d6 is free to be used +#else + andl IMM (0x8000),d6 + orl d6,d7 +#endif movel d7,a0 | now save d7 into a0, so d7 is free to | be used also @@ -580,7 +639,11 @@ SYM (__adddf3): orl d7,d0 | and put hidden bit back Ladddf$1: swap d4 | shift right exponent so that it starts +#ifndef __mcf5200__ lsrw IMM (5),d4 | in bit 0 and not bit 20 +#else + lsrl IMM (5),d4 | in bit 0 and not bit 20 +#endif | Now we have a's exponent in d4 and fraction in d0-d1 ' movel d2,d5 | save b to get exponent andl d6,d5 | get exponent in d5 @@ -592,7 +655,11 @@ Ladddf$1: orl d7,d2 | and put hidden bit back Ladddf$2: swap d5 | shift right exponent so that it starts +#ifndef __mcf5200__ lsrw IMM (5),d5 | in bit 0 and not bit 20 +#else + lsrl IMM (5),d5 | in bit 0 and not bit 20 +#endif | Now we have b's exponent in d5 and fraction in d2-d3. ' @@ -603,7 +670,11 @@ Ladddf$2: | and d4-d5-d6-d7 for the second. To do this we store (temporarily) the | exponents in a2-a3. +#ifndef __mcf5200__ moveml a2-a3,sp@- | save the address registers +#else + moveml a2-a4,sp@- | save the address registers +#endif movel d4,a2 | save the exponents movel d5,a3 | @@ -617,32 +688,88 @@ Ladddf$2: | Here we shift the numbers until the exponents are the same, and put | the largest exponent in a2. +#ifndef __mcf5200__ exg d4,a2 | get exponents back exg d5,a3 | cmpw d4,d5 | compare the exponents +#else + movel d4,a4 | get exponents back + movel a2,d4 + movel a4,a2 + movel d5,a4 + movel a3,d5 + movel a4,a3 + cmpl d4,d5 | compare the exponents +#endif beq Ladddf$3 | if equal don't shift ' bhi 9f | branch if second exponent is higher | Here we have a's exponent larger than b's, so we have to shift b. We do | this by using as counter d2: 1: movew d4,d2 | move largest exponent to d2 +#ifndef __mcf5200__ subw d5,d2 | and subtract second exponent exg d4,a2 | get back the longs we saved exg d5,a3 | +#else + subl d5,d2 | and subtract second exponent + movel d4,a4 | get back the longs we saved + movel a2,d4 + movel a4,a2 + movel d5,a4 + movel a3,d5 + movel a4,a3 +#endif | if difference is too large we don't shift (actually, we can just exit) ' +#ifndef __mcf5200__ cmpw IMM (DBL_MANT_DIG+2),d2 +#else + cmpl IMM (DBL_MANT_DIG+2),d2 +#endif bge Ladddf$b$small +#ifndef __mcf5200__ cmpw IMM (32),d2 | if difference >= 32, shift by longs +#else + cmpl IMM (32),d2 | if difference >= 32, shift by longs +#endif bge 5f -2: cmpw IMM (16),d2 | if difference >= 16, shift by words +2: +#ifndef __mcf5200__ + cmpw IMM (16),d2 | if difference >= 16, shift by words +#else + cmpl IMM (16),d2 | if difference >= 16, shift by words +#endif bge 6f bra 3f | enter dbra loop -4: lsrl IMM (1),d4 +4: +#ifndef __mcf5200__ + lsrl IMM (1),d4 roxrl IMM (1),d5 roxrl IMM (1),d6 roxrl IMM (1),d7 -3: dbra d2,4b +#else + lsrl IMM (1),d7 + btst IMM (0),d6 + beq 10f + bset IMM (31),d7 +10: lsrl IMM (1),d6 + btst IMM (0),d5 + beq 11f + bset IMM (31),d6 +11: lsrl IMM (1),d5 + btst IMM (0),d4 + beq 12f + bset IMM (31),d5 +12: lsrl IMM (1),d4 +#endif +3: +#ifndef __mcf5200__ + dbra d2,4b +#else + subql IMM (1),d2 + bpl 4b +#endif movel IMM (0),d2 movel d2,d3 bra Ladddf$4 @@ -651,7 +778,11 @@ Ladddf$2: movel d5,d6 movel d4,d5 movel IMM (0),d4 +#ifndef __mcf5200__ subw IMM (32),d2 +#else + subl IMM (32),d2 +#endif bra 2b 6: movew d6,d7 @@ -662,28 +793,82 @@ Ladddf$2: swap d5 movew IMM (0),d4 swap d4 +#ifndef __mcf5200__ subw IMM (16),d2 +#else + subl IMM (16),d2 +#endif bra 3b -9: exg d4,d5 +9: +#ifndef __mcf5200__ + exg d4,d5 movew d4,d6 subw d5,d6 | keep d5 (largest exponent) in d4 exg d4,a2 exg d5,a3 +#else + movel d5,d6 + movel d4,d5 + movel d6,d4 + subl d5,d6 + movel d4,a4 + movel a2,d4 + movel a4,a2 + movel d5,a4 + movel a3,d5 + movel a4,a3 +#endif | if difference is too large we don't shift (actually, we can just exit) ' +#ifndef __mcf5200__ cmpw IMM (DBL_MANT_DIG+2),d6 +#else + cmpl IMM (DBL_MANT_DIG+2),d6 +#endif bge Ladddf$a$small +#ifndef __mcf5200__ cmpw IMM (32),d6 | if difference >= 32, shift by longs +#else + cmpl IMM (32),d6 | if difference >= 32, shift by longs +#endif bge 5f -2: cmpw IMM (16),d6 | if difference >= 16, shift by words +2: +#ifndef __mcf5200__ + cmpw IMM (16),d6 | if difference >= 16, shift by words +#else + cmpl IMM (16),d6 | if difference >= 16, shift by words +#endif bge 6f bra 3f | enter dbra loop -4: lsrl IMM (1),d0 +4: +#ifndef __mcf5200__ + lsrl IMM (1),d0 roxrl IMM (1),d1 roxrl IMM (1),d2 roxrl IMM (1),d3 -3: dbra d6,4b +#else + lsrl IMM (1),d3 + btst IMM (0),d2 + beq 10f + bset IMM (31),d3 +10: lsrl IMM (1),d2 + btst IMM (0),d1 + beq 11f + bset IMM (31),d2 +11: lsrl IMM (1),d1 + btst IMM (0),d0 + beq 12f + bset IMM (31),d1 +12: lsrl IMM (1),d0 +#endif +3: +#ifndef __mcf5200__ + dbra d6,4b +#else + subql IMM (1),d6 + bpl 4b +#endif movel IMM (0),d7 movel d7,d6 bra Ladddf$4 @@ -692,7 +877,11 @@ Ladddf$2: movel d1,d2 movel d0,d1 movel IMM (0),d0 +#ifndef __mcf5200__ subw IMM (32),d6 +#else + subl IMM (32),d6 +#endif bra 2b 6: movew d2,d3 @@ -703,18 +892,40 @@ Ladddf$2: swap d1 movew IMM (0),d0 swap d0 +#ifndef __mcf5200__ subw IMM (16),d6 +#else + subl IMM (16),d6 +#endif bra 3b Ladddf$3: +#ifndef __mcf5200__ exg d4,a2 exg d5,a3 +#else + movel d4,a4 + movel a2,d4 + movel a4,a2 + movel d5,a4 + movel a3,d5 + movel a4,a3 +#endif Ladddf$4: | Now we have the numbers in d0--d3 and d4--d7, the exponent in a2, and | the signs in a4. | Here we have to decide whether to add or subtract the numbers: +#ifndef __mcf5200__ exg d7,a0 | get the signs exg d6,a3 | a3 is free to be used +#else + movel d7,a4 + movel a0,d7 + movel a4,a0 + movel d6,a4 + movel a3,d6 + movel a4,a3 +#endif movel d7,d6 | movew IMM (0),d7 | get a's sign in d7 ' swap d6 | @@ -722,8 +933,17 @@ Ladddf$4: eorl d7,d6 | compare the signs bmi Lsubdf$0 | if the signs are different we have | to subtract +#ifndef __mcf5200__ exg d7,a0 | else we add the numbers exg d6,a3 | +#else + movel d7,a4 + movel a0,d7 + movel a4,a0 + movel d6,a4 + movel a3,d6 + movel a4,a3 +#endif addl d7,d3 | addxl d6,d2 | addxl d5,d1 | @@ -733,7 +953,11 @@ Ladddf$4: movel a0,d7 | andl IMM (0x80000000),d7 | d7 now has the sign +#ifndef __mcf5200__ moveml sp@+,a2-a3 +#else + moveml sp@+,a2-a4 +#endif | Before rounding normalize so bit #DBL_MANT_DIG is set (we will consider | the case of denormalized numbers in the rounding routine itself). @@ -741,28 +965,64 @@ Ladddf$4: | one more bit we check this: btst IMM (DBL_MANT_DIG+1),d0 beq 1f +#ifndef __mcf5200__ lsrl IMM (1),d0 roxrl IMM (1),d1 roxrl IMM (1),d2 roxrl IMM (1),d3 addw IMM (1),d4 +#else + lsrl IMM (1),d3 + btst IMM (0),d2 + beq 10f + bset IMM (31),d3 +10: lsrl IMM (1),d2 + btst IMM (0),d1 + beq 11f + bset IMM (31),d2 +11: lsrl IMM (1),d1 + btst IMM (0),d0 + beq 12f + bset IMM (31),d1 +12: lsrl IMM (1),d0 + addl IMM (1),d4 +#endif 1: lea Ladddf$5,a0 | to return from rounding routine lea SYM (_fpCCR),a1 | check the rounding mode +#ifdef __mcf5200__ + clrl d6 +#endif movew a1@(6),d6 | rounding mode in d6 beq Lround$to$nearest +#ifndef __mcf5200__ cmpw IMM (ROUND_TO_PLUS),d6 +#else + cmpl IMM (ROUND_TO_PLUS),d6 +#endif bhi Lround$to$minus blt Lround$to$zero bra Lround$to$plus Ladddf$5: | Put back the exponent and check for overflow +#ifndef __mcf5200__ cmpw IMM (0x7ff),d4 | is the exponent big? +#else + cmpl IMM (0x7ff),d4 | is the exponent big? +#endif bge 1f bclr IMM (DBL_MANT_DIG-1),d0 +#ifndef __mcf5200__ lslw IMM (4),d4 | put exponent back into position +#else + lsll IMM (4),d4 | put exponent back into position +#endif swap d0 | +#ifndef __mcf5200__ orw d4,d0 | +#else + orl d4,d0 | +#endif swap d0 | bra Ladddf$ret 1: @@ -771,17 +1031,26 @@ Ladddf$5: Lsubdf$0: | Here we do the subtraction. +#ifndef __mcf5200__ exg d7,a0 | put sign back in a0 exg d6,a3 | +#else + movel d7,a4 + movel a0,d7 + movel a4,a0 + movel d6,a4 + movel a3,d6 + movel a4,a3 +#endif subl d7,d3 | subxl d6,d2 | subxl d5,d1 | subxl d4,d0 | beq Ladddf$ret$1 | if zero just exit bpl 1f | if positive skip the following - exg d7,a0 | + movel a0,d7 | bchg IMM (31),d7 | change sign bit in d7 - exg d7,a0 | + movel d7,a0 | negl d3 | negxl d2 | negxl d1 | and negate result @@ -790,7 +1059,11 @@ Lsubdf$0: movel a2,d4 | return exponent to d4 movel a0,d7 andl IMM (0x80000000),d7 | isolate sign bit +#ifndef __mcf5200__ moveml sp@+,a2-a3 | +#else + moveml sp@+,a2-a4 | +#endif | Before rounding normalize so bit #DBL_MANT_DIG is set (we will consider | the case of denormalized numbers in the rounding routine itself). @@ -798,26 +1071,58 @@ Lsubdf$0: | one more bit we check this: btst IMM (DBL_MANT_DIG+1),d0 beq 1f +#ifndef __mcf5200__ lsrl IMM (1),d0 roxrl IMM (1),d1 roxrl IMM (1),d2 roxrl IMM (1),d3 addw IMM (1),d4 +#else + lsrl IMM (1),d3 + btst IMM (0),d2 + beq 10f + bset IMM (31),d3 +10: lsrl IMM (1),d2 + btst IMM (0),d1 + beq 11f + bset IMM (31),d2 +11: lsrl IMM (1),d1 + btst IMM (0),d0 + beq 12f + bset IMM (31),d1 +12: lsrl IMM (1),d0 + addl IMM (1),d4 +#endif 1: lea Lsubdf$1,a0 | to return from rounding routine lea SYM (_fpCCR),a1 | check the rounding mode +#ifdef __mcf5200__ + clrl d6 +#endif movew a1@(6),d6 | rounding mode in d6 beq Lround$to$nearest +#ifndef __mcf5200__ cmpw IMM (ROUND_TO_PLUS),d6 +#else + cmpl IMM (ROUND_TO_PLUS),d6 +#endif bhi Lround$to$minus blt Lround$to$zero bra Lround$to$plus Lsubdf$1: | Put back the exponent and sign (we don't have overflow). ' bclr IMM (DBL_MANT_DIG-1),d0 +#ifndef __mcf5200__ lslw IMM (4),d4 | put exponent back into position +#else + lsll IMM (4),d4 | put exponent back into position +#endif swap d0 | +#ifndef __mcf5200__ orw d4,d0 | +#else + orl d4,d0 | +#endif swap d0 | bra Ladddf$ret @@ -825,7 +1130,11 @@ Lsubdf$1: | DBL_MANT_DIG+1) we return the other (and now we don't have to ' | check for finiteness or zero). Ladddf$a$small: +#ifndef __mcf5200__ moveml sp@+,a2-a3 +#else + moveml sp@+,a2-a4 +#endif movel a6@(16),d0 movel a6@(20),d1 lea SYM (_fpCCR),a0 @@ -835,7 +1144,11 @@ Ladddf$a$small: rts Ladddf$b$small: +#ifndef __mcf5200__ moveml sp@+,a2-a3 +#else + moveml sp@+,a2-a4 +#endif movel a6@(8),d0 movel a6@(12),d1 lea SYM (_fpCCR),a0 @@ -893,8 +1206,16 @@ Ladddf$ret: Ladddf$ret$den: | Return a denormalized number. +#ifndef __mcf5200__ lsrl IMM (1),d0 | shift right once more roxrl IMM (1),d1 | +#else + lsrl IMM (1),d1 + btst IMM (0),d0 + beq 10f + bset IMM (31),d1 +10: lsrl IMM (1),d0 +#endif bra Ladddf$ret Ladddf$nf: @@ -987,17 +1308,30 @@ SYM (__muldf3): andl d6,d0 | isolate fraction orl IMM (0x00100000),d0 | and put hidden bit back swap d4 | I like exponents in the first byte +#ifndef __mcf5200__ lsrw IMM (4),d4 | +#else + lsrl IMM (4),d4 | +#endif Lmuldf$1: andl d7,d5 | beq Lmuldf$b$den | andl d6,d2 | orl IMM (0x00100000),d2 | and put hidden bit back swap d5 | +#ifndef __mcf5200__ lsrw IMM (4),d5 | +#else + lsrl IMM (4),d5 | +#endif Lmuldf$2: | +#ifndef __mcf5200__ addw d5,d4 | add exponents subw IMM (D_BIAS+1),d4 | and subtract bias (plus one) +#else + addl d5,d4 | add exponents + subl IMM (D_BIAS+1),d4 | and subtract bias (plus one) +#endif | We are now ready to do the multiplication. The situation is as follows: | both a and b have bit 52 ( bit 20 of d0 and d2) set (even if they were @@ -1009,11 +1343,16 @@ Lmuldf$2: | | enough to keep everything in them. So we use the address registers to keep | some intermediate data. +#ifndef __mcf5200__ moveml a2-a3,sp@- | save a2 and a3 for temporary use +#else + moveml a2-a4,sp@- +#endif movel IMM (0),a2 | a2 is a null register movel d4,a3 | and a3 will preserve the exponent | First, shift d2-d3 so bit 20 becomes bit 31: +#ifndef __mcf5200__ rorl IMM (5),d2 | rotate d2 5 places right swap d2 | and swap it rorl IMM (5),d3 | do the same thing with d3 @@ -1022,6 +1361,16 @@ Lmuldf$2: | andw IMM (0x07ff),d6 | orw d6,d2 | and put them into d2 andw IMM (0xf800),d3 | clear those bits in d3 +#else + moveq IMM (11),d7 | left shift d2 11 bits + lsll d7,d2 + movel d3,d6 | get a copy of d3 + lsll d7,d3 | left shift d3 11 bits + andl IMM (0xffe00000),d6 | get the top 11 bits of d3 + moveq IMM (21),d7 | right shift them 21 bits + lsrl d7,d6 + orl d6,d2 | stick them at the end of d2 +#endif movel d2,d6 | move b into d6-d7 movel d3,d7 | move a into d4-d5 @@ -1034,9 +1383,22 @@ Lmuldf$2: | | We use a1 as counter: movel IMM (DBL_MANT_DIG-1),a1 +#ifndef __mcf5200__ exg d7,a1 +#else + movel d7,a4 + movel a1,d7 + movel a4,a1 +#endif -1: exg d7,a1 | put counter back in a1 +1: +#ifndef __mcf5200__ + exg d7,a1 | put counter back in a1 +#else + movel d7,a4 + movel a1,d7 + movel a4,a1 +#endif addl d3,d3 | shift sum once left addxl d2,d2 | addxl d1,d1 | @@ -1044,17 +1406,42 @@ Lmuldf$2: | addl d7,d7 | addxl d6,d6 | bcc 2f | if bit clear skip the following +#ifndef __mcf5200__ exg d7,a2 | +#else + movel d7,a4 + movel a2,d7 + movel a4,a2 +#endif addl d5,d3 | else add a to the sum addxl d4,d2 | addxl d7,d1 | addxl d7,d0 | +#ifndef __mcf5200__ exg d7,a2 | -2: exg d7,a1 | put counter in d7 +#else + movel d7,a4 + movel a2,d7 + movel a4,a2 +#endif +2: +#ifndef __mcf5200__ + exg d7,a1 | put counter in d7 dbf d7,1b | decrement and branch +#else + movel d7,a4 + movel a1,d7 + movel a4,a1 + subql IMM (1),d7 + bpl 1b +#endif movel a3,d4 | restore exponent +#ifndef __mcf5200__ moveml sp@+,a2-a3 +#else + moveml sp@+,a2-a4 +#endif | Now we have the product in d0-d1-d2-d3, with bit 8 of d0 set. The | first thing to do now is to normalize it so bit 8 becomes bit @@ -1067,6 +1454,7 @@ Lmuldf$2: | swap d3 movew d3,d2 movew IMM (0),d3 +#ifndef __mcf5200__ lsrl IMM (1),d0 roxrl IMM (1),d1 roxrl IMM (1),d2 @@ -1079,6 +1467,22 @@ Lmuldf$2: | roxrl IMM (1),d1 roxrl IMM (1),d2 roxrl IMM (1),d3 +#else + moveq IMM (29),d6 + lsrl IMM (3),d3 + movel d2,d7 + lsll d6,d7 + orl d7,d3 + lsrl IMM (3),d2 + movel d1,d7 + lsll d6,d7 + orl d7,d2 + lsrl IMM (3),d1 + movel d0,d7 + lsll d6,d7 + orl d7,d1 + lsrl IMM (3),d0 +#endif | Now round, check for over- and underflow, and exit. movel a0,d7 | get sign bit back into d7 @@ -1086,9 +1490,18 @@ Lmuldf$2: | btst IMM (DBL_MANT_DIG+1-32),d0 beq Lround$exit +#ifndef __mcf5200__ lsrl IMM (1),d0 roxrl IMM (1),d1 addw IMM (1),d4 +#else + lsrl IMM (1),d1 + btst IMM (0),d0 + beq 10f + bset IMM (31),d1 +10: lsrl IMM (1),d0 + addl IMM (1),d4 +#endif bra Lround$exit Lmuldf$inop: @@ -1113,8 +1526,17 @@ Lmuldf$a$nf: | NaN, in which case we return NaN. Lmuldf$b$0: movew IMM (MULTIPLY),d5 +#ifndef __mcf5200__ exg d2,d0 | put b (==0) into d0-d1 exg d3,d1 | and a (with sign bit cleared) into d2-d3 +#else + movel d2,d7 + movel d0,d2 + movel d7,d0 + movel d3,d7 + movel d1,d3 + movel d7,d1 +#endif bra 1f Lmuldf$a$0: movel a6@(16),d2 | put b into d2-d3 again @@ -1137,7 +1559,11 @@ Lmuldf$a$den: andl d6,d0 1: addl d1,d1 | shift a left until bit 20 is set addxl d0,d0 | +#ifndef __mcf5200__ subw IMM (1),d4 | and adjust exponent +#else + subl IMM (1),d4 | and adjust exponent +#endif btst IMM (20),d0 | bne Lmuldf$1 | bra 1b @@ -1147,7 +1573,11 @@ Lmuldf$b$den: andl d6,d2 1: addl d3,d3 | shift b left until bit 20 is set addxl d2,d2 | +#ifndef __mcf5200__ subw IMM (1),d5 | and adjust exponent +#else + subql IMM (1),d5 | and adjust exponent +#endif btst IMM (20),d2 | bne Lmuldf$2 | bra 1b @@ -1199,17 +1629,30 @@ SYM (__divdf3): andl d6,d0 | and isolate fraction orl IMM (0x00100000),d0 | and put hidden bit back swap d4 | I like exponents in the first byte +#ifndef __mcf5200__ lsrw IMM (4),d4 | +#else + lsrl IMM (4),d4 | +#endif Ldivdf$1: | andl d7,d5 | beq Ldivdf$b$den | andl d6,d2 | orl IMM (0x00100000),d2 swap d5 | +#ifndef __mcf5200__ lsrw IMM (4),d5 | +#else + lsrl IMM (4),d5 | +#endif Ldivdf$2: | +#ifndef __mcf5200__ subw d5,d4 | subtract exponents addw IMM (D_BIAS),d4 | and add bias +#else + subl d5,d4 | subtract exponents + addl IMM (D_BIAS),d4 | and add bias +#endif | We are now ready to do the division. We have prepared things in such a way | that the ratio of the fractions will be less than 2 but greater than 1/2. @@ -1240,7 +1683,12 @@ Ldivdf$2: | bset d5,d6 | set the corresponding bit in d6 3: addl d1,d1 | shift a by 1 addxl d0,d0 | +#ifndef __mcf5200__ dbra d5,1b | and branch back +#else + subql IMM (1), d5 + bpl 1b +#endif bra 5f 4: cmpl d1,d3 | here d0==d2, so check d1 and d3 bhi 3b | if d1 > d2 skip the subtraction @@ -1257,7 +1705,12 @@ Ldivdf$2: | bset d5,d7 | set the corresponding bit in d7 3: addl d1,d1 | shift a by 1 addxl d0,d0 | +#ifndef __mcf5200__ dbra d5,1b | and branch back +#else + subql IMM (1), d5 + bpl 1b +#endif bra 5f 4: cmpl d1,d3 | here d0==d2, so check d1 and d3 bhi 3b | if d1 > d2 skip the subtraction @@ -1270,7 +1723,12 @@ Ldivdf$2: | beq 3f | if d0==d2 check d1 and d3 2: addl d1,d1 | shift a by 1 addxl d0,d0 | +#ifndef __mcf5200__ dbra d5,1b | and branch back +#else + subql IMM (1), d5 + bpl 1b +#endif movel IMM (0),d2 | here no sticky bit was found movel d2,d3 bra 5f @@ -1281,13 +1739,23 @@ Ldivdf$2: | | to it; if you don't do this the algorithm loses in some cases). ' movel IMM (0),d2 movel d2,d3 +#ifndef __mcf5200__ subw IMM (DBL_MANT_DIG),d5 addw IMM (63),d5 cmpw IMM (31),d5 +#else + subl IMM (DBL_MANT_DIG),d5 + addl IMM (63),d5 + cmpl IMM (31),d5 +#endif bhi 2f 1: bset d5,d3 bra 5f +#ifndef __mcf5200__ subw IMM (32),d5 +#else + subl IMM (32),d5 +#endif 2: bset d5,d2 5: | Finally we are finished! Move the longs in the address registers to @@ -1302,11 +1770,28 @@ Ldivdf$2: | | not set: btst IMM (DBL_MANT_DIG-32+1),d0 beq 1f +#ifndef __mcf5200__ lsrl IMM (1),d0 roxrl IMM (1),d1 roxrl IMM (1),d2 roxrl IMM (1),d3 addw IMM (1),d4 +#else + lsrl IMM (1),d3 + btst IMM (0),d2 + beq 10f + bset IMM (31),d3 +10: lsrl IMM (1),d2 + btst IMM (0),d1 + beq 11f + bset IMM (31),d2 +11: lsrl IMM (1),d1 + btst IMM (0),d0 + beq 12f + bset IMM (31),d1 +12: lsrl IMM (1),d0 + addl IMM (1),d4 +#endif 1: | Now round, check for over- and underflow, and exit. movel a0,d7 | restore sign bit to d7 @@ -1377,7 +1862,11 @@ Ldivdf$a$den: andl d6,d0 1: addl d1,d1 | shift a left until bit 20 is set addxl d0,d0 +#ifndef __mcf5200__ subw IMM (1),d4 | and adjust exponent +#else + subl IMM (1),d4 | and adjust exponent +#endif btst IMM (DBL_MANT_DIG-32-1),d0 bne Ldivdf$1 bra 1b @@ -1387,7 +1876,11 @@ Ldivdf$b$den: andl d6,d2 1: addl d3,d3 | shift b left until bit 20 is set addxl d2,d2 +#ifndef __mcf5200__ subw IMM (1),d5 | and adjust exponent +#else + subql IMM (1),d5 | and adjust exponent +#endif btst IMM (DBL_MANT_DIG-32-1),d2 bne Ldivdf$2 bra 1b @@ -1398,7 +1891,11 @@ Lround$exit: | so that 2^21 <= d0 < 2^22, and the exponent is in the lower byte of d4. | First check for underlow in the exponent: +#ifndef __mcf5200__ cmpw IMM (-DBL_MANT_DIG-1),d4 +#else + cmpl IMM (-DBL_MANT_DIG-1),d4 +#endif blt Ld$underflow | It could happen that the exponent is less than 1, in which case the | number is denormalized. In this case we shift right and adjust the @@ -1407,9 +1904,15 @@ Lround$exit: movel d7,a0 | movel IMM (0),d6 | use d6-d7 to collect bits flushed right movel d6,d7 | use d6-d7 to collect bits flushed right +#ifndef __mcf5200__ cmpw IMM (1),d4 | if the exponent is less than 1 we +#else + cmpl IMM (1),d4 | if the exponent is less than 1 we +#endif bge 2f | have to shift right (denormalize) -1: addw IMM (1),d4 | adjust the exponent +1: +#ifndef __mcf5200__ + addw IMM (1),d4 | adjust the exponent lsrl IMM (1),d0 | shift right once roxrl IMM (1),d1 | roxrl IMM (1),d2 | @@ -1417,6 +1920,31 @@ Lround$exit: roxrl IMM (1),d6 | roxrl IMM (1),d7 | cmpw IMM (1),d4 | is the exponent 1 already? +#else + addl IMM (1),d4 | adjust the exponent + lsrl IMM (1),d7 + btst IMM (0),d6 + beq 13f + bset IMM (31),d7 +13: lsrl IMM (1),d6 + btst IMM (0),d3 + beq 14f + bset IMM (31),d6 +14: lsrl IMM (1),d3 + btst IMM (0),d2 + beq 10f + bset IMM (31),d3 +10: lsrl IMM (1),d2 + btst IMM (0),d1 + beq 11f + bset IMM (31),d2 +11: lsrl IMM (1),d1 + btst IMM (0),d0 + beq 12f + bset IMM (31),d1 +12: lsrl IMM (1),d0 + cmpl IMM (1),d4 | is the exponent 1 already? +#endif beq 2f | if not loop back bra 1b | bra Ld$underflow | safety check, shouldn't execute ' @@ -1426,9 +1954,16 @@ Lround$exit: | Now call the rounding routine (which takes care of denormalized numbers): lea Lround$0,a0 | to return from rounding routine lea SYM (_fpCCR),a1 | check the rounding mode +#ifdef __mcf5200__ + clrl d6 +#endif movew a1@(6),d6 | rounding mode in d6 beq Lround$to$nearest +#ifndef __mcf5200__ cmpw IMM (ROUND_TO_PLUS),d6 +#else + cmpl IMM (ROUND_TO_PLUS),d6 +#endif bhi Lround$to$minus blt Lround$to$zero bra Lround$to$plus @@ -1440,17 +1975,29 @@ Lround$0: | check again for underflow!). We have to check for overflow or for a | denormalized number (which also signals underflow). | Check for overflow (i.e., exponent >= 0x7ff). +#ifndef __mcf5200__ cmpw IMM (0x07ff),d4 +#else + cmpl IMM (0x07ff),d4 +#endif bge Ld$overflow | Now check for a denormalized number (exponent==0): movew d4,d4 beq Ld$den 1: | Put back the exponents and sign and return. +#ifndef __mcf5200__ lslw IMM (4),d4 | exponent back to fourth byte +#else + lsll IMM (4),d4 | exponent back to fourth byte +#endif bclr IMM (DBL_MANT_DIG-32-1),d0 swap d0 | and put back exponent +#ifndef __mcf5200__ orw d4,d0 | +#else + orl d4,d0 | +#endif swap d0 | orl d7,d0 | and sign also @@ -1542,8 +2089,17 @@ Lcmpdf$1: tstl d6 bpl 1f | If both are negative exchange them +#ifndef __mcf5200__ exg d0,d2 exg d1,d3 +#else + movel d0,d7 + movel d2,d0 + movel d7,d2 + movel d1,d7 + movel d3,d1 + movel d7,d3 +#endif 1: | Now that they are positive we just compare them as longs (does this also | work for denormalized numbers?). @@ -1608,13 +2164,22 @@ Lround$to$nearest: | Normalize shifting left until bit #DBL_MANT_DIG-32 is set or the exponent | is one (remember that a denormalized number corresponds to an | exponent of -D_BIAS+1). +#ifndef __mcf5200__ cmpw IMM (1),d4 | remember that the exponent is at least one +#else + cmpl IMM (1),d4 | remember that the exponent is at least one +#endif beq 2f | an exponent of one means denormalized addl d3,d3 | else shift and adjust the exponent addxl d2,d2 | addxl d1,d1 | addxl d0,d0 | +#ifndef __mcf5200__ dbra d4,1b | +#else + subql IMM (1), d4 + bpl 1b +#endif 2: | Now round: we do it as follows: after the shifting we can write the | fraction part as f + delta, where 1 < f < 2^25, and 0 <= delta <= 2. @@ -1636,16 +2201,34 @@ Lround$to$nearest: addl d3,d1 | addxl d2,d0 | Shift right once (because we used bit #DBL_MANT_DIG-32!). -2: lsrl IMM (1),d0 +2: +#ifndef __mcf5200__ + lsrl IMM (1),d0 roxrl IMM (1),d1 +#else + lsrl IMM (1),d1 + btst IMM (0),d0 + beq 10f + bset IMM (31),d1 +10: lsrl IMM (1),d0 +#endif | Now check again bit #DBL_MANT_DIG-32 (rounding could have produced a | 'fraction overflow' ...). btst IMM (DBL_MANT_DIG-32),d0 beq 1f +#ifndef __mcf5200__ lsrl IMM (1),d0 roxrl IMM (1),d1 addw IMM (1),d4 +#else + lsrl IMM (1),d1 + btst IMM (0),d0 + beq 10f + bset IMM (31),d1 +10: lsrl IMM (1),d0 + addl IMM (1),d4 +#endif 1: | If bit #DBL_MANT_DIG-32-1 is clear we have a denormalized number, so we | have to put the exponent to zero and return a denormalized number. @@ -1717,7 +2300,7 @@ Lf$den: | Return and signal a denormalized number orl d7,d0 movew IMM (INEXACT_RESULT+UNDERFLOW),d7 - movew IMM (SINGLE_FLOAT),d6 + moveq IMM (SINGLE_FLOAT),d6 jmp $_exception_handler Lf$infty: @@ -1726,21 +2309,21 @@ Lf$overflow: movel IMM (INFINITY),d0 orl d7,d0 movew IMM (INEXACT_RESULT+OVERFLOW),d7 - movew IMM (SINGLE_FLOAT),d6 + moveq IMM (SINGLE_FLOAT),d6 jmp $_exception_handler Lf$underflow: | Return 0 and set the exception flags movel IMM (0),d0 movew IMM (INEXACT_RESULT+UNDERFLOW),d7 - movew IMM (SINGLE_FLOAT),d6 + moveq IMM (SINGLE_FLOAT),d6 jmp $_exception_handler Lf$inop: | Return a quiet NaN and set the exception flags movel IMM (QUIET_NaN),d0 movew IMM (INEXACT_RESULT+INVALID_OPERATION),d7 - movew IMM (SINGLE_FLOAT),d6 + moveq IMM (SINGLE_FLOAT),d6 jmp $_exception_handler Lf$div$0: @@ -1748,7 +2331,7 @@ Lf$div$0: movel IMM (INFINITY),d0 orl d7,d0 movew IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7 - movew IMM (SINGLE_FLOAT),d6 + moveq IMM (SINGLE_FLOAT),d6 jmp $_exception_handler |============================================================================= @@ -1840,54 +2423,126 @@ Laddsf$2: | same, and put the largest exponent in d6. Note that we are using two | registers for each number (see the discussion by D. Knuth in "Seminumerical | Algorithms"). +#ifndef __mcf5200__ cmpw d6,d7 | compare exponents +#else + cmpl d6,d7 | compare exponents +#endif beq Laddsf$3 | if equal don't shift ' bhi 5f | branch if second exponent largest 1: subl d6,d7 | keep the largest exponent negl d7 +#ifndef __mcf5200__ lsrw IMM (8),d7 | put difference in lower byte +#else + lsrl IMM (8),d7 | put difference in lower byte +#endif | if difference is too large we don't shift (actually, we can just exit) ' +#ifndef __mcf5200__ cmpw IMM (FLT_MANT_DIG+2),d7 +#else + cmpl IMM (FLT_MANT_DIG+2),d7 +#endif bge Laddsf$b$small +#ifndef __mcf5200__ cmpw IMM (16),d7 | if difference >= 16 swap +#else + cmpl IMM (16),d7 | if difference >= 16 swap +#endif bge 4f 2: +#ifndef __mcf5200__ subw IMM (1),d7 -3: lsrl IMM (1),d2 | shift right second operand +#else + subql IMM (1), d7 +#endif +3: +#ifndef __mcf5200__ + lsrl IMM (1),d2 | shift right second operand roxrl IMM (1),d3 dbra d7,3b +#else + lsrl IMM (1),d3 + btst IMM (0),d2 + beq 10f + bset IMM (31),d3 +10: lsrl IMM (1),d2 + subql IMM (1), d7 + bpl 3b +#endif bra Laddsf$3 4: movew d2,d3 swap d3 movew d3,d2 swap d2 +#ifndef __mcf5200__ subw IMM (16),d7 +#else + subl IMM (16),d7 +#endif bne 2b | if still more bits, go back to normal case bra Laddsf$3 5: +#ifndef __mcf5200__ exg d6,d7 | exchange the exponents +#else + eorl d6,d7 + eorl d7,d6 + eorl d6,d7 +#endif subl d6,d7 | keep the largest exponent negl d7 | +#ifndef __mcf5200__ lsrw IMM (8),d7 | put difference in lower byte +#else + lsrl IMM (8),d7 | put difference in lower byte +#endif | if difference is too large we don't shift (and exit!) ' +#ifndef __mcf5200__ cmpw IMM (FLT_MANT_DIG+2),d7 +#else + cmpl IMM (FLT_MANT_DIG+2),d7 +#endif bge Laddsf$a$small +#ifndef __mcf5200__ cmpw IMM (16),d7 | if difference >= 16 swap +#else + cmpl IMM (16),d7 | if difference >= 16 swap +#endif bge 8f 6: +#ifndef __mcf5200__ subw IMM (1),d7 -7: lsrl IMM (1),d0 | shift right first operand +#else + subl IMM (1),d7 +#endif +7: +#ifndef __mcf5200__ + lsrl IMM (1),d0 | shift right first operand roxrl IMM (1),d1 dbra d7,7b +#else + lsrl IMM (1),d1 + btst IMM (0),d0 + beq 10f + bset IMM (31),d1 +10: lsrl IMM (1),d0 + subql IMM (1),d7 + bpl 7b +#endif bra Laddsf$3 8: movew d0,d1 swap d1 movew d1,d0 swap d0 +#ifndef __mcf5200__ subw IMM (16),d7 +#else + subl IMM (16),d7 +#endif bne 6b | if still more bits, go back to normal case | otherwise we fall through @@ -1896,15 +2551,30 @@ Laddsf$2: Laddsf$3: | Here we have to decide whether to add or subtract the numbers +#ifndef __mcf5200__ exg d6,a0 | get signs back exg d7,a1 | and save the exponents +#else + movel d6,d4 + movel a0,d6 + movel d4,d6 + movel d7,d4 + movel a1,d4 + movel d4,a1 +#endif eorl d6,d7 | combine sign bits bmi Lsubsf$0 | if negative a and b have opposite | sign so we actually subtract the | numbers | Here we have both positive or both negative +#ifndef __mcf5200__ exg d6,a0 | now we have the exponent in d6 +#else + movel d6,d4 + movel a0,d6 + movel d4,a0 +#endif movel a0,d7 | and sign in d7 andl IMM (0x80000000),d7 | Here we do the addition. @@ -1915,7 +2585,11 @@ Laddsf$3: | Put the exponent, in the first byte, in d2, to use the "standard" rounding | routines: movel d6,d2 +#ifndef __mcf5200__ lsrw IMM (8),d2 +#else + lsrl IMM (8),d2 +#endif | Before rounding normalize so bit #FLT_MANT_DIG is set (we will consider | the case of denormalized numbers in the rounding routine itself). @@ -1923,24 +2597,47 @@ Laddsf$3: | one more bit we check this: btst IMM (FLT_MANT_DIG+1),d0 beq 1f +#ifndef __mcf5200__ lsrl IMM (1),d0 roxrl IMM (1),d1 +#else + lsrl IMM (1),d1 + btst IMM (0),d0 + beq 10f + bset IMM (31),d1 +10: lsrl IMM (1),d0 +#endif addl IMM (1),d2 1: lea Laddsf$4,a0 | to return from rounding routine lea SYM (_fpCCR),a1 | check the rounding mode +#ifdef __mcf5200__ + clrl d6 +#endif movew a1@(6),d6 | rounding mode in d6 beq Lround$to$nearest +#ifndef __mcf5200__ cmpw IMM (ROUND_TO_PLUS),d6 +#else + cmpl IMM (ROUND_TO_PLUS),d6 +#endif bhi Lround$to$minus blt Lround$to$zero bra Lround$to$plus Laddsf$4: | Put back the exponent, but check for overflow. +#ifndef __mcf5200__ cmpw IMM (0xff),d2 +#else + cmpl IMM (0xff),d2 +#endif bhi 1f bclr IMM (FLT_MANT_DIG-1),d0 +#ifndef __mcf5200__ lslw IMM (7),d2 +#else + lsll IMM (7),d2 +#endif swap d2 orl d2,d0 bra Laddsf$ret @@ -1962,8 +2659,15 @@ Lsubsf$0: negl d1 negxl d0 1: +#ifndef __mcf5200__ exg d2,a0 | now we have the exponent in d2 lsrw IMM (8),d2 | put it in the first byte +#else + movel d2,d4 + movel a0,d2 + movel d4,a0 + lsrl IMM (8),d2 | put it in the first byte +#endif | Now d0-d1 is positive and the sign bit is in d7. @@ -1972,16 +2676,27 @@ Lsubsf$0: | the rounding routines themselves. lea Lsubsf$1,a0 | to return from rounding routine lea SYM (_fpCCR),a1 | check the rounding mode +#ifdef __mcf5200__ + clrl d6 +#endif movew a1@(6),d6 | rounding mode in d6 beq Lround$to$nearest +#ifndef __mcf5200__ cmpw IMM (ROUND_TO_PLUS),d6 +#else + cmpl IMM (ROUND_TO_PLUS),d6 +#endif bhi Lround$to$minus blt Lround$to$zero bra Lround$to$plus Lsubsf$1: | Put back the exponent (we can't have overflow!). ' bclr IMM (FLT_MANT_DIG-1),d0 +#ifndef __mcf5200__ lslw IMM (7),d2 +#else + lsll IMM (7),d2 +#endif swap d2 orl d2,d0 bra Laddsf$ret @@ -2144,17 +2859,30 @@ SYM (__mulsf3): andl d5,d0 | and isolate fraction orl d4,d0 | and put hidden bit back swap d2 | I like exponents in the first byte +#ifndef __mcf5200__ lsrw IMM (7),d2 | +#else + lsrl IMM (7),d2 | +#endif Lmulsf$1: | number andl d6,d3 | beq Lmulsf$b$den | andl d5,d1 | orl d4,d1 | swap d3 | +#ifndef __mcf5200__ lsrw IMM (7),d3 | +#else + lsrl IMM (7),d3 | +#endif Lmulsf$2: | +#ifndef __mcf5200__ addw d3,d2 | add exponents subw IMM (F_BIAS+1),d2 | and subtract bias (plus one) +#else + addl d3,d2 | add exponents + subl IMM (F_BIAS+1),d2 | and subtract bias (plus one) +#endif | We are now ready to do the multiplication. The situation is as follows: | both a and b have bit FLT_MANT_DIG-1 set (even if they were @@ -2180,28 +2908,58 @@ Lmulsf$2: | bcc 2f | if not set skip sum addl d5,d1 | add a addxl d4,d0 -2: dbf d3,1b | loop back +2: +#ifndef __mcf5200__ + dbf d3,1b | loop back +#else + subql IMM (1),d3 + bpl 1b +#endif | Now we have the product in d0-d1, with bit (FLT_MANT_DIG - 1) + FLT_MANT_DIG | (mod 32) of d0 set. The first thing to do now is to normalize it so bit | FLT_MANT_DIG is set (to do the rounding). +#ifndef __mcf5200__ rorl IMM (6),d1 swap d1 movew d1,d3 andw IMM (0x03ff),d3 andw IMM (0xfd00),d1 +#else + movel d1,d3 + lsll IMM (8),d1 + addl d1,d1 + addl d1,d1 + moveq IMM (22),d5 + lsrl d5,d3 + orl d3,d1 + andl IMM (0xfffffd00),d1 +#endif lsll IMM (8),d0 addl d0,d0 addl d0,d0 +#ifndef __mcf5200__ orw d3,d0 +#else + orl d3,d0 +#endif movew IMM (MULTIPLY),d5 btst IMM (FLT_MANT_DIG+1),d0 beq Lround$exit +#ifndef __mcf5200__ lsrl IMM (1),d0 roxrl IMM (1),d1 addw IMM (1),d2 +#else + lsrl IMM (1),d1 + btst IMM (0),d0 + beq 10f + bset IMM (31),d1 +10: lsrl IMM (1),d0 + addql IMM (1),d2 +#endif bra Lround$exit Lmulsf$inop: @@ -2246,7 +3004,11 @@ Lmulsf$a$den: movel IMM (1),d2 andl d5,d0 1: addl d0,d0 | shift a left (until bit 23 is set) +#ifndef __mcf5200__ subw IMM (1),d2 | and adjust exponent +#else + subql IMM (1),d2 | and adjust exponent +#endif btst IMM (FLT_MANT_DIG-1),d0 bne Lmulsf$1 | bra 1b | else loop back @@ -2255,7 +3017,11 @@ Lmulsf$b$den: movel IMM (1),d3 andl d5,d1 1: addl d1,d1 | shift b left until bit 23 is set +#ifndef __mcf5200__ subw IMM (1),d3 | and adjust exponent +#else + subl IMM (1),d3 | and adjust exponent +#endif btst IMM (FLT_MANT_DIG-1),d1 bne Lmulsf$2 | bra 1b | else loop back @@ -2298,17 +3064,30 @@ SYM (__divsf3): andl d5,d0 | and isolate fraction orl d4,d0 | and put hidden bit back swap d2 | I like exponents in the first byte +#ifndef __mcf5200__ lsrw IMM (7),d2 | +#else + lsrl IMM (7),d2 | +#endif Ldivsf$1: | andl d6,d3 | beq Ldivsf$b$den | andl d5,d1 | orl d4,d1 | swap d3 | +#ifndef __mcf5200__ lsrw IMM (7),d3 | +#else + lsrl IMM (7),d3 | +#endif Ldivsf$2: | +#ifndef __mcf5200__ subw d3,d2 | subtract exponents addw IMM (F_BIAS),d2 | and add bias +#else + subl d3,d2 | subtract exponents + addl IMM (F_BIAS),d2 | and add bias +#endif | We are now ready to do the division. We have prepared things in such a way | that the ratio of the fractions will be less than 2 but greater than 1/2. @@ -2329,19 +3108,34 @@ Ldivsf$2: | subl d1,d0 | if a >= b a <-- a-b beq 3f | if a is zero, exit 2: addl d0,d0 | multiply a by 2 +#ifndef __mcf5200__ dbra d3,1b +#else + subql IMM (1),d3 + bpl 1b +#endif | Now we keep going to set the sticky bit ... movew IMM (FLT_MANT_DIG),d3 1: cmpl d0,d1 ble 2f addl d0,d0 +#ifndef __mcf5200__ dbra d3,1b +#else + subql IMM(1),d3 + bpl 1b +#endif movel IMM (0),d1 bra 3f 2: movel IMM (0),d1 +#ifndef __mcf5200__ subw IMM (FLT_MANT_DIG),d3 addw IMM (31),d3 +#else + subl IMM (FLT_MANT_DIG),d3 + addl IMM (31),d3 +#endif bset d3,d1 3: movel d6,d0 | put the ratio in d0-d1 @@ -2353,7 +3147,11 @@ Ldivsf$2: | btst IMM (FLT_MANT_DIG+1),d0 beq 1f | if it is not set, then bit 24 is set lsrl IMM (1),d0 | +#ifndef __mcf5200__ addw IMM (1),d2 | +#else + addl IMM (1),d2 | +#endif 1: | Now round, check for over- and underflow, and exit. movew IMM (DIVIDE),d5 @@ -2409,7 +3207,11 @@ Ldivsf$a$den: movel IMM (1),d2 andl d5,d0 1: addl d0,d0 | shift a left until bit FLT_MANT_DIG-1 is set +#ifndef __mcf5200__ subw IMM (1),d2 | and adjust exponent +#else + subl IMM (1),d2 | and adjust exponent +#endif btst IMM (FLT_MANT_DIG-1),d0 bne Ldivsf$1 bra 1b @@ -2418,7 +3220,11 @@ Ldivsf$b$den: movel IMM (1),d3 andl d5,d1 1: addl d1,d1 | shift b left until bit FLT_MANT_DIG is set +#ifndef __mcf5200__ subw IMM (1),d3 | and adjust exponent +#else + subl IMM (1),d3 | and adjust exponent +#endif btst IMM (FLT_MANT_DIG-1),d1 bne Ldivsf$2 bra 1b @@ -2427,20 +3233,43 @@ Lround$exit: | This is a common exit point for __mulsf3 and __divsf3. | First check for underlow in the exponent: +#ifndef __mcf5200__ cmpw IMM (-FLT_MANT_DIG-1),d2 +#else + cmpl IMM (-FLT_MANT_DIG-1),d2 +#endif blt Lf$underflow | It could happen that the exponent is less than 1, in which case the | number is denormalized. In this case we shift right and adjust the | exponent until it becomes 1 or the fraction is zero (in the latter case | we signal underflow and return zero). movel IMM (0),d6 | d6 is used temporarily +#ifndef __mcf5200__ cmpw IMM (1),d2 | if the exponent is less than 1 we +#else + cmpl IMM (1),d2 | if the exponent is less than 1 we +#endif bge 2f | have to shift right (denormalize) -1: addw IMM (1),d2 | adjust the exponent +1: +#ifndef __mcf5200__ + addw IMM (1),d2 | adjust the exponent lsrl IMM (1),d0 | shift right once roxrl IMM (1),d1 | roxrl IMM (1),d6 | d6 collect bits we would lose otherwise cmpw IMM (1),d2 | is the exponent 1 already? +#else + addql IMM (1),d2 | adjust the exponent + lsrl IMM (1),d6 + btst IMM (0),d1 + beq 11f + bset IMM (31),d6 +11: lsrl IMM (1),d1 + btst IMM (0),d0 + beq 10f + bset IMM (31),d1 +10: lsrl IMM (1),d0 + cmpl IMM (1),d2 | is the exponent 1 already? +#endif beq 2f | if not loop back bra 1b | bra Lf$underflow | safety check, shouldn't execute ' @@ -2449,9 +3278,16 @@ Lround$exit: | Now call the rounding routine (which takes care of denormalized numbers): lea Lround$0,a0 | to return from rounding routine lea SYM (_fpCCR),a1 | check the rounding mode +#ifdef __mcf5200__ + clrl d6 +#endif movew a1@(6),d6 | rounding mode in d6 beq Lround$to$nearest +#ifndef __mcf5200__ cmpw IMM (ROUND_TO_PLUS),d6 +#else + cmpl IMM (ROUND_TO_PLUS),d6 +#endif bhi Lround$to$minus blt Lround$to$zero bra Lround$to$plus @@ -2463,17 +3299,29 @@ Lround$0: | check again for underflow!). We have to check for overflow or for a | denormalized number (which also signals underflow). | Check for overflow (i.e., exponent >= 255). +#ifndef __mcf5200__ cmpw IMM (0x00ff),d2 +#else + cmpl IMM (0x00ff),d2 +#endif bge Lf$overflow | Now check for a denormalized number (exponent==0). movew d2,d2 beq Lf$den 1: | Put back the exponents and sign and return. +#ifndef __mcf5200__ lslw IMM (7),d2 | exponent back to fourth byte +#else + lsll IMM (7),d2 | exponent back to fourth byte +#endif bclr IMM (FLT_MANT_DIG-1),d0 swap d0 | and put back exponent +#ifndef __mcf5200__ orw d2,d0 | +#else + orl d2,d0 +#endif swap d0 | orl d7,d0 | and sign also @@ -2557,7 +3405,13 @@ Lcmpsf$2: tstl d6 bpl 1f | If both are negative exchange them +#ifndef __mcf5200__ exg d0,d1 +#else + movel d0,d7 + movel d1,d0 + movel d7,d1 +#endif 1: | Now that they are positive we just compare them as longs (does this also | work for denormalized numbers?). @@ -2608,11 +3462,20 @@ Lround$to$nearest: | Normalize shifting left until bit #FLT_MANT_DIG is set or the exponent | is one (remember that a denormalized number corresponds to an | exponent of -F_BIAS+1). +#ifndef __mcf5200__ cmpw IMM (1),d2 | remember that the exponent is at least one +#else + cmpl IMM (1),d2 | remember that the exponent is at least one +#endif beq 2f | an exponent of one means denormalized addl d1,d1 | else shift and adjust the exponent addxl d0,d0 | +#ifndef __mcf5200__ dbra d2,1b | +#else + subql IMM (1),d2 + bpl 1b +#endif 2: | Now round: we do it as follows: after the shifting we can write the | fraction part as f + delta, where 1 < f < 2^25, and 0 <= delta <= 2. @@ -2636,7 +3499,11 @@ Lround$to$nearest: btst IMM (FLT_MANT_DIG),d0 beq 1f lsrl IMM (1),d0 +#ifndef __mcf5200__ addw IMM (1),d2 +#else + addql IMM (1),d2 +#endif 1: | If bit #FLT_MANT_DIG-1 is clear we have a denormalized number, so we | have to put the exponent to zero and return a denormalized number.