绋嬪簭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 杩斿洖鏃跺皢鍘绘墽琛岀郴缁熻皟鐢ㄧ殑杩斿洖澶勭悊浠g爜銆�

 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鍑芥暟鐨勫畾涔夈€傚悗闈㈡槸鍏剁浉搴旂殑鍙傛暟銆�

    // 鍏抽敭璇�volatile 鏀惧湪鍑芥暟鍚嶅墠鏉ヤ慨楗板嚱鏁帮紝鏄敤鏉ラ€氱煡gcc 缂栬瘧鍣ㄨ鍑芥暟涓嶄細杩斿洖,

    // 浠ヨgcc 浜х敓鏇村ソ涓€浜涚殑浠g爜銆傝缁嗚鏄庤鍙傝绗�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

     * 涓▼搴忓嚭闂銆傚攭锛屾垜鐪熼渶瑕佹煇绉嶉潪瀵归綈鈥�no-align鈥濈紪璇戞寚浠ゃ€�

     */

 61

    // 涓存椂瀹炴暟瀵瑰簲鐨勭粨鏋勩€�

 62 typedef struct {

 63      long a,b;          // 鍏�64姣旂壒灏炬暟銆傚叾涓�a涓轰綆32浣嶏紝b涓洪珮32浣嶏紙鍖呮嫭1浣嶅浐瀹氫綅锛夈€�

 64      short exponent;    // 鎸囨暟鍊笺€�

 65 } temp_real;

 66

    // 涓轰簡瑙e喅涓婇潰鑻辨枃娉ㄩ噴涓墍鎻愬強鐨勫榻愰棶棰樿€岃璁$殑缁撴瀯锛屼綔鐢ㄥ悓涓婇潰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 - 鎸囦护浠g爜銆�

    // 杩斿洖锛氭湁鏁堝湴鍧€鍊笺€�

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