|
|
1.1 ! root 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 [email protected] | ! 8: | | ! 9: | | ! 10: +---------------------------------------------------------------------------*/ ! 11: ! 12: #include "fpu_system.h" ! 13: #include "exception.h" ! 14: #include "reg_constant.h" ! 15: #include "fpu_emu.h" ! 16: ! 17: ! 18: ! 19: #define HIPOWER 13 ! 20: static unsigned short lterms[HIPOWER][4] = ! 21: { ! 22: { 0x79b5, 0xd1cf, 0x17f7, 0xb172 }, ! 23: { 0x1b56, 0x058b, 0x7bff, 0x3d7f }, ! 24: { 0x8bb0, 0x8250, 0x846b, 0x0e35 }, ! 25: { 0xbc65, 0xf747, 0x556d, 0x0276 }, ! 26: { 0x17cb, 0x9e39, 0x61ff, 0x0057 }, ! 27: { 0xe018, 0x9776, 0x1848, 0x000a }, ! 28: { 0x66f2, 0xff30, 0xffe5, 0x0000 }, ! 29: { 0x682f, 0xffb6, 0x162b, 0x0000 }, ! 30: { 0xb7ca, 0x2956, 0x01b5, 0x0000 }, ! 31: { 0xcd3e, 0x4817, 0x001e, 0x0000 }, ! 32: { 0xb7e2, 0xecbe, 0x0001, 0x0000 }, ! 33: { 0x0ed5, 0x1a27, 0x0000, 0x0000 }, ! 34: { 0x101d, 0x0222, 0x0000, 0x0000 }, ! 35: }; ! 36: ! 37: ! 38: /*--- poly_2xm1() -----------------------------------------------------------+ ! 39: | | ! 40: +---------------------------------------------------------------------------*/ ! 41: int poly_2xm1(FPU_REG *arg, FPU_REG *result) ! 42: { ! 43: short exponent; ! 44: long long Xll; ! 45: FPU_REG accum; ! 46: ! 47: ! 48: exponent = arg->exp - EXP_BIAS; ! 49: ! 50: if ( arg->tag == TW_Zero ) ! 51: { ! 52: /* Return 0.0 */ ! 53: reg_move(&CONST_Z, result); ! 54: return 0; ! 55: } ! 56: ! 57: if ( exponent >= 0 ) /* Can't hack a number >= 1.0 */ ! 58: { ! 59: arith_invalid(result); ! 60: return 1; ! 61: } ! 62: ! 63: if ( arg->sign != SIGN_POS ) /* Can't hack a number < 0.0 */ ! 64: { ! 65: arith_invalid(result); ! 66: return 1; ! 67: } ! 68: ! 69: if ( exponent < -64 ) ! 70: { ! 71: reg_move(&CONST_LN2, result); ! 72: return 0; ! 73: } ! 74: ! 75: *(unsigned *)&Xll = arg->sigl; ! 76: *(((unsigned *)&Xll)+1) = arg->sigh; ! 77: if ( exponent < -1 ) ! 78: { ! 79: /* shift the argument right by the required places */ ! 80: if ( shrx(&Xll, -1-exponent) >= 0x80000000U ) ! 81: Xll++; /* round up */ ! 82: } ! 83: ! 84: *(short *)&(accum.sign) = 0; /* will be a valid positive nr with expon = 0 */ ! 85: accum.exp = 0; ! 86: ! 87: /* Do the basic fixed point polynomial evaluation */ ! 88: polynomial((unsigned *)&accum.sigl, (unsigned *)&Xll, lterms, HIPOWER-1); ! 89: ! 90: /* Convert to 64 bit signed-compatible */ ! 91: accum.exp += EXP_BIAS - 1; ! 92: ! 93: reg_move(&accum, result); ! 94: ! 95: normalize(result); ! 96: ! 97: return 0; ! 98: ! 99: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.