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