root/kernel/FPU-emu/reg_u_mul.S

/* [previous][next][first][last][top][bottom][index][help] */
   1         .file   "reg_u_mul.S"
   2 /*---------------------------------------------------------------------------+
   3  |  reg_u_mul.S                                                              |
   4  |                                                                           |
   5  | Core multiplication routine                                               |
   6  |                                                                           |
   7  | Copyright (C) 1992,1993                                                   |
   8  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
   9  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
  10  |                                                                           |
  11  |                                                                           |
  12  +---------------------------------------------------------------------------*/
  13 
  14 /*---------------------------------------------------------------------------+
  15  |   Basic multiplication routine.                                           |
  16  |   Does not check the resulting exponent for overflow/underflow            |
  17  |                                                                           |
  18  |   reg_u_mul(FPU_REG *a, FPU_REG *b, FPU_REG *c, unsigned int cw);         |
  19  |                                                                           |
  20  |   Internal working is at approx 128 bits.                                 |
  21  |   Result is rounded to nearest 53 or 64 bits, using "nearest or even".    |
  22  +---------------------------------------------------------------------------*/
  23 
  24 #include "exception.h"
  25 #include "fpu_asm.h"
  26 #include "control_w.h"
  27 
  28 
  29 .data
  30         .align 2,0
  31 accum_0:
  32         .long   0
  33 accum_1:
  34         .long   0
  35 
  36 
  37 .text
  38         .align 2,144
  39 
  40 .globl _reg_u_mul
  41 _reg_u_mul:
  42         pushl   %ebp
  43         movl    %esp,%ebp
  44         pushl   %esi
  45         pushl   %edi
  46         pushl   %ebx
  47 
  48         movl    PARAM1,%esi
  49         movl    PARAM2,%edi
  50 
  51 #ifdef PARANOID
  52         testl   $0x80000000,SIGH(%esi)
  53         jz      L_bugged
  54         testl   $0x80000000,SIGH(%edi)
  55         jz      L_bugged
  56 #endif PARANOID
  57 
  58 #ifdef DENORM_OPERAND
  59         movl    EXP(%esi),%eax
  60         cmpl    EXP_UNDER,%eax
  61         jg      xOp1_not_denorm
  62 
  63         call    _denormal_operand
  64         orl     %eax,%eax
  65         jnz     FPU_Arith_exit
  66 
  67 xOp1_not_denorm:
  68         movl    EXP(%edi),%eax
  69         cmpl    EXP_UNDER,%eax
  70         jg      xOp2_not_denorm
  71 
  72         call    _denormal_operand
  73         orl     %eax,%eax
  74         jnz     FPU_Arith_exit
  75 
  76 xOp2_not_denorm:
  77 #endif DENORM_OPERAND
  78 
  79         xorl    %ecx,%ecx
  80         xorl    %ebx,%ebx
  81 
  82         movl    SIGL(%esi),%eax
  83         mull    SIGL(%edi)
  84         movl    %eax,accum_0
  85         movl    %edx,accum_1
  86 
  87         movl    SIGL(%esi),%eax
  88         mull    SIGH(%edi)
  89         addl    %eax,accum_1
  90         adcl    %edx,%ebx
  91 //      adcl    $0,%ecx         // overflow here is not possible
  92 
  93         movl    SIGH(%esi),%eax
  94         mull    SIGL(%edi)
  95         addl    %eax,accum_1
  96         adcl    %edx,%ebx
  97         adcl    $0,%ecx
  98 
  99         movl    SIGH(%esi),%eax
 100         mull    SIGH(%edi)
 101         addl    %eax,%ebx
 102         adcl    %edx,%ecx
 103 
 104         movl    EXP(%esi),%eax  /* Compute the exponent */
 105         addl    EXP(%edi),%eax
 106         subl    EXP_BIAS-1,%eax
 107 //  Have now finished with the sources
 108         movl    PARAM3,%edi     // Point to the destination
 109         movl    %eax,EXP(%edi)
 110 
 111 //  Now make sure that the result is normalized
 112         testl   $0x80000000,%ecx
 113         jnz     LResult_Normalised
 114 
 115         /* Normalize by shifting left one bit */
 116         shll    $1,accum_0
 117         rcll    $1,accum_1
 118         rcll    $1,%ebx
 119         rcll    $1,%ecx
 120         decl    EXP(%edi)
 121 
 122 LResult_Normalised:
 123         movl    accum_0,%eax
 124         movl    accum_1,%edx
 125         orl     %eax,%eax
 126         jz      L_extent_zero
 127 
 128         orl     $1,%edx
 129 
 130 L_extent_zero:
 131         movl    %ecx,%eax
 132         jmp     FPU_round
 133 
 134 
 135 #ifdef PARANOID
 136 L_bugged:
 137         pushl   EX_INTERNAL|0x205
 138         call    EXCEPTION
 139         pop     %ebx
 140         jmp     L_exit
 141 
 142 L_exit:
 143         popl    %ebx
 144         popl    %edi
 145         popl    %esi
 146         leave
 147         ret
 148 #endif PARANOID
 149 

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