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

/* [previous][next][first][last][top][bottom][index][help] */
   1 /*---------------------------------------------------------------------------+
   2  |  reg_norm.S                                                               |
   3  |                                                                           |
   4  | Copyright (C) 1992,1993,1994                                              |
   5  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
   6  |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
   7  |                                                                           |
   8  | Normalize the value in a FPU_REG.                                         |
   9  |                                                                           |
  10  | Call from C as:                                                           |
  11  |   void normalize(FPU_REG *n)                                              |
  12  |                                                                           |
  13  |   void normalize_nuo(FPU_REG *n)                                          |
  14  |                                                                           |
  15  +---------------------------------------------------------------------------*/
  16 
  17 #include "fpu_asm.h"
  18 
  19 
  20 .text
  21 ENTRY(normalize)
  22         pushl   %ebp
  23         movl    %esp,%ebp
  24         pushl   %ebx
  25 
  26         movl    PARAM1,%ebx
  27 
  28 #ifdef PARANOID
  29         cmpb    TW_Valid,TAG(%ebx)
  30         je      L_ok
  31 
  32         pushl   $0x220
  33         call    SYMBOL_NAME(exception)
  34         addl    $4,%esp
  35 
  36 L_ok:
  37 #endif PARANOID
  38 
  39         movl    SIGH(%ebx),%edx
  40         movl    SIGL(%ebx),%eax
  41 
  42         orl     %edx,%edx       /* ms bits */
  43         js      L_done          /* Already normalized */
  44         jnz     L_shift_1       /* Shift left 1 - 31 bits */
  45 
  46         orl     %eax,%eax
  47         jz      L_zero          /* The contents are zero */
  48 
  49         movl    %eax,%edx
  50         xorl    %eax,%eax
  51         subl    $32,EXP(%ebx)   /* This can cause an underflow */
  52 
  53 /* We need to shift left by 1 - 31 bits */
  54 L_shift_1:
  55         bsrl    %edx,%ecx       /* get the required shift in %ecx */
  56         subl    $31,%ecx
  57         negl    %ecx
  58         shld    %cl,%eax,%edx
  59         shl     %cl,%eax
  60         subl    %ecx,EXP(%ebx)  /* This can cause an underflow */
  61 
  62         movl    %edx,SIGH(%ebx)
  63         movl    %eax,SIGL(%ebx)
  64 
  65 L_done:
  66         cmpl    EXP_OVER,EXP(%ebx)
  67         jge     L_overflow
  68 
  69         cmpl    EXP_UNDER,EXP(%ebx)
  70         jle     L_underflow
  71 
  72 L_exit:
  73         popl    %ebx
  74         leave
  75         ret
  76 
  77 
  78 L_zero:
  79         movl    EXP_UNDER,EXP(%ebx)
  80         movb    TW_Zero,TAG(%ebx)
  81         jmp     L_exit
  82 
  83 L_underflow:
  84         push    %ebx
  85         call    SYMBOL_NAME(arith_underflow)
  86         pop     %ebx
  87         jmp     L_exit
  88 
  89 L_overflow:
  90         push    %ebx
  91         call    SYMBOL_NAME(arith_overflow)
  92         pop     %ebx
  93         jmp     L_exit
  94 
  95 
  96 
  97 /* Normalise without reporting underflow or overflow */
  98 ENTRY(normalize_nuo)
  99         pushl   %ebp
 100         movl    %esp,%ebp
 101         pushl   %ebx
 102 
 103         movl    PARAM1,%ebx
 104 
 105 #ifdef PARANOID
 106         cmpb    TW_Valid,TAG(%ebx)
 107         je      L_ok_nuo
 108 
 109         pushl   $0x221
 110         call    SYMBOL_NAME(exception)
 111         addl    $4,%esp
 112 
 113 L_ok_nuo:
 114 #endif PARANOID
 115 
 116         movl    SIGH(%ebx),%edx
 117         movl    SIGL(%ebx),%eax
 118 
 119         orl     %edx,%edx       /* ms bits */
 120         js      L_exit          /* Already normalized */
 121         jnz     L_nuo_shift_1   /* Shift left 1 - 31 bits */
 122 
 123         orl     %eax,%eax
 124         jz      L_zero          /* The contents are zero */
 125 
 126         movl    %eax,%edx
 127         xorl    %eax,%eax
 128         subl    $32,EXP(%ebx)   /* This can cause an underflow */
 129 
 130 /* We need to shift left by 1 - 31 bits */
 131 L_nuo_shift_1:
 132         bsrl    %edx,%ecx       /* get the required shift in %ecx */
 133         subl    $31,%ecx
 134         negl    %ecx
 135         shld    %cl,%eax,%edx
 136         shl     %cl,%eax
 137         subl    %ecx,EXP(%ebx)  /* This can cause an underflow */
 138 
 139         movl    %edx,SIGH(%ebx)
 140         movl    %eax,SIGL(%ebx)
 141         jmp     L_exit
 142 
 143 

/* [previous][next][first][last][top][bottom][index][help] */