📄 do_func.s
字号:
/* do_func.s - Motorola 68040 FP routine jump table (EXC) *//* Copyright 1991-1993 Wind River Systems, Inc. */ .data .globl _copyright_wind_river .long _copyright_wind_river/*modification history--------------------01g,31may96,ms updated to mototorola version 2.301f,14jun95,tpr changed fbxx to fbxxl.01e,21jul93,kdl added .text (SPR #2372).01d,23aug92,jcf changed bxxx to jxx.01c,26may92,rrr the tree shuffle01b,10jan92,kdl added modification history; general cleanup.01a,15aug91,kdl original version, from Motorola FPSP v2.0.*//*DESCRIPTION do_funcsa 3.4 2/18/91Do_func performs the unimplemented operation. The operationto be performed is determined from the lower 7 bits of theextension word (except in the case of fmovecr and fsincos).The opcode and tag bits form an index into a jump table intbldosa. Cases of zero, infinity and NaN are handled in__x_do_func by forcing the default result. Normalized anddenormalized (there are no unnormalized numbers at thispoint) are passed onto the emulation code.CMDREG1B and STAG are extracted from the fsave frameand combined to form the table index. The function calledwill start with a0 pointing to the ETEMP operand. Dyadicfunctions can find FPTEMP at a0@(-12).Called functions return their result in fp0. Sincos returnssin(x) in fp0 and cos(x) in fp1. Copyright (C) Motorola, Inc. 1990 All Rights Reserved THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA The copyright notice above does not evidence any actual or intended publication of such source code.DO_FUNC idnt 2,1 Motorola 040 Floating Point Software Package section 8NOMANUAL*/#include "fpsp040E.h"| xref __x_t_dz2| xref __x_t_operr| xref __x_t_inx2| xref __x_t_resdnrm| xref __x_dst_nan| xref __x_src_nan| xref __x_nrm_set| xref __x_sto_cos| xref __x_tblpre| xref __x_slognp1,__x_slogn,__x_slog10,__x_slog2| xref __x_slognd,__x_slog10d,__x_slog2d| xref __x_smod,__x_srem| xref __x_sscale| xref __x_smovcrPONE: .long 0x3fff0000,0x80000000,0x00000000 | +1MONE: .long 0xbfff0000,0x80000000,0x00000000 | -1PZERO: .long 0x00000000,0x00000000,0x00000000 | +0MZERO: .long 0x80000000,0x00000000,0x00000000 | -0PINF: .long 0x7fff0000,0x00000000,0x00000000 | +infMINF: .long 0xffff0000,0x00000000,0x00000000 | -infQNAN: .long 0x7fff0000,0xffffffff,0xffffffff | non-signaling nanPPIBY2: .long 0x3FFF0000,0xC90FDAA2,0x2168C235 | +PI/2MPIBY2: .long 0xbFFF0000,0xC90FDAA2,0x2168C235 | -PI/2 .globl __x_do_func .text__x_do_func: clrb a6@(CU_ONLY)|| Check for fmovecr. It does not follow the format of fp gen| unimplemented instructions. The test is on the upper 6 bits|| if they are 0x17, the inst is fmovecr. Call entry __x_smovcr| directly.| bfextu a6@(CMDREG1B){#0:#6},d0 | get opclass and src fields cmpil #0x17,d0 | if op class and size fields are 0x17,| | it is FMOVECR| if not, continue jne not_fmovecr jmp __x_smovcr | fmovecr| jmp directly to emulationnot_fmovecr: movew a6@(CMDREG1B),d0 andl #0x7F,d0 cmpil #0x38,d0 | if the extension is >= 0x38, jge __x_serror | it is illegal bfextu a6@(STAG){#0:#3},d1 lsll #3,d0 | make room for STAG addl d1,d0 | combine for final index into table lea __x_tblpre,a1 | start of monster jump table movel a1@(d0:w:4),a1 | real target address lea a6@(ETEMP),a0 | a0 is pointer to src op movel a6@(USER_FPCR),d1 andl #0xFF,d1 | discard all but rounding mode/prec fmovel #0,fpcr jmp a1@|| ERROR| .globl __x_serror__x_serror: st a6@(STORE_FLG) rts|| These routines load forced values into fp0. They are called| by index into tbldo.|| Load a signed zero to fp0 and set inex2/ainex| .globl __x_snzrinx__x_snzrinx: btst #sign_bit,a0@(LOCAL_EX) | get sign of source operand jne ld_mzinx | if negative, branch bsrl __x_ld_pzero | bsr so we can return and set inx jra __x_t_inx2 | now, set the inx for the next instld_mzinx: bsrl __x_ld_mzero | if neg, load neg zero, return here jra __x_t_inx2 | now, set the inx for the next inst|| Load a signed zero to fp0| do not set inex2/ainex| .globl __x_szero__x_szero: btst #sign_bit,a0@(LOCAL_EX) | get sign of source operand jne __x_ld_mzero | if neg, load neg zero jra __x_ld_pzero | load positive zero|| Load a signed infinity to fp0| do not set inex2/ainex| .globl __x_sinf__x_sinf: btst #sign_bit,a0@(LOCAL_EX) | get sign of source operand jne __x_ld_minf | if negative branch jra __x_ld_pinf|| Load a signed one to fp0| do not set inex2/ainex| .globl __x_sone__x_sone: btst #sign_bit,a0@(LOCAL_EX) | check sign of source jne __x_ld_mone jra __x_ld_pone|| Load a signed pi/2 to fp0| do not set inex2/ainex| .globl __x_spi_2__x_spi_2: btst #sign_bit,a0@(LOCAL_EX) | check sign of source jne __x_ld_mpi2 jra __x_ld_ppi2|| Load either a +0 or +inf for plus/minus operand| .globl __x_szr_inf__x_szr_inf: btst #sign_bit,a0@(LOCAL_EX) | check sign of source jne __x_ld_pzero jra __x_ld_pinf|| Result is either an operr or +inf for plus/minus operand| [Used by __x_slogn, __x_slognp1, __x_slog10, and __x_slog2]| .globl __x_sopr_inf__x_sopr_inf: btst #sign_bit,a0@(LOCAL_EX) | check sign of source jne __x_t_operr jra __x_ld_pinf|| FLOGNP1| .globl __x_sslognp1__x_sslognp1: fmovemx a0@,fp0-fp0 fcmpb #-1,fp0 fbgtl __x_slognp1 fbeql __x_t_dz2 | if = -1, divide by zero exception fmovel #0,FPSR | clr N flag jra __x_t_operr | take care of operands < -1|| FETOXM1| .globl __x_setoxm1i__x_setoxm1i: btst #sign_bit,a0@(LOCAL_EX) | check sign of source jne __x_ld_mone jra __x_ld_pinf|| FLOGN|| Test for 1.0 as an input argument, returning +zero. Also check| the sign and return operr if negative.| .globl __x_sslogn__x_sslogn: btst #sign_bit,a0@(LOCAL_EX) jne __x_t_operr | take care of operands < 0 cmpiw #0x3fff,a0@(LOCAL_EX) | test for 1.0 input jne __x_slogn cmpil #0x80000000,a0@(LOCAL_HI) jne __x_slogn tstl a0@(LOCAL_LO) jne __x_slogn fmovex PZERO,fp0 rts .globl __x_sslognd__x_sslognd: btst #sign_bit,a0@(LOCAL_EX) jeq __x_slognd jra __x_t_operr | take care of operands < 0|| FLOG10| .globl __x_sslog10__x_sslog10: btst #sign_bit,a0@(LOCAL_EX) jne __x_t_operr | take care of operands < 0 cmpiw #0x3fff,a0@(LOCAL_EX) | test for 1.0 input jne __x_slog10 cmpil #0x80000000,a0@(LOCAL_HI) jne __x_slog10 tstl a0@(LOCAL_LO) jne __x_slog10 fmovex PZERO,fp0 rts .globl __x_sslog10d__x_sslog10d: btst #sign_bit,a0@(LOCAL_EX) jeq __x_slog10d jra __x_t_operr | take care of operands < 0|| FLOG2| .globl __x_sslog2__x_sslog2: btst #sign_bit,a0@(LOCAL_EX) jne __x_t_operr | take care of operands < 0 cmpiw #0x3fff,a0@(LOCAL_EX) | test for 1.0 input jne __x_slog2 cmpil #0x80000000,a0@(LOCAL_HI) jne __x_slog2 tstl a0@(LOCAL_LO) jne __x_slog2 fmovex PZERO,fp0 rts .globl __x_sslog2d__x_sslog2d: btst #sign_bit,a0@(LOCAL_EX) jeq __x_slog2d jra __x_t_operr | take care of operands < 0|| FMOD|__x_pmodt:| | 0x21 fmod| | dtag,stag .long __x_smod | 00,00 norm,norm = normal .long __x_smod_oper | 00,01 norm,zero = nan with operr .long __x_smod_fpn | 00,10 norm,inf = fpn .long __x_smod_snan | 00,11 norm,nan = nan .long __x_smod_zro | 01,00 zero,norm = +-zero .long __x_smod_oper | 01,01 zero,zero = nan with operr .long __x_smod_zro | 01,10 zero,inf = +-zero .long __x_smod_snan | 01,11 zero,nan = nan .long __x_smod_oper | 10,00 inf,norm = nan with operr .long __x_smod_oper | 10,01 inf,zero = nan with operr .long __x_smod_oper | 10,10 inf,inf = nan with operr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -