����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