xref: /linux/arch/m68k/fpsp040/x_operr.S (revision e5451c8f8330e03ad3cfa16048b4daf961af434f)
11da177e4SLinus Torvalds|
21da177e4SLinus Torvalds|	x_operr.sa 3.5 7/1/91
31da177e4SLinus Torvalds|
41da177e4SLinus Torvalds|	fpsp_operr --- FPSP handler for operand error exception
51da177e4SLinus Torvalds|
61da177e4SLinus Torvalds|	See 68040 User's Manual pp. 9-44f
71da177e4SLinus Torvalds|
81da177e4SLinus Torvalds| Note 1: For trap disabled 040 does the following:
91da177e4SLinus Torvalds| If the dest is a fp reg, then an extended precision non_signaling
101da177e4SLinus Torvalds| NAN is stored in the dest reg.  If the dest format is b, w, or l and
111da177e4SLinus Torvalds| the source op is a NAN, then garbage is stored as the result (actually
121da177e4SLinus Torvalds| the upper 32 bits of the mantissa are sent to the integer unit). If
131da177e4SLinus Torvalds| the dest format is integer (b, w, l) and the operr is caused by
141da177e4SLinus Torvalds| integer overflow, or the source op is inf, then the result stored is
151da177e4SLinus Torvalds| garbage.
161da177e4SLinus Torvalds| There are three cases in which operr is incorrectly signaled on the
171da177e4SLinus Torvalds| 040.  This occurs for move_out of format b, w, or l for the largest
181da177e4SLinus Torvalds| negative integer (-2^7 for b, -2^15 for w, -2^31 for l).
191da177e4SLinus Torvalds|
201da177e4SLinus Torvalds|	  On opclass = 011 fmove.(b,w,l) that causes a conversion
211da177e4SLinus Torvalds|	  overflow -> OPERR, the exponent in wbte (and fpte) is:
221da177e4SLinus Torvalds|		byte    56 - (62 - exp)
231da177e4SLinus Torvalds|		word    48 - (62 - exp)
241da177e4SLinus Torvalds|		long    32 - (62 - exp)
251da177e4SLinus Torvalds|
261da177e4SLinus Torvalds|			where exp = (true exp) - 1
271da177e4SLinus Torvalds|
281da177e4SLinus Torvalds|  So, wbtemp and fptemp will contain the following on erroneously
291da177e4SLinus Torvalds|	  signalled operr:
301da177e4SLinus Torvalds|			fpts = 1
311da177e4SLinus Torvalds|			fpte = $4000  (15 bit externally)
321da177e4SLinus Torvalds|		byte	fptm = $ffffffff ffffff80
331da177e4SLinus Torvalds|		word	fptm = $ffffffff ffff8000
341da177e4SLinus Torvalds|		long	fptm = $ffffffff 80000000
351da177e4SLinus Torvalds|
361da177e4SLinus Torvalds| Note 2: For trap enabled 040 does the following:
371da177e4SLinus Torvalds| If the inst is move_out, then same as Note 1.
381da177e4SLinus Torvalds| If the inst is not move_out, the dest is not modified.
391da177e4SLinus Torvalds| The exceptional operand is not defined for integer overflow
401da177e4SLinus Torvalds| during a move_out.
411da177e4SLinus Torvalds|
421da177e4SLinus Torvalds
431da177e4SLinus Torvalds|		Copyright (C) Motorola, Inc. 1990
441da177e4SLinus Torvalds|			All Rights Reserved
451da177e4SLinus Torvalds|
46*e00d82d0SMatt Waddel|       For details on the license for this file, please see the
47*e00d82d0SMatt Waddel|       file, README, in this same directory.
481da177e4SLinus Torvalds
491da177e4SLinus TorvaldsX_OPERR:	|idnt    2,1 | Motorola 040 Floating Point Software Package
501da177e4SLinus Torvalds
511da177e4SLinus Torvalds	|section	8
521da177e4SLinus Torvalds
531da177e4SLinus Torvalds#include "fpsp.h"
541da177e4SLinus Torvalds
551da177e4SLinus Torvalds	|xref	mem_write
561da177e4SLinus Torvalds	|xref	real_operr
571da177e4SLinus Torvalds	|xref	real_inex
581da177e4SLinus Torvalds	|xref	get_fline
591da177e4SLinus Torvalds	|xref	fpsp_done
601da177e4SLinus Torvalds	|xref	reg_dest
611da177e4SLinus Torvalds
621da177e4SLinus Torvalds	.global	fpsp_operr
631da177e4SLinus Torvaldsfpsp_operr:
641da177e4SLinus Torvalds|
651da177e4SLinus Torvalds	link		%a6,#-LOCAL_SIZE
661da177e4SLinus Torvalds	fsave		-(%a7)
671da177e4SLinus Torvalds	moveml		%d0-%d1/%a0-%a1,USER_DA(%a6)
681da177e4SLinus Torvalds	fmovemx	%fp0-%fp3,USER_FP0(%a6)
691da177e4SLinus Torvalds	fmoveml	%fpcr/%fpsr/%fpiar,USER_FPCR(%a6)
701da177e4SLinus Torvalds
711da177e4SLinus Torvalds|
721da177e4SLinus Torvalds| Check if this is an opclass 3 instruction.
731da177e4SLinus Torvalds|  If so, fall through, else branch to operr_end
741da177e4SLinus Torvalds|
751da177e4SLinus Torvalds	btstb	#TFLAG,T_BYTE(%a6)
761da177e4SLinus Torvalds	beqs	operr_end
771da177e4SLinus Torvalds
781da177e4SLinus Torvalds|
791da177e4SLinus Torvalds| If the destination size is B,W,or L, the operr must be
801da177e4SLinus Torvalds| handled here.
811da177e4SLinus Torvalds|
821da177e4SLinus Torvalds	movel	CMDREG1B(%a6),%d0
831da177e4SLinus Torvalds	bfextu	%d0{#3:#3},%d0	|0=long, 4=word, 6=byte
841da177e4SLinus Torvalds	cmpib	#0,%d0		|determine size; check long
851da177e4SLinus Torvalds	beq	operr_long
861da177e4SLinus Torvalds	cmpib	#4,%d0		|check word
871da177e4SLinus Torvalds	beq	operr_word
881da177e4SLinus Torvalds	cmpib	#6,%d0		|check byte
891da177e4SLinus Torvalds	beq	operr_byte
901da177e4SLinus Torvalds
911da177e4SLinus Torvalds|
921da177e4SLinus Torvalds| The size is not B,W,or L, so the operr is handled by the
931da177e4SLinus Torvalds| kernel handler.  Set the operr bits and clean up, leaving
941da177e4SLinus Torvalds| only the integer exception frame on the stack, and the
951da177e4SLinus Torvalds| fpu in the original exceptional state.
961da177e4SLinus Torvalds|
971da177e4SLinus Torvaldsoperr_end:
981da177e4SLinus Torvalds	bsetb		#operr_bit,FPSR_EXCEPT(%a6)
991da177e4SLinus Torvalds	bsetb		#aiop_bit,FPSR_AEXCEPT(%a6)
1001da177e4SLinus Torvalds
1011da177e4SLinus Torvalds	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
1021da177e4SLinus Torvalds	fmovemx	USER_FP0(%a6),%fp0-%fp3
1031da177e4SLinus Torvalds	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
1041da177e4SLinus Torvalds	frestore	(%a7)+
1051da177e4SLinus Torvalds	unlk		%a6
1061da177e4SLinus Torvalds	bral		real_operr
1071da177e4SLinus Torvalds
1081da177e4SLinus Torvaldsoperr_long:
1091da177e4SLinus Torvalds	moveql	#4,%d1		|write size to d1
1101da177e4SLinus Torvalds	moveb	STAG(%a6),%d0	|test stag for nan
1111da177e4SLinus Torvalds	andib	#0xe0,%d0		|clr all but tag
1121da177e4SLinus Torvalds	cmpib	#0x60,%d0		|check for nan
1131da177e4SLinus Torvalds	beq	operr_nan
1141da177e4SLinus Torvalds	cmpil	#0x80000000,FPTEMP_LO(%a6) |test if ls lword is special
1151da177e4SLinus Torvalds	bnes	chklerr		|if not equal, check for incorrect operr
1161da177e4SLinus Torvalds	bsr	check_upper	|check if exp and ms mant are special
1171da177e4SLinus Torvalds	tstl	%d0
1181da177e4SLinus Torvalds	bnes	chklerr		|if d0 is true, check for incorrect operr
1191da177e4SLinus Torvalds	movel	#0x80000000,%d0	|store special case result
1201da177e4SLinus Torvalds	bsr	operr_store
1211da177e4SLinus Torvalds	bra	not_enabled	|clean and exit
1221da177e4SLinus Torvalds|
1231da177e4SLinus Torvalds|	CHECK FOR INCORRECTLY GENERATED OPERR EXCEPTION HERE
1241da177e4SLinus Torvalds|
1251da177e4SLinus Torvaldschklerr:
1261da177e4SLinus Torvalds	movew	FPTEMP_EX(%a6),%d0
1271da177e4SLinus Torvalds	andw	#0x7FFF,%d0	|ignore sign bit
1281da177e4SLinus Torvalds	cmpw	#0x3FFE,%d0	|this is the only possible exponent value
1291da177e4SLinus Torvalds	bnes	chklerr2
1301da177e4SLinus Torvaldsfixlong:
1311da177e4SLinus Torvalds	movel	FPTEMP_LO(%a6),%d0
1321da177e4SLinus Torvalds	bsr	operr_store
1331da177e4SLinus Torvalds	bra	not_enabled
1341da177e4SLinus Torvaldschklerr2:
1351da177e4SLinus Torvalds	movew	FPTEMP_EX(%a6),%d0
1361da177e4SLinus Torvalds	andw	#0x7FFF,%d0	|ignore sign bit
1371da177e4SLinus Torvalds	cmpw	#0x4000,%d0
1381da177e4SLinus Torvalds	bcc	store_max	|exponent out of range
1391da177e4SLinus Torvalds
1401da177e4SLinus Torvalds	movel	FPTEMP_LO(%a6),%d0
1411da177e4SLinus Torvalds	andl	#0x7FFF0000,%d0	|look for all 1's on bits 30-16
1421da177e4SLinus Torvalds	cmpl	#0x7FFF0000,%d0
1431da177e4SLinus Torvalds	beqs	fixlong
1441da177e4SLinus Torvalds
1451da177e4SLinus Torvalds	tstl	FPTEMP_LO(%a6)
1461da177e4SLinus Torvalds	bpls	chklepos
1471da177e4SLinus Torvalds	cmpl	#0xFFFFFFFF,FPTEMP_HI(%a6)
1481da177e4SLinus Torvalds	beqs	fixlong
1491da177e4SLinus Torvalds	bra	store_max
1501da177e4SLinus Torvaldschklepos:
1511da177e4SLinus Torvalds	tstl	FPTEMP_HI(%a6)
1521da177e4SLinus Torvalds	beqs	fixlong
1531da177e4SLinus Torvalds	bra	store_max
1541da177e4SLinus Torvalds
1551da177e4SLinus Torvaldsoperr_word:
1561da177e4SLinus Torvalds	moveql	#2,%d1		|write size to d1
1571da177e4SLinus Torvalds	moveb	STAG(%a6),%d0	|test stag for nan
1581da177e4SLinus Torvalds	andib	#0xe0,%d0		|clr all but tag
1591da177e4SLinus Torvalds	cmpib	#0x60,%d0		|check for nan
1601da177e4SLinus Torvalds	beq	operr_nan
1611da177e4SLinus Torvalds	cmpil	#0xffff8000,FPTEMP_LO(%a6) |test if ls lword is special
1621da177e4SLinus Torvalds	bnes	chkwerr		|if not equal, check for incorrect operr
1631da177e4SLinus Torvalds	bsr	check_upper	|check if exp and ms mant are special
1641da177e4SLinus Torvalds	tstl	%d0
1651da177e4SLinus Torvalds	bnes	chkwerr		|if d0 is true, check for incorrect operr
1661da177e4SLinus Torvalds	movel	#0x80000000,%d0	|store special case result
1671da177e4SLinus Torvalds	bsr	operr_store
1681da177e4SLinus Torvalds	bra	not_enabled	|clean and exit
1691da177e4SLinus Torvalds|
1701da177e4SLinus Torvalds|	CHECK FOR INCORRECTLY GENERATED OPERR EXCEPTION HERE
1711da177e4SLinus Torvalds|
1721da177e4SLinus Torvaldschkwerr:
1731da177e4SLinus Torvalds	movew	FPTEMP_EX(%a6),%d0
1741da177e4SLinus Torvalds	andw	#0x7FFF,%d0	|ignore sign bit
1751da177e4SLinus Torvalds	cmpw	#0x3FFE,%d0	|this is the only possible exponent value
1761da177e4SLinus Torvalds	bnes	store_max
1771da177e4SLinus Torvalds	movel	FPTEMP_LO(%a6),%d0
1781da177e4SLinus Torvalds	swap	%d0
1791da177e4SLinus Torvalds	bsr	operr_store
1801da177e4SLinus Torvalds	bra	not_enabled
1811da177e4SLinus Torvalds
1821da177e4SLinus Torvaldsoperr_byte:
1831da177e4SLinus Torvalds	moveql	#1,%d1		|write size to d1
1841da177e4SLinus Torvalds	moveb	STAG(%a6),%d0	|test stag for nan
1851da177e4SLinus Torvalds	andib	#0xe0,%d0		|clr all but tag
1861da177e4SLinus Torvalds	cmpib	#0x60,%d0		|check for nan
1871da177e4SLinus Torvalds	beqs	operr_nan
1881da177e4SLinus Torvalds	cmpil	#0xffffff80,FPTEMP_LO(%a6) |test if ls lword is special
1891da177e4SLinus Torvalds	bnes	chkberr		|if not equal, check for incorrect operr
1901da177e4SLinus Torvalds	bsr	check_upper	|check if exp and ms mant are special
1911da177e4SLinus Torvalds	tstl	%d0
1921da177e4SLinus Torvalds	bnes	chkberr		|if d0 is true, check for incorrect operr
1931da177e4SLinus Torvalds	movel	#0x80000000,%d0	|store special case result
1941da177e4SLinus Torvalds	bsr	operr_store
1951da177e4SLinus Torvalds	bra	not_enabled	|clean and exit
1961da177e4SLinus Torvalds|
1971da177e4SLinus Torvalds|	CHECK FOR INCORRECTLY GENERATED OPERR EXCEPTION HERE
1981da177e4SLinus Torvalds|
1991da177e4SLinus Torvaldschkberr:
2001da177e4SLinus Torvalds	movew	FPTEMP_EX(%a6),%d0
2011da177e4SLinus Torvalds	andw	#0x7FFF,%d0	|ignore sign bit
2021da177e4SLinus Torvalds	cmpw	#0x3FFE,%d0	|this is the only possible exponent value
2031da177e4SLinus Torvalds	bnes	store_max
2041da177e4SLinus Torvalds	movel	FPTEMP_LO(%a6),%d0
2051da177e4SLinus Torvalds	asll	#8,%d0
2061da177e4SLinus Torvalds	swap	%d0
2071da177e4SLinus Torvalds	bsr	operr_store
2081da177e4SLinus Torvalds	bra	not_enabled
2091da177e4SLinus Torvalds
2101da177e4SLinus Torvalds|
2111da177e4SLinus Torvalds| This operr condition is not of the special case.  Set operr
2121da177e4SLinus Torvalds| and aiop and write the portion of the nan to memory for the
2131da177e4SLinus Torvalds| given size.
2141da177e4SLinus Torvalds|
2151da177e4SLinus Torvaldsoperr_nan:
2161da177e4SLinus Torvalds	orl	#opaop_mask,USER_FPSR(%a6) |set operr & aiop
2171da177e4SLinus Torvalds
2181da177e4SLinus Torvalds	movel	ETEMP_HI(%a6),%d0	|output will be from upper 32 bits
2191da177e4SLinus Torvalds	bsr	operr_store
2201da177e4SLinus Torvalds	bra	end_operr
2211da177e4SLinus Torvalds|
2221da177e4SLinus Torvalds| Store_max loads the max pos or negative for the size, sets
2231da177e4SLinus Torvalds| the operr and aiop bits, and clears inex and ainex, incorrectly
2241da177e4SLinus Torvalds| set by the 040.
2251da177e4SLinus Torvalds|
2261da177e4SLinus Torvaldsstore_max:
2271da177e4SLinus Torvalds	orl	#opaop_mask,USER_FPSR(%a6) |set operr & aiop
2281da177e4SLinus Torvalds	bclrb	#inex2_bit,FPSR_EXCEPT(%a6)
2291da177e4SLinus Torvalds	bclrb	#ainex_bit,FPSR_AEXCEPT(%a6)
2301da177e4SLinus Torvalds	fmovel	#0,%FPSR
2311da177e4SLinus Torvalds
2321da177e4SLinus Torvalds	tstw	FPTEMP_EX(%a6)	|check sign
2331da177e4SLinus Torvalds	blts	load_neg
2341da177e4SLinus Torvalds	movel	#0x7fffffff,%d0
2351da177e4SLinus Torvalds	bsr	operr_store
2361da177e4SLinus Torvalds	bra	end_operr
2371da177e4SLinus Torvaldsload_neg:
2381da177e4SLinus Torvalds	movel	#0x80000000,%d0
2391da177e4SLinus Torvalds	bsr	operr_store
2401da177e4SLinus Torvalds	bra	end_operr
2411da177e4SLinus Torvalds
2421da177e4SLinus Torvalds|
2431da177e4SLinus Torvalds| This routine stores the data in d0, for the given size in d1,
2441da177e4SLinus Torvalds| to memory or data register as required.  A read of the fline
2451da177e4SLinus Torvalds| is required to determine the destination.
2461da177e4SLinus Torvalds|
2471da177e4SLinus Torvaldsoperr_store:
2481da177e4SLinus Torvalds	movel	%d0,L_SCR1(%a6)	|move write data to L_SCR1
2491da177e4SLinus Torvalds	movel	%d1,-(%a7)	|save register size
2501da177e4SLinus Torvalds	bsrl	get_fline	|fline returned in d0
2511da177e4SLinus Torvalds	movel	(%a7)+,%d1
2521da177e4SLinus Torvalds	bftst	%d0{#26:#3}		|if mode is zero, dest is Dn
2531da177e4SLinus Torvalds	bnes	dest_mem
2541da177e4SLinus Torvalds|
2551da177e4SLinus Torvalds| Destination is Dn.  Get register number from d0. Data is on
2561da177e4SLinus Torvalds| the stack at (a7). D1 has size: 1=byte,2=word,4=long/single
2571da177e4SLinus Torvalds|
2581da177e4SLinus Torvalds	andil	#7,%d0		|isolate register number
2591da177e4SLinus Torvalds	cmpil	#4,%d1
2601da177e4SLinus Torvalds	beqs	op_long		|the most frequent case
2611da177e4SLinus Torvalds	cmpil	#2,%d1
2621da177e4SLinus Torvalds	bnes	op_con
2631da177e4SLinus Torvalds	orl	#8,%d0
2641da177e4SLinus Torvalds	bras	op_con
2651da177e4SLinus Torvaldsop_long:
2661da177e4SLinus Torvalds	orl	#0x10,%d0
2671da177e4SLinus Torvaldsop_con:
2681da177e4SLinus Torvalds	movel	%d0,%d1		|format size:reg for reg_dest
2691da177e4SLinus Torvalds	bral	reg_dest	|call to reg_dest returns to caller
2701da177e4SLinus Torvalds|				;of operr_store
2711da177e4SLinus Torvalds|
2721da177e4SLinus Torvalds| Destination is memory.  Get <ea> from integer exception frame
2731da177e4SLinus Torvalds| and call mem_write.
2741da177e4SLinus Torvalds|
2751da177e4SLinus Torvaldsdest_mem:
2761da177e4SLinus Torvalds	leal	L_SCR1(%a6),%a0	|put ptr to write data in a0
2771da177e4SLinus Torvalds	movel	EXC_EA(%a6),%a1	|put user destination address in a1
2781da177e4SLinus Torvalds	movel	%d1,%d0		|put size in d0
2791da177e4SLinus Torvalds	bsrl	mem_write
2801da177e4SLinus Torvalds	rts
2811da177e4SLinus Torvalds|
2821da177e4SLinus Torvalds| Check the exponent for $c000 and the upper 32 bits of the
2831da177e4SLinus Torvalds| mantissa for $ffffffff.  If both are true, return d0 clr
2841da177e4SLinus Torvalds| and store the lower n bits of the least lword of FPTEMP
2851da177e4SLinus Torvalds| to d0 for write out.  If not, it is a real operr, and set d0.
2861da177e4SLinus Torvalds|
2871da177e4SLinus Torvaldscheck_upper:
2881da177e4SLinus Torvalds	cmpil	#0xffffffff,FPTEMP_HI(%a6) |check if first byte is all 1's
2891da177e4SLinus Torvalds	bnes	true_operr	|if not all 1's then was true operr
2901da177e4SLinus Torvalds	cmpiw	#0xc000,FPTEMP_EX(%a6) |check if incorrectly signalled
2911da177e4SLinus Torvalds	beqs	not_true_operr	|branch if not true operr
2921da177e4SLinus Torvalds	cmpiw	#0xbfff,FPTEMP_EX(%a6) |check if incorrectly signalled
2931da177e4SLinus Torvalds	beqs	not_true_operr	|branch if not true operr
2941da177e4SLinus Torvaldstrue_operr:
2951da177e4SLinus Torvalds	movel	#1,%d0		|signal real operr
2961da177e4SLinus Torvalds	rts
2971da177e4SLinus Torvaldsnot_true_operr:
2981da177e4SLinus Torvalds	clrl	%d0		|signal no real operr
2991da177e4SLinus Torvalds	rts
3001da177e4SLinus Torvalds
3011da177e4SLinus Torvalds|
3021da177e4SLinus Torvalds| End_operr tests for operr enabled.  If not, it cleans up the stack
3031da177e4SLinus Torvalds| and does an rte.  If enabled, it cleans up the stack and branches
3041da177e4SLinus Torvalds| to the kernel operr handler with only the integer exception
3051da177e4SLinus Torvalds| frame on the stack and the fpu in the original exceptional state
3061da177e4SLinus Torvalds| with correct data written to the destination.
3071da177e4SLinus Torvalds|
3081da177e4SLinus Torvaldsend_operr:
3091da177e4SLinus Torvalds	btstb		#operr_bit,FPCR_ENABLE(%a6)
3101da177e4SLinus Torvalds	beqs		not_enabled
3111da177e4SLinus Torvaldsenabled:
3121da177e4SLinus Torvalds	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
3131da177e4SLinus Torvalds	fmovemx	USER_FP0(%a6),%fp0-%fp3
3141da177e4SLinus Torvalds	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
3151da177e4SLinus Torvalds	frestore	(%a7)+
3161da177e4SLinus Torvalds	unlk		%a6
3171da177e4SLinus Torvalds	bral		real_operr
3181da177e4SLinus Torvalds
3191da177e4SLinus Torvaldsnot_enabled:
3201da177e4SLinus Torvalds|
3211da177e4SLinus Torvalds| It is possible to have either inex2 or inex1 exceptions with the
3221da177e4SLinus Torvalds| operr.  If the inex enable bit is set in the FPCR, and either
3231da177e4SLinus Torvalds| inex2 or inex1 occurred, we must clean up and branch to the
3241da177e4SLinus Torvalds| real inex handler.
3251da177e4SLinus Torvalds|
3261da177e4SLinus Torvaldsck_inex:
3271da177e4SLinus Torvalds	moveb	FPCR_ENABLE(%a6),%d0
3281da177e4SLinus Torvalds	andb	FPSR_EXCEPT(%a6),%d0
3291da177e4SLinus Torvalds	andib	#0x3,%d0
3301da177e4SLinus Torvalds	beq	operr_exit
3311da177e4SLinus Torvalds|
3321da177e4SLinus Torvalds| Inexact enabled and reported, and we must take an inexact exception.
3331da177e4SLinus Torvalds|
3341da177e4SLinus Torvaldstake_inex:
3351da177e4SLinus Torvalds	moveb		#INEX_VEC,EXC_VEC+1(%a6)
3361da177e4SLinus Torvalds	movel		USER_FPSR(%a6),FPSR_SHADOW(%a6)
3371da177e4SLinus Torvalds	orl		#sx_mask,E_BYTE(%a6)
3381da177e4SLinus Torvalds	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
3391da177e4SLinus Torvalds	fmovemx	USER_FP0(%a6),%fp0-%fp3
3401da177e4SLinus Torvalds	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
3411da177e4SLinus Torvalds	frestore	(%a7)+
3421da177e4SLinus Torvalds	unlk		%a6
3431da177e4SLinus Torvalds	bral		real_inex
3441da177e4SLinus Torvalds|
3451da177e4SLinus Torvalds| Since operr is only an E1 exception, there is no need to frestore
3461da177e4SLinus Torvalds| any state back to the fpu.
3471da177e4SLinus Torvalds|
3481da177e4SLinus Torvaldsoperr_exit:
3491da177e4SLinus Torvalds	moveml		USER_DA(%a6),%d0-%d1/%a0-%a1
3501da177e4SLinus Torvalds	fmovemx	USER_FP0(%a6),%fp0-%fp3
3511da177e4SLinus Torvalds	fmoveml	USER_FPCR(%a6),%fpcr/%fpsr/%fpiar
3521da177e4SLinus Torvalds	unlk		%a6
3531da177e4SLinus Torvalds	bral		fpsp_done
3541da177e4SLinus Torvalds
3551da177e4SLinus Torvalds	|end
356