This source file includes following definitions.
- fnop
- fclex
- finit
- finit_
- fstsw_ax
- fstsw_
- fp_nop
- fld_i_
- fxch_i
- ffree_
- ffreep
- fst_i_
- fstp_i
1
2
3
4
5
6
7
8
9
10
11
12
13 #include "fpu_system.h"
14 #include "exception.h"
15 #include "fpu_emu.h"
16 #include "status_w.h"
17 #include "control_w.h"
18
19
20 static void fnop(void)
21 {
22 }
23
24 void fclex(void)
25 {
26 partial_status &= ~(SW_Backward|SW_Summary|SW_Stack_Fault|SW_Precision|
27 SW_Underflow|SW_Overflow|SW_Zero_Div|SW_Denorm_Op|
28 SW_Invalid);
29 NO_NET_DATA_EFFECT;
30 FPU_entry_eip = ip_offset;
31 }
32
33
34 void finit()
35 {
36 int r;
37 control_word = 0x037f;
38 partial_status = 0;
39 top = 0;
40 for (r = 0; r < 8; r++)
41 {
42 regs[r].tag = TW_Empty;
43 }
44
45
46 data_operand_offset = 0;
47 operand_selector = 0;
48 NO_NET_DATA_EFFECT;
49 FPU_entry_op_cs = 0;
50 FPU_entry_eip = ip_offset = 0;
51 }
52
53
54
55
56 #define feni fnop
57 #define fdisi fnop
58 #define fsetpm fnop
59
60 static FUNC const finit_table[] = {
61 feni, fdisi, fclex, finit,
62 fsetpm, FPU_illegal, FPU_illegal, FPU_illegal
63 };
64
65 void finit_()
66 {
67 (finit_table[FPU_rm])();
68 }
69
70
71 static void fstsw_ax(void)
72 {
73 *(short *) &FPU_EAX = status_word();
74 NO_NET_INSTR_EFFECT;
75 }
76
77 static FUNC const fstsw_table[] = {
78 fstsw_ax, FPU_illegal, FPU_illegal, FPU_illegal,
79 FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
80 };
81
82 void fstsw_()
83 {
84 (fstsw_table[FPU_rm])();
85 }
86
87
88 static FUNC const fp_nop_table[] = {
89 fnop, FPU_illegal, FPU_illegal, FPU_illegal,
90 FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
91 };
92
93 void fp_nop()
94 {
95 (fp_nop_table[FPU_rm])();
96 }
97
98
99 void fld_i_()
100 {
101 FPU_REG *st_new_ptr;
102
103 if ( STACK_OVERFLOW )
104 { stack_overflow(); return; }
105
106
107 if ( NOT_EMPTY(FPU_rm) )
108 { reg_move(&st(FPU_rm), st_new_ptr); push(); }
109 else
110 {
111 if ( control_word & EX_Invalid )
112 {
113
114 push();
115 stack_underflow();
116 }
117 else
118 EXCEPTION(EX_StackUnder);
119 }
120
121 }
122
123
124 void fxch_i()
125 {
126
127 FPU_REG t;
128 register FPU_REG *sti_ptr = &st(FPU_rm);
129
130 if ( FPU_st0_tag == TW_Empty )
131 {
132 if ( sti_ptr->tag == TW_Empty )
133 {
134 stack_underflow();
135 stack_underflow_i(FPU_rm);
136 return;
137 }
138 if ( control_word & CW_Invalid )
139 reg_move(sti_ptr, FPU_st0_ptr);
140 stack_underflow_i(FPU_rm);
141 return;
142 }
143 if ( sti_ptr->tag == TW_Empty )
144 {
145 if ( control_word & CW_Invalid )
146 reg_move(FPU_st0_ptr, sti_ptr);
147 stack_underflow();
148 return;
149 }
150 clear_C1();
151 reg_move(FPU_st0_ptr, &t);
152 reg_move(sti_ptr, FPU_st0_ptr);
153 reg_move(&t, sti_ptr);
154 }
155
156
157 void ffree_()
158 {
159
160 st(FPU_rm).tag = TW_Empty;
161 }
162
163
164 void ffreep()
165 {
166
167 st(FPU_rm).tag = TW_Empty;
168 pop();
169 }
170
171
172 void fst_i_()
173 {
174
175 reg_move(FPU_st0_ptr, &st(FPU_rm));
176 }
177
178
179 void fstp_i()
180 {
181
182 reg_move(FPU_st0_ptr, &st(FPU_rm));
183 pop();
184 }
185