root/kernel/FPU-emu/polynomial.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /*---------------------------------------------------------------------------+
   2  |  polynomial.S                                                             |
   3  |                                                                           |
   4  | Fixed point arithmetic polynomial evaluation.                             |
   5  |                                                                           |
   6  | Copyright (C) 1992,1993                                                   |
   7  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
   8  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
   9  |                                                                           |
  10  | Call from C as:                                                           |
  11  |   void polynomial(unsigned accum[], unsigned x[], unsigned terms[][2],    |
  12  |                   int n)                                                  |
  13  |                                                                           |
  14  | Computes:                                                                 |
  15  | terms[0] + (terms[1] + (terms[2] + ... + (terms[n-1]*x)*x)*x)*x) ... )*x  |
  16  | The result is returned in accum.                                          |
  17  |                                                                           |
  18  +---------------------------------------------------------------------------*/
  19 
  20         .file   "fpolynom.s"
  21 
  22 #include "fpu_asm.h"
  23 
  24 
  25 //      #define EXTRA_PRECISE
  26 
  27 #define TERM_SIZE       $8
  28 
  29 
  30 .text
  31         .align 2,144
  32 .globl _polynomial
  33 _polynomial:
  34         pushl   %ebp
  35         movl    %esp,%ebp
  36         subl    $32,%esp
  37         pushl   %esi
  38         pushl   %edi
  39         pushl   %ebx
  40 
  41         movl    PARAM1,%esi             // accum
  42         movl    PARAM2,%edi             // x
  43         movl    PARAM3,%ebx             // terms
  44         movl    PARAM4,%ecx             // n
  45 
  46         movl    TERM_SIZE,%eax
  47         mull    %ecx
  48         movl    %eax,%ecx
  49 
  50         movl    4(%ebx,%ecx,1),%edx     // terms[n]
  51         movl    %edx,-20(%ebp)
  52         movl    (%ebx,%ecx,1),%edx      // terms[n]
  53         movl    %edx,-24(%ebp)          
  54         xor     %eax,%eax
  55         movl    %eax,-28(%ebp)
  56 
  57         subl    TERM_SIZE,%ecx
  58         js      L_accum_done
  59 
  60 L_accum_loop:
  61         xor     %eax,%eax
  62         movl    %eax,-4(%ebp)
  63         movl    %eax,-8(%ebp)
  64 
  65 #ifdef EXTRA_PRECISE
  66         movl    -28(%ebp),%eax
  67         mull    4(%edi)                 // x ms long
  68         movl    %edx,-12(%ebp)
  69 #endif EXTRA_PRECISE
  70 
  71         movl    -24(%ebp),%eax
  72         mull    (%edi)                  // x ls long
  73 //      movl    %eax,-16(%ebp)          // Not needed
  74         addl    %edx,-12(%ebp)
  75         adcl    $0,-8(%ebp)
  76 
  77         movl    -24(%ebp),%eax
  78         mull    4(%edi)                 // x ms long
  79         addl    %eax,-12(%ebp)
  80         adcl    %edx,-8(%ebp)
  81         adcl    $0,-4(%ebp)
  82 
  83         movl    -20(%ebp),%eax
  84         mull    (%edi)
  85         addl    %eax,-12(%ebp)
  86         adcl    %edx,-8(%ebp)
  87         adcl    $0,-4(%ebp)
  88 
  89         movl    -20(%ebp),%eax
  90         mull    4(%edi)
  91         addl    %eax,-8(%ebp)
  92         adcl    %edx,-4(%ebp)
  93 
  94 /* Now add the next term */
  95         movl    (%ebx,%ecx,1),%eax
  96         addl    %eax,-8(%ebp)
  97         movl    4(%ebx,%ecx,1),%eax
  98         adcl    %eax,-4(%ebp)
  99 
 100 /* And put into the second register */
 101         movl    -4(%ebp),%eax
 102         movl    %eax,-20(%ebp)
 103         movl    -8(%ebp),%eax
 104         movl    %eax,-24(%ebp)
 105 
 106 #ifdef EXTRA_PRECISE
 107         movl    -12(%ebp),%eax
 108         movl    %eax,-28(%ebp)
 109 #else
 110         testb   $128,-25(%ebp)
 111         je      L_no_poly_round
 112 
 113         addl    $1,-24(%ebp)
 114         adcl    $0,-20(%ebp)
 115 L_no_poly_round:
 116 #endif EXTRA_PRECISE
 117 
 118         subl    TERM_SIZE,%ecx
 119         jns     L_accum_loop
 120 
 121 L_accum_done:
 122 #ifdef EXTRA_PRECISE
 123 /* And round the result */
 124         testb   $128,-25(%ebp)
 125         je      L_poly_done
 126 
 127         addl    $1,-24(%ebp)
 128         adcl    $0,-20(%ebp)
 129 #endif EXTRA_PRECISE
 130 
 131 L_poly_done:
 132         movl    -24(%ebp),%eax
 133         movl    %eax,(%esi)
 134         movl    -20(%ebp),%eax
 135         movl    %eax,4(%esi)
 136 
 137         popl    %ebx
 138         popl    %edi
 139         popl    %esi
 140         leave
 141         ret

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