root/arch/x86/math-emu/reg_norm.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 /*---------------------------------------------------------------------------+
   3  |  reg_norm.S                                                               |
   4  |                                                                           |
   5  | Copyright (C) 1992,1993,1994,1995,1997                                    |
   6  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
   7  |                       Australia.  E-mail billm@suburbia.net               |
   8  |                                                                           |
   9  | Normalize the value in a FPU_REG.                                         |
  10  |                                                                           |
  11  | Call from C as:                                                           |
  12  |    int FPU_normalize(FPU_REG *n)                                          |
  13  |                                                                           |
  14  |    int FPU_normalize_nuo(FPU_REG *n)                                      |
  15  |                                                                           |
  16  |    Return value is the tag of the answer, or-ed with FPU_Exception if     |
  17  |    one was raised, or -1 on internal error.                               |
  18  |                                                                           |
  19  +---------------------------------------------------------------------------*/
  20 
  21 #include "fpu_emu.h"
  22 
  23 
  24 .text
  25 ENTRY(FPU_normalize)
  26         pushl   %ebp
  27         movl    %esp,%ebp
  28         pushl   %ebx
  29 
  30         movl    PARAM1,%ebx
  31 
  32         movl    SIGH(%ebx),%edx
  33         movl    SIGL(%ebx),%eax
  34 
  35         orl     %edx,%edx       /* ms bits */
  36         js      L_done          /* Already normalized */
  37         jnz     L_shift_1       /* Shift left 1 - 31 bits */
  38 
  39         orl     %eax,%eax
  40         jz      L_zero          /* The contents are zero */
  41 
  42         movl    %eax,%edx
  43         xorl    %eax,%eax
  44         subw    $32,EXP(%ebx)   /* This can cause an underflow */
  45 
  46 /* We need to shift left by 1 - 31 bits */
  47 L_shift_1:
  48         bsrl    %edx,%ecx       /* get the required shift in %ecx */
  49         subl    $31,%ecx
  50         negl    %ecx
  51         shld    %cl,%eax,%edx
  52         shl     %cl,%eax
  53         subw    %cx,EXP(%ebx)   /* This can cause an underflow */
  54 
  55         movl    %edx,SIGH(%ebx)
  56         movl    %eax,SIGL(%ebx)
  57 
  58 L_done:
  59         cmpw    EXP_OVER,EXP(%ebx)
  60         jge     L_overflow
  61 
  62         cmpw    EXP_UNDER,EXP(%ebx)
  63         jle     L_underflow
  64 
  65 L_exit_valid:
  66         movl    TAG_Valid,%eax
  67 
  68         /* Convert the exponent to 80x87 form. */
  69         addw    EXTENDED_Ebias,EXP(%ebx)
  70         andw    $0x7fff,EXP(%ebx)
  71 
  72 L_exit:
  73         popl    %ebx
  74         leave
  75         ret
  76 
  77 
  78 L_zero:
  79         movw    $0,EXP(%ebx)
  80         movl    TAG_Zero,%eax
  81         jmp     L_exit
  82 
  83 L_underflow:
  84         /* Convert the exponent to 80x87 form. */
  85         addw    EXTENDED_Ebias,EXP(%ebx)
  86         push    %ebx
  87         call    arith_underflow
  88         pop     %ebx
  89         jmp     L_exit
  90 
  91 L_overflow:
  92         /* Convert the exponent to 80x87 form. */
  93         addw    EXTENDED_Ebias,EXP(%ebx)
  94         push    %ebx
  95         call    arith_overflow
  96         pop     %ebx
  97         jmp     L_exit
  98 ENDPROC(FPU_normalize)
  99 
 100 
 101 
 102 /* Normalise without reporting underflow or overflow */
 103 ENTRY(FPU_normalize_nuo)
 104         pushl   %ebp
 105         movl    %esp,%ebp
 106         pushl   %ebx
 107 
 108         movl    PARAM1,%ebx
 109 
 110         movl    SIGH(%ebx),%edx
 111         movl    SIGL(%ebx),%eax
 112 
 113         orl     %edx,%edx       /* ms bits */
 114         js      L_exit_nuo_valid        /* Already normalized */
 115         jnz     L_nuo_shift_1   /* Shift left 1 - 31 bits */
 116 
 117         orl     %eax,%eax
 118         jz      L_exit_nuo_zero         /* The contents are zero */
 119 
 120         movl    %eax,%edx
 121         xorl    %eax,%eax
 122         subw    $32,EXP(%ebx)   /* This can cause an underflow */
 123 
 124 /* We need to shift left by 1 - 31 bits */
 125 L_nuo_shift_1:
 126         bsrl    %edx,%ecx       /* get the required shift in %ecx */
 127         subl    $31,%ecx
 128         negl    %ecx
 129         shld    %cl,%eax,%edx
 130         shl     %cl,%eax
 131         subw    %cx,EXP(%ebx)   /* This can cause an underflow */
 132 
 133         movl    %edx,SIGH(%ebx)
 134         movl    %eax,SIGL(%ebx)
 135 
 136 L_exit_nuo_valid:
 137         movl    TAG_Valid,%eax
 138 
 139         popl    %ebx
 140         leave
 141         ret
 142 
 143 L_exit_nuo_zero:
 144         movl    TAG_Zero,%eax
 145         movw    EXP_UNDER,EXP(%ebx)
 146 
 147         popl    %ebx
 148         leave
 149         ret
 150 ENDPROC(FPU_normalize_nuo)

/* [<][>][^][v][top][bottom][index][help] */