📄 reg_u_mul.s
字号:
.file "reg_u_mul.S"/*---------------------------------------------------------------------------+ | reg_u_mul.S | | | | Core multiplication routine | | | | Copyright (C) 1992,1993,1995,1997 | | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia | | E-mail billm@suburbia.net | | | | | +---------------------------------------------------------------------------*//*---------------------------------------------------------------------------+ | Basic multiplication routine. | | Does not check the resulting exponent for overflow/underflow | | | | FPU_u_mul(FPU_REG *a, FPU_REG *b, FPU_REG *c, unsigned int cw); | | | | Internal working is at approx 128 bits. | | Result is rounded to nearest 53 or 64 bits, using "nearest or even". | +---------------------------------------------------------------------------*/#include "exception.h"#include "fpu_emu.h"#include "control_w.h"#ifndef NON_REENTRANT_FPU/* Local storage on the stack: */#define FPU_accum_0 -4(%ebp) /* ms word */#define FPU_accum_1 -8(%ebp)#else/* Local storage in a static area: */.data .align 4,0FPU_accum_0: .long 0FPU_accum_1: .long 0#endif NON_REENTRANT_FPU.textENTRY(FPU_u_mul) pushl %ebp movl %esp,%ebp#ifndef NON_REENTRANT_FPU subl $8,%esp#endif NON_REENTRANT_FPU pushl %esi pushl %edi pushl %ebx movl PARAM1,%esi movl PARAM2,%edi#ifdef PARANOID testl $0x80000000,SIGH(%esi) jz L_bugged testl $0x80000000,SIGH(%edi) jz L_bugged#endif PARANOID xorl %ecx,%ecx xorl %ebx,%ebx movl SIGL(%esi),%eax mull SIGL(%edi) movl %eax,FPU_accum_0 movl %edx,FPU_accum_1 movl SIGL(%esi),%eax mull SIGH(%edi) addl %eax,FPU_accum_1 adcl %edx,%ebx/* adcl $0,%ecx // overflow here is not possible */ movl SIGH(%esi),%eax mull SIGL(%edi) addl %eax,FPU_accum_1 adcl %edx,%ebx adcl $0,%ecx movl SIGH(%esi),%eax mull SIGH(%edi) addl %eax,%ebx adcl %edx,%ecx /* Get the sum of the exponents. */ movl PARAM6,%eax subl EXP_BIAS-1,%eax /* Two denormals can cause an exponent underflow */ cmpl EXP_WAY_UNDER,%eax jg Exp_not_underflow /* Set to a really low value allow correct handling */ movl EXP_WAY_UNDER,%eaxExp_not_underflow:/* Have now finished with the sources */ movl PARAM3,%edi /* Point to the destination */ movw %ax,EXP(%edi)/* Now make sure that the result is normalized */ testl $0x80000000,%ecx jnz LResult_Normalised /* Normalize by shifting left one bit */ shll $1,FPU_accum_0 rcll $1,FPU_accum_1 rcll $1,%ebx rcll $1,%ecx decw EXP(%edi)LResult_Normalised: movl FPU_accum_0,%eax movl FPU_accum_1,%edx orl %eax,%eax jz L_extent_zero orl $1,%edxL_extent_zero: movl %ecx,%eax jmp fpu_reg_round#ifdef PARANOIDL_bugged: pushl EX_INTERNAL|0x205 call EXCEPTION pop %ebx jmp L_exitL_exit: popl %ebx popl %edi popl %esi leave ret#endif PARANOID
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -