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,1993                                                   |
   5  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
   6  |                       Australia.  E-mail apm233m@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         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 // L_shift_32:
  43         movl    %eax,%edx
  44         xorl    %eax,%eax
  45         subl    $32,EXP(%ebx)   // This can cause an underflow
  46 
  47 /* We need to shift left by 1 - 31 bits */
  48 L_shift_1:
  49         bsrl    %edx,%ecx       /* get the required shift in %ecx */
  50         subl    $31,%ecx
  51         negl    %ecx
  52         shld    %cl,%eax,%edx
  53         shl     %cl,%eax
  54         subl    %ecx,EXP(%ebx)  // This can cause an underflow
  55 
  56         movl    %edx,SIGH(%ebx)
  57         movl    %eax,SIGL(%ebx)
  58 
  59 L_done:
  60         cmpl    EXP_OVER,EXP(%ebx)
  61         jge     L_overflow
  62 
  63         cmpl    EXP_UNDER,EXP(%ebx)
  64         jle     L_underflow
  65 
  66 L_exit:
  67         popl    %ebx
  68         leave
  69         ret
  70 
  71 
  72 L_zero:
  73         movl    EXP_UNDER,EXP(%ebx)
  74         movb    TW_Zero,TAG(%ebx)
  75         jmp     L_exit
  76 
  77 L_underflow:
  78         push    %ebx
  79         call    _arith_underflow
  80         pop     %ebx
  81         jmp     L_exit
  82 
  83 L_overflow:
  84         push    %ebx
  85         call    _arith_overflow
  86         pop     %ebx
  87         jmp     L_exit
  88 
  89 
  90 
  91 // Normalise without reporting underflow or overflow
  92         .align 2,144
  93 .globl _normalize_nuo
  94 
  95 _normalize_nuo:
  96         pushl   %ebp
  97         movl    %esp,%ebp
  98         pushl   %ebx
  99 
 100         movl    PARAM1,%ebx
 101 
 102         movl    SIGH(%ebx),%edx
 103         movl    SIGL(%ebx),%eax
 104 
 105         orl     %edx,%edx       // ms bits
 106         js      L_exit          // Already normalized
 107         jnz     L_nuo_shift_1   // Shift left 1 - 31 bits
 108 
 109         orl     %eax,%eax
 110         jz      L_zero          // The contents are zero
 111 
 112 // L_nuo_shift_32:
 113         movl    %eax,%edx
 114         xorl    %eax,%eax
 115         subl    $32,EXP(%ebx)   // This can cause an underflow
 116 
 117 /* We need to shift left by 1 - 31 bits */
 118 L_nuo_shift_1:
 119         bsrl    %edx,%ecx       /* get the required shift in %ecx */
 120         subl    $31,%ecx
 121         negl    %ecx
 122         shld    %cl,%eax,%edx
 123         shl     %cl,%eax
 124         subl    %ecx,EXP(%ebx)  // This can cause an underflow
 125 
 126         movl    %edx,SIGH(%ebx)
 127         movl    %eax,SIGL(%ebx)
 128         jmp     L_exit
 129 
 130 

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