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 
  30 .data
  31         .align 2,0
  32 accum_0:
  33         .long   0
  34 accum_1:
  35         .long   0
  36 
  37 
  38 .text
  39         .align 2,144
  40 
  41 .globl _reg_u_mul
  42 _reg_u_mul:
  43         pushl   %ebp
  44         movl    %esp,%ebp
  45         pushl   %esi
  46         pushl   %edi
  47         pushl   %ebx
  48 
  49         movl    PARAM1,%esi
  50         movl    PARAM2,%edi
  51 
  52 #ifdef PARANOID
  53         testl   $0x80000000,SIGH(%esi)
  54         jz      L_bugged
  55         testl   $0x80000000,SIGH(%edi)
  56         jz      L_bugged
  57 #endif PARANOID
  58 
  59         xorl    %ecx,%ecx
  60         xorl    %ebx,%ebx
  61 
  62         movl    SIGL(%esi),%eax
  63         mull    SIGL(%edi)
  64         movl    %eax,accum_0
  65         movl    %edx,accum_1
  66 
  67         movl    SIGL(%esi),%eax
  68         mull    SIGH(%edi)
  69         addl    %eax,accum_1
  70         adcl    %edx,%ebx
  71 //      adcl    $0,%ecx         // overflow here is not possible
  72 
  73         movl    SIGH(%esi),%eax
  74         mull    SIGL(%edi)
  75         addl    %eax,accum_1
  76         adcl    %edx,%ebx
  77         adcl    $0,%ecx
  78 
  79         movl    SIGH(%esi),%eax
  80         mull    SIGH(%edi)
  81         addl    %eax,%ebx
  82         adcl    %edx,%ecx
  83 
  84         movl    EXP(%esi),%eax  /* Compute the exponent */
  85         addl    EXP(%edi),%eax
  86 //  Have now finished with the sources
  87         movl    PARAM3,%edi     // Point to the destination
  88         movl    %eax,EXP(%edi)
  89 
  90 //  Now make sure that the result is normalized
  91         testl   $0x80000000,%ecx
  92         jnz     LResult_Normalised
  93 
  94         /* Normalize by shifting left one bit */
  95         shll    $1,accum_0
  96         rcll    $1,accum_1
  97         rcll    $1,%ebx
  98         rcll    $1,%ecx
  99         decl    EXP(%edi)
 100 
 101 LResult_Normalised:
 102         movl    accum_0,%eax
 103         movl    accum_1,%edx
 104         orl     %eax,%eax
 105         jz      L_extent_zero
 106 
 107         orl     $1,%edx
 108 
 109 L_extent_zero:
 110         movl    %ecx,%eax
 111         jmp     FPU_round
 112 
 113 
 114 #ifdef PARANOID
 115 L_bugged:
 116         pushl   EX_INTERNAL|0x205
 117         call    EXCEPTION
 118         pop     %ebx
 119         jmp     L_exit
 120 
 121 L_exit:
 122         popl    %ebx
 123         popl    %edi
 124         popl    %esi
 125         leave
 126         ret
 127 #endif PARANOID
 128 

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