18c2ecf20Sopenharmony_ci|
28c2ecf20Sopenharmony_ci|	x_ovfl.sa 3.5 7/1/91
38c2ecf20Sopenharmony_ci|
48c2ecf20Sopenharmony_ci|	fpsp_ovfl --- FPSP handler for overflow exception
58c2ecf20Sopenharmony_ci|
68c2ecf20Sopenharmony_ci|	Overflow occurs when a floating-point intermediate result is
78c2ecf20Sopenharmony_ci|	too large to be represented in a floating-point data register,
88c2ecf20Sopenharmony_ci|	or when storing to memory, the contents of a floating-point
98c2ecf20Sopenharmony_ci|	data register are too large to be represented in the
108c2ecf20Sopenharmony_ci|	destination format.
118c2ecf20Sopenharmony_ci|
128c2ecf20Sopenharmony_ci| Trap disabled results
138c2ecf20Sopenharmony_ci|
148c2ecf20Sopenharmony_ci| If the instruction is move_out, then garbage is stored in the
158c2ecf20Sopenharmony_ci| destination.  If the instruction is not move_out, then the
168c2ecf20Sopenharmony_ci| destination is not affected.  For 68881 compatibility, the
178c2ecf20Sopenharmony_ci| following values should be stored at the destination, based
188c2ecf20Sopenharmony_ci| on the current rounding mode:
198c2ecf20Sopenharmony_ci|
208c2ecf20Sopenharmony_ci|  RN	Infinity with the sign of the intermediate result.
218c2ecf20Sopenharmony_ci|  RZ	Largest magnitude number, with the sign of the
228c2ecf20Sopenharmony_ci|	intermediate result.
238c2ecf20Sopenharmony_ci|  RM   For pos overflow, the largest pos number. For neg overflow,
248c2ecf20Sopenharmony_ci|	-infinity
258c2ecf20Sopenharmony_ci|  RP   For pos overflow, +infinity. For neg overflow, the largest
268c2ecf20Sopenharmony_ci|	neg number
278c2ecf20Sopenharmony_ci|
288c2ecf20Sopenharmony_ci| Trap enabled results
298c2ecf20Sopenharmony_ci| All trap disabled code applies.  In addition the exceptional
308c2ecf20Sopenharmony_ci| operand needs to be made available to the users exception handler
318c2ecf20Sopenharmony_ci| with a bias of $6000 subtracted from the exponent.
328c2ecf20Sopenharmony_ci|
338c2ecf20Sopenharmony_ci|
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci|		Copyright (C) Motorola, Inc. 1990
368c2ecf20Sopenharmony_ci|			All Rights Reserved
378c2ecf20Sopenharmony_ci|
388c2ecf20Sopenharmony_ci|       For details on the license for this file, please see the
398c2ecf20Sopenharmony_ci|       file, README, in this same directory.
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ciX_OVFL:	|idnt    2,1 | Motorola 040 Floating Point Software Package
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	|section	8
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci#include "fpsp.h"
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	|xref	ovf_r_x2
488c2ecf20Sopenharmony_ci	|xref	ovf_r_x3
498c2ecf20Sopenharmony_ci	|xref	store
508c2ecf20Sopenharmony_ci	|xref	real_ovfl
518c2ecf20Sopenharmony_ci	|xref	real_inex
528c2ecf20Sopenharmony_ci	|xref	fpsp_done
538c2ecf20Sopenharmony_ci	|xref	g_opcls
548c2ecf20Sopenharmony_ci	|xref	b1238_fix
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	.global	fpsp_ovfl
578c2ecf20Sopenharmony_cifpsp_ovfl:
588c2ecf20Sopenharmony_ci	link		%a6,#-LOCAL_SIZE
598c2ecf20Sopenharmony_ci	fsave		-(%a7)
608c2ecf20Sopenharmony_ci	moveml		%d0-%d1/%a0-%a1,USER_DA(%a6)
618c2ecf20Sopenharmony_ci	fmovemx	%fp0-%fp3,USER_FP0(%a6)
628c2ecf20Sopenharmony_ci	fmoveml	%fpcr/%fpsr/%fpiar,USER_FPCR(%a6)
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci|
658c2ecf20Sopenharmony_ci|	The 040 doesn't set the AINEX bit in the FPSR, the following
668c2ecf20Sopenharmony_ci|	line temporarily rectifies this error.
678c2ecf20Sopenharmony_ci|
688c2ecf20Sopenharmony_ci	bsetb	#ainex_bit,FPSR_AEXCEPT(%a6)
698c2ecf20Sopenharmony_ci|
708c2ecf20Sopenharmony_ci	bsrl	ovf_adj		|denormalize, round & store interm op
718c2ecf20Sopenharmony_ci|
728c2ecf20Sopenharmony_ci|	if overflow traps not enabled check for inexact exception
738c2ecf20Sopenharmony_ci|
748c2ecf20Sopenharmony_ci	btstb	#ovfl_bit,FPCR_ENABLE(%a6)
758c2ecf20Sopenharmony_ci	beqs	ck_inex
768c2ecf20Sopenharmony_ci|
778c2ecf20Sopenharmony_ci	btstb		#E3,E_BYTE(%a6)
788c2ecf20Sopenharmony_ci	beqs		no_e3_1
798c2ecf20Sopenharmony_ci	bfextu		CMDREG3B(%a6){#6:#3},%d0	|get dest reg no
808c2ecf20Sopenharmony_ci	bclrb		%d0,FPR_DIRTY_BITS(%a6)	|clr dest dirty bit
818c2ecf20Sopenharmony_ci	bsrl		b1238_fix
828c2ecf20Sopenharmony_ci	movel		USER_FPSR(%a6),FPSR_SHADOW(%a6)
838c2ecf20Sopenharmony_ci	orl		#sx_mask,E_BYTE(%a6)
848c2ecf20Sopenharmony_cino_e3_1:
858c2ecf20Sopenharmony_ci	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
868c2ecf20Sopenharmony_ci	fmovemx	USER_FP0(%a6),%fp0-%fp3
878c2ecf20Sopenharmony_ci	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
888c2ecf20Sopenharmony_ci	frestore	(%a7)+
898c2ecf20Sopenharmony_ci	unlk		%a6
908c2ecf20Sopenharmony_ci	bral		real_ovfl
918c2ecf20Sopenharmony_ci|
928c2ecf20Sopenharmony_ci| It is possible to have either inex2 or inex1 exceptions with the
938c2ecf20Sopenharmony_ci| ovfl.  If the inex enable bit is set in the FPCR, and either
948c2ecf20Sopenharmony_ci| inex2 or inex1 occurred, we must clean up and branch to the
958c2ecf20Sopenharmony_ci| real inex handler.
968c2ecf20Sopenharmony_ci|
978c2ecf20Sopenharmony_cick_inex:
988c2ecf20Sopenharmony_ci|	move.b		FPCR_ENABLE(%a6),%d0
998c2ecf20Sopenharmony_ci|	and.b		FPSR_EXCEPT(%a6),%d0
1008c2ecf20Sopenharmony_ci|	andi.b		#$3,%d0
1018c2ecf20Sopenharmony_ci	btstb		#inex2_bit,FPCR_ENABLE(%a6)
1028c2ecf20Sopenharmony_ci	beqs		ovfl_exit
1038c2ecf20Sopenharmony_ci|
1048c2ecf20Sopenharmony_ci| Inexact enabled and reported, and we must take an inexact exception.
1058c2ecf20Sopenharmony_ci|
1068c2ecf20Sopenharmony_citake_inex:
1078c2ecf20Sopenharmony_ci	btstb		#E3,E_BYTE(%a6)
1088c2ecf20Sopenharmony_ci	beqs		no_e3_2
1098c2ecf20Sopenharmony_ci	bfextu		CMDREG3B(%a6){#6:#3},%d0	|get dest reg no
1108c2ecf20Sopenharmony_ci	bclrb		%d0,FPR_DIRTY_BITS(%a6)	|clr dest dirty bit
1118c2ecf20Sopenharmony_ci	bsrl		b1238_fix
1128c2ecf20Sopenharmony_ci	movel		USER_FPSR(%a6),FPSR_SHADOW(%a6)
1138c2ecf20Sopenharmony_ci	orl		#sx_mask,E_BYTE(%a6)
1148c2ecf20Sopenharmony_cino_e3_2:
1158c2ecf20Sopenharmony_ci	moveb		#INEX_VEC,EXC_VEC+1(%a6)
1168c2ecf20Sopenharmony_ci	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
1178c2ecf20Sopenharmony_ci	fmovemx	USER_FP0(%a6),%fp0-%fp3
1188c2ecf20Sopenharmony_ci	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
1198c2ecf20Sopenharmony_ci	frestore	(%a7)+
1208c2ecf20Sopenharmony_ci	unlk		%a6
1218c2ecf20Sopenharmony_ci	bral		real_inex
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ciovfl_exit:
1248c2ecf20Sopenharmony_ci	bclrb	#E3,E_BYTE(%a6)	|test and clear E3 bit
1258c2ecf20Sopenharmony_ci	beqs	e1_set
1268c2ecf20Sopenharmony_ci|
1278c2ecf20Sopenharmony_ci| Clear dirty bit on dest resister in the frame before branching
1288c2ecf20Sopenharmony_ci| to b1238_fix.
1298c2ecf20Sopenharmony_ci|
1308c2ecf20Sopenharmony_ci	bfextu		CMDREG3B(%a6){#6:#3},%d0	|get dest reg no
1318c2ecf20Sopenharmony_ci	bclrb		%d0,FPR_DIRTY_BITS(%a6)	|clr dest dirty bit
1328c2ecf20Sopenharmony_ci	bsrl		b1238_fix		|test for bug1238 case
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	movel		USER_FPSR(%a6),FPSR_SHADOW(%a6)
1358c2ecf20Sopenharmony_ci	orl		#sx_mask,E_BYTE(%a6)
1368c2ecf20Sopenharmony_ci	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
1378c2ecf20Sopenharmony_ci	fmovemx	USER_FP0(%a6),%fp0-%fp3
1388c2ecf20Sopenharmony_ci	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
1398c2ecf20Sopenharmony_ci	frestore	(%a7)+
1408c2ecf20Sopenharmony_ci	unlk		%a6
1418c2ecf20Sopenharmony_ci	bral		fpsp_done
1428c2ecf20Sopenharmony_cie1_set:
1438c2ecf20Sopenharmony_ci	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
1448c2ecf20Sopenharmony_ci	fmovemx	USER_FP0(%a6),%fp0-%fp3
1458c2ecf20Sopenharmony_ci	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
1468c2ecf20Sopenharmony_ci	unlk		%a6
1478c2ecf20Sopenharmony_ci	bral		fpsp_done
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci|
1508c2ecf20Sopenharmony_ci|	ovf_adj
1518c2ecf20Sopenharmony_ci|
1528c2ecf20Sopenharmony_ciovf_adj:
1538c2ecf20Sopenharmony_ci|
1548c2ecf20Sopenharmony_ci| Have a0 point to the correct operand.
1558c2ecf20Sopenharmony_ci|
1568c2ecf20Sopenharmony_ci	btstb	#E3,E_BYTE(%a6)	|test E3 bit
1578c2ecf20Sopenharmony_ci	beqs	ovf_e1
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	lea	WBTEMP(%a6),%a0
1608c2ecf20Sopenharmony_ci	bras	ovf_com
1618c2ecf20Sopenharmony_ciovf_e1:
1628c2ecf20Sopenharmony_ci	lea	ETEMP(%a6),%a0
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ciovf_com:
1658c2ecf20Sopenharmony_ci	bclrb	#sign_bit,LOCAL_EX(%a0)
1668c2ecf20Sopenharmony_ci	sne	LOCAL_SGN(%a0)
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci	bsrl	g_opcls		|returns opclass in d0
1698c2ecf20Sopenharmony_ci	cmpiw	#3,%d0		|check for opclass3
1708c2ecf20Sopenharmony_ci	bnes	not_opc011
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci|
1738c2ecf20Sopenharmony_ci| FPSR_CC is saved and restored because ovf_r_x3 affects it. The
1748c2ecf20Sopenharmony_ci| CCs are defined to be 'not affected' for the opclass3 instruction.
1758c2ecf20Sopenharmony_ci|
1768c2ecf20Sopenharmony_ci	moveb	FPSR_CC(%a6),L_SCR1(%a6)
1778c2ecf20Sopenharmony_ci	bsrl	ovf_r_x3	|returns a0 pointing to result
1788c2ecf20Sopenharmony_ci	moveb	L_SCR1(%a6),FPSR_CC(%a6)
1798c2ecf20Sopenharmony_ci	bral	store		|stores to memory or register
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_cinot_opc011:
1828c2ecf20Sopenharmony_ci	bsrl	ovf_r_x2	|returns a0 pointing to result
1838c2ecf20Sopenharmony_ci	bral	store		|stores to memory or register
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci	|end
186