root/kernel/FPU-emu/reg_norm.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /*---------------------------------------------------------------------------+
   2  |  reg_norm.S                                                               |
   3  |                                                                           |
   4  | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
   5  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
   6  |                                                                           |
   7  | Normalize the value in a FPU_REG.                                         |
   8  |                                                                           |
   9  | Call from C as:                                                           |
  10  |   void normalize(FPU_REG *n)                                              |
  11  |                                                                           |
  12  +---------------------------------------------------------------------------*/
  13 
  14 #include "fpu_asm.h"
  15 
  16 
  17 .text
  18 
  19         .align 2,144
  20 .globl _normalize
  21 
  22 _normalize:
  23         pushl   %ebp
  24         movl    %esp,%ebp
  25         pushl   %ebx
  26 
  27         movl    PARAM1,%ebx
  28 
  29         movl    SIGH(%ebx),%edx
  30         movl    SIGL(%ebx),%eax
  31 
  32         orl     %edx,%edx       // ms bits
  33         js      L_done          // Already normalized
  34         jnz     L_shift_1       // Shift left 1 - 31 bits
  35 
  36         orl     %eax,%eax
  37         jz      L_zero          // The contents are zero
  38 
  39 L_shift_32:
  40         movl    %eax,%edx
  41         xorl    %eax,%eax
  42         subl    $32,EXP(%ebx)   // This can cause an underflow
  43 
  44 /* We need to shift left by 1 - 31 bits */
  45 L_shift_1:
  46         bsrl    %edx,%ecx       /* get the required shift in %ecx */
  47         subl    $31,%ecx
  48         negl    %ecx
  49         shld    %cl,%eax,%edx
  50         shl     %cl,%eax
  51         subl    %ecx,EXP(%ebx)  // This can cause an underflow
  52 
  53         movl    %edx,SIGH(%ebx)
  54         movl    %eax,SIGL(%ebx)
  55 
  56 L_done:
  57         cmpl    EXP_OVER,EXP(%ebx)
  58         jge     L_overflow
  59 
  60         cmpl    EXP_UNDER,EXP(%ebx)
  61         jle     L_underflow
  62 
  63 L_exit:
  64         popl    %ebx
  65         leave
  66         ret
  67 
  68 
  69 L_zero:
  70         movl    EXP_UNDER,EXP(%ebx)
  71         movb    TW_Zero,TAG(%ebx)
  72         jmp     L_exit
  73 
  74 L_underflow:
  75         push    %ebx
  76         call    _arith_underflow
  77         pop     %ebx
  78         jmp     L_exit
  79 
  80 L_overflow:
  81         push    %ebx
  82         call    _arith_overflow
  83         pop     %ebx
  84         jmp     L_exit

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