Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*---------------------------------------------------------------------------+
0003  |  reg_norm.S                                                               |
0004  |                                                                           |
0005  | Copyright (C) 1992,1993,1994,1995,1997                                    |
0006  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
0007  |                       Australia.  E-mail billm@suburbia.net               |
0008  |                                                                           |
0009  | Normalize the value in a FPU_REG.                                         |
0010  |                                                                           |
0011  | Call from C as:                                                           |
0012  |    int FPU_normalize(FPU_REG *n)                                          |
0013  |                                                                           |
0014  |    int FPU_normalize_nuo(FPU_REG *n)                                      |
0015  |                                                                           |
0016  |    Return value is the tag of the answer, or-ed with FPU_Exception if     |
0017  |    one was raised, or -1 on internal error.                               |
0018  |                                                                           |
0019  +---------------------------------------------------------------------------*/
0020 
0021 #include "fpu_emu.h"
0022 
0023 
0024 .text
0025 SYM_FUNC_START(FPU_normalize)
0026     pushl   %ebp
0027     movl    %esp,%ebp
0028     pushl   %ebx
0029 
0030     movl    PARAM1,%ebx
0031 
0032     movl    SIGH(%ebx),%edx
0033     movl    SIGL(%ebx),%eax
0034 
0035     orl %edx,%edx   /* ms bits */
0036     js  L_done      /* Already normalized */
0037     jnz L_shift_1   /* Shift left 1 - 31 bits */
0038 
0039     orl %eax,%eax
0040     jz  L_zero      /* The contents are zero */
0041 
0042     movl    %eax,%edx
0043     xorl    %eax,%eax
0044     subw    $32,EXP(%ebx)   /* This can cause an underflow */
0045 
0046 /* We need to shift left by 1 - 31 bits */
0047 L_shift_1:
0048     bsrl    %edx,%ecx   /* get the required shift in %ecx */
0049     subl    $31,%ecx
0050     negl    %ecx
0051     shld    %cl,%eax,%edx
0052     shl %cl,%eax
0053     subw    %cx,EXP(%ebx)   /* This can cause an underflow */
0054 
0055     movl    %edx,SIGH(%ebx)
0056     movl    %eax,SIGL(%ebx)
0057 
0058 L_done:
0059     cmpw    EXP_OVER,EXP(%ebx)
0060     jge L_overflow
0061 
0062     cmpw    EXP_UNDER,EXP(%ebx)
0063     jle L_underflow
0064 
0065 L_exit_valid:
0066     movl    TAG_Valid,%eax
0067 
0068     /* Convert the exponent to 80x87 form. */
0069     addw    EXTENDED_Ebias,EXP(%ebx)
0070     andw    $0x7fff,EXP(%ebx)
0071 
0072 L_exit:
0073     popl    %ebx
0074     leave
0075     RET
0076 
0077 
0078 L_zero:
0079     movw    $0,EXP(%ebx)
0080     movl    TAG_Zero,%eax
0081     jmp L_exit
0082 
0083 L_underflow:
0084     /* Convert the exponent to 80x87 form. */
0085     addw    EXTENDED_Ebias,EXP(%ebx)
0086     push    %ebx
0087     call    arith_underflow
0088     pop %ebx
0089     jmp L_exit
0090 
0091 L_overflow:
0092     /* Convert the exponent to 80x87 form. */
0093     addw    EXTENDED_Ebias,EXP(%ebx)
0094     push    %ebx
0095     call    arith_overflow
0096     pop %ebx
0097     jmp L_exit
0098 SYM_FUNC_END(FPU_normalize)
0099 
0100 
0101 
0102 /* Normalise without reporting underflow or overflow */
0103 SYM_FUNC_START(FPU_normalize_nuo)
0104     pushl   %ebp
0105     movl    %esp,%ebp
0106     pushl   %ebx
0107 
0108     movl    PARAM1,%ebx
0109 
0110     movl    SIGH(%ebx),%edx
0111     movl    SIGL(%ebx),%eax
0112 
0113     orl %edx,%edx   /* ms bits */
0114     js  L_exit_nuo_valid    /* Already normalized */
0115     jnz L_nuo_shift_1   /* Shift left 1 - 31 bits */
0116 
0117     orl %eax,%eax
0118     jz  L_exit_nuo_zero     /* The contents are zero */
0119 
0120     movl    %eax,%edx
0121     xorl    %eax,%eax
0122     subw    $32,EXP(%ebx)   /* This can cause an underflow */
0123 
0124 /* We need to shift left by 1 - 31 bits */
0125 L_nuo_shift_1:
0126     bsrl    %edx,%ecx   /* get the required shift in %ecx */
0127     subl    $31,%ecx
0128     negl    %ecx
0129     shld    %cl,%eax,%edx
0130     shl %cl,%eax
0131     subw    %cx,EXP(%ebx)   /* This can cause an underflow */
0132 
0133     movl    %edx,SIGH(%ebx)
0134     movl    %eax,SIGL(%ebx)
0135 
0136 L_exit_nuo_valid:
0137     movl    TAG_Valid,%eax
0138 
0139     popl    %ebx
0140     leave
0141     RET
0142 
0143 L_exit_nuo_zero:
0144     movl    TAG_Zero,%eax
0145     movw    EXP_UNDER,EXP(%ebx)
0146 
0147     popl    %ebx
0148     leave
0149     RET
0150 SYM_FUNC_END(FPU_normalize_nuo)