root/kernel/FPU-emu/poly_2xm1.c

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

DEFINITIONS

This source file includes following definitions.
  1. poly_2xm1

   1 /*---------------------------------------------------------------------------+
   2  |  poly_2xm1.c                                                              |
   3  |                                                                           |
   4  | Function to compute 2^x-1 by a polynomial approximation.                  |
   5  |                                                                           |
   6  | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
   7  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
   8  |                                                                           |
   9  |                                                                           |
  10  +---------------------------------------------------------------------------*/
  11 
  12 #include "exception.h"
  13 #include "reg_constant.h"
  14 #include "fpu_emu.h"
  15 
  16 
  17 
  18 #define HIPOWER 13
  19 static unsigned short   lterms[HIPOWER][4] =
  20         {
  21         { 0x79b5, 0xd1cf, 0x17f7, 0xb172 },
  22         { 0x1b56, 0x058b, 0x7bff, 0x3d7f },
  23         { 0x8bb0, 0x8250, 0x846b, 0x0e35 },
  24         { 0xbc65, 0xf747, 0x556d, 0x0276 },
  25         { 0x17cb, 0x9e39, 0x61ff, 0x0057 },
  26         { 0xe018, 0x9776, 0x1848, 0x000a },
  27         { 0x66f2, 0xff30, 0xffe5, 0x0000 },
  28         { 0x682f, 0xffb6, 0x162b, 0x0000 },
  29         { 0xb7ca, 0x2956, 0x01b5, 0x0000 },
  30         { 0xcd3e, 0x4817, 0x001e, 0x0000 },
  31         { 0xb7e2, 0xecbe, 0x0001, 0x0000 },
  32         { 0x0ed5, 0x1a27, 0x0000, 0x0000 },
  33         { 0x101d, 0x0222, 0x0000, 0x0000 },
  34         };
  35 
  36 
  37 /*--- poly_2xm1() -----------------------------------------------------------+
  38  |                                                                           |
  39  +---------------------------------------------------------------------------*/
  40 int     poly_2xm1(FPU_REG *arg, FPU_REG *result)
     /* [previous][next][first][last][top][bottom][index][help] */
  41 {
  42   short         exponent;
  43   long long     Xll;
  44   FPU_REG           accum;
  45 
  46 
  47   exponent = arg->exp - EXP_BIAS;
  48 
  49   if ( arg->tag == TW_Zero )
  50     {
  51       /* Return 0.0 */
  52       reg_move(&CONST_Z, result);
  53       return 0;
  54     }
  55 
  56   if ( exponent >= 0 )  /* Can't hack a number >= 1.0 */
  57     {
  58       arith_invalid(result);
  59       return 1;
  60     }
  61 
  62   if ( arg->sign != SIGN_POS )  /* Can't hack a number < 0.0 */
  63     {
  64       arith_invalid(result);
  65       return 1;
  66     }
  67   
  68   if ( exponent < -64 )
  69     {
  70       reg_move(&CONST_LN2, result);
  71       return 0;
  72     }
  73 
  74   *(unsigned *)&Xll = arg->sigl;
  75   *(((unsigned *)&Xll)+1) = arg->sigh;
  76   if ( exponent < -1 )
  77     {
  78       /* shift the argument right by the required places */
  79       if ( shrx(&Xll, -1-exponent) >= 0x80000000U )
  80         Xll++;  /* round up */
  81     }
  82 
  83   *(short *)&(accum.sign) = 0; /* will be a valid positive nr with expon = 0 */
  84   accum.exp = 0;
  85 
  86   /* Do the basic fixed point polynomial evaluation */
  87   polynomial((unsigned *)&accum.sigl, (unsigned *)&Xll, lterms, HIPOWER-1);
  88 
  89   /* Convert to 64 bit signed-compatible */
  90   accum.exp += EXP_BIAS - 1;
  91 
  92   reg_move(&accum, result);
  93 
  94   normalize(result);
  95 
  96   return 0;
  97 
  98 }

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