~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/x86/math-emu/reg_constant.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*---------------------------------------------------------------------------+
 
2
 |  reg_constant.c                                                           |
 
3
 |                                                                           |
 
4
 | All of the constant FPU_REGs                                              |
 
5
 |                                                                           |
 
6
 | Copyright (C) 1992,1993,1994,1997                                         |
 
7
 |                     W. Metzenthen, 22 Parker St, Ormond, Vic 3163,        |
 
8
 |                     Australia.  E-mail   billm@suburbia.net               |
 
9
 |                                                                           |
 
10
 |                                                                           |
 
11
 +---------------------------------------------------------------------------*/
 
12
 
 
13
#include "fpu_system.h"
 
14
#include "fpu_emu.h"
 
15
#include "status_w.h"
 
16
#include "reg_constant.h"
 
17
#include "control_w.h"
 
18
 
 
19
#define MAKE_REG(s, e, l, h) { l, h, \
 
20
                ((EXTENDED_Ebias+(e)) | ((SIGN_##s != 0)*0x8000)) }
 
21
 
 
22
FPU_REG const CONST_1 = MAKE_REG(POS, 0, 0x00000000, 0x80000000);
 
23
#if 0
 
24
FPU_REG const CONST_2 = MAKE_REG(POS, 1, 0x00000000, 0x80000000);
 
25
FPU_REG const CONST_HALF = MAKE_REG(POS, -1, 0x00000000, 0x80000000);
 
26
#endif /*  0  */
 
27
static FPU_REG const CONST_L2T = MAKE_REG(POS, 1, 0xcd1b8afe, 0xd49a784b);
 
28
static FPU_REG const CONST_L2E = MAKE_REG(POS, 0, 0x5c17f0bc, 0xb8aa3b29);
 
29
FPU_REG const CONST_PI = MAKE_REG(POS, 1, 0x2168c235, 0xc90fdaa2);
 
30
FPU_REG const CONST_PI2 = MAKE_REG(POS, 0, 0x2168c235, 0xc90fdaa2);
 
31
FPU_REG const CONST_PI4 = MAKE_REG(POS, -1, 0x2168c235, 0xc90fdaa2);
 
32
static FPU_REG const CONST_LG2 = MAKE_REG(POS, -2, 0xfbcff799, 0x9a209a84);
 
33
static FPU_REG const CONST_LN2 = MAKE_REG(POS, -1, 0xd1cf79ac, 0xb17217f7);
 
34
 
 
35
/* Extra bits to take pi/2 to more than 128 bits precision. */
 
36
FPU_REG const CONST_PI2extra = MAKE_REG(NEG, -66,
 
37
                                        0xfc8f8cbb, 0xece675d1);
 
38
 
 
39
/* Only the sign (and tag) is used in internal zeroes */
 
40
FPU_REG const CONST_Z = MAKE_REG(POS, EXP_UNDER, 0x0, 0x0);
 
41
 
 
42
/* Only the sign and significand (and tag) are used in internal NaNs */
 
43
/* The 80486 never generates one of these
 
44
FPU_REG const CONST_SNAN = MAKE_REG(POS, EXP_OVER, 0x00000001, 0x80000000);
 
45
 */
 
46
/* This is the real indefinite QNaN */
 
47
FPU_REG const CONST_QNaN = MAKE_REG(NEG, EXP_OVER, 0x00000000, 0xC0000000);
 
48
 
 
49
/* Only the sign (and tag) is used in internal infinities */
 
50
FPU_REG const CONST_INF = MAKE_REG(POS, EXP_OVER, 0x00000000, 0x80000000);
 
51
 
 
52
static void fld_const(FPU_REG const * c, int adj, u_char tag)
 
53
{
 
54
        FPU_REG *st_new_ptr;
 
55
 
 
56
        if (STACK_OVERFLOW) {
 
57
                FPU_stack_overflow();
 
58
                return;
 
59
        }
 
60
        push();
 
61
        reg_copy(c, st_new_ptr);
 
62
        st_new_ptr->sigl += adj;        /* For all our fldxxx constants, we don't need to
 
63
                                           borrow or carry. */
 
64
        FPU_settag0(tag);
 
65
        clear_C1();
 
66
}
 
67
 
 
68
/* A fast way to find out whether x is one of RC_DOWN or RC_CHOP
 
69
   (and not one of RC_RND or RC_UP).
 
70
   */
 
71
#define DOWN_OR_CHOP(x)  (x & RC_DOWN)
 
72
 
 
73
static void fld1(int rc)
 
74
{
 
75
        fld_const(&CONST_1, 0, TAG_Valid);
 
76
}
 
77
 
 
78
static void fldl2t(int rc)
 
79
{
 
80
        fld_const(&CONST_L2T, (rc == RC_UP) ? 1 : 0, TAG_Valid);
 
81
}
 
82
 
 
83
static void fldl2e(int rc)
 
84
{
 
85
        fld_const(&CONST_L2E, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
 
86
}
 
87
 
 
88
static void fldpi(int rc)
 
89
{
 
90
        fld_const(&CONST_PI, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
 
91
}
 
92
 
 
93
static void fldlg2(int rc)
 
94
{
 
95
        fld_const(&CONST_LG2, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
 
96
}
 
97
 
 
98
static void fldln2(int rc)
 
99
{
 
100
        fld_const(&CONST_LN2, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
 
101
}
 
102
 
 
103
static void fldz(int rc)
 
104
{
 
105
        fld_const(&CONST_Z, 0, TAG_Zero);
 
106
}
 
107
 
 
108
typedef void (*FUNC_RC) (int);
 
109
 
 
110
static FUNC_RC constants_table[] = {
 
111
        fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, (FUNC_RC) FPU_illegal
 
112
};
 
113
 
 
114
void fconst(void)
 
115
{
 
116
        (constants_table[FPU_rm]) (control_word & CW_RC);
 
117
}