xref: /linux/arch/m68k/math-emu/fp_entry.S (revision 96910b6d)
11da177e4SLinus Torvalds/*
21da177e4SLinus Torvalds * fp_emu.S
31da177e4SLinus Torvalds *
41da177e4SLinus Torvalds * Copyright Roman Zippel, 1997.  All rights reserved.
51da177e4SLinus Torvalds *
61da177e4SLinus Torvalds * Redistribution and use in source and binary forms, with or without
71da177e4SLinus Torvalds * modification, are permitted provided that the following conditions
81da177e4SLinus Torvalds * are met:
91da177e4SLinus Torvalds * 1. Redistributions of source code must retain the above copyright
101da177e4SLinus Torvalds *    notice, and the entire permission notice in its entirety,
111da177e4SLinus Torvalds *    including the disclaimer of warranties.
121da177e4SLinus Torvalds * 2. Redistributions in binary form must reproduce the above copyright
131da177e4SLinus Torvalds *    notice, this list of conditions and the following disclaimer in the
141da177e4SLinus Torvalds *    documentation and/or other materials provided with the distribution.
151da177e4SLinus Torvalds * 3. The name of the author may not be used to endorse or promote
161da177e4SLinus Torvalds *    products derived from this software without specific prior
171da177e4SLinus Torvalds *    written permission.
181da177e4SLinus Torvalds *
191da177e4SLinus Torvalds * ALTERNATIVELY, this product may be distributed under the terms of
201da177e4SLinus Torvalds * the GNU General Public License, in which case the provisions of the GPL are
211da177e4SLinus Torvalds * required INSTEAD OF the above restrictions.  (This clause is
221da177e4SLinus Torvalds * necessary due to a potential bad interaction between the GPL and
231da177e4SLinus Torvalds * the restrictions contained in a BSD-style copyright.)
241da177e4SLinus Torvalds *
251da177e4SLinus Torvalds * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
261da177e4SLinus Torvalds * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
271da177e4SLinus Torvalds * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
281da177e4SLinus Torvalds * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
291da177e4SLinus Torvalds * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
301da177e4SLinus Torvalds * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
311da177e4SLinus Torvalds * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
321da177e4SLinus Torvalds * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
331da177e4SLinus Torvalds * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
341da177e4SLinus Torvalds * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
351da177e4SLinus Torvalds * OF THE POSSIBILITY OF SUCH DAMAGE.
361da177e4SLinus Torvalds */
371da177e4SLinus Torvalds
381da177e4SLinus Torvalds#include <linux/linkage.h>
391da177e4SLinus Torvalds#include <asm/entry.h>
401da177e4SLinus Torvalds
411da177e4SLinus Torvalds#include "fp_emu.h"
421da177e4SLinus Torvalds
431da177e4SLinus Torvalds	.globl	fpu_emu
441da177e4SLinus Torvalds	.globl	fp_debugprint
451da177e4SLinus Torvalds	.globl	fp_err_ua1,fp_err_ua2
461da177e4SLinus Torvalds
471da177e4SLinus Torvalds	.text
481da177e4SLinus Torvaldsfpu_emu:
491da177e4SLinus Torvalds	SAVE_ALL_INT
501da177e4SLinus Torvalds	GET_CURRENT(%d0)
511da177e4SLinus Torvalds
521da177e4SLinus Torvalds#if defined(CPU_M68020_OR_M68030) && defined(CPU_M68040_OR_M68060)
531da177e4SLinus Torvalds        tst.l	m68k_is040or060
541da177e4SLinus Torvalds        jeq	1f
551da177e4SLinus Torvalds#endif
561da177e4SLinus Torvalds#if defined(CPU_M68040_OR_M68060)
571da177e4SLinus Torvalds	move.l	(FPS_PC2,%sp),(FPS_PC,%sp)
581da177e4SLinus Torvalds#endif
591da177e4SLinus Torvalds1:
601da177e4SLinus Torvalds	| emulate the instruction
611da177e4SLinus Torvalds	jsr	fp_scan
621da177e4SLinus Torvalds
631da177e4SLinus Torvalds#if defined(CONFIG_M68060)
641da177e4SLinus Torvalds#if !defined(CPU_M68060_ONLY)
651da177e4SLinus Torvalds	btst	#3,m68k_cputype+3
661da177e4SLinus Torvalds	jeq	1f
671da177e4SLinus Torvalds#endif
681da177e4SLinus Torvalds	btst	#7,(FPS_SR,%sp)
691da177e4SLinus Torvalds	jne	fp_sendtrace060
701da177e4SLinus Torvalds#endif
711da177e4SLinus Torvalds1:
721da177e4SLinus Torvalds	| emulation successful?
731da177e4SLinus Torvalds	tst.l	%d0
741da177e4SLinus Torvalds	jeq	ret_from_exception
751da177e4SLinus Torvalds
761da177e4SLinus Torvalds	| send some signal to program here
771da177e4SLinus Torvalds
781da177e4SLinus Torvalds	jra	ret_from_exception
791da177e4SLinus Torvalds
801da177e4SLinus Torvalds	| we jump here after an access error while trying to access
811da177e4SLinus Torvalds	| user space, we correct stackpointer and send a SIGSEGV to
821da177e4SLinus Torvalds	| the user process
831da177e4SLinus Torvaldsfp_err_ua2:
841da177e4SLinus Torvalds	addq.l	#4,%sp
851da177e4SLinus Torvaldsfp_err_ua1:
861da177e4SLinus Torvalds	addq.l	#4,%sp
871da177e4SLinus Torvalds	move.l	%a0,-(%sp)
88*96910b6dSHeiko Carstens	pea	LSEGV_MAPERR
89*96910b6dSHeiko Carstens	pea	LSIGSEGV
901da177e4SLinus Torvalds	jsr	fpemu_signal
911da177e4SLinus Torvalds	add.w	#12,%sp
921da177e4SLinus Torvalds	jra	ret_from_exception
931da177e4SLinus Torvalds
941da177e4SLinus Torvalds#if defined(CONFIG_M68060)
951da177e4SLinus Torvalds	| send a trace signal if we are debugged
961da177e4SLinus Torvalds	| it does not really belong here, but...
971da177e4SLinus Torvaldsfp_sendtrace060:
981da177e4SLinus Torvalds	move.l	(FPS_PC,%sp),-(%sp)
99*96910b6dSHeiko Carstens	pea	LTRAP_TRACE
100*96910b6dSHeiko Carstens	pea	LSIGTRAP
1011da177e4SLinus Torvalds	jsr	fpemu_signal
1021da177e4SLinus Torvalds	add.w	#12,%sp
1031da177e4SLinus Torvalds	jra	ret_from_exception
1041da177e4SLinus Torvalds#endif
1051da177e4SLinus Torvalds
1061da177e4SLinus Torvalds	.globl	fp_get_data_reg, fp_put_data_reg
1071da177e4SLinus Torvalds	.globl	fp_get_addr_reg, fp_put_addr_reg
1081da177e4SLinus Torvalds
1091da177e4SLinus Torvalds	| Entry points to get/put a register. Some of them can be get/put
1101da177e4SLinus Torvalds	| directly, others are on the stack, as we read/write the stack
1111da177e4SLinus Torvalds	| directly here, these function may only be called from within
1121da177e4SLinus Torvalds	| instruction decoding, otherwise the stack pointer is incorrect
1131da177e4SLinus Torvalds	| and the stack gets corrupted.
1141da177e4SLinus Torvaldsfp_get_data_reg:
1151da177e4SLinus Torvalds	jmp	([0f:w,%pc,%d0.w*4])
1161da177e4SLinus Torvalds
1171da177e4SLinus Torvalds	.align	4
1181da177e4SLinus Torvalds0:
1191da177e4SLinus Torvalds	.long	fp_get_d0, fp_get_d1
1201da177e4SLinus Torvalds	.long	fp_get_d2, fp_get_d3
1211da177e4SLinus Torvalds	.long	fp_get_d4, fp_get_d5
1221da177e4SLinus Torvalds	.long	fp_get_d6, fp_get_d7
1231da177e4SLinus Torvalds
1241da177e4SLinus Torvaldsfp_get_d0:
125f159ee78SHeiko Carstens	move.l	(PT_OFF_D0+8,%sp),%d0
1261da177e4SLinus Torvalds	printf	PREGISTER,"{d0->%08x}",1,%d0
1271da177e4SLinus Torvalds	rts
1281da177e4SLinus Torvalds
1291da177e4SLinus Torvaldsfp_get_d1:
130f159ee78SHeiko Carstens	move.l	(PT_OFF_D1+8,%sp),%d0
1311da177e4SLinus Torvalds	printf	PREGISTER,"{d1->%08x}",1,%d0
1321da177e4SLinus Torvalds	rts
1331da177e4SLinus Torvalds
1341da177e4SLinus Torvaldsfp_get_d2:
135f159ee78SHeiko Carstens	move.l	(PT_OFF_D2+8,%sp),%d0
1361da177e4SLinus Torvalds	printf	PREGISTER,"{d2->%08x}",1,%d0
1371da177e4SLinus Torvalds	rts
1381da177e4SLinus Torvalds
1391da177e4SLinus Torvaldsfp_get_d3:
1401da177e4SLinus Torvalds	move.l	%d3,%d0
1411da177e4SLinus Torvalds	printf	PREGISTER,"{d3->%08x}",1,%d0
1421da177e4SLinus Torvalds	rts
1431da177e4SLinus Torvalds
1441da177e4SLinus Torvaldsfp_get_d4:
1451da177e4SLinus Torvalds	move.l	%d4,%d0
1461da177e4SLinus Torvalds	printf	PREGISTER,"{d4->%08x}",1,%d0
1471da177e4SLinus Torvalds	rts
1481da177e4SLinus Torvalds
1491da177e4SLinus Torvaldsfp_get_d5:
1501da177e4SLinus Torvalds	move.l	%d5,%d0
1511da177e4SLinus Torvalds	printf	PREGISTER,"{d5->%08x}",1,%d0
1521da177e4SLinus Torvalds	rts
1531da177e4SLinus Torvalds
1541da177e4SLinus Torvaldsfp_get_d6:
1551da177e4SLinus Torvalds	move.l	%d6,%d0
1561da177e4SLinus Torvalds	printf	PREGISTER,"{d6->%08x}",1,%d0
1571da177e4SLinus Torvalds	rts
1581da177e4SLinus Torvalds
1591da177e4SLinus Torvaldsfp_get_d7:
1601da177e4SLinus Torvalds	move.l	%d7,%d0
1611da177e4SLinus Torvalds	printf	PREGISTER,"{d7->%08x}",1,%d0
1621da177e4SLinus Torvalds	rts
1631da177e4SLinus Torvalds
1641da177e4SLinus Torvaldsfp_put_data_reg:
1651da177e4SLinus Torvalds	jmp	([0f:w,%pc,%d1.w*4])
1661da177e4SLinus Torvalds
1671da177e4SLinus Torvalds	.align	4
1681da177e4SLinus Torvalds0:
1691da177e4SLinus Torvalds	.long	fp_put_d0, fp_put_d1
1701da177e4SLinus Torvalds	.long	fp_put_d2, fp_put_d3
1711da177e4SLinus Torvalds	.long	fp_put_d4, fp_put_d5
1721da177e4SLinus Torvalds	.long	fp_put_d6, fp_put_d7
1731da177e4SLinus Torvalds
1741da177e4SLinus Torvaldsfp_put_d0:
1751da177e4SLinus Torvalds	printf	PREGISTER,"{d0<-%08x}",1,%d0
176f159ee78SHeiko Carstens	move.l	%d0,(PT_OFF_D0+8,%sp)
1771da177e4SLinus Torvalds	rts
1781da177e4SLinus Torvalds
1791da177e4SLinus Torvaldsfp_put_d1:
1801da177e4SLinus Torvalds	printf	PREGISTER,"{d1<-%08x}",1,%d0
181f159ee78SHeiko Carstens	move.l	%d0,(PT_OFF_D1+8,%sp)
1821da177e4SLinus Torvalds	rts
1831da177e4SLinus Torvalds
1841da177e4SLinus Torvaldsfp_put_d2:
1851da177e4SLinus Torvalds	printf	PREGISTER,"{d2<-%08x}",1,%d0
186f159ee78SHeiko Carstens	move.l	%d0,(PT_OFF_D2+8,%sp)
1871da177e4SLinus Torvalds	rts
1881da177e4SLinus Torvalds
1891da177e4SLinus Torvaldsfp_put_d3:
1901da177e4SLinus Torvalds	printf	PREGISTER,"{d3<-%08x}",1,%d0
1911da177e4SLinus Torvalds|	move.l	%d0,%d3
192f159ee78SHeiko Carstens	move.l	%d0,(PT_OFF_D3+8,%sp)
1931da177e4SLinus Torvalds	rts
1941da177e4SLinus Torvalds
1951da177e4SLinus Torvaldsfp_put_d4:
1961da177e4SLinus Torvalds	printf	PREGISTER,"{d4<-%08x}",1,%d0
1971da177e4SLinus Torvalds|	move.l	%d0,%d4
198f159ee78SHeiko Carstens	move.l	%d0,(PT_OFF_D4+8,%sp)
1991da177e4SLinus Torvalds	rts
2001da177e4SLinus Torvalds
2011da177e4SLinus Torvaldsfp_put_d5:
2021da177e4SLinus Torvalds	printf	PREGISTER,"{d5<-%08x}",1,%d0
2031da177e4SLinus Torvalds|	move.l	%d0,%d5
204f159ee78SHeiko Carstens	move.l	%d0,(PT_OFF_D5+8,%sp)
2051da177e4SLinus Torvalds	rts
2061da177e4SLinus Torvalds
2071da177e4SLinus Torvaldsfp_put_d6:
2081da177e4SLinus Torvalds	printf	PREGISTER,"{d6<-%08x}",1,%d0
2091da177e4SLinus Torvalds	move.l	%d0,%d6
2101da177e4SLinus Torvalds	rts
2111da177e4SLinus Torvalds
2121da177e4SLinus Torvaldsfp_put_d7:
2131da177e4SLinus Torvalds	printf	PREGISTER,"{d7<-%08x}",1,%d0
2141da177e4SLinus Torvalds	move.l	%d0,%d7
2151da177e4SLinus Torvalds	rts
2161da177e4SLinus Torvalds
2171da177e4SLinus Torvaldsfp_get_addr_reg:
2181da177e4SLinus Torvalds	jmp	([0f:w,%pc,%d0.w*4])
2191da177e4SLinus Torvalds
2201da177e4SLinus Torvalds	.align	4
2211da177e4SLinus Torvalds0:
2221da177e4SLinus Torvalds	.long	fp_get_a0, fp_get_a1
2231da177e4SLinus Torvalds	.long	fp_get_a2, fp_get_a3
2241da177e4SLinus Torvalds	.long	fp_get_a4, fp_get_a5
2251da177e4SLinus Torvalds	.long	fp_get_a6, fp_get_a7
2261da177e4SLinus Torvalds
2271da177e4SLinus Torvaldsfp_get_a0:
228f159ee78SHeiko Carstens	move.l	(PT_OFF_A0+8,%sp),%a0
2291da177e4SLinus Torvalds	printf	PREGISTER,"{a0->%08x}",1,%a0
2301da177e4SLinus Torvalds	rts
2311da177e4SLinus Torvalds
2321da177e4SLinus Torvaldsfp_get_a1:
233f159ee78SHeiko Carstens	move.l	(PT_OFF_A1+8,%sp),%a0
2341da177e4SLinus Torvalds	printf	PREGISTER,"{a1->%08x}",1,%a0
2351da177e4SLinus Torvalds	rts
2361da177e4SLinus Torvalds
2371da177e4SLinus Torvaldsfp_get_a2:
238f159ee78SHeiko Carstens	move.l	(PT_OFF_A2+8,%sp),%a0
2391da177e4SLinus Torvalds	printf	PREGISTER,"{a2->%08x}",1,%a0
2401da177e4SLinus Torvalds	rts
2411da177e4SLinus Torvalds
2421da177e4SLinus Torvaldsfp_get_a3:
2431da177e4SLinus Torvalds	move.l	%a3,%a0
2441da177e4SLinus Torvalds	printf	PREGISTER,"{a3->%08x}",1,%a0
2451da177e4SLinus Torvalds	rts
2461da177e4SLinus Torvalds
2471da177e4SLinus Torvaldsfp_get_a4:
2481da177e4SLinus Torvalds	move.l	%a4,%a0
2491da177e4SLinus Torvalds	printf	PREGISTER,"{a4->%08x}",1,%a0
2501da177e4SLinus Torvalds	rts
2511da177e4SLinus Torvalds
2521da177e4SLinus Torvaldsfp_get_a5:
2531da177e4SLinus Torvalds	move.l	%a5,%a0
2541da177e4SLinus Torvalds	printf	PREGISTER,"{a5->%08x}",1,%a0
2551da177e4SLinus Torvalds	rts
2561da177e4SLinus Torvalds
2571da177e4SLinus Torvaldsfp_get_a6:
2581da177e4SLinus Torvalds	move.l	%a6,%a0
2591da177e4SLinus Torvalds	printf	PREGISTER,"{a6->%08x}",1,%a0
2601da177e4SLinus Torvalds	rts
2611da177e4SLinus Torvalds
2621da177e4SLinus Torvaldsfp_get_a7:
2631da177e4SLinus Torvalds	move.l	%usp,%a0
2641da177e4SLinus Torvalds	printf	PREGISTER,"{a7->%08x}",1,%a0
2651da177e4SLinus Torvalds	rts
2661da177e4SLinus Torvalds
2671da177e4SLinus Torvaldsfp_put_addr_reg:
2681da177e4SLinus Torvalds	jmp	([0f:w,%pc,%d0.w*4])
2691da177e4SLinus Torvalds
2701da177e4SLinus Torvalds	.align	4
2711da177e4SLinus Torvalds0:
2721da177e4SLinus Torvalds	.long	fp_put_a0, fp_put_a1
2731da177e4SLinus Torvalds	.long	fp_put_a2, fp_put_a3
2741da177e4SLinus Torvalds	.long	fp_put_a4, fp_put_a5
2751da177e4SLinus Torvalds	.long	fp_put_a6, fp_put_a7
2761da177e4SLinus Torvalds
2771da177e4SLinus Torvaldsfp_put_a0:
2781da177e4SLinus Torvalds	printf	PREGISTER,"{a0<-%08x}",1,%a0
279f159ee78SHeiko Carstens	move.l	%a0,(PT_OFF_A0+8,%sp)
2801da177e4SLinus Torvalds	rts
2811da177e4SLinus Torvalds
2821da177e4SLinus Torvaldsfp_put_a1:
2831da177e4SLinus Torvalds	printf	PREGISTER,"{a1<-%08x}",1,%a0
284f159ee78SHeiko Carstens	move.l	%a0,(PT_OFF_A1+8,%sp)
2851da177e4SLinus Torvalds	rts
2861da177e4SLinus Torvalds
2871da177e4SLinus Torvaldsfp_put_a2:
2881da177e4SLinus Torvalds	printf	PREGISTER,"{a2<-%08x}",1,%a0
289f159ee78SHeiko Carstens	move.l	%a0,(PT_OFF_A2+8,%sp)
2901da177e4SLinus Torvalds	rts
2911da177e4SLinus Torvalds
2921da177e4SLinus Torvaldsfp_put_a3:
2931da177e4SLinus Torvalds	printf	PREGISTER,"{a3<-%08x}",1,%a0
2941da177e4SLinus Torvalds	move.l	%a0,%a3
2951da177e4SLinus Torvalds	rts
2961da177e4SLinus Torvalds
2971da177e4SLinus Torvaldsfp_put_a4:
2981da177e4SLinus Torvalds	printf	PREGISTER,"{a4<-%08x}",1,%a0
2991da177e4SLinus Torvalds	move.l	%a0,%a4
3001da177e4SLinus Torvalds	rts
3011da177e4SLinus Torvalds
3021da177e4SLinus Torvaldsfp_put_a5:
3031da177e4SLinus Torvalds	printf	PREGISTER,"{a5<-%08x}",1,%a0
3041da177e4SLinus Torvalds	move.l	%a0,%a5
3051da177e4SLinus Torvalds	rts
3061da177e4SLinus Torvalds
3071da177e4SLinus Torvaldsfp_put_a6:
3081da177e4SLinus Torvalds	printf	PREGISTER,"{a6<-%08x}",1,%a0
3091da177e4SLinus Torvalds	move.l	%a0,%a6
3101da177e4SLinus Torvalds	rts
3111da177e4SLinus Torvalds
3121da177e4SLinus Torvaldsfp_put_a7:
3131da177e4SLinus Torvalds	printf	PREGISTER,"{a7<-%08x}",1,%a0
3141da177e4SLinus Torvalds	move.l	%a0,%usp
3151da177e4SLinus Torvalds	rts
3161da177e4SLinus Torvalds
3171da177e4SLinus Torvalds	.data
3181da177e4SLinus Torvalds	.align	4
3191da177e4SLinus Torvalds
3201da177e4SLinus Torvaldsfp_debugprint:
3211da177e4SLinus Torvalds|	.long	PMDECODE
3221da177e4SLinus Torvalds	.long	PMINSTR+PMDECODE+PMCONV+PMNORM
3231da177e4SLinus Torvalds|	.long	PMCONV+PMNORM+PMINSTR
3241da177e4SLinus Torvalds|	.long	0
325