����14-24 linux/include/linux/math_emu.h
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 #include <linux/sched.h> // ���ȳ���ͷ�ļ�������������ṹtask_struct������0 �����ݣ�
// ����һЩ�й��������������úͻ�ȡ��Ƕ��ʽ��ຯ������䡣
10
// CPU�����쳣�ж�int 7ʱ��ջ�зֲ������ݹ��ɵĽṹ����ϵͳ����ʱ�ں�ջ�����ݷֲ����ơ�
11 struct info {
12 long ___math_ret; // math_emulate()�����ߣ�int7�����ص�ַ��
13 long ___orig_eip; // ��ʱ����ԭEIP �ĵط���
14 long ___edi; // �쳣�ж�int7 ����������ջ�ļĴ�����
15 long ___esi;
16 long ___ebp;
17 long ___sys_call_ret; // �ж�7 ����ʱ��ȥִ��ϵͳ���õķ��ش������롣
18 long ___eax; // ���²��֣�18--30 �У���ϵͳ����ʱջ�нṹ��ͬ��
19 long ___ebx;
20 long ___ecx;
21 long ___edx;
22 long ___orig_eax; // �粻��ϵͳ���ö��������ж�ʱ����ֵΪ-1��
23 long ___fs;
24 long ___es;
25 long ___ds;
26 long ___eip; // 26 -- 30 �� ��CPU �Զ���ջ��
27 long ___cs;
28 long ___eflags;
29 long ___esp;
30 long ___ss;
31 };
32
// Ϊ��������info�ṹ�и��ֶΣ�ջ�����ݣ��������һЩ������
33 #define EAX (info->___eax)
34 #define EBX (info->___ebx)
35 #define ECX (info->___ecx)
36 #define EDX (info->___edx)
37 #define ESI (info->___esi)
38 #define EDI (info->___edi)
39 #define EBP (info->___ebp)
40 #define ESP (info->___esp)
41 #define EIP (info->___eip)
42 #define ORIG_EIP (info->___orig_eip)
43 #define EFLAGS (info->___eflags)
44 #define DS (*(unsigned short *) &(info->___ds))
45 #define ES (*(unsigned short *) &(info->___es))
46 #define FS (*(unsigned short *) &(info->___fs))
47 #define CS (*(unsigned short *) &(info->___cs))
48 #define SS (*(unsigned short *) &(info->___ss))
49
// ��ֹ��ѧЭ�����������������math_emulation.c������ʵ��(L488�У���
// ����52-53���Ϻ궨���ʵ�������ǰ�__math_abort���¶���Ϊһ�����᷵�صĺ���
// ������ǰ�������volatile�����ú��ǰ���֣�
// (volatile void (*)(struct info *,unsigned int))
// �Ǻ������Ͷ��壬��������ָ�� __math_abort�����Ķ��塣����������Ӧ�IJ�����
// �ؼ���volatile ���ں�����ǰ�����κ�����������֪ͨgcc �������ú������᷵��,
// ����gcc ��������һЩ�Ĵ��롣��ϸ˵����μ���3�� $3.3.2�����ݡ�
// �������ĺ궨�壬����ҪĿ�ľ�������__math_abort����������������ͨ�з��غ�����
// �ֿ�����ʹ�ú궨��math_abort() ʱ���������صĺ�����
50 void __math_abort(struct info *, unsigned int);
51
52 #define math_abort(x,y) \
53 (((volatile void (*)(struct info *,unsigned int)) __math_abort)((x),(y)))
54
55 /*
56 * Gcc forces this stupid alignment problem: I want to use only two longs
57 * for the temporary real 64-bit mantissa, but then gcc aligns out the
58 * structure to 12 bytes which breaks things in math_emulate.c. Shit. I
59 * want some kind of "no-alignt" pragma or something.
60 */
/*
* Gcc��ǿ���������Ķ������⣺��ֻ��ʹ������long������������ʾ64���ص�
* ��ʱʵ��β��������gccȴ�Ὣ�ýṹ��12�ֽ������룬�⽫����math_emulate.c
* �г�������⡣����������Ҫij�ַǶ��롰no-align������ָ�
*/
61
// ��ʱʵ����Ӧ�Ľṹ��
62 typedef struct {
63 long a,b; // ��64����β��������aΪ��32λ��bΪ��32λ������1λ�̶�λ����
64 short exponent; // ָ��ֵ��
65 } temp_real;
66
// Ϊ�˽������Ӣ��ע�������ἰ�Ķ����������ƵĽṹ������ͬ����temp_real�ṹ��
67 typedef struct {
68 short m0,m1,m2,m3;
69 short exponent;
70 } temp_real_unaligned;
71
// ��temp_real����ֵa��ֵ��80387ջ�Ĵ���b (ST(i))��
72 #define real_to_real(a,b) \
73 ((*(long long *) (b) = *(long long *) (a)),((b)->exponent = (a)->exponent))
74
// ��ʵ����˫���ȣ��ṹ��
75 typedef struct {
76 long a,b; // a Ϊ��ʵ���ĵ�32λ��bΪ��32λ��
77 } long_real;
78
79 typedef long short_real; // �����ʵ�����͡�
80
// ��ʱ�����ṹ��
81 typedef struct {
82 long a,b; // a ��32�b��32�
83 short sign; // ���ű�־��
84 } temp_int;
85
// 80387Э�������ڲ���״̬�ּĴ������ݶ�Ӧ�Ľṹ�����μ�ͼ11-6��
86 struct swd {
87 int ie:1; // ��Ч�����쳣��
88 int de:1; // �ǹ���쳣��
89 int ze:1; // �����쳣��
90 int oe:1; // ������쳣��
91 int ue:1; // ������쳣��
92 int pe:1; // �����쳣��
93 int sf:1; // ջ������־����ʾ�ۼ��������ɵ��쳣��
94 int ir:1; // ir, b: ������6λ�κ�δ�����쳣����������λ��
95 int c0:1; // c0--c3: ����������
96 int c1:1;
97 int c2:1;
98 int top:3; // ָʾ80387�е�ǰλ��ջ����80λ�Ĵ�����
99 int c3:1;
100 int b:1;
101 };
102
// 80387�ڲ��Ĵ������Ʒ�ʽ������
103 #define I387 (current->tss.i387) // ���̵�80387״̬��Ϣ���μ�sched.h�ļ���
104 #define SWD (*(struct swd *) &I387.swd) // 80387��״̬�����֡�
105 #define ROUNDING ((I387.cwd >> 10) & 3) // ȡ��������������Ʒ�ʽ��
106 #define PRECISION ((I387.cwd >> 8) & 3) // ȡ�������о��ȿ��Ʒ�ʽ��
107
// ���徫����Чλ������
108 #define BITS24 0 // ������Ч����24λ�����μ�ͼ11-6��
109 #define BITS53 2 // ������Ч����53λ��
110 #define BITS64 3 // ������Ч����64λ��
111
// �������뷽ʽ������
112 #define ROUND_NEAREST 0 // ���뷽ʽ�����뵽�����ż����
113 #define ROUND_DOWN 1 // ���뷽ʽ���������ޡ�
114 #define ROUND_UP 2 // ���뷽ʽ�����������ޡ�
115 #define ROUND_0 3 // ���뷽ʽ�������0��
116
// �������塣
117 #define CONSTZ (temp_real_unaligned) {0x0000,0x0000,0x0000,0x0000,0x0000} // 0
118 #define CONST1 (temp_real_unaligned) {0x0000,0x0000,0x0000,0x8000,0x3FFF} // 1.0
119 #define CONSTPI (temp_real_unaligned) {0xC235,0x2168,0xDAA2,0xC90F,0x4000} // Pi
120 #define CONSTLN2 (temp_real_unaligned) {0x79AC,0xD1CF,0x17F7,0xB172,0x3FFE} // Loge(2)
121 #define CONSTLG2 (temp_real_unaligned) {0xF799,0xFBCF,0x9A84,0x9A20,0x3FFD} // Log10(2)
122 #define CONSTL2E (temp_real_unaligned) {0xF0BC,0x5C17,0x3B29,0xB8AA,0x3FFF} // Log2(e)
123 #define CONSTL2T (temp_real_unaligned) {0x8AFE,0xCD1B,0x784B,0xD49A,0x4000} // Log2(10)
124
// ����80387��״̬
125 #define set_IE() (I387.swd |= 1)
126 #define set_DE() (I387.swd |= 2)
127 #define set_ZE() (I387.swd |= 4)
128 #define set_OE() (I387.swd |= 8)
129 #define set_UE() (I387.swd |= 16)
130 #define set_PE() (I387.swd |= 32)
131
// ����80387����������
132 #define set_C0() (I387.swd |= 0x0100)
133 #define set_C1() (I387.swd |= 0x0200)
134 #define set_C2() (I387.swd |= 0x0400)
135 #define set_C3() (I387.swd |= 0x4000)
136
137 /* ea.c */
138
// �������ָ���в�����ʹ�õ�����Ч��ֵַ��������ָ����Ѱַģʽ�ֽڼ�����Ч��ֵַ��
// ������__info - �ж�ʱջ�����ݶ�Ӧ�ṹ��__code - ָ����롣
// ���أ���Ч��ֵַ��
139 char * ea(struct info * __info, unsigned short __code);
140
141 /* convert.c */
142
// ������������ת����������convert.c�ļ���ʵ�֡�
143 void short_to_temp(const short_real * __a, temp_real * __b);
144 void long_to_temp(const long_real * __a, temp_real * __b);
145 void temp_to_short(const temp_real * __a, short_real * __b);
146 void temp_to_long(const temp_real * __a, long_real * __b);
147 void real_to_int(const temp_real * __a, temp_int * __b);
148 void int_to_real(const temp_int * __a, temp_real * __b);
149
150 /* get_put.c */
151
// ��ȡ�����������ĺ�����
152 void get_short_real(temp_real *, struct info *, unsigned short);
153 void get_long_real(temp_real *, struct info *, unsigned short);
154 void get_temp_real(temp_real *, struct info *, unsigned short);
155 void get_short_int(temp_real *, struct info *, unsigned short);
156 void get_long_int(temp_real *, struct info *, unsigned short);
157 void get_longlong_int(temp_real *, struct info *, unsigned short);
158 void get_BCD(temp_real *, struct info *, unsigned short);
159 void put_short_real(const temp_real *, struct info *, unsigned short);
160 void put_long_real(const temp_real *, struct info *, unsigned short);
161 void put_temp_real(const temp_real *, struct info *, unsigned short);
162 void put_short_int(const temp_real *, struct info *, unsigned short);
163 void put_long_int(const temp_real *, struct info *, unsigned short);
164 void put_longlong_int(const temp_real *, struct info *, unsigned short);
165 void put_BCD(const temp_real *, struct info *, unsigned short);
166
167 /* add.c */
168
// ���渡��ӷ�ָ��ĺ�����
169 void fadd(const temp_real *, const temp_real *, temp_real *);
170
171 /* mul.c */
172
// ���渡��˷�ָ�
173 void fmul(const temp_real *, const temp_real *, temp_real *);
174
175 /* div.c */
176
// ���渡�����ָ�
177 void fdiv(const temp_real *, const temp_real *, temp_real *);
178
179 /* compare.c */
180
// �ȽϺ�����
181 void fcom(const temp_real *, const temp_real *); // ���渡��ָ��FCOM���Ƚ���������
182 void fucom(const temp_real *, const temp_real *); // ���渡��ָ��FUCOM������Ƚϡ�
183 void ftst(const temp_real *); // ���渡��ָ��FTST��ջ���ۼ�����0�Ƚϡ�
184
185 #endif
186