X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=gcc%2Fconfig%2Fm68k%2Flb1sf68.asm;fp=gcc%2Fconfig%2Fm68k%2Flb1sf68.asm;h=4bafbfb188b1a5023c80aa259bb95dad489ed24e;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=7bcee2eabe489e72166e1bcadf4ff8a719672d53;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/gcc/config/m68k/lb1sf68.asm b/gcc/config/m68k/lb1sf68.asm index 7bcee2ea..4bafbfb1 100644 --- a/gcc/config/m68k/lb1sf68.asm +++ b/gcc/config/m68k/lb1sf68.asm @@ -1,36 +1,26 @@ /* libgcc routines for 68000 w/o floating-point hardware. - Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1994, 1996, 1997, 1998, 2008, 2009 Free Software Foundation, Inc. -This file is part of GNU CC. +This file is part of GCC. -GNU CC is free software; you can redistribute it and/or modify it +GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any +Free Software Foundation; either version 3, or (at your option) any later version. -In addition to the permissions in the GNU General Public License, the -Free Software Foundation gives you unlimited permission to link the -compiled version of this file with other programs, and to distribute -those programs without any restriction coming from the use of this -file. (The General Public License restrictions do apply in other -respects; for example, they cover modification of the file, and -distribution when not linked into another program.) - This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. -/* As a special exception, if you link this library with files - compiled with GCC to produce an executable, this does not cause - the resulting executable to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ /* Use this one for any 680x0; assumes no floating point hardware. The trailing " '" appearing on some lines is for ANSI preprocessors. Yuk. @@ -61,6 +51,18 @@ Boston, MA 02111-1307, USA. */ #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) +/* Note that X is a function. */ + +#ifdef __ELF__ +#define FUNC(x) .type SYM(x),function +#else +/* The .proc pseudo-op is accepted, but ignored, by GAS. We could just + define this to the empty string for non-ELF systems, but defining it + to .proc means that the information is available to the assembler if + the need arises. */ +#define FUNC(x) .proc +#endif + /* Use the right prefix for registers. */ #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) @@ -86,6 +88,140 @@ Boston, MA 02111-1307, USA. */ #define a6 REG (a6) #define fp REG (fp) #define sp REG (sp) +#define pc REG (pc) + +/* Provide a few macros to allow for PIC code support. + * With PIC, data is stored A5 relative so we've got to take a bit of special + * care to ensure that all loads of global data is via A5. PIC also requires + * jumps and subroutine calls to be PC relative rather than absolute. We cheat + * a little on this and in the PIC case, we use short offset branches and + * hope that the final object code is within range (which it should be). + */ +#ifndef __PIC__ + + /* Non PIC (absolute/relocatable) versions */ + + .macro PICCALL addr + jbsr \addr + .endm + + .macro PICJUMP addr + jmp \addr + .endm + + .macro PICLEA sym, reg + lea \sym, \reg + .endm + + .macro PICPEA sym, areg + pea \sym + .endm + +#else /* __PIC__ */ + +# if defined (__uClinux__) + + /* Versions for uClinux */ + +# if defined(__ID_SHARED_LIBRARY__) + + /* -mid-shared-library versions */ + + .macro PICLEA sym, reg + movel a5@(_current_shared_library_a5_offset_), \reg + movel \sym@GOT(\reg), \reg + .endm + + .macro PICPEA sym, areg + movel a5@(_current_shared_library_a5_offset_), \areg + movel \sym@GOT(\areg), sp@- + .endm + + .macro PICCALL addr + PICLEA \addr,a0 + jsr a0@ + .endm + + .macro PICJUMP addr + PICLEA \addr,a0 + jmp a0@ + .endm + +# else /* !__ID_SHARED_LIBRARY__ */ + + /* Versions for -msep-data */ + + .macro PICLEA sym, reg + movel \sym@GOT(a5), \reg + .endm + + .macro PICPEA sym, areg + movel \sym@GOT(a5), sp@- + .endm + + .macro PICCALL addr +#if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__) + lea \addr-.-8,a0 + jsr pc@(a0) +#else + bsr \addr +#endif + .endm + + .macro PICJUMP addr + /* ISA C has no bra.l instruction, and since this assembly file + gets assembled into multiple object files, we avoid the + bra instruction entirely. */ +#if defined (__mcoldfire__) && !defined (__mcfisab__) + lea \addr-.-8,a0 + jmp pc@(a0) +#else + bra \addr +#endif + .endm + +# endif + +# else /* !__uClinux__ */ + + /* Versions for Linux */ + + .macro PICLEA sym, reg + movel #_GLOBAL_OFFSET_TABLE_@GOTPC, \reg + lea (-6, pc, \reg), \reg + movel \sym@GOT(\reg), \reg + .endm + + .macro PICPEA sym, areg + movel #_GLOBAL_OFFSET_TABLE_@GOTPC, \areg + lea (-6, pc, \areg), \areg + movel \sym@GOT(\areg), sp@- + .endm + + .macro PICCALL addr +#if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__) + lea \addr-.-8,a0 + jsr pc@(a0) +#else + bsr \addr +#endif + .endm + + .macro PICJUMP addr + /* ISA C has no bra.l instruction, and since this assembly file + gets assembled into multiple object files, we avoid the + bra instruction entirely. */ +#if defined (__mcoldfire__) && !defined (__mcfisab__) + lea \addr-.-8,a0 + jmp pc@(a0) +#else + bra \addr +#endif + .endm + +# endif +#endif /* __PIC__ */ + #ifdef L_floatex @@ -213,8 +349,8 @@ TRUNCDFSF = 7 | void __clear_sticky_bits(void); SYM (__clear_sticky_bit): - lea SYM (_fpCCR),a0 -#ifndef __mcf5200__ + PICLEA SYM (_fpCCR),a0 +#ifndef __mcoldfire__ movew IMM (0),a0@(STICK) #else clr.w a0@(STICK) @@ -246,9 +382,9 @@ SYM (__clear_sticky_bit): FPTRAP = 15 $_exception_handler: - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew d7,a0@(EBITS) | set __exception_bits -#ifndef __mcf5200__ +#ifndef __mcoldfire__ orw d7,a0@(STICK) | and __sticky_bits #else movew a0@(STICK),d4 @@ -259,7 +395,7 @@ $_exception_handler: movew d5,a0@(LASTO) | and __last_operation | Now put the operands in place: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (SINGLE_FLOAT),d6 #else cmpl IMM (SINGLE_FLOAT),d6 @@ -274,7 +410,7 @@ $_exception_handler: movel a6@(12),a0@(OPER2) 2: | And check whether the exception is trap-enabled: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ andw a0@(TRAPE),d7 | is exception trap-enabled? #else clrl d6 @@ -282,9 +418,9 @@ $_exception_handler: andl d6,d7 #endif beq 1f | no, exit - pea SYM (_fpCCR) | yes, push address of _fpCCR + PICPEA SYM (_fpCCR),a1 | yes, push address of _fpCCR trap IMM (FPTRAP) | and trap -#ifndef __mcf5200__ +#ifndef __mcoldfire__ 1: moveml sp@+,d2-d7 | restore data registers #else 1: moveml sp@,d2-d7 @@ -297,14 +433,14 @@ $_exception_handler: #ifdef L_mulsi3 .text - .proc + FUNC(__mulsi3) .globl SYM (__mulsi3) SYM (__mulsi3): movew sp@(4), d0 /* x0 -> d0 */ muluw sp@(10), d0 /* x0*y1 */ movew sp@(6), d1 /* x1 -> d1 */ muluw sp@(8), d1 /* x1*y0 */ -#ifndef __mcf5200__ +#ifndef __mcoldfire__ addw d1, d0 #else addl d1, d0 @@ -320,10 +456,10 @@ SYM (__mulsi3): #ifdef L_udivsi3 .text - .proc + FUNC(__udivsi3) .globl SYM (__udivsi3) SYM (__udivsi3): -#ifndef __mcf5200__ +#ifndef __mcoldfire__ movel d2, sp@- movel sp@(12), d1 /* d1 = divisor */ movel sp@(8), d0 /* d0 = dividend */ @@ -346,11 +482,11 @@ L4: lsrl IMM (1), d1 /* shift divisor */ lsrl IMM (1), d0 /* shift dividend */ cmpl IMM (0x10000), d1 /* still divisor >= 2 ^ 16 ? */ jcc L4 - divu d1, d0 /* now we have 16 bit divisor */ + divu d1, d0 /* now we have 16-bit divisor */ andl IMM (0xffff), d0 /* mask out divisor, ignore remainder */ -/* Multiply the 16 bit tentative quotient with the 32 bit divisor. Because of - the operand ranges, this might give a 33 bit product. If this product is +/* Multiply the 16-bit tentative quotient with the 32-bit divisor. Because of + the operand ranges, this might give a 33-bit product. If this product is greater than the dividend, the tentative quotient was too large. */ movel d2, d1 mulu d0, d1 /* low part, 32 bits */ @@ -368,9 +504,9 @@ L5: subql IMM (1), d0 /* adjust quotient */ L6: movel sp@+, d2 rts -#else /* __mcf5200__ */ +#else /* __mcoldfire__ */ -/* Coldfire implementation of non-restoring division algorithm from +/* ColdFire implementation of non-restoring division algorithm from Hennessy & Patterson, Appendix A. */ link a6,IMM (-12) moveml d2-d4,sp@ @@ -390,13 +526,13 @@ L2: subql IMM (1),d4 moveml sp@,d2-d4 | restore data registers unlk a6 | and return rts -#endif /* __mcf5200__ */ +#endif /* __mcoldfire__ */ #endif /* L_udivsi3 */ #ifdef L_divsi3 .text - .proc + FUNC(__divsi3) .globl SYM (__divsi3) SYM (__divsi3): movel d2, sp@- @@ -405,7 +541,7 @@ SYM (__divsi3): movel sp@(12), d1 /* d1 = divisor */ jpl L1 negl d1 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ negb d2 /* change sign because divisor <0 */ #else negl d2 /* change sign because divisor <0 */ @@ -413,7 +549,7 @@ SYM (__divsi3): L1: movel sp@(8), d0 /* d0 = dividend */ jpl L2 negl d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ negb d2 #else negl d2 @@ -421,7 +557,7 @@ L1: movel sp@(8), d0 /* d0 = dividend */ L2: movel d1, sp@- movel d0, sp@- - jbsr SYM (__udivsi3) /* divide abs(dividend) by abs(divisor) */ + PICCALL SYM (__udivsi3) /* divide abs(dividend) by abs(divisor) */ addql IMM (8), sp tstb d2 @@ -434,20 +570,20 @@ L3: movel sp@+, d2 #ifdef L_umodsi3 .text - .proc + FUNC(__umodsi3) .globl SYM (__umodsi3) SYM (__umodsi3): movel sp@(8), d1 /* d1 = divisor */ movel sp@(4), d0 /* d0 = dividend */ movel d1, sp@- movel d0, sp@- - jbsr SYM (__udivsi3) + PICCALL SYM (__udivsi3) addql IMM (8), sp movel sp@(8), d1 /* d1 = divisor */ -#ifndef __mcf5200__ +#ifndef __mcoldfire__ movel d1, sp@- movel d0, sp@- - jbsr SYM (__mulsi3) /* d0 = (a/b)*b */ + PICCALL SYM (__mulsi3) /* d0 = (a/b)*b */ addql IMM (8), sp #else mulsl d1,d0 @@ -460,20 +596,20 @@ SYM (__umodsi3): #ifdef L_modsi3 .text - .proc + FUNC(__modsi3) .globl SYM (__modsi3) SYM (__modsi3): movel sp@(8), d1 /* d1 = divisor */ movel sp@(4), d0 /* d0 = dividend */ movel d1, sp@- movel d0, sp@- - jbsr SYM (__divsi3) + PICCALL SYM (__divsi3) addql IMM (8), sp movel sp@(8), d1 /* d1 = divisor */ -#ifndef __mcf5200__ +#ifndef __mcoldfire__ movel d1, sp@- movel d0, sp@- - jbsr SYM (__mulsi3) /* d0 = (a/b)*b */ + PICCALL SYM (__mulsi3) /* d0 = (a/b)*b */ addql IMM (8), sp #else mulsl d1,d0 @@ -529,6 +665,8 @@ ROUND_TO_MINUS = 3 | round result towards minus infinity .globl SYM (__divdf3) .globl SYM (__negdf2) .globl SYM (__cmpdf2) + .globl SYM (__cmpdf2_internal) + .hidden SYM (__cmpdf2_internal) .text .even @@ -540,7 +678,7 @@ Ld$den: orl d7,d0 movew IMM (INEXACT_RESULT+UNDERFLOW),d7 moveq IMM (DOUBLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Ld$infty: Ld$overflow: @@ -550,7 +688,7 @@ Ld$overflow: orl d7,d0 movew IMM (INEXACT_RESULT+OVERFLOW),d7 moveq IMM (DOUBLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Ld$underflow: | Return 0 and set the exception flags @@ -558,7 +696,7 @@ Ld$underflow: movel d0,d1 movew IMM (INEXACT_RESULT+UNDERFLOW),d7 moveq IMM (DOUBLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Ld$inop: | Return a quiet NaN and set the exception flags @@ -566,7 +704,7 @@ Ld$inop: movel d0,d1 movew IMM (INEXACT_RESULT+INVALID_OPERATION),d7 moveq IMM (DOUBLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Ld$div$0: | Return a properly signed INFINITY and set the exception flags @@ -575,7 +713,7 @@ Ld$div$0: orl d7,d0 movew IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7 moveq IMM (DOUBLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler |============================================================================= |============================================================================= @@ -602,6 +740,7 @@ Ld$div$0: |============================================================================= | double __subdf3(double, double); + FUNC(__subdf3) SYM (__subdf3): bchg IMM (31),sp@(12) | change sign of second operand | and fall through, so we always add @@ -610,8 +749,9 @@ SYM (__subdf3): |============================================================================= | double __adddf3(double, double); + FUNC(__adddf3) SYM (__adddf3): -#ifndef __mcf5200__ +#ifndef __mcoldfire__ link a6,IMM (0) | everything will be done in registers moveml d2-d7,sp@- | save all data registers and a2 (but d0-d1) #else @@ -635,7 +775,7 @@ SYM (__adddf3): andl IMM (0x80000000),d7 | isolate a's sign bit ' swap d6 | and also b's sign bit ' -#ifndef __mcf5200__ +#ifndef __mcoldfire__ 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 ' @@ -662,7 +802,7 @@ SYM (__adddf3): orl d7,d0 | and put hidden bit back Ladddf$1: swap d4 | shift right exponent so that it starts -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrw IMM (5),d4 | in bit 0 and not bit 20 #else lsrl IMM (5),d4 | in bit 0 and not bit 20 @@ -678,7 +818,7 @@ Ladddf$1: orl d7,d2 | and put hidden bit back Ladddf$2: swap d5 | shift right exponent so that it starts -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrw IMM (5),d5 | in bit 0 and not bit 20 #else lsrl IMM (5),d5 | in bit 0 and not bit 20 @@ -693,7 +833,7 @@ Ladddf$2: | and d4-d5-d6-d7 for the second. To do this we store (temporarily) the | exponents in a2-a3. -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml a2-a3,sp@- | save the address registers #else movel a2,sp@- @@ -713,7 +853,7 @@ Ladddf$2: | Here we shift the numbers until the exponents are the same, and put | the largest exponent in a2. -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d4,a2 | get exponents back exg d5,a3 | cmpw d4,d5 | compare the exponents @@ -732,7 +872,7 @@ Ladddf$2: | 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__ +#ifndef __mcoldfire__ subw d5,d2 | and subtract second exponent exg d4,a2 | get back the longs we saved exg d5,a3 | @@ -746,20 +886,20 @@ Ladddf$2: movel a4,a3 #endif | if difference is too large we don't shift (actually, we can just exit) ' -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (DBL_MANT_DIG+2),d2 #else cmpl IMM (DBL_MANT_DIG+2),d2 #endif bge Ladddf$b$small -#ifndef __mcf5200__ +#ifndef __mcoldfire__ 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: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (16),d2 | if difference >= 16, shift by words #else cmpl IMM (16),d2 | if difference >= 16, shift by words @@ -768,7 +908,7 @@ Ladddf$2: bra 3f | enter dbra loop 4: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrl IMM (1),d4 roxrl IMM (1),d5 roxrl IMM (1),d6 @@ -789,7 +929,7 @@ Ladddf$2: 12: lsrl IMM (1),d4 #endif 3: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ dbra d2,4b #else subql IMM (1),d2 @@ -803,7 +943,7 @@ Ladddf$2: movel d5,d6 movel d4,d5 movel IMM (0),d4 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (32),d2 #else subl IMM (32),d2 @@ -818,7 +958,7 @@ Ladddf$2: swap d5 movew IMM (0),d4 swap d4 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (16),d2 #else subl IMM (16),d2 @@ -826,7 +966,7 @@ Ladddf$2: bra 3b 9: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d4,d5 movew d4,d6 subw d5,d6 | keep d5 (largest exponent) in d4 @@ -845,20 +985,20 @@ Ladddf$2: movel a4,a3 #endif | if difference is too large we don't shift (actually, we can just exit) ' -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (DBL_MANT_DIG+2),d6 #else cmpl IMM (DBL_MANT_DIG+2),d6 #endif bge Ladddf$a$small -#ifndef __mcf5200__ +#ifndef __mcoldfire__ 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: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (16),d6 | if difference >= 16, shift by words #else cmpl IMM (16),d6 | if difference >= 16, shift by words @@ -867,7 +1007,7 @@ Ladddf$2: bra 3f | enter dbra loop 4: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrl IMM (1),d0 roxrl IMM (1),d1 roxrl IMM (1),d2 @@ -888,7 +1028,7 @@ Ladddf$2: 12: lsrl IMM (1),d0 #endif 3: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ dbra d6,4b #else subql IMM (1),d6 @@ -902,7 +1042,7 @@ Ladddf$2: movel d1,d2 movel d0,d1 movel IMM (0),d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (32),d6 #else subl IMM (32),d6 @@ -917,14 +1057,14 @@ Ladddf$2: swap d1 movew IMM (0),d0 swap d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (16),d6 #else subl IMM (16),d6 #endif bra 3b Ladddf$3: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d4,a2 exg d5,a3 #else @@ -940,7 +1080,7 @@ Ladddf$4: | the signs in a4. | Here we have to decide whether to add or subtract the numbers: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d7,a0 | get the signs exg d6,a3 | a3 is free to be used #else @@ -958,7 +1098,7 @@ Ladddf$4: eorl d7,d6 | compare the signs bmi Lsubdf$0 | if the signs are different we have | to subtract -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d7,a0 | else we add the numbers exg d6,a3 | #else @@ -978,7 +1118,7 @@ Ladddf$4: movel a0,d7 | andl IMM (0x80000000),d7 | d7 now has the sign -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,a2-a3 #else movel sp@+,a4 @@ -992,7 +1132,7 @@ Ladddf$4: | one more bit we check this: btst IMM (DBL_MANT_DIG+1),d0 beq 1f -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrl IMM (1),d0 roxrl IMM (1),d1 roxrl IMM (1),d2 @@ -1015,14 +1155,14 @@ Ladddf$4: 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__ + lea pc@(Ladddf$5),a0 | to return from rounding routine + PICLEA SYM (_fpCCR),a1 | check the rounding mode +#ifdef __mcoldfire__ clrl d6 #endif movew a1@(6),d6 | rounding mode in d6 beq Lround$to$nearest -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (ROUND_TO_PLUS),d6 #else cmpl IMM (ROUND_TO_PLUS),d6 @@ -1032,20 +1172,20 @@ Ladddf$4: bra Lround$to$plus Ladddf$5: | Put back the exponent and check for overflow -#ifndef __mcf5200__ +#ifndef __mcoldfire__ 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__ +#ifndef __mcoldfire__ lslw IMM (4),d4 | put exponent back into position #else lsll IMM (4),d4 | put exponent back into position #endif swap d0 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ orw d4,d0 | #else orl d4,d0 | @@ -1053,12 +1193,12 @@ Ladddf$5: swap d0 | bra Ladddf$ret 1: - movew IMM (ADD),d5 + moveq IMM (ADD),d5 bra Ld$overflow Lsubdf$0: | Here we do the subtraction. -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d7,a0 | put sign back in a0 exg d6,a3 | #else @@ -1086,7 +1226,7 @@ Lsubdf$0: movel a2,d4 | return exponent to d4 movel a0,d7 andl IMM (0x80000000),d7 | isolate sign bit -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,a2-a3 | #else movel sp@+,a4 @@ -1100,7 +1240,7 @@ Lsubdf$0: | one more bit we check this: btst IMM (DBL_MANT_DIG+1),d0 beq 1f -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrl IMM (1),d0 roxrl IMM (1),d1 roxrl IMM (1),d2 @@ -1123,14 +1263,14 @@ Lsubdf$0: 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__ + lea pc@(Lsubdf$1),a0 | to return from rounding routine + PICLEA SYM (_fpCCR),a1 | check the rounding mode +#ifdef __mcoldfire__ clrl d6 #endif movew a1@(6),d6 | rounding mode in d6 beq Lround$to$nearest -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (ROUND_TO_PLUS),d6 #else cmpl IMM (ROUND_TO_PLUS),d6 @@ -1141,13 +1281,13 @@ Lsubdf$0: Lsubdf$1: | Put back the exponent and sign (we don't have overflow). ' bclr IMM (DBL_MANT_DIG-1),d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lslw IMM (4),d4 | put exponent back into position #else lsll IMM (4),d4 | put exponent back into position #endif swap d0 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ orw d4,d0 | #else orl d4,d0 | @@ -1159,7 +1299,7 @@ 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__ +#ifndef __mcoldfire__ moveml sp@+,a2-a3 #else movel sp@+,a4 @@ -1168,9 +1308,9 @@ Ladddf$a$small: #endif movel a6@(16),d0 movel a6@(20),d1 - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 | restore data registers #else moveml sp@,d2-d7 @@ -1181,7 +1321,7 @@ Ladddf$a$small: rts Ladddf$b$small: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,a2-a3 #else movel sp@+,a4 @@ -1190,9 +1330,9 @@ Ladddf$b$small: #endif movel a6@(8),d0 movel a6@(12),d1 - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 | restore data registers #else moveml sp@,d2-d7 @@ -1215,12 +1355,17 @@ Ladddf$b: | Return b (if a is zero) movel d2,d0 movel d3,d1 - bra 1f + bne 1f | Check if b is -0 + cmpl IMM (0x80000000),d0 + bne 1f + andl IMM (0x80000000),d7 | Use the sign of a + clrl d0 + bra Ladddf$ret Ladddf$a: movel a6@(8),d0 movel a6@(12),d1 1: - movew IMM (ADD),d5 + moveq IMM (ADD),d5 | Check for NaN and +/-INFINITY. movel d0,d7 | andl IMM (0x80000000),d7 | @@ -1238,7 +1383,7 @@ Ladddf$a: bra Ld$infty | Ladddf$ret$1: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,a2-a3 | restore regs and exit #else movel sp@+,a4 @@ -1248,10 +1393,10 @@ Ladddf$ret$1: Ladddf$ret: | Normal exit. - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ orl d7,d0 | put sign bit back -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 #else moveml sp@,d2-d7 @@ -1263,7 +1408,7 @@ Ladddf$ret: Ladddf$ret$den: | Return a denormalized number. -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrl IMM (1),d0 | shift right once more roxrl IMM (1),d1 | #else @@ -1276,7 +1421,7 @@ Ladddf$ret$den: bra Ladddf$ret Ladddf$nf: - movew IMM (ADD),d5 + moveq IMM (ADD),d5 | This could be faster but it is not worth the effort, since it is not | executed very often. We sacrifice speed for clarity here. movel a6@(8),d0 | get the numbers back (remember that we @@ -1328,8 +1473,9 @@ Ladddf$nf: |============================================================================= | double __muldf3(double, double); + FUNC(__muldf3) SYM (__muldf3): -#ifndef __mcf5200__ +#ifndef __mcoldfire__ link a6,IMM (0) moveml d2-d7,sp@- #else @@ -1370,7 +1516,7 @@ 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__ +#ifndef __mcoldfire__ lsrw IMM (4),d4 | #else lsrl IMM (4),d4 | @@ -1381,13 +1527,13 @@ Lmuldf$1: andl d6,d2 | orl IMM (0x00100000),d2 | and put hidden bit back swap d5 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrw IMM (4),d5 | #else lsrl IMM (4),d5 | #endif Lmuldf$2: | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ addw d5,d4 | add exponents subw IMM (D_BIAS+1),d4 | and subtract bias (plus one) #else @@ -1405,7 +1551,7 @@ Lmuldf$2: | | enough to keep everything in them. So we use the address registers to keep | some intermediate data. -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml a2-a3,sp@- | save a2 and a3 for temporary use #else movel a2,sp@- @@ -1416,7 +1562,7 @@ Lmuldf$2: | movel d4,a3 | and a3 will preserve the exponent | First, shift d2-d3 so bit 20 becomes bit 31: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ rorl IMM (5),d2 | rotate d2 5 places right swap d2 | and swap it rorl IMM (5),d3 | do the same thing with d3 @@ -1447,7 +1593,7 @@ Lmuldf$2: | | We use a1 as counter: movel IMM (DBL_MANT_DIG-1),a1 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d7,a1 #else movel d7,a4 @@ -1456,7 +1602,7 @@ Lmuldf$2: | #endif 1: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d7,a1 | put counter back in a1 #else movel d7,a4 @@ -1470,7 +1616,7 @@ Lmuldf$2: | addl d7,d7 | addxl d6,d6 | bcc 2f | if bit clear skip the following -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d7,a2 | #else movel d7,a4 @@ -1481,7 +1627,7 @@ Lmuldf$2: | addxl d4,d2 | addxl d7,d1 | addxl d7,d0 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d7,a2 | #else movel d7,a4 @@ -1489,7 +1635,7 @@ Lmuldf$2: | movel a4,a2 #endif 2: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d7,a1 | put counter in d7 dbf d7,1b | decrement and branch #else @@ -1501,7 +1647,7 @@ Lmuldf$2: | #endif movel a3,d4 | restore exponent -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,a2-a3 #else movel sp@+,a4 @@ -1520,7 +1666,7 @@ Lmuldf$2: | swap d3 movew d3,d2 movew IMM (0),d3 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrl IMM (1),d0 roxrl IMM (1),d1 roxrl IMM (1),d2 @@ -1552,11 +1698,11 @@ Lmuldf$2: | | Now round, check for over- and underflow, and exit. movel a0,d7 | get sign bit back into d7 - movew IMM (MULTIPLY),d5 + moveq IMM (MULTIPLY),d5 btst IMM (DBL_MANT_DIG+1-32),d0 beq Lround$exit -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrl IMM (1),d0 roxrl IMM (1),d1 addw IMM (1),d4 @@ -1571,18 +1717,18 @@ Lmuldf$2: | bra Lround$exit Lmuldf$inop: - movew IMM (MULTIPLY),d5 + moveq IMM (MULTIPLY),d5 bra Ld$inop Lmuldf$b$nf: - movew IMM (MULTIPLY),d5 + moveq IMM (MULTIPLY),d5 movel a0,d7 | get sign bit back into d7 tstl d3 | we know d2 == 0x7ff00000, so check d3 bne Ld$inop | if d3 <> 0 b is NaN bra Ld$overflow | else we have overflow (since a is finite) Lmuldf$a$nf: - movew IMM (MULTIPLY),d5 + moveq IMM (MULTIPLY),d5 movel a0,d7 | get sign bit back into d7 tstl d1 | we know d0 == 0x7ff00000, so check d1 bne Ld$inop | if d1 <> 0 a is NaN @@ -1591,28 +1737,28 @@ Lmuldf$a$nf: | If either number is zero return zero, unless the other is +/-INFINITY or | NaN, in which case we return NaN. Lmuldf$b$0: - movew IMM (MULTIPLY),d5 -#ifndef __mcf5200__ + moveq IMM (MULTIPLY),d5 +#ifndef __mcoldfire__ exg d2,d0 | put b (==0) into d0-d1 exg d3,d1 | and a (with sign bit cleared) into d2-d3 + movel a0,d0 | set result sign #else - movel d2,d7 - movel d0,d2 - movel d7,d0 - movel d3,d7 + movel d0,d2 | put a into d2-d3 movel d1,d3 - movel d7,d1 + movel a0,d0 | put result zero into d0-d1 + movq IMM(0),d1 #endif bra 1f Lmuldf$a$0: + movel a0,d0 | set result sign movel a6@(16),d2 | put b into d2-d3 again movel a6@(20),d3 | bclr IMM (31),d2 | clear sign bit 1: cmpl IMM (0x7ff00000),d2 | check for non-finiteness bge Ld$inop | in case NaN or +/-INFINITY return NaN - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 #else moveml sp@,d2-d7 @@ -1631,7 +1777,7 @@ Lmuldf$a$den: andl d6,d0 1: addl d1,d1 | shift a left until bit 20 is set addxl d0,d0 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (1),d4 | and adjust exponent #else subl IMM (1),d4 | and adjust exponent @@ -1645,7 +1791,7 @@ Lmuldf$b$den: andl d6,d2 1: addl d3,d3 | shift b left until bit 20 is set addxl d2,d2 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (1),d5 | and adjust exponent #else subql IMM (1),d5 | and adjust exponent @@ -1660,8 +1806,9 @@ Lmuldf$b$den: |============================================================================= | double __divdf3(double, double); + FUNC(__divdf3) SYM (__divdf3): -#ifndef __mcf5200__ +#ifndef __mcoldfire__ link a6,IMM (0) moveml d2-d7,sp@- #else @@ -1706,7 +1853,7 @@ 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__ +#ifndef __mcoldfire__ lsrw IMM (4),d4 | #else lsrl IMM (4),d4 | @@ -1717,13 +1864,13 @@ Ldivdf$1: | andl d6,d2 | orl IMM (0x00100000),d2 swap d5 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrw IMM (4),d5 | #else lsrl IMM (4),d5 | #endif Ldivdf$2: | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw d5,d4 | subtract exponents addw IMM (D_BIAS),d4 | and add bias #else @@ -1760,7 +1907,7 @@ Ldivdf$2: | bset d5,d6 | set the corresponding bit in d6 3: addl d1,d1 | shift a by 1 addxl d0,d0 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ dbra d5,1b | and branch back #else subql IMM (1), d5 @@ -1782,7 +1929,7 @@ Ldivdf$2: | bset d5,d7 | set the corresponding bit in d7 3: addl d1,d1 | shift a by 1 addxl d0,d0 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ dbra d5,1b | and branch back #else subql IMM (1), d5 @@ -1800,7 +1947,7 @@ Ldivdf$2: | beq 3f | if d0==d2 check d1 and d3 2: addl d1,d1 | shift a by 1 addxl d0,d0 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ dbra d5,1b | and branch back #else subql IMM (1), d5 @@ -1816,7 +1963,7 @@ 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__ +#ifndef __mcoldfire__ subw IMM (DBL_MANT_DIG),d5 addw IMM (63),d5 cmpw IMM (31),d5 @@ -1828,7 +1975,7 @@ Ldivdf$2: | bhi 2f 1: bset d5,d3 bra 5f -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (32),d5 #else subl IMM (32),d5 @@ -1847,7 +1994,7 @@ Ldivdf$2: | | not set: btst IMM (DBL_MANT_DIG-32+1),d0 beq 1f -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrl IMM (1),d0 roxrl IMM (1),d1 roxrl IMM (1),d2 @@ -1872,18 +2019,18 @@ Ldivdf$2: | 1: | Now round, check for over- and underflow, and exit. movel a0,d7 | restore sign bit to d7 - movew IMM (DIVIDE),d5 + moveq IMM (DIVIDE),d5 bra Lround$exit Ldivdf$inop: - movew IMM (DIVIDE),d5 + moveq IMM (DIVIDE),d5 bra Ld$inop Ldivdf$a$0: | If a is zero check to see whether b is zero also. In that case return | NaN; then check if b is NaN, and return NaN also in that case. Else -| return zero. - movew IMM (DIVIDE),d5 +| return a properly signed zero. + moveq IMM (DIVIDE),d5 bclr IMM (31),d2 | movel d2,d4 | orl d3,d4 | @@ -1893,11 +2040,11 @@ Ldivdf$a$0: blt 1f | tstl d3 | bne Ld$inop | -1: movel IMM (0),d0 | else return zero - movel d0,d1 | - lea SYM (_fpCCR),a0 | clear exception flags +1: movel a0,d0 | else return signed zero + moveq IMM(0),d1 | + PICLEA SYM (_fpCCR),a0 | clear exception flags movew IMM (0),a0@ | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 | #else moveml sp@,d2-d7 | @@ -1908,7 +2055,7 @@ Ldivdf$a$0: rts | Ldivdf$b$0: - movew IMM (DIVIDE),d5 + moveq IMM (DIVIDE),d5 | If we got here a is not zero. Check if a is NaN; in that case return NaN, | else return +/-INFINITY. Remember that a is in d0 with the sign bit | cleared already. @@ -1920,14 +2067,14 @@ Ldivdf$b$0: bra Ld$div$0 | else signal DIVIDE_BY_ZERO Ldivdf$b$nf: - movew IMM (DIVIDE),d5 + moveq IMM (DIVIDE),d5 | If d2 == 0x7ff00000 we have to check d3. tstl d3 | bne Ld$inop | if d3 <> 0, b is NaN bra Ld$underflow | else b is +/-INFINITY, so signal underflow Ldivdf$a$nf: - movew IMM (DIVIDE),d5 + moveq IMM (DIVIDE),d5 | If d0 == 0x7ff00000 we have to check d1. tstl d1 | bne Ld$inop | if d1 <> 0, a is NaN @@ -1945,7 +2092,7 @@ Ldivdf$a$den: andl d6,d0 1: addl d1,d1 | shift a left until bit 20 is set addxl d0,d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (1),d4 | and adjust exponent #else subl IMM (1),d4 | and adjust exponent @@ -1959,7 +2106,7 @@ Ldivdf$b$den: andl d6,d2 1: addl d3,d3 | shift b left until bit 20 is set addxl d2,d2 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (1),d5 | and adjust exponent #else subql IMM (1),d5 | and adjust exponent @@ -1974,7 +2121,7 @@ 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__ +#ifndef __mcoldfire__ cmpw IMM (-DBL_MANT_DIG-1),d4 #else cmpl IMM (-DBL_MANT_DIG-1),d4 @@ -1987,14 +2134,14 @@ 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__ +#ifndef __mcoldfire__ 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: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ addw IMM (1),d4 | adjust the exponent lsrl IMM (1),d0 | shift right once roxrl IMM (1),d1 | @@ -2035,14 +2182,14 @@ Lround$exit: orl d7,d3 | the bits which were flushed right movel a0,d7 | get back sign bit into d7 | 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__ + lea pc@(Lround$0),a0 | to return from rounding routine + PICLEA SYM (_fpCCR),a1 | check the rounding mode +#ifdef __mcoldfire__ clrl d6 #endif movew a1@(6),d6 | rounding mode in d6 beq Lround$to$nearest -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (ROUND_TO_PLUS),d6 #else cmpl IMM (ROUND_TO_PLUS),d6 @@ -2058,7 +2205,7 @@ 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__ +#ifndef __mcoldfire__ cmpw IMM (0x07ff),d4 #else cmpl IMM (0x07ff),d4 @@ -2069,14 +2216,14 @@ Lround$0: beq Ld$den 1: | Put back the exponents and sign and return. -#ifndef __mcf5200__ +#ifndef __mcoldfire__ 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__ +#ifndef __mcoldfire__ orw d4,d0 | #else orl d4,d0 | @@ -2084,9 +2231,9 @@ Lround$0: swap d0 | orl d7,d0 | and sign also - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 #else moveml sp@,d2-d7 @@ -2101,15 +2248,16 @@ Lround$0: |============================================================================= | double __negdf2(double, double); + FUNC(__negdf2) SYM (__negdf2): -#ifndef __mcf5200__ +#ifndef __mcoldfire__ link a6,IMM (0) moveml d2-d7,sp@- #else link a6,IMM (-24) moveml d2-d7,sp@ #endif - movew IMM (NEGATE),d5 + moveq IMM (NEGATE),d5 movel a6@(8),d0 | get number to negate in d0-d1 movel a6@(12),d1 | bchg IMM (31),d0 | negate @@ -2126,9 +2274,9 @@ SYM (__negdf2): movel d0,d7 | else get sign and return INFINITY andl IMM (0x80000000),d7 bra Ld$infty -1: lea SYM (_fpCCR),a0 +1: PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 #else moveml sp@,d2-d7 @@ -2148,16 +2296,16 @@ GREATER = 1 LESS = -1 EQUAL = 0 -| int __cmpdf2(double, double); -SYM (__cmpdf2): -#ifndef __mcf5200__ +| int __cmpdf2_internal(double, double, int); +SYM (__cmpdf2_internal): +#ifndef __mcoldfire__ link a6,IMM (0) moveml d2-d7,sp@- | save registers #else link a6,IMM (-24) moveml d2-d7,sp@ #endif - movew IMM (COMPARE),d5 + moveq IMM (COMPARE),d5 movel a6@(8),d0 | get first operand movel a6@(12),d1 | movel a6@(16),d2 | get second operand @@ -2168,15 +2316,15 @@ SYM (__cmpdf2): bclr IMM (31),d0 | and clear signs in d0 and d2 movel d2,d7 | bclr IMM (31),d2 | - cmpl IMM (0x7fff0000),d0 | check for a == NaN - bhi Ld$inop | if d0 > 0x7ff00000, a is NaN + cmpl IMM (0x7ff00000),d0 | check for a == NaN + bhi Lcmpd$inop | if d0 > 0x7ff00000, a is NaN beq Lcmpdf$a$nf | if equal can be INFINITY, so check d1 movel d0,d4 | copy into d4 to test for zero orl d1,d4 | beq Lcmpdf$a$0 | Lcmpdf$0: - cmpl IMM (0x7fff0000),d2 | check for b == NaN - bhi Ld$inop | if d2 > 0x7ff00000, b is NaN + cmpl IMM (0x7ff00000),d2 | check for b == NaN + bhi Lcmpd$inop | if d2 > 0x7ff00000, b is NaN beq Lcmpdf$b$nf | if equal can be INFINITY, so check d3 movel d2,d4 | orl d3,d4 | @@ -2194,7 +2342,7 @@ Lcmpdf$1: tstl d6 bpl 1f | If both are negative exchange them -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d0,d2 exg d1,d3 #else @@ -2217,7 +2365,7 @@ Lcmpdf$1: bne Lcmpdf$a$gt$b | |b| < |a| | If we got here a == b. movel IMM (EQUAL),d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 | put back the registers #else moveml sp@,d2-d7 @@ -2228,7 +2376,7 @@ Lcmpdf$1: rts Lcmpdf$a$gt$b: movel IMM (GREATER),d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 | put back the registers #else moveml sp@,d2-d7 @@ -2239,7 +2387,7 @@ Lcmpdf$a$gt$b: rts Lcmpdf$b$gt$a: movel IMM (LESS),d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 | put back the registers #else moveml sp@,d2-d7 @@ -2266,6 +2414,25 @@ Lcmpdf$b$nf: bne Ld$inop bra Lcmpdf$1 +Lcmpd$inop: + movl a6@(24),d0 + moveq IMM (INEXACT_RESULT+INVALID_OPERATION),d7 + moveq IMM (DOUBLE_FLOAT),d6 + PICJUMP $_exception_handler + +| int __cmpdf2(double, double); + FUNC(__cmpdf2) +SYM (__cmpdf2): + link a6,IMM (0) + pea 1 + movl a6@(20),sp@- + movl a6@(16),sp@- + movl a6@(12),sp@- + movl a6@(8),sp@- + PICCALL SYM (__cmpdf2_internal) + unlk a6 + rts + |============================================================================= | rounding routines |============================================================================= @@ -2287,7 +2454,7 @@ 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__ +#ifndef __mcoldfire__ 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 @@ -2297,7 +2464,7 @@ Lround$to$nearest: addxl d2,d2 | addxl d1,d1 | addxl d0,d0 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ dbra d4,1b | #else subql IMM (1), d4 @@ -2325,7 +2492,7 @@ Lround$to$nearest: addxl d2,d0 | Shift right once (because we used bit #DBL_MANT_DIG-32!). 2: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrl IMM (1),d0 roxrl IMM (1),d1 #else @@ -2340,7 +2507,7 @@ Lround$to$nearest: | 'fraction overflow' ...). btst IMM (DBL_MANT_DIG-32),d0 beq 1f -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrl IMM (1),d0 roxrl IMM (1),d1 addw IMM (1),d4 @@ -2413,6 +2580,8 @@ ROUND_TO_MINUS = 3 | round result towards minus infinity .globl SYM (__divsf3) .globl SYM (__negsf2) .globl SYM (__cmpsf2) + .globl SYM (__cmpsf2_internal) + .hidden SYM (__cmpsf2_internal) | These are common routines to return and signal exceptions. @@ -2422,40 +2591,40 @@ ROUND_TO_MINUS = 3 | round result towards minus infinity Lf$den: | Return and signal a denormalized number orl d7,d0 - movew IMM (INEXACT_RESULT+UNDERFLOW),d7 + moveq IMM (INEXACT_RESULT+UNDERFLOW),d7 moveq IMM (SINGLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Lf$infty: Lf$overflow: | Return a properly signed INFINITY and set the exception flags movel IMM (INFINITY),d0 orl d7,d0 - movew IMM (INEXACT_RESULT+OVERFLOW),d7 + moveq IMM (INEXACT_RESULT+OVERFLOW),d7 moveq IMM (SINGLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Lf$underflow: | Return 0 and set the exception flags - movel IMM (0),d0 - movew IMM (INEXACT_RESULT+UNDERFLOW),d7 + moveq IMM (0),d0 + moveq IMM (INEXACT_RESULT+UNDERFLOW),d7 moveq IMM (SINGLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_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 + moveq IMM (INEXACT_RESULT+INVALID_OPERATION),d7 moveq IMM (SINGLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Lf$div$0: | Return a properly signed INFINITY and set the exception flags movel IMM (INFINITY),d0 orl d7,d0 - movew IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7 + moveq IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7 moveq IMM (SINGLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler |============================================================================= |============================================================================= @@ -2482,6 +2651,7 @@ Lf$div$0: |============================================================================= | float __subsf3(float, float); + FUNC(__subsf3) SYM (__subsf3): bchg IMM (31),sp@(8) | change sign of second operand | and fall through @@ -2490,8 +2660,9 @@ SYM (__subsf3): |============================================================================= | float __addsf3(float, float); + FUNC(__addsf3) SYM (__addsf3): -#ifndef __mcf5200__ +#ifndef __mcoldfire__ link a6,IMM (0) | everything will be done in registers moveml d2-d7,sp@- | save all data registers but d0-d1 #else @@ -2500,16 +2671,13 @@ SYM (__addsf3): #endif movel a6@(8),d0 | get first operand movel a6@(12),d1 | get second operand - movel d0,d6 | get d0's sign bit ' + movel d0,a0 | get d0's sign bit ' addl d0,d0 | check and clear sign bit of a beq Laddsf$b | if zero return second operand - movel d1,d7 | save b's sign bit ' + movel d1,a1 | save b's sign bit ' addl d1,d1 | get rid of sign bit beq Laddsf$a | if zero return first operand - movel d6,a0 | save signs in address registers - movel d7,a1 | so we can use d6 and d7 - | Get the exponents and check for denormalized and/or infinity. movel IMM (0x00ffffff),d4 | mask to get fraction @@ -2551,7 +2719,7 @@ 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__ +#ifndef __mcoldfire__ cmpw d6,d7 | compare exponents #else cmpl d6,d7 | compare exponents @@ -2561,32 +2729,32 @@ Laddsf$2: 1: subl d6,d7 | keep the largest exponent negl d7 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ 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__ +#ifndef __mcoldfire__ cmpw IMM (FLT_MANT_DIG+2),d7 #else cmpl IMM (FLT_MANT_DIG+2),d7 #endif bge Laddsf$b$small -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (16),d7 | if difference >= 16 swap #else cmpl IMM (16),d7 | if difference >= 16 swap #endif bge 4f 2: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (1),d7 #else subql IMM (1), d7 #endif 3: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrl IMM (1),d2 | shift right second operand roxrl IMM (1),d3 dbra d7,3b @@ -2605,7 +2773,7 @@ Laddsf$2: swap d3 movew d3,d2 swap d2 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (16),d7 #else subl IMM (16),d7 @@ -2613,7 +2781,7 @@ Laddsf$2: bne 2b | if still more bits, go back to normal case bra Laddsf$3 5: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d6,d7 | exchange the exponents #else eorl d6,d7 @@ -2622,32 +2790,32 @@ Laddsf$2: #endif subl d6,d7 | keep the largest exponent negl d7 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ 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__ +#ifndef __mcoldfire__ cmpw IMM (FLT_MANT_DIG+2),d7 #else cmpl IMM (FLT_MANT_DIG+2),d7 #endif bge Laddsf$a$small -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (16),d7 | if difference >= 16 swap #else cmpl IMM (16),d7 | if difference >= 16 swap #endif bge 8f 6: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (1),d7 #else subl IMM (1),d7 #endif 7: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrl IMM (1),d0 | shift right first operand roxrl IMM (1),d1 dbra d7,7b @@ -2666,7 +2834,7 @@ Laddsf$2: swap d1 movew d1,d0 swap d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (16),d7 #else subl IMM (16),d7 @@ -2679,7 +2847,7 @@ Laddsf$2: Laddsf$3: | Here we have to decide whether to add or subtract the numbers -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d6,a0 | get signs back exg d7,a1 | and save the exponents #else @@ -2696,7 +2864,7 @@ Laddsf$3: | numbers | Here we have both positive or both negative -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d6,a0 | now we have the exponent in d6 #else movel d6,d4 @@ -2713,7 +2881,7 @@ Laddsf$3: | Put the exponent, in the first byte, in d2, to use the "standard" rounding | routines: movel d6,d2 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrw IMM (8),d2 #else lsrl IMM (8),d2 @@ -2725,7 +2893,7 @@ Laddsf$3: | one more bit we check this: btst IMM (FLT_MANT_DIG+1),d0 beq 1f -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrl IMM (1),d0 roxrl IMM (1),d1 #else @@ -2737,14 +2905,14 @@ Laddsf$3: #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__ + lea pc@(Laddsf$4),a0 | to return from rounding routine + PICLEA SYM (_fpCCR),a1 | check the rounding mode +#ifdef __mcoldfire__ clrl d6 #endif movew a1@(6),d6 | rounding mode in d6 beq Lround$to$nearest -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (ROUND_TO_PLUS),d6 #else cmpl IMM (ROUND_TO_PLUS),d6 @@ -2754,14 +2922,14 @@ Laddsf$3: bra Lround$to$plus Laddsf$4: | Put back the exponent, but check for overflow. -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (0xff),d2 #else cmpl IMM (0xff),d2 #endif bhi 1f bclr IMM (FLT_MANT_DIG-1),d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lslw IMM (7),d2 #else lsll IMM (7),d2 @@ -2770,7 +2938,7 @@ Laddsf$4: orl d2,d0 bra Laddsf$ret 1: - movew IMM (ADD),d5 + moveq IMM (ADD),d5 bra Lf$overflow Lsubsf$0: @@ -2787,7 +2955,7 @@ Lsubsf$0: negl d1 negxl d0 1: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d2,a0 | now we have the exponent in d2 lsrw IMM (8),d2 | put it in the first byte #else @@ -2802,14 +2970,14 @@ Lsubsf$0: | Note that we do not have to normalize, since in the subtraction bit | #FLT_MANT_DIG+1 is never set, and denormalized numbers are handled by | the rounding routines themselves. - lea Lsubsf$1,a0 | to return from rounding routine - lea SYM (_fpCCR),a1 | check the rounding mode -#ifdef __mcf5200__ + lea pc@(Lsubsf$1),a0 | to return from rounding routine + PICLEA SYM (_fpCCR),a1 | check the rounding mode +#ifdef __mcoldfire__ clrl d6 #endif movew a1@(6),d6 | rounding mode in d6 beq Lround$to$nearest -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (ROUND_TO_PLUS),d6 #else cmpl IMM (ROUND_TO_PLUS),d6 @@ -2820,7 +2988,7 @@ Lsubsf$0: Lsubsf$1: | Put back the exponent (we can't have overflow!). ' bclr IMM (FLT_MANT_DIG-1),d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lslw IMM (7),d2 #else lsll IMM (7),d2 @@ -2834,9 +3002,9 @@ Lsubsf$1: | check for finiteness or zero). Laddsf$a$small: movel a6@(12),d0 - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 | restore data registers #else moveml sp@,d2-d7 @@ -2848,9 +3016,9 @@ Laddsf$a$small: Laddsf$b$small: movel a6@(8),d0 - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 | restore data registers #else moveml sp@,d2-d7 @@ -2880,12 +3048,17 @@ Laddsf$b$den: Laddsf$b: | Return b (if a is zero). movel a6@(12),d0 - bra 1f + cmpl IMM (0x80000000),d0 | Check if b is -0 + bne 1f + movel a0,d7 + andl IMM (0x80000000),d7 | Use the sign of a + clrl d0 + bra Laddsf$ret Laddsf$a: | Return a (if b is zero). movel a6@(8),d0 1: - movew IMM (ADD),d5 + moveq IMM (ADD),d5 | We have to check for NaN and +/-infty. movel d0,d7 andl IMM (0x80000000),d7 | put sign in d7 @@ -2905,10 +3078,10 @@ Laddsf$a: Laddsf$ret: | Normal exit (a and b nonzero, result is not NaN nor +/-infty). | We have to clear the exception flags (just the exception type). - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ orl d7,d0 | put sign bit -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 | restore data registers #else moveml sp@,d2-d7 @@ -2931,7 +3104,7 @@ Laddsf$ret$den: | NaN, but if it is finite we return INFINITY with the corresponding sign. Laddsf$nf: - movew IMM (ADD),d5 + moveq IMM (ADD),d5 | This could be faster but it is not worth the effort, since it is not | executed very often. We sacrifice speed for clarity here. movel a6@(8),d0 | get the numbers back (remember that we @@ -2974,8 +3147,9 @@ Laddsf$nf: |============================================================================= | float __mulsf3(float, float); + FUNC(__mulsf3) SYM (__mulsf3): -#ifndef __mcf5200__ +#ifndef __mcoldfire__ link a6,IMM (0) moveml d2-d7,sp@- #else @@ -3010,7 +3184,7 @@ 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__ +#ifndef __mcoldfire__ lsrw IMM (7),d2 | #else lsrl IMM (7),d2 | @@ -3021,13 +3195,13 @@ Lmulsf$1: | number andl d5,d1 | orl d4,d1 | swap d3 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrw IMM (7),d3 | #else lsrl IMM (7),d3 | #endif Lmulsf$2: | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ addw d3,d2 | add exponents subw IMM (F_BIAS+1),d2 | and subtract bias (plus one) #else @@ -3052,7 +3226,7 @@ Lmulsf$2: | lsll IMM (31-FLT_MANT_DIG+1),d6 | Start the loop (we loop #FLT_MANT_DIG times): - movew IMM (FLT_MANT_DIG-1),d3 + moveq IMM (FLT_MANT_DIG-1),d3 1: addl d1,d1 | shift sum addxl d0,d0 lsll IMM (1),d6 | get bit bn @@ -3060,7 +3234,7 @@ Lmulsf$2: | addl d5,d1 | add a addxl d4,d0 2: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ dbf d3,1b | loop back #else subql IMM (1),d3 @@ -3070,7 +3244,7 @@ Lmulsf$2: | | 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__ +#ifndef __mcoldfire__ rorl IMM (6),d1 swap d1 movew d1,d3 @@ -3089,17 +3263,17 @@ Lmulsf$2: | lsll IMM (8),d0 addl d0,d0 addl d0,d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ orw d3,d0 #else orl d3,d0 #endif - movew IMM (MULTIPLY),d5 + moveq IMM (MULTIPLY),d5 btst IMM (FLT_MANT_DIG+1),d0 beq Lround$exit -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrl IMM (1),d0 roxrl IMM (1),d1 addw IMM (1),d2 @@ -3114,15 +3288,15 @@ Lmulsf$2: | bra Lround$exit Lmulsf$inop: - movew IMM (MULTIPLY),d5 + moveq IMM (MULTIPLY),d5 bra Lf$inop Lmulsf$overflow: - movew IMM (MULTIPLY),d5 + moveq IMM (MULTIPLY),d5 bra Lf$overflow Lmulsf$inf: - movew IMM (MULTIPLY),d5 + moveq IMM (MULTIPLY),d5 | If either is NaN return NaN; else both are (maybe infinite) numbers, so | return INFINITY with the correct sign (which is in d7). cmpl d6,d1 | is b NaN? @@ -3133,7 +3307,6 @@ Lmulsf$inf: | or NaN, in which case we return NaN. Lmulsf$b$0: | Here d1 (==b) is zero. - movel d1,d0 | put b into d0 (just a zero) movel a6@(8),d1 | get a again to check for non-finiteness bra 1f Lmulsf$a$0: @@ -3141,9 +3314,10 @@ Lmulsf$a$0: 1: bclr IMM (31),d1 | clear sign bit cmpl IMM (INFINITY),d1 | and check for a large exponent bge Lf$inop | if b is +/-INFINITY or NaN return NaN - lea SYM (_fpCCR),a0 | else return zero + movel d7,d0 | else return signed zero + PICLEA SYM (_fpCCR),a0 | movew IMM (0),a0@ | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 | #else moveml sp@,d2-d7 @@ -3161,7 +3335,7 @@ Lmulsf$a$den: movel IMM (1),d2 andl d5,d0 1: addl d0,d0 | shift a left (until bit 23 is set) -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (1),d2 | and adjust exponent #else subql IMM (1),d2 | and adjust exponent @@ -3174,10 +3348,10 @@ Lmulsf$b$den: movel IMM (1),d3 andl d5,d1 1: addl d1,d1 | shift b left until bit 23 is set -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (1),d3 | and adjust exponent #else - subl IMM (1),d3 | and adjust exponent + subql IMM (1),d3 | and adjust exponent #endif btst IMM (FLT_MANT_DIG-1),d1 bne Lmulsf$2 | @@ -3188,8 +3362,9 @@ Lmulsf$b$den: |============================================================================= | float __divsf3(float, float); + FUNC(__divsf3) SYM (__divsf3): -#ifndef __mcf5200__ +#ifndef __mcoldfire__ link a6,IMM (0) moveml d2-d7,sp@- #else @@ -3226,7 +3401,7 @@ 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__ +#ifndef __mcoldfire__ lsrw IMM (7),d2 | #else lsrl IMM (7),d2 | @@ -3237,13 +3412,13 @@ Ldivsf$1: | andl d5,d1 | orl d4,d1 | swap d3 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ lsrw IMM (7),d3 | #else lsrl IMM (7),d3 | #endif Ldivsf$2: | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw d3,d2 | subtract exponents addw IMM (F_BIAS),d2 | and add bias #else @@ -3263,14 +3438,14 @@ Ldivsf$2: | movel IMM (0),d6 | movel d6,d7 - movew IMM (FLT_MANT_DIG+1),d3 + moveq IMM (FLT_MANT_DIG+1),d3 1: cmpl d0,d1 | is a < b? bhi 2f | bset d3,d6 | set a bit in d6 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__ +#ifndef __mcoldfire__ dbra d3,1b #else subql IMM (1),d3 @@ -3278,11 +3453,11 @@ Ldivsf$2: | #endif | Now we keep going to set the sticky bit ... - movew IMM (FLT_MANT_DIG),d3 + moveq IMM (FLT_MANT_DIG),d3 1: cmpl d0,d1 ble 2f addl d0,d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ dbra d3,1b #else subql IMM(1),d3 @@ -3291,7 +3466,7 @@ Ldivsf$2: | movel IMM (0),d1 bra 3f 2: movel IMM (0),d1 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ subw IMM (FLT_MANT_DIG),d3 addw IMM (31),d3 #else @@ -3309,41 +3484,41 @@ 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__ +#ifndef __mcoldfire__ addw IMM (1),d2 | #else addl IMM (1),d2 | #endif 1: | Now round, check for over- and underflow, and exit. - movew IMM (DIVIDE),d5 + moveq IMM (DIVIDE),d5 bra Lround$exit Ldivsf$inop: - movew IMM (DIVIDE),d5 + moveq IMM (DIVIDE),d5 bra Lf$inop Ldivsf$overflow: - movew IMM (DIVIDE),d5 + moveq IMM (DIVIDE),d5 bra Lf$overflow Ldivsf$underflow: - movew IMM (DIVIDE),d5 + moveq IMM (DIVIDE),d5 bra Lf$underflow Ldivsf$a$0: - movew IMM (DIVIDE),d5 + moveq IMM (DIVIDE),d5 | If a is zero check to see whether b is zero also. In that case return | NaN; then check if b is NaN, and return NaN also in that case. Else -| return zero. +| return a properly signed zero. andl IMM (0x7fffffff),d1 | clear sign bit and test b beq Lf$inop | if b is also zero return NaN cmpl IMM (INFINITY),d1 | check for NaN bhi Lf$inop | - movel IMM (0),d0 | else return zero - lea SYM (_fpCCR),a0 | + movel d7,d0 | else return signed zero + PICLEA SYM (_fpCCR),a0 | movew IMM (0),a0@ | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 | #else moveml sp@,d2-d7 | @@ -3354,7 +3529,7 @@ Ldivsf$a$0: rts | Ldivsf$b$0: - movew IMM (DIVIDE),d5 + moveq IMM (DIVIDE),d5 | If we got here a is not zero. Check if a is NaN; in that case return NaN, | else return +/-INFINITY. Remember that a is in d0 with the sign bit | cleared already. @@ -3363,7 +3538,7 @@ Ldivsf$b$0: bra Lf$div$0 | else signal DIVIDE_BY_ZERO Ldivsf$inf: - movew IMM (DIVIDE),d5 + moveq IMM (DIVIDE),d5 | If a is INFINITY we have to check b cmpl IMM (INFINITY),d1 | compare b with INFINITY bge Lf$inop | if b is NaN or INFINITY return NaN @@ -3375,7 +3550,7 @@ 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__ +#ifndef __mcoldfire__ subw IMM (1),d2 | and adjust exponent #else subl IMM (1),d2 | and adjust exponent @@ -3388,7 +3563,7 @@ 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__ +#ifndef __mcoldfire__ subw IMM (1),d3 | and adjust exponent #else subl IMM (1),d3 | and adjust exponent @@ -3401,7 +3576,7 @@ Lround$exit: | This is a common exit point for __mulsf3 and __divsf3. | First check for underlow in the exponent: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (-FLT_MANT_DIG-1),d2 #else cmpl IMM (-FLT_MANT_DIG-1),d2 @@ -3412,14 +3587,14 @@ Lround$exit: | 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__ +#ifndef __mcoldfire__ 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: -#ifndef __mcf5200__ +#ifndef __mcoldfire__ addw IMM (1),d2 | adjust the exponent lsrl IMM (1),d0 | shift right once roxrl IMM (1),d1 | @@ -3444,14 +3619,14 @@ Lround$exit: 2: orl d6,d1 | this is a trick so we don't lose ' | the extra bits which were flushed right | 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__ + lea pc@(Lround$0),a0 | to return from rounding routine + PICLEA SYM (_fpCCR),a1 | check the rounding mode +#ifdef __mcoldfire__ clrl d6 #endif movew a1@(6),d6 | rounding mode in d6 beq Lround$to$nearest -#ifndef __mcf5200__ +#ifndef __mcoldfire__ cmpw IMM (ROUND_TO_PLUS),d6 #else cmpl IMM (ROUND_TO_PLUS),d6 @@ -3467,7 +3642,7 @@ 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__ +#ifndef __mcoldfire__ cmpw IMM (0x00ff),d2 #else cmpl IMM (0x00ff),d2 @@ -3478,14 +3653,14 @@ Lround$0: beq Lf$den 1: | Put back the exponents and sign and return. -#ifndef __mcf5200__ +#ifndef __mcoldfire__ 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__ +#ifndef __mcoldfire__ orw d2,d0 | #else orl d2,d0 @@ -3493,9 +3668,9 @@ Lround$0: swap d0 | orl d7,d0 | and sign also - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 #else moveml sp@,d2-d7 @@ -3513,15 +3688,16 @@ Lround$0: | and +/-INFINITY. | float __negsf2(float); + FUNC(__negsf2) SYM (__negsf2): -#ifndef __mcf5200__ +#ifndef __mcoldfire__ link a6,IMM (0) moveml d2-d7,sp@- #else link a6,IMM (-24) moveml d2-d7,sp@ #endif - movew IMM (NEGATE),d5 + moveq IMM (NEGATE),d5 movel a6@(8),d0 | get number to negate in d0 bchg IMM (31),d0 | negate movel d0,d1 | make a positive copy @@ -3534,9 +3710,9 @@ SYM (__negsf2): movel d0,d7 | else get sign and return INFINITY andl IMM (0x80000000),d7 bra Lf$infty -1: lea SYM (_fpCCR),a0 +1: PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 #else moveml sp@,d2-d7 @@ -3556,16 +3732,16 @@ GREATER = 1 LESS = -1 EQUAL = 0 -| int __cmpsf2(float, float); -SYM (__cmpsf2): -#ifndef __mcf5200__ +| int __cmpsf2_internal(float, float, int); +SYM (__cmpsf2_internal): +#ifndef __mcoldfire__ link a6,IMM (0) moveml d2-d7,sp@- | save registers #else link a6,IMM (-24) moveml d2-d7,sp@ #endif - movew IMM (COMPARE),d5 + moveq IMM (COMPARE),d5 movel a6@(8),d0 | get first operand movel a6@(12),d1 | get second operand | Check if either is NaN, and in that case return garbage and signal @@ -3575,13 +3751,13 @@ SYM (__cmpsf2): andl IMM (0x7fffffff),d0 beq Lcmpsf$a$0 cmpl IMM (0x7f800000),d0 - bhi Lf$inop + bhi Lcmpf$inop Lcmpsf$1: movel d1,d7 andl IMM (0x7fffffff),d1 beq Lcmpsf$b$0 cmpl IMM (0x7f800000),d1 - bhi Lf$inop + bhi Lcmpf$inop Lcmpsf$2: | Check the signs eorl d6,d7 @@ -3595,7 +3771,7 @@ Lcmpsf$2: tstl d6 bpl 1f | If both are negative exchange them -#ifndef __mcf5200__ +#ifndef __mcoldfire__ exg d0,d1 #else movel d0,d7 @@ -3610,7 +3786,7 @@ Lcmpsf$2: bne Lcmpsf$a$gt$b | |b| < |a| | If we got here a == b. movel IMM (EQUAL),d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 | put back the registers #else moveml sp@,d2-d7 @@ -3619,7 +3795,7 @@ Lcmpsf$2: rts Lcmpsf$a$gt$b: movel IMM (GREATER),d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 | put back the registers #else moveml sp@,d2-d7 @@ -3630,7 +3806,7 @@ Lcmpsf$a$gt$b: rts Lcmpsf$b$gt$a: movel IMM (LESS),d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ moveml sp@+,d2-d7 | put back the registers #else moveml sp@,d2-d7 @@ -3647,6 +3823,23 @@ Lcmpsf$b$0: bclr IMM (31),d7 bra Lcmpsf$2 +Lcmpf$inop: + movl a6@(16),d0 + moveq IMM (INEXACT_RESULT+INVALID_OPERATION),d7 + moveq IMM (SINGLE_FLOAT),d6 + PICJUMP $_exception_handler + +| int __cmpsf2(float, float); + FUNC(__cmpsf2) +SYM (__cmpsf2): + link a6,IMM (0) + pea 1 + movl a6@(12),sp@- + movl a6@(8),sp@- + PICCALL SYM (__cmpsf2_internal) + unlk a6 + rts + |============================================================================= | rounding routines |============================================================================= @@ -3668,7 +3861,7 @@ 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__ +#ifndef __mcoldfire__ 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 @@ -3676,7 +3869,7 @@ Lround$to$nearest: beq 2f | an exponent of one means denormalized addl d1,d1 | else shift and adjust the exponent addxl d0,d0 | -#ifndef __mcf5200__ +#ifndef __mcoldfire__ dbra d2,1b | #else subql IMM (1),d2 @@ -3705,7 +3898,7 @@ Lround$to$nearest: btst IMM (FLT_MANT_DIG),d0 beq 1f lsrl IMM (1),d0 -#ifndef __mcf5200__ +#ifndef __mcoldfire__ addw IMM (1),d2 #else addql IMM (1),d2 @@ -3731,93 +3924,101 @@ Lround$to$minus: | simply calls __cmpdf2. It would be more efficient to give the | __cmpdf2 routine several names, but separating them out will make it | easier to write efficient versions of these routines someday. +| If the operands recompare unordered unordered __gtdf2 and __gedf2 return -1. +| The other routines return 1. #ifdef L_eqdf2 .text - .proc + FUNC(__eqdf2) .globl SYM (__eqdf2) SYM (__eqdf2): link a6,IMM (0) + pea 1 movl a6@(20),sp@- movl a6@(16),sp@- movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpdf2) + PICCALL SYM (__cmpdf2_internal) unlk a6 rts #endif /* L_eqdf2 */ #ifdef L_nedf2 .text - .proc + FUNC(__nedf2) .globl SYM (__nedf2) SYM (__nedf2): link a6,IMM (0) + pea 1 movl a6@(20),sp@- movl a6@(16),sp@- movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpdf2) + PICCALL SYM (__cmpdf2_internal) unlk a6 rts #endif /* L_nedf2 */ #ifdef L_gtdf2 .text - .proc + FUNC(__gtdf2) .globl SYM (__gtdf2) SYM (__gtdf2): link a6,IMM (0) + pea -1 movl a6@(20),sp@- movl a6@(16),sp@- movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpdf2) + PICCALL SYM (__cmpdf2_internal) unlk a6 rts #endif /* L_gtdf2 */ #ifdef L_gedf2 .text - .proc + FUNC(__gedf2) .globl SYM (__gedf2) SYM (__gedf2): link a6,IMM (0) + pea -1 movl a6@(20),sp@- movl a6@(16),sp@- movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpdf2) + PICCALL SYM (__cmpdf2_internal) unlk a6 rts #endif /* L_gedf2 */ #ifdef L_ltdf2 .text - .proc + FUNC(__ltdf2) .globl SYM (__ltdf2) SYM (__ltdf2): link a6,IMM (0) + pea 1 movl a6@(20),sp@- movl a6@(16),sp@- movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpdf2) + PICCALL SYM (__cmpdf2_internal) unlk a6 rts #endif /* L_ltdf2 */ #ifdef L_ledf2 .text - .proc + FUNC(__ledf2) .globl SYM (__ledf2) SYM (__ledf2): link a6,IMM (0) + pea 1 movl a6@(20),sp@- movl a6@(16),sp@- movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpdf2) + PICCALL SYM (__cmpdf2_internal) unlk a6 rts #endif /* L_ledf2 */ @@ -3827,78 +4028,89 @@ SYM (__ledf2): #ifdef L_eqsf2 .text - .proc + FUNC(__eqsf2) .globl SYM (__eqsf2) SYM (__eqsf2): link a6,IMM (0) + pea 1 movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpsf2) + PICCALL SYM (__cmpsf2_internal) unlk a6 rts #endif /* L_eqsf2 */ #ifdef L_nesf2 .text - .proc + FUNC(__nesf2) .globl SYM (__nesf2) SYM (__nesf2): link a6,IMM (0) + pea 1 movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpsf2) + PICCALL SYM (__cmpsf2_internal) unlk a6 rts #endif /* L_nesf2 */ #ifdef L_gtsf2 .text - .proc + FUNC(__gtsf2) .globl SYM (__gtsf2) SYM (__gtsf2): link a6,IMM (0) + pea -1 movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpsf2) + PICCALL SYM (__cmpsf2_internal) unlk a6 rts #endif /* L_gtsf2 */ #ifdef L_gesf2 .text - .proc + FUNC(__gesf2) .globl SYM (__gesf2) SYM (__gesf2): link a6,IMM (0) + pea -1 movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpsf2) + PICCALL SYM (__cmpsf2_internal) unlk a6 rts #endif /* L_gesf2 */ #ifdef L_ltsf2 .text - .proc + FUNC(__ltsf2) .globl SYM (__ltsf2) SYM (__ltsf2): link a6,IMM (0) + pea 1 movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpsf2) + PICCALL SYM (__cmpsf2_internal) unlk a6 rts #endif /* L_ltsf2 */ #ifdef L_lesf2 .text - .proc + FUNC(__lesf2) .globl SYM (__lesf2) SYM (__lesf2): link a6,IMM (0) + pea 1 movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpsf2) + PICCALL SYM (__cmpsf2_internal) unlk a6 rts #endif /* L_lesf2 */ + +#if defined (__ELF__) && defined (__linux__) + /* Make stack non-executable for ELF linux targets. */ + .section .note.GNU-stack,"",@progbits +#endif