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