1*1da177e4SLinus Torvalds/* 2*1da177e4SLinus Torvalds * fp_scan.S 3*1da177e4SLinus Torvalds * 4*1da177e4SLinus Torvalds * Copyright Roman Zippel, 1997. All rights reserved. 5*1da177e4SLinus Torvalds * 6*1da177e4SLinus Torvalds * Redistribution and use in source and binary forms, with or without 7*1da177e4SLinus Torvalds * modification, are permitted provided that the following conditions 8*1da177e4SLinus Torvalds * are met: 9*1da177e4SLinus Torvalds * 1. Redistributions of source code must retain the above copyright 10*1da177e4SLinus Torvalds * notice, and the entire permission notice in its entirety, 11*1da177e4SLinus Torvalds * including the disclaimer of warranties. 12*1da177e4SLinus Torvalds * 2. Redistributions in binary form must reproduce the above copyright 13*1da177e4SLinus Torvalds * notice, this list of conditions and the following disclaimer in the 14*1da177e4SLinus Torvalds * documentation and/or other materials provided with the distribution. 15*1da177e4SLinus Torvalds * 3. The name of the author may not be used to endorse or promote 16*1da177e4SLinus Torvalds * products derived from this software without specific prior 17*1da177e4SLinus Torvalds * written permission. 18*1da177e4SLinus Torvalds * 19*1da177e4SLinus Torvalds * ALTERNATIVELY, this product may be distributed under the terms of 20*1da177e4SLinus Torvalds * the GNU General Public License, in which case the provisions of the GPL are 21*1da177e4SLinus Torvalds * required INSTEAD OF the above restrictions. (This clause is 22*1da177e4SLinus Torvalds * necessary due to a potential bad interaction between the GPL and 23*1da177e4SLinus Torvalds * the restrictions contained in a BSD-style copyright.) 24*1da177e4SLinus Torvalds * 25*1da177e4SLinus Torvalds * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 26*1da177e4SLinus Torvalds * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27*1da177e4SLinus Torvalds * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28*1da177e4SLinus Torvalds * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 29*1da177e4SLinus Torvalds * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30*1da177e4SLinus Torvalds * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31*1da177e4SLinus Torvalds * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32*1da177e4SLinus Torvalds * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 33*1da177e4SLinus Torvalds * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34*1da177e4SLinus Torvalds * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 35*1da177e4SLinus Torvalds * OF THE POSSIBILITY OF SUCH DAMAGE. 36*1da177e4SLinus Torvalds */ 37*1da177e4SLinus Torvalds 38*1da177e4SLinus Torvalds#include "fp_emu.h" 39*1da177e4SLinus Torvalds#include "fp_decode.h" 40*1da177e4SLinus Torvalds 41*1da177e4SLinus Torvalds .globl fp_scan, fp_datasize 42*1da177e4SLinus Torvalds 43*1da177e4SLinus Torvalds .data 44*1da177e4SLinus Torvalds 45*1da177e4SLinus Torvalds| %d2 - first two instr words 46*1da177e4SLinus Torvalds| %d1 - operand size 47*1da177e4SLinus Torvalds 48*1da177e4SLinus Torvalds/* operand formats are: 49*1da177e4SLinus Torvalds 50*1da177e4SLinus Torvalds Long = 0, i.e. fmove.l 51*1da177e4SLinus Torvalds Single, i.e. fmove.s 52*1da177e4SLinus Torvalds Extended, i.e. fmove.x 53*1da177e4SLinus Torvalds Packed-BCD, i.e. fmove.p 54*1da177e4SLinus Torvalds Word, i.e. fmove.w 55*1da177e4SLinus Torvalds Double, i.e. fmove.d 56*1da177e4SLinus Torvalds*/ 57*1da177e4SLinus Torvalds 58*1da177e4SLinus Torvalds .text 59*1da177e4SLinus Torvalds 60*1da177e4SLinus Torvalds| On entry: 61*1da177e4SLinus Torvalds| FPDATA - base of emulated FPU registers 62*1da177e4SLinus Torvalds 63*1da177e4SLinus Torvaldsfp_scan: 64*1da177e4SLinus Torvalds| normal fpu instruction? (this excludes fsave/frestore) 65*1da177e4SLinus Torvalds fp_get_pc %a0 66*1da177e4SLinus Torvalds printf PDECODE,"%08x: ",1,%a0 67*1da177e4SLinus Torvalds getuser.b (%a0),%d0,fp_err_ua1,%a0 68*1da177e4SLinus Torvalds#if 1 69*1da177e4SLinus Torvalds cmp.b #0xf2,%d0 | cpid = 1 70*1da177e4SLinus Torvalds#else 71*1da177e4SLinus Torvalds cmp.b #0xfc,%d0 | cpid = 6 72*1da177e4SLinus Torvalds#endif 73*1da177e4SLinus Torvalds jne fp_nonstd 74*1da177e4SLinus Torvalds| first two instruction words are kept in %d2 75*1da177e4SLinus Torvalds getuser.l (%a0)+,%d2,fp_err_ua1,%a0 76*1da177e4SLinus Torvalds fp_put_pc %a0 77*1da177e4SLinus Torvaldsfp_decode_cond: | separate conditional instr 78*1da177e4SLinus Torvalds fp_decode_cond_instr_type 79*1da177e4SLinus Torvalds 80*1da177e4SLinus Torvalds .long fp_decode_move, fp_fscc 81*1da177e4SLinus Torvalds .long fp_fbccw, fp_fbccl 82*1da177e4SLinus Torvalds 83*1da177e4SLinus Torvaldsfp_decode_move: | separate move instr 84*1da177e4SLinus Torvalds fp_decode_move_instr_type 85*1da177e4SLinus Torvalds 86*1da177e4SLinus Torvalds .long fp_fgen_fp, fp_ill 87*1da177e4SLinus Torvalds .long fp_fgen_ea, fp_fmove_fp2mem 88*1da177e4SLinus Torvalds .long fp_fmovem_cr, fp_fmovem_cr 89*1da177e4SLinus Torvalds .long fp_fmovem_fp, fp_fmovem_fp 90*1da177e4SLinus Torvalds 91*1da177e4SLinus Torvalds| now all arithmetic instr and a few move instr are left 92*1da177e4SLinus Torvaldsfp_fgen_fp: | source is a fpu register 93*1da177e4SLinus Torvalds clr.b (FPD_FPSR+2,FPDATA) | clear the exception byte 94*1da177e4SLinus Torvalds fp_decode_sourcespec 95*1da177e4SLinus Torvalds printf PDECODE,"f<op>.x fp%d",1,%d0 96*1da177e4SLinus Torvalds fp_get_fp_reg 97*1da177e4SLinus Torvalds lea (FPD_TEMPFP1,FPDATA),%a1 | copy src into a temp location 98*1da177e4SLinus Torvalds move.l (%a0)+,(%a1)+ 99*1da177e4SLinus Torvalds move.l (%a0)+,(%a1)+ 100*1da177e4SLinus Torvalds move.l (%a0),(%a1) 101*1da177e4SLinus Torvalds lea (-8,%a1),%a0 102*1da177e4SLinus Torvalds jra fp_getdest 103*1da177e4SLinus Torvalds 104*1da177e4SLinus Torvaldsfp_fgen_ea: | source is <ea> 105*1da177e4SLinus Torvalds clr.b (FPD_FPSR+2,FPDATA) | clear the exception byte 106*1da177e4SLinus Torvalds | sort out fmovecr, keep data size in %d1 107*1da177e4SLinus Torvalds fp_decode_sourcespec 108*1da177e4SLinus Torvalds cmp.w #7,%d0 109*1da177e4SLinus Torvalds jeq fp_fmovecr 110*1da177e4SLinus Torvalds move.w %d0,%d1 | store data size twice in %d1 111*1da177e4SLinus Torvalds swap %d1 | one can be trashed below 112*1da177e4SLinus Torvalds move.w %d0,%d1 113*1da177e4SLinus Torvalds#ifdef FPU_EMU_DEBUG 114*1da177e4SLinus Torvalds lea 0f,%a0 115*1da177e4SLinus Torvalds clr.l %d0 116*1da177e4SLinus Torvalds move.b (%a0,%d1.w),%d0 117*1da177e4SLinus Torvalds printf PDECODE,"f<op>.%c ",1,%d0 118*1da177e4SLinus Torvalds 119*1da177e4SLinus Torvalds .data 120*1da177e4SLinus Torvalds0: .byte 'l','s','x','p','w','d','b',0 121*1da177e4SLinus Torvalds .previous 122*1da177e4SLinus Torvalds#endif 123*1da177e4SLinus Torvalds 124*1da177e4SLinus Torvalds/* 125*1da177e4SLinus Torvalds fp_getsource, fp_getdest 126*1da177e4SLinus Torvalds 127*1da177e4SLinus Torvalds basically, we end up with a pointer to the source operand in 128*1da177e4SLinus Torvalds %a1, and a pointer to the destination operand in %a0. both 129*1da177e4SLinus Torvalds are, of course, 96-bit extended floating point numbers. 130*1da177e4SLinus Torvalds*/ 131*1da177e4SLinus Torvalds 132*1da177e4SLinus Torvaldsfp_getsource: 133*1da177e4SLinus Torvalds | decode addressing mode for source 134*1da177e4SLinus Torvalds fp_decode_addr_mode 135*1da177e4SLinus Torvalds 136*1da177e4SLinus Torvalds .long fp_data, fp_ill 137*1da177e4SLinus Torvalds .long fp_indirect, fp_postinc 138*1da177e4SLinus Torvalds .long fp_predecr, fp_disp16 139*1da177e4SLinus Torvalds .long fp_extmode0, fp_extmode1 140*1da177e4SLinus Torvalds 141*1da177e4SLinus Torvalds | addressing mode: data register direct 142*1da177e4SLinus Torvaldsfp_data: 143*1da177e4SLinus Torvalds fp_mode_data_direct 144*1da177e4SLinus Torvalds jsr fp_get_data_reg 145*1da177e4SLinus Torvalds lea (FPD_TEMPFP1,FPDATA),%a0 146*1da177e4SLinus Torvalds jmp ([0f:w,%pc,%d1.w*4]) 147*1da177e4SLinus Torvalds 148*1da177e4SLinus Torvalds .align 4 149*1da177e4SLinus Torvalds0: 150*1da177e4SLinus Torvalds .long fp_data_long, fp_data_single 151*1da177e4SLinus Torvalds .long fp_ill, fp_ill 152*1da177e4SLinus Torvalds .long fp_data_word, fp_ill 153*1da177e4SLinus Torvalds .long fp_data_byte, fp_ill 154*1da177e4SLinus Torvalds 155*1da177e4SLinus Torvalds | data types that fit in an integer data register 156*1da177e4SLinus Torvaldsfp_data_byte: 157*1da177e4SLinus Torvalds extb.l %d0 158*1da177e4SLinus Torvalds jra fp_data_long 159*1da177e4SLinus Torvalds 160*1da177e4SLinus Torvaldsfp_data_word: 161*1da177e4SLinus Torvalds ext.l %d0 162*1da177e4SLinus Torvalds 163*1da177e4SLinus Torvaldsfp_data_long: 164*1da177e4SLinus Torvalds jsr fp_conv_long2ext 165*1da177e4SLinus Torvalds jra fp_getdest 166*1da177e4SLinus Torvalds 167*1da177e4SLinus Torvaldsfp_data_single: 168*1da177e4SLinus Torvalds jsr fp_conv_single2ext 169*1da177e4SLinus Torvalds jra fp_getdest 170*1da177e4SLinus Torvalds 171*1da177e4SLinus Torvalds | addressing mode: address register indirect 172*1da177e4SLinus Torvaldsfp_indirect: 173*1da177e4SLinus Torvalds fp_mode_addr_indirect 174*1da177e4SLinus Torvalds jra fp_fetchsource 175*1da177e4SLinus Torvalds 176*1da177e4SLinus Torvalds | addressing mode: address register indirect with postincrement 177*1da177e4SLinus Torvaldsfp_postinc: 178*1da177e4SLinus Torvalds fp_mode_addr_indirect_postinc 179*1da177e4SLinus Torvalds jra fp_fetchsource 180*1da177e4SLinus Torvalds 181*1da177e4SLinus Torvalds | addressing mode: address register indirect with predecrement 182*1da177e4SLinus Torvaldsfp_predecr: 183*1da177e4SLinus Torvalds fp_mode_addr_indirect_predec 184*1da177e4SLinus Torvalds jra fp_fetchsource 185*1da177e4SLinus Torvalds 186*1da177e4SLinus Torvalds | addressing mode: address register/programm counter indirect 187*1da177e4SLinus Torvalds | with 16bit displacement 188*1da177e4SLinus Torvaldsfp_disp16: 189*1da177e4SLinus Torvalds fp_mode_addr_indirect_disp16 190*1da177e4SLinus Torvalds jra fp_fetchsource 191*1da177e4SLinus Torvalds 192*1da177e4SLinus Torvalds | all other indirect addressing modes will finally end up here 193*1da177e4SLinus Torvaldsfp_extmode0: 194*1da177e4SLinus Torvalds fp_mode_addr_indirect_extmode0 195*1da177e4SLinus Torvalds jra fp_fetchsource 196*1da177e4SLinus Torvalds 197*1da177e4SLinus Torvalds| all pc relative addressing modes and immediate/absolute modes end up here 198*1da177e4SLinus Torvalds| the first ones are sent to fp_extmode0 or fp_disp16 199*1da177e4SLinus Torvalds| and only the latter are handled here 200*1da177e4SLinus Torvaldsfp_extmode1: 201*1da177e4SLinus Torvalds fp_decode_addr_reg 202*1da177e4SLinus Torvalds jmp ([0f:w,%pc,%d0*4]) 203*1da177e4SLinus Torvalds 204*1da177e4SLinus Torvalds .align 4 205*1da177e4SLinus Torvalds0: 206*1da177e4SLinus Torvalds .long fp_abs_short, fp_abs_long 207*1da177e4SLinus Torvalds .long fp_disp16, fp_extmode0 208*1da177e4SLinus Torvalds .long fp_immediate, fp_ill 209*1da177e4SLinus Torvalds .long fp_ill, fp_ill 210*1da177e4SLinus Torvalds 211*1da177e4SLinus Torvalds | addressing mode: absolute short 212*1da177e4SLinus Torvaldsfp_abs_short: 213*1da177e4SLinus Torvalds fp_mode_abs_short 214*1da177e4SLinus Torvalds jra fp_fetchsource 215*1da177e4SLinus Torvalds 216*1da177e4SLinus Torvalds | addressing mode: absolute long 217*1da177e4SLinus Torvaldsfp_abs_long: 218*1da177e4SLinus Torvalds fp_mode_abs_long 219*1da177e4SLinus Torvalds jra fp_fetchsource 220*1da177e4SLinus Torvalds 221*1da177e4SLinus Torvalds | addressing mode: immediate data 222*1da177e4SLinus Torvaldsfp_immediate: 223*1da177e4SLinus Torvalds printf PDECODE,"#" 224*1da177e4SLinus Torvalds fp_get_pc %a0 225*1da177e4SLinus Torvalds move.w (fp_datasize,%d1.w*2),%d0 226*1da177e4SLinus Torvalds addq.w #1,%d0 227*1da177e4SLinus Torvalds and.w #-2,%d0 228*1da177e4SLinus Torvalds#ifdef FPU_EMU_DEBUG 229*1da177e4SLinus Torvalds movem.l %d0/%d1,-(%sp) 230*1da177e4SLinus Torvalds movel %a0,%a1 231*1da177e4SLinus Torvalds clr.l %d1 232*1da177e4SLinus Torvalds jra 2f 233*1da177e4SLinus Torvalds1: getuser.b (%a1)+,%d1,fp_err_ua1,%a1 234*1da177e4SLinus Torvalds printf PDECODE,"%02x",1,%d1 235*1da177e4SLinus Torvalds2: dbra %d0,1b 236*1da177e4SLinus Torvalds movem.l (%sp)+,%d0/%d1 237*1da177e4SLinus Torvalds#endif 238*1da177e4SLinus Torvalds lea (%a0,%d0.w),%a1 239*1da177e4SLinus Torvalds fp_put_pc %a1 240*1da177e4SLinus Torvalds| jra fp_fetchsource 241*1da177e4SLinus Torvalds 242*1da177e4SLinus Torvaldsfp_fetchsource: 243*1da177e4SLinus Torvalds move.l %a0,%a1 244*1da177e4SLinus Torvalds swap %d1 245*1da177e4SLinus Torvalds lea (FPD_TEMPFP1,FPDATA),%a0 246*1da177e4SLinus Torvalds jmp ([0f:w,%pc,%d1.w*4]) 247*1da177e4SLinus Torvalds 248*1da177e4SLinus Torvalds .align 4 249*1da177e4SLinus Torvalds0: .long fp_long, fp_single 250*1da177e4SLinus Torvalds .long fp_ext, fp_pack 251*1da177e4SLinus Torvalds .long fp_word, fp_double 252*1da177e4SLinus Torvalds .long fp_byte, fp_ill 253*1da177e4SLinus Torvalds 254*1da177e4SLinus Torvaldsfp_long: 255*1da177e4SLinus Torvalds getuser.l (%a1),%d0,fp_err_ua1,%a1 256*1da177e4SLinus Torvalds jsr fp_conv_long2ext 257*1da177e4SLinus Torvalds jra fp_getdest 258*1da177e4SLinus Torvalds 259*1da177e4SLinus Torvaldsfp_single: 260*1da177e4SLinus Torvalds getuser.l (%a1),%d0,fp_err_ua1,%a1 261*1da177e4SLinus Torvalds jsr fp_conv_single2ext 262*1da177e4SLinus Torvalds jra fp_getdest 263*1da177e4SLinus Torvalds 264*1da177e4SLinus Torvaldsfp_ext: 265*1da177e4SLinus Torvalds getuser.l (%a1)+,%d0,fp_err_ua1,%a1 266*1da177e4SLinus Torvalds lsr.l #8,%d0 267*1da177e4SLinus Torvalds lsr.l #7,%d0 268*1da177e4SLinus Torvalds lsr.w #1,%d0 269*1da177e4SLinus Torvalds move.l %d0,(%a0)+ 270*1da177e4SLinus Torvalds getuser.l (%a1)+,%d0,fp_err_ua1,%a1 271*1da177e4SLinus Torvalds move.l %d0,(%a0)+ 272*1da177e4SLinus Torvalds getuser.l (%a1),%d0,fp_err_ua1,%a1 273*1da177e4SLinus Torvalds move.l %d0,(%a0) 274*1da177e4SLinus Torvalds subq.l #8,%a0 275*1da177e4SLinus Torvalds jra fp_getdest 276*1da177e4SLinus Torvalds 277*1da177e4SLinus Torvaldsfp_pack: 278*1da177e4SLinus Torvalds /* not supported yet */ 279*1da177e4SLinus Torvalds jra fp_ill 280*1da177e4SLinus Torvalds 281*1da177e4SLinus Torvaldsfp_word: 282*1da177e4SLinus Torvalds getuser.w (%a1),%d0,fp_err_ua1,%a1 283*1da177e4SLinus Torvalds ext.l %d0 284*1da177e4SLinus Torvalds jsr fp_conv_long2ext 285*1da177e4SLinus Torvalds jra fp_getdest 286*1da177e4SLinus Torvalds 287*1da177e4SLinus Torvaldsfp_double: 288*1da177e4SLinus Torvalds jsr fp_conv_double2ext 289*1da177e4SLinus Torvalds jra fp_getdest 290*1da177e4SLinus Torvalds 291*1da177e4SLinus Torvaldsfp_byte: 292*1da177e4SLinus Torvalds getuser.b (%a1),%d0,fp_err_ua1,%a1 293*1da177e4SLinus Torvalds extb.l %d0 294*1da177e4SLinus Torvalds jsr fp_conv_long2ext 295*1da177e4SLinus Torvalds| jra fp_getdest 296*1da177e4SLinus Torvalds 297*1da177e4SLinus Torvaldsfp_getdest: 298*1da177e4SLinus Torvalds move.l %a0,%a1 299*1da177e4SLinus Torvalds bfextu %d2{#22,#3},%d0 300*1da177e4SLinus Torvalds printf PDECODE,",fp%d\n",1,%d0 301*1da177e4SLinus Torvalds fp_get_fp_reg 302*1da177e4SLinus Torvalds movem.l %a0/%a1,-(%sp) 303*1da177e4SLinus Torvalds pea fp_finalrounding 304*1da177e4SLinus Torvalds bfextu %d2{#25,#7},%d0 305*1da177e4SLinus Torvalds jmp ([0f:w,%pc,%d0*4]) 306*1da177e4SLinus Torvalds 307*1da177e4SLinus Torvalds .align 4 308*1da177e4SLinus Torvalds0: 309*1da177e4SLinus Torvalds .long fp_fmove_mem2fp, fp_fint, fp_fsinh, fp_fintrz 310*1da177e4SLinus Torvalds .long fp_fsqrt, fp_ill, fp_flognp1, fp_ill 311*1da177e4SLinus Torvalds .long fp_fetoxm1, fp_ftanh, fp_fatan, fp_ill 312*1da177e4SLinus Torvalds .long fp_fasin, fp_fatanh, fp_fsin, fp_ftan 313*1da177e4SLinus Torvalds .long fp_fetox, fp_ftwotox, fp_ftentox, fp_ill 314*1da177e4SLinus Torvalds .long fp_flogn, fp_flog10, fp_flog2, fp_ill 315*1da177e4SLinus Torvalds .long fp_fabs, fp_fcosh, fp_fneg, fp_ill 316*1da177e4SLinus Torvalds .long fp_facos, fp_fcos, fp_fgetexp, fp_fgetman 317*1da177e4SLinus Torvalds .long fp_fdiv, fp_fmod, fp_fadd, fp_fmul 318*1da177e4SLinus Torvalds .long fpa_fsgldiv, fp_frem, fp_fscale, fpa_fsglmul 319*1da177e4SLinus Torvalds .long fp_fsub, fp_ill, fp_ill, fp_ill 320*1da177e4SLinus Torvalds .long fp_ill, fp_ill, fp_ill, fp_ill 321*1da177e4SLinus Torvalds .long fp_fsincos0, fp_fsincos1, fp_fsincos2, fp_fsincos3 322*1da177e4SLinus Torvalds .long fp_fsincos4, fp_fsincos5, fp_fsincos6, fp_fsincos7 323*1da177e4SLinus Torvalds .long fp_fcmp, fp_ill, fp_ftst, fp_ill 324*1da177e4SLinus Torvalds .long fp_ill, fp_ill, fp_ill, fp_ill 325*1da177e4SLinus Torvalds .long fp_fsmove, fp_fssqrt, fp_ill, fp_ill 326*1da177e4SLinus Torvalds .long fp_fdmove, fp_fdsqrt, fp_ill, fp_ill 327*1da177e4SLinus Torvalds .long fp_ill, fp_ill, fp_ill, fp_ill 328*1da177e4SLinus Torvalds .long fp_ill, fp_ill, fp_ill, fp_ill 329*1da177e4SLinus Torvalds .long fp_ill, fp_ill, fp_ill, fp_ill 330*1da177e4SLinus Torvalds .long fp_ill, fp_ill, fp_ill, fp_ill 331*1da177e4SLinus Torvalds .long fp_fsabs, fp_ill, fp_fsneg, fp_ill 332*1da177e4SLinus Torvalds .long fp_fdabs, fp_ill, fp_fdneg, fp_ill 333*1da177e4SLinus Torvalds .long fp_fsdiv, fp_ill, fp_fsadd, fp_fsmul 334*1da177e4SLinus Torvalds .long fp_fddiv, fp_ill, fp_fdadd, fp_fdmul 335*1da177e4SLinus Torvalds .long fp_fssub, fp_ill, fp_ill, fp_ill 336*1da177e4SLinus Torvalds .long fp_fdsub, fp_ill, fp_ill, fp_ill 337*1da177e4SLinus Torvalds .long fp_ill, fp_ill, fp_ill, fp_ill 338*1da177e4SLinus Torvalds .long fp_ill, fp_ill, fp_ill, fp_ill 339*1da177e4SLinus Torvalds .long fp_ill, fp_ill, fp_ill, fp_ill 340*1da177e4SLinus Torvalds .long fp_ill, fp_ill, fp_ill, fp_ill 341*1da177e4SLinus Torvalds 342*1da177e4SLinus Torvalds | Instructions follow 343*1da177e4SLinus Torvalds 344*1da177e4SLinus Torvalds | Move an (emulated) ROM constant 345*1da177e4SLinus Torvaldsfp_fmovecr: 346*1da177e4SLinus Torvalds bfextu %d2{#27,#5},%d0 347*1da177e4SLinus Torvalds printf PINSTR,"fp_fmovecr #%d",1,%d0 348*1da177e4SLinus Torvalds move.l %d0,%d1 349*1da177e4SLinus Torvalds add.l %d0,%d0 350*1da177e4SLinus Torvalds add.l %d1,%d0 351*1da177e4SLinus Torvalds lea (fp_constants,%d0*4),%a0 352*1da177e4SLinus Torvalds move.l #0x801cc0ff,%d0 353*1da177e4SLinus Torvalds addq.l #1,%d1 354*1da177e4SLinus Torvalds lsl.l %d1,%d0 355*1da177e4SLinus Torvalds jcc 1f 356*1da177e4SLinus Torvalds fp_set_sr FPSR_EXC_INEX2 | INEX2 exception 357*1da177e4SLinus Torvalds1: moveq #-128,%d0 | continue with fmove 358*1da177e4SLinus Torvalds and.l %d0,%d2 359*1da177e4SLinus Torvalds jra fp_getdest 360*1da177e4SLinus Torvalds 361*1da177e4SLinus Torvalds .data 362*1da177e4SLinus Torvalds .align 4 363*1da177e4SLinus Torvaldsfp_constants: 364*1da177e4SLinus Torvalds .long 0x00004000,0xc90fdaa2,0x2168c235 | pi 365*1da177e4SLinus Torvalds .extend 0,0,0,0,0,0,0,0,0,0 366*1da177e4SLinus Torvalds .long 0x00003ffd,0x9a209a84,0xfbcff798 | log10(2) 367*1da177e4SLinus Torvalds .long 0x00004000,0xadf85458,0xa2bb4a9a | e 368*1da177e4SLinus Torvalds .long 0x00003fff,0xb8aa3b29,0x5c17f0bc | log2(e) 369*1da177e4SLinus Torvalds .long 0x00003ffd,0xde5bd8a9,0x37287195 | log10(e) 370*1da177e4SLinus Torvalds .long 0x00000000,0x00000000,0x00000000 | 0.0 371*1da177e4SLinus Torvalds .long 0x00003ffe,0xb17217f7,0xd1cf79ac | 1n(2) 372*1da177e4SLinus Torvalds .long 0x00004000,0x935d8ddd,0xaaa8ac17 | 1n(10) 373*1da177e4SLinus Torvalds | read this as "1.0 * 2^0" - note the high bit in the mantissa 374*1da177e4SLinus Torvalds .long 0x00003fff,0x80000000,0x00000000 | 10^0 375*1da177e4SLinus Torvalds .long 0x00004002,0xa0000000,0x00000000 | 10^1 376*1da177e4SLinus Torvalds .long 0x00004005,0xc8000000,0x00000000 | 10^2 377*1da177e4SLinus Torvalds .long 0x0000400c,0x9c400000,0x00000000 | 10^4 378*1da177e4SLinus Torvalds .long 0x00004019,0xbebc2000,0x00000000 | 10^8 379*1da177e4SLinus Torvalds .long 0x00004034,0x8e1bc9bf,0x04000000 | 10^16 380*1da177e4SLinus Torvalds .long 0x00004069,0x9dc5ada8,0x2b70b59e | 10^32 381*1da177e4SLinus Torvalds .long 0x000040d3,0xc2781f49,0xffcfa6d5 | 10^64 382*1da177e4SLinus Torvalds .long 0x000041a8,0x93ba47c9,0x80e98ce0 | 10^128 383*1da177e4SLinus Torvalds .long 0x00004351,0xaa7eebfb,0x9df9de8e | 10^256 384*1da177e4SLinus Torvalds .long 0x000046a3,0xe319a0ae,0xa60e91c7 | 10^512 385*1da177e4SLinus Torvalds .long 0x00004d48,0xc9767586,0x81750c17 | 10^1024 386*1da177e4SLinus Torvalds .long 0x00005a92,0x9e8b3b5d,0xc53d5de5 | 10^2048 387*1da177e4SLinus Torvalds .long 0x00007525,0xc4605202,0x8a20979b | 10^4096 388*1da177e4SLinus Torvalds .previous 389*1da177e4SLinus Torvalds 390*1da177e4SLinus Torvaldsfp_fmove_mem2fp: 391*1da177e4SLinus Torvalds printf PINSTR,"fmove %p,%p\n",2,%a0,%a1 392*1da177e4SLinus Torvalds move.l (%a1)+,(%a0)+ 393*1da177e4SLinus Torvalds move.l (%a1)+,(%a0)+ 394*1da177e4SLinus Torvalds move.l (%a1),(%a0) 395*1da177e4SLinus Torvalds subq.l #8,%a0 396*1da177e4SLinus Torvalds rts 397*1da177e4SLinus Torvalds 398*1da177e4SLinus Torvaldsfpa_fsglmul: 399*1da177e4SLinus Torvalds move.l #fp_finalrounding_single_fast,(%sp) 400*1da177e4SLinus Torvalds jra fp_fsglmul 401*1da177e4SLinus Torvalds 402*1da177e4SLinus Torvaldsfpa_fsgldiv: 403*1da177e4SLinus Torvalds move.l #fp_finalrounding_single_fast,(%sp) 404*1da177e4SLinus Torvalds jra fp_fsgldiv 405*1da177e4SLinus Torvalds 406*1da177e4SLinus Torvalds.macro fp_dosingleprec instr 407*1da177e4SLinus Torvalds printf PINSTR,"single " 408*1da177e4SLinus Torvalds move.l #fp_finalrounding_single,(%sp) 409*1da177e4SLinus Torvalds jra \instr 410*1da177e4SLinus Torvalds.endm 411*1da177e4SLinus Torvalds 412*1da177e4SLinus Torvalds.macro fp_dodoubleprec instr 413*1da177e4SLinus Torvalds printf PINSTR,"double " 414*1da177e4SLinus Torvalds move.l #fp_finalrounding_double,(%sp) 415*1da177e4SLinus Torvalds jra \instr 416*1da177e4SLinus Torvalds.endm 417*1da177e4SLinus Torvalds 418*1da177e4SLinus Torvaldsfp_fsmove: 419*1da177e4SLinus Torvalds fp_dosingleprec fp_fmove_mem2fp 420*1da177e4SLinus Torvalds 421*1da177e4SLinus Torvaldsfp_fssqrt: 422*1da177e4SLinus Torvalds fp_dosingleprec fp_fsqrt 423*1da177e4SLinus Torvalds 424*1da177e4SLinus Torvaldsfp_fdmove: 425*1da177e4SLinus Torvalds fp_dodoubleprec fp_fmove_mem2fp 426*1da177e4SLinus Torvalds 427*1da177e4SLinus Torvaldsfp_fdsqrt: 428*1da177e4SLinus Torvalds fp_dodoubleprec fp_fsqrt 429*1da177e4SLinus Torvalds 430*1da177e4SLinus Torvaldsfp_fsabs: 431*1da177e4SLinus Torvalds fp_dosingleprec fp_fabs 432*1da177e4SLinus Torvalds 433*1da177e4SLinus Torvaldsfp_fsneg: 434*1da177e4SLinus Torvalds fp_dosingleprec fp_fneg 435*1da177e4SLinus Torvalds 436*1da177e4SLinus Torvaldsfp_fdabs: 437*1da177e4SLinus Torvalds fp_dodoubleprec fp_fabs 438*1da177e4SLinus Torvalds 439*1da177e4SLinus Torvaldsfp_fdneg: 440*1da177e4SLinus Torvalds fp_dodoubleprec fp_fneg 441*1da177e4SLinus Torvalds 442*1da177e4SLinus Torvaldsfp_fsdiv: 443*1da177e4SLinus Torvalds fp_dosingleprec fp_fdiv 444*1da177e4SLinus Torvalds 445*1da177e4SLinus Torvaldsfp_fsadd: 446*1da177e4SLinus Torvalds fp_dosingleprec fp_fadd 447*1da177e4SLinus Torvalds 448*1da177e4SLinus Torvaldsfp_fsmul: 449*1da177e4SLinus Torvalds fp_dosingleprec fp_fmul 450*1da177e4SLinus Torvalds 451*1da177e4SLinus Torvaldsfp_fddiv: 452*1da177e4SLinus Torvalds fp_dodoubleprec fp_fdiv 453*1da177e4SLinus Torvalds 454*1da177e4SLinus Torvaldsfp_fdadd: 455*1da177e4SLinus Torvalds fp_dodoubleprec fp_fadd 456*1da177e4SLinus Torvalds 457*1da177e4SLinus Torvaldsfp_fdmul: 458*1da177e4SLinus Torvalds fp_dodoubleprec fp_fmul 459*1da177e4SLinus Torvalds 460*1da177e4SLinus Torvaldsfp_fssub: 461*1da177e4SLinus Torvalds fp_dosingleprec fp_fsub 462*1da177e4SLinus Torvalds 463*1da177e4SLinus Torvaldsfp_fdsub: 464*1da177e4SLinus Torvalds fp_dodoubleprec fp_fsub 465*1da177e4SLinus Torvalds 466*1da177e4SLinus Torvaldsfp_nonstd: 467*1da177e4SLinus Torvalds fp_get_pc %a0 468*1da177e4SLinus Torvalds getuser.l (%a0),%d0,fp_err_ua1,%a0 469*1da177e4SLinus Torvalds printf ,"nonstd ((%08x)=%08x)\n",2,%a0,%d0 470*1da177e4SLinus Torvalds moveq #-1,%d0 471*1da177e4SLinus Torvalds rts 472*1da177e4SLinus Torvalds 473*1da177e4SLinus Torvalds .data 474*1da177e4SLinus Torvalds .align 4 475*1da177e4SLinus Torvalds 476*1da177e4SLinus Torvalds | data sizes corresponding to the operand formats 477*1da177e4SLinus Torvaldsfp_datasize: 478*1da177e4SLinus Torvalds .word 4, 4, 12, 12, 2, 8, 1, 0 479