kernel tree reorganization stage 1: Major cvs repository work (not logged as
[dragonfly.git] / sys / i386 / i386 / math_emu.h
... / ...
CommitLineData
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.4 2003/06/18 18:29:55 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
22typedef struct {
23 int32_t a,b;
24 short exponent;
25} temp_real;
26
27typedef 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
35typedef struct {
36 int32_t a,b;
37} long_real;
38
39typedef int32_t short_real;
40
41typedef struct {
42 int32_t a,b;
43 short sign;
44} temp_int;
45
46struct 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};
62struct 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_pcb)->pcb_save.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
109static char * ea(struct trapframe *, unsigned short);
110
111/* convert.c */
112
113static void frndint(const temp_real * __a, temp_real * __b);
114static void Fscale(const temp_real *, const temp_real *, temp_real *);
115static void short_to_temp(const short_real * __a, temp_real * __b);
116static void long_to_temp(const long_real * __a, temp_real * __b);
117static void temp_to_short(const temp_real * __a, short_real * __b);
118static void temp_to_long(const temp_real * __a, long_real * __b);
119static void real_to_int(const temp_real * __a, temp_int * __b);
120static void int_to_real(const temp_int * __a, temp_real * __b);
121
122/* get_put.c */
123
124static void get_short_real(temp_real *, struct trapframe *, unsigned short);
125static void get_long_real(temp_real *, struct trapframe *, unsigned short);
126static void get_temp_real(temp_real *, struct trapframe *, unsigned short);
127static void get_short_int(temp_real *, struct trapframe *, unsigned short);
128static void get_long_int(temp_real *, struct trapframe *, unsigned short);
129static void get_longlong_int(temp_real *, struct trapframe *, unsigned short);
130static void get_BCD(temp_real *, struct trapframe *, unsigned short);
131static void put_short_real(const temp_real *, struct trapframe *, unsigned short);
132static void put_long_real(const temp_real *, struct trapframe *, unsigned short);
133static void put_temp_real(const temp_real *, struct trapframe *, unsigned short);
134static void put_short_int(const temp_real *, struct trapframe *, unsigned short);
135static void put_long_int(const temp_real *, struct trapframe *, unsigned short);
136static void put_longlong_int(const temp_real *, struct trapframe *, unsigned short);
137static void put_BCD(const temp_real *, struct trapframe *, unsigned short);
138
139/* add.c */
140
141static void fadd(const temp_real *, const temp_real *, temp_real *);
142
143/* mul.c */
144
145static void fmul(const temp_real *, const temp_real *, temp_real *);
146
147/* div.c */
148
149static void fdiv(const temp_real *, const temp_real *, temp_real *);
150
151/* compare.c */
152
153static void fcom(const temp_real *, const temp_real *);
154static void fucom(const temp_real *, const temp_real *);
155static void ftst(const temp_real *);
156
157#endif