File Index
Files and directories
Sign in
FILE

x_ovfl.S

File preview with syntax highlighting.

linux-6.19.14/arch/m68k/fpsp040/x_ovfl.S S
  1|
  2|	x_ovfl.sa 3.5 7/1/91
  3|
  4|	fpsp_ovfl --- FPSP handler for overflow exception
  5|
  6|	Overflow occurs when a floating-point intermediate result is
  7|	too large to be represented in a floating-point data register,
  8|	or when storing to memory, the contents of a floating-point
  9|	data register are too large to be represented in the
 10|	destination format.
 11|
 12| Trap disabled results
 13|
 14| If the instruction is move_out, then garbage is stored in the
 15| destination.  If the instruction is not move_out, then the
 16| destination is not affected.  For 68881 compatibility, the
 17| following values should be stored at the destination, based
 18| on the current rounding mode:
 19|
 20|  RN	Infinity with the sign of the intermediate result.
 21|  RZ	Largest magnitude number, with the sign of the
 22|	intermediate result.
 23|  RM   For pos overflow, the largest pos number. For neg overflow,
 24|	-infinity
 25|  RP   For pos overflow, +infinity. For neg overflow, the largest
 26|	neg number
 27|
 28| Trap enabled results
 29| All trap disabled code applies.  In addition the exceptional
 30| operand needs to be made available to the users exception handler
 31| with a bias of $6000 subtracted from the exponent.
 32|
 33|
 34
 35|		Copyright (C) Motorola, Inc. 1990
 36|			All Rights Reserved
 37|
 38|       For details on the license for this file, please see the
 39|       file, README, in this same directory.
 40
 41X_OVFL:	|idnt    2,1 | Motorola 040 Floating Point Software Package
 42
 43	|section	8
 44
 45#include "fpsp.h"
 46
 47	|xref	ovf_r_x2
 48	|xref	ovf_r_x3
 49	|xref	store
 50	|xref	real_ovfl
 51	|xref	real_inex
 52	|xref	fpsp_done
 53	|xref	g_opcls
 54	|xref	b1238_fix
 55
 56	.global	fpsp_ovfl
 57fpsp_ovfl:
 58	link		%a6,#-LOCAL_SIZE
 59	fsave		-(%a7)
 60	moveml		%d0-%d1/%a0-%a1,USER_DA(%a6)
 61	fmovemx	%fp0-%fp3,USER_FP0(%a6)
 62	fmoveml	%fpcr/%fpsr/%fpiar,USER_FPCR(%a6)
 63
 64|
 65|	The 040 doesn't set the AINEX bit in the FPSR, the following
 66|	line temporarily rectifies this error.
 67|
 68	bsetb	#ainex_bit,FPSR_AEXCEPT(%a6)
 69|
 70	bsrl	ovf_adj		|denormalize, round & store interm op
 71|
 72|	if overflow traps not enabled check for inexact exception
 73|
 74	btstb	#ovfl_bit,FPCR_ENABLE(%a6)
 75	beqs	ck_inex
 76|
 77	btstb		#E3,E_BYTE(%a6)
 78	beqs		no_e3_1
 79	bfextu		CMDREG3B(%a6){#6:#3},%d0	|get dest reg no
 80	bclrb		%d0,FPR_DIRTY_BITS(%a6)	|clr dest dirty bit
 81	bsrl		b1238_fix
 82	movel		USER_FPSR(%a6),FPSR_SHADOW(%a6)
 83	orl		#sx_mask,E_BYTE(%a6)
 84no_e3_1:
 85	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
 86	fmovemx	USER_FP0(%a6),%fp0-%fp3
 87	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
 88	frestore	(%a7)+
 89	unlk		%a6
 90	bral		real_ovfl
 91|
 92| It is possible to have either inex2 or inex1 exceptions with the
 93| ovfl.  If the inex enable bit is set in the FPCR, and either
 94| inex2 or inex1 occurred, we must clean up and branch to the
 95| real inex handler.
 96|
 97ck_inex:
 98|	move.b		FPCR_ENABLE(%a6),%d0
 99|	and.b		FPSR_EXCEPT(%a6),%d0
100|	andi.b		#$3,%d0
101	btstb		#inex2_bit,FPCR_ENABLE(%a6)
102	beqs		ovfl_exit
103|
104| Inexact enabled and reported, and we must take an inexact exception.
105|
106take_inex:
107	btstb		#E3,E_BYTE(%a6)
108	beqs		no_e3_2
109	bfextu		CMDREG3B(%a6){#6:#3},%d0	|get dest reg no
110	bclrb		%d0,FPR_DIRTY_BITS(%a6)	|clr dest dirty bit
111	bsrl		b1238_fix
112	movel		USER_FPSR(%a6),FPSR_SHADOW(%a6)
113	orl		#sx_mask,E_BYTE(%a6)
114no_e3_2:
115	moveb		#INEX_VEC,EXC_VEC+1(%a6)
116	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
117	fmovemx	USER_FP0(%a6),%fp0-%fp3
118	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
119	frestore	(%a7)+
120	unlk		%a6
121	bral		real_inex
122
123ovfl_exit:
124	bclrb	#E3,E_BYTE(%a6)	|test and clear E3 bit
125	beqs	e1_set
126|
127| Clear dirty bit on dest resister in the frame before branching
128| to b1238_fix.
129|
130	bfextu		CMDREG3B(%a6){#6:#3},%d0	|get dest reg no
131	bclrb		%d0,FPR_DIRTY_BITS(%a6)	|clr dest dirty bit
132	bsrl		b1238_fix		|test for bug1238 case
133
134	movel		USER_FPSR(%a6),FPSR_SHADOW(%a6)
135	orl		#sx_mask,E_BYTE(%a6)
136	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
137	fmovemx	USER_FP0(%a6),%fp0-%fp3
138	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
139	frestore	(%a7)+
140	unlk		%a6
141	bral		fpsp_done
142e1_set:
143	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
144	fmovemx	USER_FP0(%a6),%fp0-%fp3
145	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
146	unlk		%a6
147	bral		fpsp_done
148
149|
150|	ovf_adj
151|
152ovf_adj:
153|
154| Have a0 point to the correct operand.
155|
156	btstb	#E3,E_BYTE(%a6)	|test E3 bit
157	beqs	ovf_e1
158
159	lea	WBTEMP(%a6),%a0
160	bras	ovf_com
161ovf_e1:
162	lea	ETEMP(%a6),%a0
163
164ovf_com:
165	bclrb	#sign_bit,LOCAL_EX(%a0)
166	sne	LOCAL_SGN(%a0)
167
168	bsrl	g_opcls		|returns opclass in d0
169	cmpiw	#3,%d0		|check for opclass3
170	bnes	not_opc011
171
172|
173| FPSR_CC is saved and restored because ovf_r_x3 affects it. The
174| CCs are defined to be 'not affected' for the opclass3 instruction.
175|
176	moveb	FPSR_CC(%a6),L_SCR1(%a6)
177	bsrl	ovf_r_x3	|returns a0 pointing to result
178	moveb	L_SCR1(%a6),FPSR_CC(%a6)
179	bral	store		|stores to memory or register
180
181not_opc011:
182	bsrl	ovf_r_x2	|returns a0 pointing to result
183	bral	store		|stores to memory or register
184
185	|end
~/ Read-only file preview.