root/drivers/FPU-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 
  22         .align 2,144
  23 .globl _normalize
  24 
  25 _normalize:
  26         pushl   %ebp
  27         movl    %esp,%ebp
  28         pushl   %ebx
  29 
  30         movl    PARAM1,%ebx
  31 
  32 #ifdef PARANOID
  33         cmpb    TW_Valid,TAG(%ebx)
  34         je      L_ok
  35 
  36         pushl   $0x220
  37         call    _exception
  38         addl    $4,%esp
  39 
  40 L_ok:
  41 #endif PARANOID
  42 
  43         movl    SIGH(%ebx),%edx
  44         movl    SIGL(%ebx),%eax
  45 
  46         orl     %edx,%edx       /* ms bits */
  47         js      L_done          /* Already normalized */
  48         jnz     L_shift_1       /* Shift left 1 - 31 bits */
  49 
  50         orl     %eax,%eax
  51         jz      L_zero          /* The contents are zero */
  52 
  53         movl    %eax,%edx
  54         xorl    %eax,%eax
  55         subl    $32,EXP(%ebx)   /* This can cause an underflow */
  56 
  57 /* We need to shift left by 1 - 31 bits */
  58 L_shift_1:
  59         bsrl    %edx,%ecx       /* get the required shift in %ecx */
  60         subl    $31,%ecx
  61         negl    %ecx
  62         shld    %cl,%eax,%edx
  63         shl     %cl,%eax
  64         subl    %ecx,EXP(%ebx)  /* This can cause an underflow */
  65 
  66         movl    %edx,SIGH(%ebx)
  67         movl    %eax,SIGL(%ebx)
  68 
  69 L_done:
  70         cmpl    EXP_OVER,EXP(%ebx)
  71         jge     L_overflow
  72 
  73         cmpl    EXP_UNDER,EXP(%ebx)
  74         jle     L_underflow
  75 
  76 L_exit:
  77         popl    %ebx
  78         leave
  79         ret
  80 
  81 
  82 L_zero:
  83         movl    EXP_UNDER,EXP(%ebx)
  84         movb    TW_Zero,TAG(%ebx)
  85         jmp     L_exit
  86 
  87 L_underflow:
  88         push    %ebx
  89         call    _arith_underflow
  90         pop     %ebx
  91         jmp     L_exit
  92 
  93 L_overflow:
  94         push    %ebx
  95         call    _arith_overflow
  96         pop     %ebx
  97         jmp     L_exit
  98 
  99 
 100 
 101 /* Normalise without reporting underflow or overflow */
 102         .align 2,144
 103 .globl _normalize_nuo
 104 
 105 _normalize_nuo:
 106         pushl   %ebp
 107         movl    %esp,%ebp
 108         pushl   %ebx
 109 
 110         movl    PARAM1,%ebx
 111 
 112 #ifdef PARANOID
 113         cmpb    TW_Valid,TAG(%ebx)
 114         je      L_ok_nuo
 115 
 116         pushl   $0x221
 117         call    _exception
 118         addl    $4,%esp
 119 
 120 L_ok_nuo:
 121 #endif PARANOID
 122 
 123         movl    SIGH(%ebx),%edx
 124         movl    SIGL(%ebx),%eax
 125 
 126         orl     %edx,%edx       /* ms bits */
 127         js      L_exit          /* Already normalized */
 128         jnz     L_nuo_shift_1   /* Shift left 1 - 31 bits */
 129 
 130         orl     %eax,%eax
 131         jz      L_zero          /* The contents are zero */
 132 
 133         movl    %eax,%edx
 134         xorl    %eax,%eax
 135         subl    $32,EXP(%ebx)   /* This can cause an underflow */
 136 
 137 /* We need to shift left by 1 - 31 bits */
 138 L_nuo_shift_1:
 139         bsrl    %edx,%ecx       /* get the required shift in %ecx */
 140         subl    $31,%ecx
 141         negl    %ecx
 142         shld    %cl,%eax,%edx
 143         shl     %cl,%eax
 144         subl    %ecx,EXP(%ebx)  /* This can cause an underflow */
 145 
 146         movl    %edx,SIGH(%ebx)
 147         movl    %eax,SIGL(%ebx)
 148         jmp     L_exit
 149 
 150 

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