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