root/arch/i386/math-emu/poly.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. mul_32_32
  2. add_Xsig_Xsig
  3. add_two_Xsig
  4. negate_Xsig

   1 /*---------------------------------------------------------------------------+
   2  |  poly.h                                                                   |
   3  |                                                                           |
   4  |  Header file for the FPU-emu poly*.c source files.                        |
   5  |                                                                           |
   6  | Copyright (C) 1994                                                        |
   7  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
   8  |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
   9  |                                                                           |
  10  | Declarations and definitions for functions operating on Xsig (12-byte     |
  11  | extended-significand) quantities.                                         |
  12  |                                                                           |
  13  +---------------------------------------------------------------------------*/
  14 
  15 #ifndef _POLY_H
  16 #define _POLY_H
  17 
  18 /* This 12-byte structure is used to improve the accuracy of computation
  19    of transcendental functions.
  20    Intended to be used to get results better than 8-byte computation
  21    allows. 9-byte would probably be sufficient.
  22    */
  23 typedef struct {
  24   unsigned long lsw;
  25   unsigned long midw;
  26   unsigned long msw;
  27 } Xsig;
  28 
  29 asmlinkage void mul64(unsigned long long const *a, unsigned long long const *b,
  30                       unsigned long long *result);
  31 asmlinkage void polynomial_Xsig(Xsig *, const unsigned long long *x,
  32                                 const unsigned long long terms[], const int n);
  33 
  34 asmlinkage void mul32_Xsig(Xsig *, const unsigned long mult);
  35 asmlinkage void mul64_Xsig(Xsig *, const unsigned long long *mult);
  36 asmlinkage void mul_Xsig_Xsig(Xsig *dest, const Xsig *mult);
  37 
  38 asmlinkage void shr_Xsig(Xsig *, const int n);
  39 asmlinkage int round_Xsig(Xsig *);
  40 asmlinkage int norm_Xsig(Xsig *);
  41 asmlinkage void div_Xsig(Xsig *x1, const Xsig *x2, const Xsig *dest);
  42 
  43 /* Macro to extract the most significant 32 bits from a long long */
  44 #define LL_MSW(x)     (((unsigned long *)&x)[1])
  45 
  46 /* Macro to initialize an Xsig struct */
  47 #define MK_XSIG(a,b,c)     { c, b, a }
  48 
  49 /* Macro to access the 8 ms bytes of an Xsig as a long long */
  50 #define XSIG_LL(x)         (*(unsigned long long *)&x.midw)
  51 
  52 
  53 /*
  54    Need to run gcc with optimizations on to get these to
  55    actually be in-line.
  56    */
  57 
  58 /* Multiply two fixed-point 32 bit numbers. */
  59 extern inline void mul_32_32(const unsigned long arg1,
     /* [previous][next][first][last][top][bottom][index][help] */
  60                              const unsigned long arg2,
  61                              unsigned long *out)
  62 {
  63   asm volatile ("movl %1,%%eax; mull %2; movl %%edx,%0" \
  64                 :"=g" (*out) \
  65                 :"g" (arg1), "g" (arg2) \
  66                 :"ax","dx");
  67 }
  68 
  69 
  70 /* Add the 12 byte Xsig x2 to Xsig dest, with no checks for overflow. */
  71 extern inline void add_Xsig_Xsig(Xsig *dest, const Xsig *x2)
     /* [previous][next][first][last][top][bottom][index][help] */
  72 {
  73   asm volatile ("movl %1,%%edi; movl %2,%%esi;
  74                  movl (%%esi),%%eax; addl %%eax,(%%edi);
  75                  movl 4(%%esi),%%eax; adcl %%eax,4(%%edi);
  76                  movl 8(%%esi),%%eax; adcl %%eax,8(%%edi);"
  77                  :"=g" (*dest):"g" (dest), "g" (x2)
  78                  :"ax","si","di");
  79 }
  80 
  81 
  82 /* Add the 12 byte Xsig x2 to Xsig dest, adjust exp if overflow occurs. */
  83 /* Note: the constraints in the asm statement didn't always work properly
  84    with gcc 2.5.8.  Changing from using edi to using ecx got around the
  85    problem, but keep fingers crossed! */
  86 extern inline int add_two_Xsig(Xsig *dest, const Xsig *x2, long int *exp)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {
  88   asm volatile ("movl %2,%%ecx; movl %3,%%esi;
  89                  movl (%%esi),%%eax; addl %%eax,(%%ecx);
  90                  movl 4(%%esi),%%eax; adcl %%eax,4(%%ecx);
  91                  movl 8(%%esi),%%eax; adcl %%eax,8(%%ecx);
  92                  jnc 0f;
  93                  rcrl 8(%%ecx); rcrl 4(%%ecx); rcrl (%%ecx)
  94                  movl %4,%%ecx; incl (%%ecx)
  95                  movl $1,%%eax; jmp 1f;
  96                  0: xorl %%eax,%%eax;
  97                  1:"
  98                 :"=g" (*exp), "=g" (*dest)
  99                 :"g" (dest), "g" (x2), "g" (exp)
 100                 :"cx","si","ax");
 101 }
 102 
 103 
 104 /* Negate (subtract from 1.0) the 12 byte Xsig */
 105 /* This is faster in a loop on my 386 than using the "neg" instruction. */
 106 extern inline void negate_Xsig(Xsig *x)
     /* [previous][next][first][last][top][bottom][index][help] */
 107 {
 108   asm volatile("movl %1,%%esi; "
 109                "xorl %%ecx,%%ecx; "
 110                "movl %%ecx,%%eax; subl (%%esi),%%eax; movl %%eax,(%%esi); "
 111                "movl %%ecx,%%eax; sbbl 4(%%esi),%%eax; movl %%eax,4(%%esi); "
 112                "movl %%ecx,%%eax; sbbl 8(%%esi),%%eax; movl %%eax,8(%%esi); "
 113                :"=g" (*x):"g" (x):"si","ax","cx");
 114 }
 115 
 116 #endif _POLY_H

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