1*4882a593Smuzhiyun/* 2*4882a593Smuzhiyun * fp_emu.S 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Copyright Roman Zippel, 1997. All rights reserved. 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * Redistribution and use in source and binary forms, with or without 7*4882a593Smuzhiyun * modification, are permitted provided that the following conditions 8*4882a593Smuzhiyun * are met: 9*4882a593Smuzhiyun * 1. Redistributions of source code must retain the above copyright 10*4882a593Smuzhiyun * notice, and the entire permission notice in its entirety, 11*4882a593Smuzhiyun * including the disclaimer of warranties. 12*4882a593Smuzhiyun * 2. Redistributions in binary form must reproduce the above copyright 13*4882a593Smuzhiyun * notice, this list of conditions and the following disclaimer in the 14*4882a593Smuzhiyun * documentation and/or other materials provided with the distribution. 15*4882a593Smuzhiyun * 3. The name of the author may not be used to endorse or promote 16*4882a593Smuzhiyun * products derived from this software without specific prior 17*4882a593Smuzhiyun * written permission. 18*4882a593Smuzhiyun * 19*4882a593Smuzhiyun * ALTERNATIVELY, this product may be distributed under the terms of 20*4882a593Smuzhiyun * the GNU General Public License, in which case the provisions of the GPL are 21*4882a593Smuzhiyun * required INSTEAD OF the above restrictions. (This clause is 22*4882a593Smuzhiyun * necessary due to a potential bad interaction between the GPL and 23*4882a593Smuzhiyun * the restrictions contained in a BSD-style copyright.) 24*4882a593Smuzhiyun * 25*4882a593Smuzhiyun * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 26*4882a593Smuzhiyun * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27*4882a593Smuzhiyun * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28*4882a593Smuzhiyun * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 29*4882a593Smuzhiyun * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30*4882a593Smuzhiyun * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31*4882a593Smuzhiyun * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32*4882a593Smuzhiyun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 33*4882a593Smuzhiyun * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34*4882a593Smuzhiyun * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 35*4882a593Smuzhiyun * OF THE POSSIBILITY OF SUCH DAMAGE. 36*4882a593Smuzhiyun */ 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun#include <linux/linkage.h> 39*4882a593Smuzhiyun#include <asm/entry.h> 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun#include "fp_emu.h" 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun .globl fpu_emu 44*4882a593Smuzhiyun .globl fp_debugprint 45*4882a593Smuzhiyun .globl fp_err_ua1,fp_err_ua2 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun .text 48*4882a593Smuzhiyunfpu_emu: 49*4882a593Smuzhiyun SAVE_ALL_INT 50*4882a593Smuzhiyun GET_CURRENT(%d0) 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun#if defined(CPU_M68020_OR_M68030) && defined(CPU_M68040_OR_M68060) 53*4882a593Smuzhiyun tst.l m68k_is040or060 54*4882a593Smuzhiyun jeq 1f 55*4882a593Smuzhiyun#endif 56*4882a593Smuzhiyun#if defined(CPU_M68040_OR_M68060) 57*4882a593Smuzhiyun move.l (FPS_PC2,%sp),(FPS_PC,%sp) 58*4882a593Smuzhiyun#endif 59*4882a593Smuzhiyun1: 60*4882a593Smuzhiyun | emulate the instruction 61*4882a593Smuzhiyun jsr fp_scan 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun#if defined(CONFIG_M68060) 64*4882a593Smuzhiyun#if !defined(CPU_M68060_ONLY) 65*4882a593Smuzhiyun btst #3,m68k_cputype+3 66*4882a593Smuzhiyun jeq 1f 67*4882a593Smuzhiyun#endif 68*4882a593Smuzhiyun btst #7,(FPS_SR,%sp) 69*4882a593Smuzhiyun jne fp_sendtrace060 70*4882a593Smuzhiyun#endif 71*4882a593Smuzhiyun1: 72*4882a593Smuzhiyun | emulation successful? 73*4882a593Smuzhiyun tst.l %d0 74*4882a593Smuzhiyun jeq ret_from_exception 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun | send some signal to program here 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun jra ret_from_exception 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun | we jump here after an access error while trying to access 81*4882a593Smuzhiyun | user space, we correct stackpointer and send a SIGSEGV to 82*4882a593Smuzhiyun | the user process 83*4882a593Smuzhiyunfp_err_ua2: 84*4882a593Smuzhiyun addq.l #4,%sp 85*4882a593Smuzhiyunfp_err_ua1: 86*4882a593Smuzhiyun addq.l #4,%sp 87*4882a593Smuzhiyun move.l %a0,-(%sp) 88*4882a593Smuzhiyun pea LSEGV_MAPERR 89*4882a593Smuzhiyun pea LSIGSEGV 90*4882a593Smuzhiyun jsr fpemu_signal 91*4882a593Smuzhiyun add.w #12,%sp 92*4882a593Smuzhiyun jra ret_from_exception 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun#if defined(CONFIG_M68060) 95*4882a593Smuzhiyun | send a trace signal if we are debugged 96*4882a593Smuzhiyun | it does not really belong here, but... 97*4882a593Smuzhiyunfp_sendtrace060: 98*4882a593Smuzhiyun move.l (FPS_PC,%sp),-(%sp) 99*4882a593Smuzhiyun pea LTRAP_TRACE 100*4882a593Smuzhiyun pea LSIGTRAP 101*4882a593Smuzhiyun jsr fpemu_signal 102*4882a593Smuzhiyun add.w #12,%sp 103*4882a593Smuzhiyun jra ret_from_exception 104*4882a593Smuzhiyun#endif 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun .globl fp_get_data_reg, fp_put_data_reg 107*4882a593Smuzhiyun .globl fp_get_addr_reg, fp_put_addr_reg 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun | Entry points to get/put a register. Some of them can be get/put 110*4882a593Smuzhiyun | directly, others are on the stack, as we read/write the stack 111*4882a593Smuzhiyun | directly here, these function may only be called from within 112*4882a593Smuzhiyun | instruction decoding, otherwise the stack pointer is incorrect 113*4882a593Smuzhiyun | and the stack gets corrupted. 114*4882a593Smuzhiyunfp_get_data_reg: 115*4882a593Smuzhiyun jmp ([0f:w,%pc,%d0.w*4]) 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun .align 4 118*4882a593Smuzhiyun0: 119*4882a593Smuzhiyun .long fp_get_d0, fp_get_d1 120*4882a593Smuzhiyun .long fp_get_d2, fp_get_d3 121*4882a593Smuzhiyun .long fp_get_d4, fp_get_d5 122*4882a593Smuzhiyun .long fp_get_d6, fp_get_d7 123*4882a593Smuzhiyun 124*4882a593Smuzhiyunfp_get_d0: 125*4882a593Smuzhiyun move.l (PT_OFF_D0+8,%sp),%d0 126*4882a593Smuzhiyun printf PREGISTER,"{d0->%08x}",1,%d0 127*4882a593Smuzhiyun rts 128*4882a593Smuzhiyun 129*4882a593Smuzhiyunfp_get_d1: 130*4882a593Smuzhiyun move.l (PT_OFF_D1+8,%sp),%d0 131*4882a593Smuzhiyun printf PREGISTER,"{d1->%08x}",1,%d0 132*4882a593Smuzhiyun rts 133*4882a593Smuzhiyun 134*4882a593Smuzhiyunfp_get_d2: 135*4882a593Smuzhiyun move.l (PT_OFF_D2+8,%sp),%d0 136*4882a593Smuzhiyun printf PREGISTER,"{d2->%08x}",1,%d0 137*4882a593Smuzhiyun rts 138*4882a593Smuzhiyun 139*4882a593Smuzhiyunfp_get_d3: 140*4882a593Smuzhiyun move.l %d3,%d0 141*4882a593Smuzhiyun printf PREGISTER,"{d3->%08x}",1,%d0 142*4882a593Smuzhiyun rts 143*4882a593Smuzhiyun 144*4882a593Smuzhiyunfp_get_d4: 145*4882a593Smuzhiyun move.l %d4,%d0 146*4882a593Smuzhiyun printf PREGISTER,"{d4->%08x}",1,%d0 147*4882a593Smuzhiyun rts 148*4882a593Smuzhiyun 149*4882a593Smuzhiyunfp_get_d5: 150*4882a593Smuzhiyun move.l %d5,%d0 151*4882a593Smuzhiyun printf PREGISTER,"{d5->%08x}",1,%d0 152*4882a593Smuzhiyun rts 153*4882a593Smuzhiyun 154*4882a593Smuzhiyunfp_get_d6: 155*4882a593Smuzhiyun move.l %d6,%d0 156*4882a593Smuzhiyun printf PREGISTER,"{d6->%08x}",1,%d0 157*4882a593Smuzhiyun rts 158*4882a593Smuzhiyun 159*4882a593Smuzhiyunfp_get_d7: 160*4882a593Smuzhiyun move.l %d7,%d0 161*4882a593Smuzhiyun printf PREGISTER,"{d7->%08x}",1,%d0 162*4882a593Smuzhiyun rts 163*4882a593Smuzhiyun 164*4882a593Smuzhiyunfp_put_data_reg: 165*4882a593Smuzhiyun jmp ([0f:w,%pc,%d1.w*4]) 166*4882a593Smuzhiyun 167*4882a593Smuzhiyun .align 4 168*4882a593Smuzhiyun0: 169*4882a593Smuzhiyun .long fp_put_d0, fp_put_d1 170*4882a593Smuzhiyun .long fp_put_d2, fp_put_d3 171*4882a593Smuzhiyun .long fp_put_d4, fp_put_d5 172*4882a593Smuzhiyun .long fp_put_d6, fp_put_d7 173*4882a593Smuzhiyun 174*4882a593Smuzhiyunfp_put_d0: 175*4882a593Smuzhiyun printf PREGISTER,"{d0<-%08x}",1,%d0 176*4882a593Smuzhiyun move.l %d0,(PT_OFF_D0+8,%sp) 177*4882a593Smuzhiyun rts 178*4882a593Smuzhiyun 179*4882a593Smuzhiyunfp_put_d1: 180*4882a593Smuzhiyun printf PREGISTER,"{d1<-%08x}",1,%d0 181*4882a593Smuzhiyun move.l %d0,(PT_OFF_D1+8,%sp) 182*4882a593Smuzhiyun rts 183*4882a593Smuzhiyun 184*4882a593Smuzhiyunfp_put_d2: 185*4882a593Smuzhiyun printf PREGISTER,"{d2<-%08x}",1,%d0 186*4882a593Smuzhiyun move.l %d0,(PT_OFF_D2+8,%sp) 187*4882a593Smuzhiyun rts 188*4882a593Smuzhiyun 189*4882a593Smuzhiyunfp_put_d3: 190*4882a593Smuzhiyun printf PREGISTER,"{d3<-%08x}",1,%d0 191*4882a593Smuzhiyun| move.l %d0,%d3 192*4882a593Smuzhiyun move.l %d0,(PT_OFF_D3+8,%sp) 193*4882a593Smuzhiyun rts 194*4882a593Smuzhiyun 195*4882a593Smuzhiyunfp_put_d4: 196*4882a593Smuzhiyun printf PREGISTER,"{d4<-%08x}",1,%d0 197*4882a593Smuzhiyun| move.l %d0,%d4 198*4882a593Smuzhiyun move.l %d0,(PT_OFF_D4+8,%sp) 199*4882a593Smuzhiyun rts 200*4882a593Smuzhiyun 201*4882a593Smuzhiyunfp_put_d5: 202*4882a593Smuzhiyun printf PREGISTER,"{d5<-%08x}",1,%d0 203*4882a593Smuzhiyun| move.l %d0,%d5 204*4882a593Smuzhiyun move.l %d0,(PT_OFF_D5+8,%sp) 205*4882a593Smuzhiyun rts 206*4882a593Smuzhiyun 207*4882a593Smuzhiyunfp_put_d6: 208*4882a593Smuzhiyun printf PREGISTER,"{d6<-%08x}",1,%d0 209*4882a593Smuzhiyun move.l %d0,%d6 210*4882a593Smuzhiyun rts 211*4882a593Smuzhiyun 212*4882a593Smuzhiyunfp_put_d7: 213*4882a593Smuzhiyun printf PREGISTER,"{d7<-%08x}",1,%d0 214*4882a593Smuzhiyun move.l %d0,%d7 215*4882a593Smuzhiyun rts 216*4882a593Smuzhiyun 217*4882a593Smuzhiyunfp_get_addr_reg: 218*4882a593Smuzhiyun jmp ([0f:w,%pc,%d0.w*4]) 219*4882a593Smuzhiyun 220*4882a593Smuzhiyun .align 4 221*4882a593Smuzhiyun0: 222*4882a593Smuzhiyun .long fp_get_a0, fp_get_a1 223*4882a593Smuzhiyun .long fp_get_a2, fp_get_a3 224*4882a593Smuzhiyun .long fp_get_a4, fp_get_a5 225*4882a593Smuzhiyun .long fp_get_a6, fp_get_a7 226*4882a593Smuzhiyun 227*4882a593Smuzhiyunfp_get_a0: 228*4882a593Smuzhiyun move.l (PT_OFF_A0+8,%sp),%a0 229*4882a593Smuzhiyun printf PREGISTER,"{a0->%08x}",1,%a0 230*4882a593Smuzhiyun rts 231*4882a593Smuzhiyun 232*4882a593Smuzhiyunfp_get_a1: 233*4882a593Smuzhiyun move.l (PT_OFF_A1+8,%sp),%a0 234*4882a593Smuzhiyun printf PREGISTER,"{a1->%08x}",1,%a0 235*4882a593Smuzhiyun rts 236*4882a593Smuzhiyun 237*4882a593Smuzhiyunfp_get_a2: 238*4882a593Smuzhiyun move.l (PT_OFF_A2+8,%sp),%a0 239*4882a593Smuzhiyun printf PREGISTER,"{a2->%08x}",1,%a0 240*4882a593Smuzhiyun rts 241*4882a593Smuzhiyun 242*4882a593Smuzhiyunfp_get_a3: 243*4882a593Smuzhiyun move.l %a3,%a0 244*4882a593Smuzhiyun printf PREGISTER,"{a3->%08x}",1,%a0 245*4882a593Smuzhiyun rts 246*4882a593Smuzhiyun 247*4882a593Smuzhiyunfp_get_a4: 248*4882a593Smuzhiyun move.l %a4,%a0 249*4882a593Smuzhiyun printf PREGISTER,"{a4->%08x}",1,%a0 250*4882a593Smuzhiyun rts 251*4882a593Smuzhiyun 252*4882a593Smuzhiyunfp_get_a5: 253*4882a593Smuzhiyun move.l %a5,%a0 254*4882a593Smuzhiyun printf PREGISTER,"{a5->%08x}",1,%a0 255*4882a593Smuzhiyun rts 256*4882a593Smuzhiyun 257*4882a593Smuzhiyunfp_get_a6: 258*4882a593Smuzhiyun move.l %a6,%a0 259*4882a593Smuzhiyun printf PREGISTER,"{a6->%08x}",1,%a0 260*4882a593Smuzhiyun rts 261*4882a593Smuzhiyun 262*4882a593Smuzhiyunfp_get_a7: 263*4882a593Smuzhiyun move.l %usp,%a0 264*4882a593Smuzhiyun printf PREGISTER,"{a7->%08x}",1,%a0 265*4882a593Smuzhiyun rts 266*4882a593Smuzhiyun 267*4882a593Smuzhiyunfp_put_addr_reg: 268*4882a593Smuzhiyun jmp ([0f:w,%pc,%d0.w*4]) 269*4882a593Smuzhiyun 270*4882a593Smuzhiyun .align 4 271*4882a593Smuzhiyun0: 272*4882a593Smuzhiyun .long fp_put_a0, fp_put_a1 273*4882a593Smuzhiyun .long fp_put_a2, fp_put_a3 274*4882a593Smuzhiyun .long fp_put_a4, fp_put_a5 275*4882a593Smuzhiyun .long fp_put_a6, fp_put_a7 276*4882a593Smuzhiyun 277*4882a593Smuzhiyunfp_put_a0: 278*4882a593Smuzhiyun printf PREGISTER,"{a0<-%08x}",1,%a0 279*4882a593Smuzhiyun move.l %a0,(PT_OFF_A0+8,%sp) 280*4882a593Smuzhiyun rts 281*4882a593Smuzhiyun 282*4882a593Smuzhiyunfp_put_a1: 283*4882a593Smuzhiyun printf PREGISTER,"{a1<-%08x}",1,%a0 284*4882a593Smuzhiyun move.l %a0,(PT_OFF_A1+8,%sp) 285*4882a593Smuzhiyun rts 286*4882a593Smuzhiyun 287*4882a593Smuzhiyunfp_put_a2: 288*4882a593Smuzhiyun printf PREGISTER,"{a2<-%08x}",1,%a0 289*4882a593Smuzhiyun move.l %a0,(PT_OFF_A2+8,%sp) 290*4882a593Smuzhiyun rts 291*4882a593Smuzhiyun 292*4882a593Smuzhiyunfp_put_a3: 293*4882a593Smuzhiyun printf PREGISTER,"{a3<-%08x}",1,%a0 294*4882a593Smuzhiyun move.l %a0,%a3 295*4882a593Smuzhiyun rts 296*4882a593Smuzhiyun 297*4882a593Smuzhiyunfp_put_a4: 298*4882a593Smuzhiyun printf PREGISTER,"{a4<-%08x}",1,%a0 299*4882a593Smuzhiyun move.l %a0,%a4 300*4882a593Smuzhiyun rts 301*4882a593Smuzhiyun 302*4882a593Smuzhiyunfp_put_a5: 303*4882a593Smuzhiyun printf PREGISTER,"{a5<-%08x}",1,%a0 304*4882a593Smuzhiyun move.l %a0,%a5 305*4882a593Smuzhiyun rts 306*4882a593Smuzhiyun 307*4882a593Smuzhiyunfp_put_a6: 308*4882a593Smuzhiyun printf PREGISTER,"{a6<-%08x}",1,%a0 309*4882a593Smuzhiyun move.l %a0,%a6 310*4882a593Smuzhiyun rts 311*4882a593Smuzhiyun 312*4882a593Smuzhiyunfp_put_a7: 313*4882a593Smuzhiyun printf PREGISTER,"{a7<-%08x}",1,%a0 314*4882a593Smuzhiyun move.l %a0,%usp 315*4882a593Smuzhiyun rts 316*4882a593Smuzhiyun 317*4882a593Smuzhiyun .data 318*4882a593Smuzhiyun .align 4 319*4882a593Smuzhiyun 320*4882a593Smuzhiyunfp_debugprint: 321*4882a593Smuzhiyun| .long PMDECODE 322*4882a593Smuzhiyun .long PMINSTR+PMDECODE+PMCONV+PMNORM 323*4882a593Smuzhiyun| .long PMCONV+PMNORM+PMINSTR 324*4882a593Smuzhiyun| .long 0 325