This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[m68k] fix denorm mult


This patch fixes mul-subnormal-single-1.

The 'movew imm,reg' instruction only sets the bottom 16 bits of reg. This led to a problem in mulsf3 when the second operand was a denormal -- we'd end up with an iteration count of 0xffff0017 instead of 0x17. I went through lb1sf68 auditing all the uses of 'movew imm', replacing them with moveq where appropriate.

tested on m68k-elf for coldfire with qemu, ok?
Shall I apply to 4.1 also?

nathan

--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2006-01-31  Nathan Sidwell  <nathan@voldemort.voldemort.codesourcery.com>

	* gcc/config/m68k/lb1sf68.asm: Use moveq to load small constants.

Index: config/m68k/lb1sf68.asm
===================================================================
--- config/m68k/lb1sf68.asm	(revision 110253)
+++ config/m68k/lb1sf68.asm	(working copy)
@@ -1124,7 +1124,7 @@
 	swap	d0		|
 	bra	Ladddf$ret
 1:
-	movew	IMM (ADD),d5
+	moveq	IMM (ADD),d5
 	bra	Ld$overflow
 
 Lsubdf$0:
@@ -1296,7 +1296,7 @@
 	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	|
@@ -1352,7 +1352,7 @@
 	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
@@ -1628,7 +1628,7 @@
 	
 | 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
@@ -1647,18 +1647,18 @@
 	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
@@ -1667,7 +1667,7 @@
 | 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
+	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
@@ -1948,18 +1948,18 @@
 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
+	moveq	IMM (DIVIDE),d5
 	bclr	IMM (31),d2	|
 	movel	d2,d4		| 
 	orl	d3,d4		| 
@@ -1984,7 +1984,7 @@
 	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.
@@ -1996,14 +1996,14 @@
 	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
@@ -2185,7 +2185,7 @@
 	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
@@ -2233,7 +2233,7 @@
 	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
@@ -2344,7 +2344,7 @@
 
 Lcmpd$inop:
 	movl	a6@(24),d0
-	movew	IMM (INEXACT_RESULT+INVALID_OPERATION),d7
+	moveq	IMM (INEXACT_RESULT+INVALID_OPERATION),d7
 	moveq	IMM (DOUBLE_FLOAT),d6
 	PICJUMP	$_exception_handler
 
@@ -2517,7 +2517,7 @@
 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
 	PICJUMP	$_exception_handler
 
@@ -2526,21 +2526,21 @@
 | 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
 	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
 	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
 	PICJUMP	$_exception_handler
 
@@ -2548,7 +2548,7 @@
 | 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
 	PICJUMP	$_exception_handler
 
@@ -2862,7 +2862,7 @@
 	orl	d2,d0
 	bra	Laddsf$ret
 1:
-	movew	IMM (ADD),d5
+	moveq	IMM (ADD),d5
 	bra	Lf$overflow
 
 Lsubsf$0:
@@ -2982,7 +2982,7 @@
 | 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
@@ -3028,7 +3028,7 @@
 | 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
@@ -3149,7 +3149,7 @@
 	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
@@ -3192,7 +3192,7 @@
 	orl	d3,d0
 #endif
 
-	movew	IMM (MULTIPLY),d5
+	moveq	IMM (MULTIPLY),d5
 	
 	btst	IMM (FLT_MANT_DIG+1),d0
 	beq	Lround$exit
@@ -3211,15 +3211,15 @@
 	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?
@@ -3274,7 +3274,7 @@
 #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	|
@@ -3360,7 +3360,7 @@
 	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
@@ -3375,7 +3375,7 @@
 #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
@@ -3413,23 +3413,23 @@
 #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.
@@ -3451,7 +3451,7 @@
 	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.
@@ -3460,7 +3460,7 @@
 	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
@@ -3618,7 +3618,7 @@
 	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
@@ -3662,7 +3662,7 @@
 	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
@@ -3746,7 +3746,7 @@
 
 Lcmpf$inop:
 	movl	a6@(16),d0
-	movew	IMM (INEXACT_RESULT+INVALID_OPERATION),d7
+	moveq	IMM (INEXACT_RESULT+INVALID_OPERATION),d7
 	moveq	IMM (SINGLE_FLOAT),d6
 	PICJUMP	$_exception_handler
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]