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