Merge from vendor branch LIBPCAP:
[dragonfly.git] / sys / i386 / i386 / math_emu.h
1 /*
2  * linux/include/linux/math_emu.h
3  *
4  * (C) 1991 Linus Torvalds
5  *
6  * $FreeBSD: src/sys/i386/i386/math_emu.h,v 1.7.2.1 2001/08/15 01:23:50 peter Exp $
7  * $DragonFly: src/sys/i386/i386/Attic/math_emu.h,v 1.5 2004/04/30 00:59:52 dillon Exp $
8  */
9 #ifndef _LINUX_MATH_EMU_H
10 #define _LINUX_MATH_EMU_H
11
12 /*#define math_abort(x,y) \
13 (((volatile void (*)(struct info *,unsigned int)) __math_abort)((x),(y)))*/
14
15 /*
16  * Gcc forces this stupid alignment problem: I want to use only two int32_t's
17  * for the temporary real 64-bit mantissa, but then gcc aligns out the
18  * structure to 12 bytes which breaks things in math_emulate.c. Shit. I
19  * want some kind of "no-alignt" pragma or something.
20  */
21
22 typedef struct {
23         int32_t a,b;
24         short exponent;
25 } temp_real;
26
27 typedef struct {
28         short m0,m1,m2,m3;
29         short exponent;
30 } temp_real_unaligned;
31
32 #define real_to_real(a,b) \
33 ((*(long long *) (b) = *(long long *) (a)),((b)->exponent = (a)->exponent))
34
35 typedef struct {
36         int32_t a,b;
37 } long_real;
38
39 typedef int32_t short_real;
40
41 typedef struct {
42         int32_t a,b;
43         short sign;
44 } temp_int;
45
46 struct swd {
47         int ie:1;
48         int de:1;
49         int ze:1;
50         int oe:1;
51         int ue:1;
52         int pe:1;
53         int sf:1;
54         int ir:1;
55         int c0:1;
56         int c1:1;
57         int c2:1;
58         int top:3;
59         int c3:1;
60         int b:1;
61 };
62 struct i387_struct {
63         int32_t cwd;
64         int32_t swd;
65         int32_t twd;
66         int32_t fip;
67         int32_t fcs;
68         int32_t foo;
69         int32_t fos;
70         int32_t st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
71 };
72
73 #define I387 (*(struct i387_struct *)(&curthread->td_savefpu->sv_87))
74 #define SWD (*(struct swd *) &I387.swd)
75 #define ROUNDING ((I387.cwd >> 10) & 3)
76 #define PRECISION ((I387.cwd >> 8) & 3)
77
78 #define BITS24  0
79 #define BITS53  2
80 #define BITS64  3
81
82 #define ROUND_NEAREST   0
83 #define ROUND_DOWN      1
84 #define ROUND_UP        2
85 #define ROUND_0         3
86
87 #define CONSTZ   (temp_real_unaligned) {0x0000,0x0000,0x0000,0x0000,0x0000}
88 #define CONST1   (temp_real_unaligned) {0x0000,0x0000,0x0000,0x8000,0x3FFF}
89 #define CONSTPI  (temp_real_unaligned) {0xC235,0x2168,0xDAA2,0xC90F,0x4000}
90 #define CONSTLN2 (temp_real_unaligned) {0x79AC,0xD1CF,0x17F7,0xB172,0x3FFE}
91 #define CONSTLG2 (temp_real_unaligned) {0xF799,0xFBCF,0x9A84,0x9A20,0x3FFD}
92 #define CONSTL2E (temp_real_unaligned) {0xF0BC,0x5C17,0x3B29,0xB8AA,0x3FFF}
93 #define CONSTL2T (temp_real_unaligned) {0x8AFE,0xCD1B,0x784B,0xD49A,0x4000}
94
95 #define set_IE() (I387.swd |= 1)
96 #define set_DE() (I387.swd |= 2)
97 #define set_ZE() (I387.swd |= 4)
98 #define set_OE() (I387.swd |= 8)
99 #define set_UE() (I387.swd |= 16)
100 #define set_PE() (I387.swd |= 32)
101
102 #define set_C0() (I387.swd |= 0x0100)
103 #define set_C1() (I387.swd |= 0x0200)
104 #define set_C2() (I387.swd |= 0x0400)
105 #define set_C3() (I387.swd |= 0x4000)
106
107 /* ea.c */
108
109 static char * ea(struct trapframe *, unsigned short);
110
111 /* convert.c */
112
113 static void frndint(const temp_real * __a, temp_real * __b);
114 static void Fscale(const temp_real *, const temp_real *, temp_real *);
115 static void short_to_temp(const short_real * __a, temp_real * __b);
116 static void long_to_temp(const long_real * __a, temp_real * __b);
117 static void temp_to_short(const temp_real * __a, short_real * __b);
118 static void temp_to_long(const temp_real * __a, long_real * __b);
119 static void real_to_int(const temp_real * __a, temp_int * __b);
120 static void int_to_real(const temp_int * __a, temp_real * __b);
121
122 /* get_put.c */
123
124 static void get_short_real(temp_real *, struct trapframe *, unsigned short);
125 static void get_long_real(temp_real *, struct trapframe *, unsigned short);
126 static void get_temp_real(temp_real *, struct trapframe *, unsigned short);
127 static void get_short_int(temp_real *, struct trapframe *, unsigned short);
128 static void get_long_int(temp_real *, struct trapframe *, unsigned short);
129 static void get_longlong_int(temp_real *, struct trapframe *, unsigned short);
130 static void get_BCD(temp_real *, struct trapframe *, unsigned short);
131 static void put_short_real(const temp_real *, struct trapframe *, unsigned short);
132 static void put_long_real(const temp_real *, struct trapframe *, unsigned short);
133 static void put_temp_real(const temp_real *, struct trapframe *, unsigned short);
134 static void put_short_int(const temp_real *, struct trapframe *, unsigned short);
135 static void put_long_int(const temp_real *, struct trapframe *, unsigned short);
136 static void put_longlong_int(const temp_real *, struct trapframe *, unsigned short);
137 static void put_BCD(const temp_real *, struct trapframe *, unsigned short);
138
139 /* add.c */
140
141 static void fadd(const temp_real *, const temp_real *, temp_real *);
142
143 /* mul.c */
144
145 static void fmul(const temp_real *, const temp_real *, temp_real *);
146
147 /* div.c */
148
149 static void fdiv(const temp_real *, const temp_real *, temp_real *);
150
151 /* compare.c */
152
153 static void fcom(const temp_real *, const temp_real *);
154 static void fucom(const temp_real *, const temp_real *);
155 static void ftst(const temp_real *);
156
157 #endif