root/drivers/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   billm@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   // Do not use: not complete */
  26 
  27 #define TERM_SIZE       $8
  28 #define SUM_MS          -20(%ebp)       /* sum ms long */
  29 #define SUM_MIDDLE      -24(%ebp)       /* sum middle long */
  30 #define SUM_LS          -28(%ebp)       /* sum ls long */
  31 #define SUM_LS_HI       -25(%ebp)       /* high byte of sum ls */
  32 #define ACCUM_MS        -4(%ebp)        /* accum ms long */
  33 #define ACCUM_MIDDLE    -8(%ebp)        /* accum middle long */
  34 #define ACCUM_LS        -12(%ebp)       /* accum ls long */
  35 #define ACCUM_LS_HI     -9(%ebp)        /* high byte of accum ls */
  36 
  37 .text
  38         .align 2,144
  39 .globl _polynomial
  40 _polynomial:
  41         pushl   %ebp
  42         movl    %esp,%ebp
  43         subl    $32,%esp
  44         pushl   %esi
  45         pushl   %edi
  46         pushl   %ebx
  47 
  48         movl    PARAM2,%esi             /* x */
  49         movl    PARAM3,%edi             /* terms */
  50 
  51         movl    TERM_SIZE,%eax
  52         mull    PARAM4                  /* n */
  53         addl    %eax,%edi
  54 
  55         movl    4(%edi),%edx            /* terms[n] */
  56         movl    %edx,SUM_MS
  57         movl    (%edi),%edx             /* terms[n] */
  58         movl    %edx,SUM_MIDDLE
  59         xor     %eax,%eax
  60         movl    %eax,SUM_LS
  61 
  62         subl    TERM_SIZE,%edi
  63         decl    PARAM4
  64         js      L_accum_done
  65 
  66 L_accum_loop:
  67         xor     %eax,%eax
  68         movl    %eax,ACCUM_MS
  69         movl    %eax,ACCUM_MIDDLE
  70 
  71         movl    SUM_MIDDLE,%eax
  72         mull    (%esi)                  /* x ls long */
  73 /*      movl    %eax,-16(%ebp)          // Not needed */
  74         movl    %edx,ACCUM_LS
  75 
  76         movl    SUM_MIDDLE,%eax
  77         mull    4(%esi)                 /* x ms long */
  78         addl    %eax,ACCUM_LS
  79         adcl    %edx,ACCUM_MIDDLE
  80         adcl    $0,ACCUM_MS
  81 
  82         movl    SUM_MS,%eax
  83         mull    (%esi)                  /* x ls long */
  84         addl    %eax,ACCUM_LS
  85         adcl    %edx,ACCUM_MIDDLE
  86         adcl    $0,ACCUM_MS
  87 
  88         movl    SUM_MS,%eax
  89         mull    4(%esi)                 /* x ms long */
  90         addl    %eax,ACCUM_MIDDLE
  91         adcl    %edx,ACCUM_MS
  92 
  93 /*
  94  * Now put the sum of next term and the accumulator
  95  * into the sum register
  96  */
  97         movl    ACCUM_MIDDLE,%eax
  98         addl    (%edi),%eax             /* term ls long */
  99         movl    %eax,SUM_MIDDLE
 100         movl    ACCUM_MS,%eax
 101         adcl    4(%edi),%eax            /* term ms long */
 102         movl    %eax,SUM_MS
 103 
 104 #ifdef EXTRA_PRECISE
 105         movl    ACCUM_LS,%eax
 106         movl    %eax,SUM_LS
 107 #else
 108         testb   $0x80,ACCUM_LS_HI       /* ms bit of ACCUM_LS */
 109         je      L_no_poly_round
 110 
 111         addl    $1,SUM_MIDDLE
 112         adcl    $0,SUM_MS
 113 L_no_poly_round:
 114 #endif EXTRA_PRECISE
 115 
 116         subl    TERM_SIZE,%edi
 117         decl    PARAM4
 118         jns     L_accum_loop
 119 
 120 L_accum_done:
 121 #ifdef EXTRA_PRECISE
 122 /* Round the result */
 123         testb   $128,SUM_LS_HI
 124         je      L_poly_done
 125 
 126         addl    $1,SUM_MIDDLE
 127         adcl    $0,SUM_MS
 128 #endif EXTRA_PRECISE
 129 
 130 L_poly_done:
 131         movl    PARAM1,%edi             /* accum */
 132         movl    SUM_MIDDLE,%eax
 133         movl    %eax,(%edi)
 134         movl    SUM_MS,%eax
 135         movl    %eax,4(%edi)
 136 
 137         popl    %ebx
 138         popl    %edi
 139         popl    %esi
 140         leave
 141         ret

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