This source file includes following definitions.
- load_store_instr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <asm/segment.h>
22
23 #include "fpu_system.h"
24 #include "exception.h"
25 #include "fpu_emu.h"
26 #include "status_w.h"
27 #include "control_w.h"
28
29
30 #define _NONE_ 0
31 #define _REG0_ 1
32 #define _PUSH_ 3
33 #define _null_ 4
34
35 #define pop_0() { st0_ptr->tag = TW_Empty; top++; }
36
37
38 static unsigned char const type_table[32] = {
39 _PUSH_, _PUSH_, _PUSH_, _PUSH_,
40 _null_, _null_, _null_, _null_,
41 _REG0_, _REG0_, _REG0_, _REG0_,
42 _REG0_, _REG0_, _REG0_, _REG0_,
43 _NONE_, _null_, _NONE_, _PUSH_,
44 _NONE_, _PUSH_, _null_, _PUSH_,
45 _NONE_, _null_, _NONE_, _REG0_,
46 _NONE_, _REG0_, _NONE_, _REG0_
47 };
48
49 unsigned char const data_sizes_16[32] = {
50 4, 4, 8, 2, 0, 0, 0, 0,
51 4, 4, 8, 2, 4, 4, 8, 2,
52 14, 0, 94, 10, 2, 10, 0, 8,
53 14, 0, 94, 10, 2, 10, 2, 8
54 };
55
56 unsigned char const data_sizes_32[32] = {
57 4, 4, 8, 2, 0, 0, 0, 0,
58 4, 4, 8, 2, 4, 4, 8, 2,
59 28, 0,108, 10, 2, 10, 0, 8,
60 28, 0,108, 10, 2, 10, 2, 8
61 };
62
63 int load_store_instr(unsigned char type, fpu_addr_modes addr_modes,
64 void *data_address)
65 {
66 FPU_REG loaded_data;
67 FPU_REG *st0_ptr;
68
69 st0_ptr = NULL;
70
71 if ( addr_modes.default_mode & PROTECTED )
72 {
73 if ( addr_modes.default_mode == SEG32 )
74 {
75 if ( access_limit < data_sizes_32[type] )
76 math_abort(FPU_info,SIGSEGV);
77 }
78 else if ( addr_modes.default_mode == PM16 )
79 {
80 if ( access_limit < data_sizes_16[type] )
81 math_abort(FPU_info,SIGSEGV);
82 }
83 #ifdef PARANOID
84 else
85 EXCEPTION(EX_INTERNAL|0x140);
86 #endif PARANOID
87 }
88
89 switch ( type_table[type] )
90 {
91 case _NONE_:
92 break;
93 case _REG0_:
94 st0_ptr = &st(0);
95
96 break;
97 case _PUSH_:
98 {
99 st0_ptr = &st(-1);
100 if ( st0_ptr->tag != TW_Empty )
101 { stack_overflow(); return 0; }
102 top--;
103 }
104 break;
105 case _null_:
106 FPU_illegal();
107 return 0;
108 #ifdef PARANOID
109 default:
110 EXCEPTION(EX_INTERNAL|0x141);
111 return 0;
112 #endif PARANOID
113 }
114
115 switch ( type )
116 {
117 case 000:
118 clear_C1();
119 reg_load_single((float *)data_address, &loaded_data);
120 if ( (loaded_data.tag == TW_NaN) &&
121 real_2op_NaN(&loaded_data, &loaded_data, &loaded_data) )
122 {
123 top++;
124 break;
125 }
126 reg_move(&loaded_data, st0_ptr);
127 break;
128 case 001:
129 clear_C1();
130 reg_load_int32((long *)data_address, st0_ptr);
131 break;
132 case 002:
133 clear_C1();
134 reg_load_double((double *)data_address, &loaded_data);
135 if ( (loaded_data.tag == TW_NaN) &&
136 real_2op_NaN(&loaded_data, &loaded_data, &loaded_data) )
137 {
138 top++;
139 break;
140 }
141 reg_move(&loaded_data, st0_ptr);
142 break;
143 case 003:
144 clear_C1();
145 reg_load_int16((short *)data_address, st0_ptr);
146 break;
147 case 010:
148 clear_C1();
149 reg_store_single((float *)data_address, st0_ptr);
150 break;
151 case 011:
152 clear_C1();
153 reg_store_int32((long *)data_address, st0_ptr);
154 break;
155 case 012:
156 clear_C1();
157 reg_store_double((double *)data_address, st0_ptr);
158 break;
159 case 013:
160 clear_C1();
161 reg_store_int16((short *)data_address, st0_ptr);
162 break;
163 case 014:
164 clear_C1();
165 if ( reg_store_single((float *)data_address, st0_ptr) )
166 pop_0();
167
168 break;
169 case 015:
170 clear_C1();
171 if ( reg_store_int32((long *)data_address, st0_ptr) )
172 pop_0();
173
174 break;
175 case 016:
176 clear_C1();
177 if ( reg_store_double((double *)data_address, st0_ptr) )
178 pop_0();
179
180 break;
181 case 017:
182 clear_C1();
183 if ( reg_store_int16((short *)data_address, st0_ptr) )
184 pop_0();
185
186 break;
187 case 020:
188 fldenv(addr_modes, (char *)data_address);
189
190
191 return 1;
192 case 022:
193 frstor(addr_modes, (char *)data_address);
194
195
196 return 1;
197 case 023:
198 clear_C1();
199 reg_load_bcd((char *)data_address, st0_ptr);
200 break;
201 case 024:
202 RE_ENTRANT_CHECK_OFF;
203 FPU_verify_area(VERIFY_READ, data_address, 2);
204 control_word = get_fs_word((unsigned short *) data_address);
205 RE_ENTRANT_CHECK_ON;
206 if ( partial_status & ~control_word & CW_Exceptions )
207 partial_status |= (SW_Summary | SW_Backward);
208 else
209 partial_status &= ~(SW_Summary | SW_Backward);
210 #ifdef PECULIAR_486
211 control_word |= 0x40;
212 #endif PECULIAR_486
213 return 1;
214 case 025:
215 clear_C1();
216 reg_load_extended((long double *)data_address, st0_ptr);
217 break;
218 case 027:
219 clear_C1();
220 reg_load_int64((long long *)data_address, st0_ptr);
221 break;
222 case 030:
223 fstenv(addr_modes, (char *)data_address);
224 return 1;
225 case 032:
226 fsave(addr_modes, (char *)data_address);
227 return 1;
228 case 033:
229 clear_C1();
230 if ( reg_store_bcd((char *)data_address, st0_ptr) )
231 pop_0();
232
233 break;
234 case 034:
235 RE_ENTRANT_CHECK_OFF;
236 FPU_verify_area(VERIFY_WRITE,data_address,2);
237 put_fs_word(control_word, (short *) data_address);
238 RE_ENTRANT_CHECK_ON;
239 return 1;
240 case 035:
241 clear_C1();
242 if ( reg_store_extended((long double *)data_address, st0_ptr) )
243 pop_0();
244
245 break;
246 case 036:
247 RE_ENTRANT_CHECK_OFF;
248 FPU_verify_area(VERIFY_WRITE,data_address,2);
249 put_fs_word(status_word(),(short *) data_address);
250 RE_ENTRANT_CHECK_ON;
251 return 1;
252 case 037:
253 clear_C1();
254 if ( reg_store_int64((long long *)data_address, st0_ptr) )
255 pop_0();
256
257 break;
258 }
259 return 0;
260 }