Commit 3ec9c4fcc649d6a32c3a9fba6add43a996248937
1 parent
2f87c607
separated helpers from micro operations
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@204 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
908 additions
and
841 deletions
exec-i386.h
@@ -190,14 +190,21 @@ register struct CPUX86State *env asm("r27"); | @@ -190,14 +190,21 @@ register struct CPUX86State *env asm("r27"); | ||
190 | #endif | 190 | #endif |
191 | 191 | ||
192 | #ifdef __alpha__ | 192 | #ifdef __alpha__ |
193 | +/* the symbols are considered non exported so a br immediate is generated */ | ||
194 | +#define __hidden __attribute__((visibility("hidden"))) | ||
195 | +#else | ||
196 | +#define __hidden | ||
197 | +#endif | ||
198 | + | ||
199 | +#ifdef __alpha__ | ||
193 | /* Suggested by Richard Henderson. This will result in code like | 200 | /* Suggested by Richard Henderson. This will result in code like |
194 | ldah $0,__op_param1($29) !gprelhigh | 201 | ldah $0,__op_param1($29) !gprelhigh |
195 | lda $0,__op_param1($0) !gprellow | 202 | lda $0,__op_param1($0) !gprellow |
196 | We can then conveniently change $29 to $31 and adapt the offsets to | 203 | We can then conveniently change $29 to $31 and adapt the offsets to |
197 | emit the appropriate constant. */ | 204 | emit the appropriate constant. */ |
198 | -extern int __op_param1 __attribute__((visibility("hidden"))); | ||
199 | -extern int __op_param2 __attribute__((visibility("hidden"))); | ||
200 | -extern int __op_param3 __attribute__((visibility("hidden"))); | 205 | +extern int __op_param1 __hidden; |
206 | +extern int __op_param2 __hidden; | ||
207 | +extern int __op_param3 __hidden; | ||
201 | #define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; }) | 208 | #define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; }) |
202 | #define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; }) | 209 | #define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; }) |
203 | #define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; }) | 210 | #define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; }) |
@@ -220,15 +227,173 @@ typedef struct CCTable { | @@ -220,15 +227,173 @@ typedef struct CCTable { | ||
220 | extern CCTable cc_table[]; | 227 | extern CCTable cc_table[]; |
221 | 228 | ||
222 | void load_seg(int seg_reg, int selector, unsigned cur_eip); | 229 | void load_seg(int seg_reg, int selector, unsigned cur_eip); |
223 | -void cpu_lock(void); | ||
224 | -void cpu_unlock(void); | 230 | +void __hidden cpu_lock(void); |
231 | +void __hidden cpu_unlock(void); | ||
225 | void raise_interrupt(int intno, int is_int, int error_code, | 232 | void raise_interrupt(int intno, int is_int, int error_code, |
226 | unsigned int next_eip); | 233 | unsigned int next_eip); |
227 | void raise_exception_err(int exception_index, int error_code); | 234 | void raise_exception_err(int exception_index, int error_code); |
228 | void raise_exception(int exception_index); | 235 | void raise_exception(int exception_index); |
229 | -void cpu_loop_exit(void); | 236 | +void __hidden cpu_loop_exit(void); |
230 | void helper_fsave(uint8_t *ptr, int data32); | 237 | void helper_fsave(uint8_t *ptr, int data32); |
231 | void helper_frstor(uint8_t *ptr, int data32); | 238 | void helper_frstor(uint8_t *ptr, int data32); |
232 | 239 | ||
233 | void OPPROTO op_movl_eflags_T0(void); | 240 | void OPPROTO op_movl_eflags_T0(void); |
234 | void OPPROTO op_movl_T0_eflags(void); | 241 | void OPPROTO op_movl_T0_eflags(void); |
242 | +void raise_interrupt(int intno, int is_int, int error_code, | ||
243 | + unsigned int next_eip); | ||
244 | +void raise_exception_err(int exception_index, int error_code); | ||
245 | +void raise_exception(int exception_index); | ||
246 | +void helper_cpuid(void); | ||
247 | +void helper_lsl(void); | ||
248 | +void helper_lar(void); | ||
249 | + | ||
250 | + | ||
251 | +#ifdef USE_X86LDOUBLE | ||
252 | +/* use long double functions */ | ||
253 | +#define lrint lrintl | ||
254 | +#define llrint llrintl | ||
255 | +#define fabs fabsl | ||
256 | +#define sin sinl | ||
257 | +#define cos cosl | ||
258 | +#define sqrt sqrtl | ||
259 | +#define pow powl | ||
260 | +#define log logl | ||
261 | +#define tan tanl | ||
262 | +#define atan2 atan2l | ||
263 | +#define floor floorl | ||
264 | +#define ceil ceill | ||
265 | +#define rint rintl | ||
266 | +#endif | ||
267 | + | ||
268 | +extern int lrint(CPU86_LDouble x); | ||
269 | +extern int64_t llrint(CPU86_LDouble x); | ||
270 | +extern CPU86_LDouble fabs(CPU86_LDouble x); | ||
271 | +extern CPU86_LDouble sin(CPU86_LDouble x); | ||
272 | +extern CPU86_LDouble cos(CPU86_LDouble x); | ||
273 | +extern CPU86_LDouble sqrt(CPU86_LDouble x); | ||
274 | +extern CPU86_LDouble pow(CPU86_LDouble, CPU86_LDouble); | ||
275 | +extern CPU86_LDouble log(CPU86_LDouble x); | ||
276 | +extern CPU86_LDouble tan(CPU86_LDouble x); | ||
277 | +extern CPU86_LDouble atan2(CPU86_LDouble, CPU86_LDouble); | ||
278 | +extern CPU86_LDouble floor(CPU86_LDouble x); | ||
279 | +extern CPU86_LDouble ceil(CPU86_LDouble x); | ||
280 | +extern CPU86_LDouble rint(CPU86_LDouble x); | ||
281 | + | ||
282 | +#define RC_MASK 0xc00 | ||
283 | +#define RC_NEAR 0x000 | ||
284 | +#define RC_DOWN 0x400 | ||
285 | +#define RC_UP 0x800 | ||
286 | +#define RC_CHOP 0xc00 | ||
287 | + | ||
288 | +#define MAXTAN 9223372036854775808.0 | ||
289 | + | ||
290 | +#ifdef USE_X86LDOUBLE | ||
291 | + | ||
292 | +/* only for x86 */ | ||
293 | +typedef union { | ||
294 | + long double d; | ||
295 | + struct { | ||
296 | + unsigned long long lower; | ||
297 | + unsigned short upper; | ||
298 | + } l; | ||
299 | +} CPU86_LDoubleU; | ||
300 | + | ||
301 | +/* the following deal with x86 long double-precision numbers */ | ||
302 | +#define MAXEXPD 0x7fff | ||
303 | +#define EXPBIAS 16383 | ||
304 | +#define EXPD(fp) (fp.l.upper & 0x7fff) | ||
305 | +#define SIGND(fp) ((fp.l.upper) & 0x8000) | ||
306 | +#define MANTD(fp) (fp.l.lower) | ||
307 | +#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS | ||
308 | + | ||
309 | +#else | ||
310 | + | ||
311 | +typedef union { | ||
312 | + double d; | ||
313 | +#ifndef WORDS_BIGENDIAN | ||
314 | + struct { | ||
315 | + uint32_t lower; | ||
316 | + int32_t upper; | ||
317 | + } l; | ||
318 | +#else | ||
319 | + struct { | ||
320 | + int32_t upper; | ||
321 | + uint32_t lower; | ||
322 | + } l; | ||
323 | +#endif | ||
324 | + int64_t ll; | ||
325 | +} CPU86_LDoubleU; | ||
326 | + | ||
327 | +/* the following deal with IEEE double-precision numbers */ | ||
328 | +#define MAXEXPD 0x7ff | ||
329 | +#define EXPBIAS 1023 | ||
330 | +#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) | ||
331 | +#define SIGND(fp) ((fp.l.upper) & 0x80000000) | ||
332 | +#define MANTD(fp) (fp.ll & ((1LL << 52) - 1)) | ||
333 | +#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20) | ||
334 | +#endif | ||
335 | + | ||
336 | +static inline void fpush(void) | ||
337 | +{ | ||
338 | + env->fpstt = (env->fpstt - 1) & 7; | ||
339 | + env->fptags[env->fpstt] = 0; /* validate stack entry */ | ||
340 | +} | ||
341 | + | ||
342 | +static inline void fpop(void) | ||
343 | +{ | ||
344 | + env->fptags[env->fpstt] = 1; /* invvalidate stack entry */ | ||
345 | + env->fpstt = (env->fpstt + 1) & 7; | ||
346 | +} | ||
347 | + | ||
348 | +#ifndef USE_X86LDOUBLE | ||
349 | +static inline CPU86_LDouble helper_fldt(uint8_t *ptr) | ||
350 | +{ | ||
351 | + CPU86_LDoubleU temp; | ||
352 | + int upper, e; | ||
353 | + /* mantissa */ | ||
354 | + upper = lduw(ptr + 8); | ||
355 | + /* XXX: handle overflow ? */ | ||
356 | + e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */ | ||
357 | + e |= (upper >> 4) & 0x800; /* sign */ | ||
358 | + temp.ll = ((ldq(ptr) >> 11) & ((1LL << 52) - 1)) | ((uint64_t)e << 52); | ||
359 | + return temp.d; | ||
360 | +} | ||
361 | + | ||
362 | +static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) | ||
363 | +{ | ||
364 | + CPU86_LDoubleU temp; | ||
365 | + int e; | ||
366 | + temp.d = f; | ||
367 | + /* mantissa */ | ||
368 | + stq(ptr, (MANTD(temp) << 11) | (1LL << 63)); | ||
369 | + /* exponent + sign */ | ||
370 | + e = EXPD(temp) - EXPBIAS + 16383; | ||
371 | + e |= SIGND(temp) >> 16; | ||
372 | + stw(ptr + 8, e); | ||
373 | +} | ||
374 | +#endif | ||
375 | + | ||
376 | +void helper_fldt_ST0_A0(void); | ||
377 | +void helper_fstt_ST0_A0(void); | ||
378 | +void helper_fbld_ST0_A0(void); | ||
379 | +void helper_fbst_ST0_A0(void); | ||
380 | +void helper_f2xm1(void); | ||
381 | +void helper_fyl2x(void); | ||
382 | +void helper_fptan(void); | ||
383 | +void helper_fpatan(void); | ||
384 | +void helper_fxtract(void); | ||
385 | +void helper_fprem1(void); | ||
386 | +void helper_fprem(void); | ||
387 | +void helper_fyl2xp1(void); | ||
388 | +void helper_fsqrt(void); | ||
389 | +void helper_fsincos(void); | ||
390 | +void helper_frndint(void); | ||
391 | +void helper_fscale(void); | ||
392 | +void helper_fsin(void); | ||
393 | +void helper_fcos(void); | ||
394 | +void helper_fxam_ST0(void); | ||
395 | +void helper_fstenv(uint8_t *ptr, int data32); | ||
396 | +void helper_fldenv(uint8_t *ptr, int data32); | ||
397 | +void helper_fsave(uint8_t *ptr, int data32); | ||
398 | +void helper_frstor(uint8_t *ptr, int data32); | ||
399 | + |
helper-i386.c
0 โ 100644
1 | +/* | ||
2 | + * i386 helpers | ||
3 | + * | ||
4 | + * Copyright (c) 2003 Fabrice Bellard | ||
5 | + * | ||
6 | + * This library is free software; you can redistribute it and/or | ||
7 | + * modify it under the terms of the GNU Lesser General Public | ||
8 | + * License as published by the Free Software Foundation; either | ||
9 | + * version 2 of the License, or (at your option) any later version. | ||
10 | + * | ||
11 | + * This library is distributed in the hope that it will be useful, | ||
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | + * Lesser General Public License for more details. | ||
15 | + * | ||
16 | + * You should have received a copy of the GNU Lesser General Public | ||
17 | + * License along with this library; if not, write to the Free Software | ||
18 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | + */ | ||
20 | +#include "exec-i386.h" | ||
21 | + | ||
22 | +#if 0 | ||
23 | +/* full interrupt support (only useful for real CPU emulation, not | ||
24 | + finished) - I won't do it any time soon, finish it if you want ! */ | ||
25 | +void raise_interrupt(int intno, int is_int, int error_code, | ||
26 | + unsigned int next_eip) | ||
27 | +{ | ||
28 | + SegmentDescriptorTable *dt; | ||
29 | + uint8_t *ptr; | ||
30 | + int type, dpl, cpl; | ||
31 | + uint32_t e1, e2; | ||
32 | + | ||
33 | + dt = &env->idt; | ||
34 | + if (intno * 8 + 7 > dt->limit) | ||
35 | + raise_exception_err(EXCP0D_GPF, intno * 8 + 2); | ||
36 | + ptr = dt->base + intno * 8; | ||
37 | + e1 = ldl(ptr); | ||
38 | + e2 = ldl(ptr + 4); | ||
39 | + /* check gate type */ | ||
40 | + type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; | ||
41 | + switch(type) { | ||
42 | + case 5: /* task gate */ | ||
43 | + case 6: /* 286 interrupt gate */ | ||
44 | + case 7: /* 286 trap gate */ | ||
45 | + case 14: /* 386 interrupt gate */ | ||
46 | + case 15: /* 386 trap gate */ | ||
47 | + break; | ||
48 | + default: | ||
49 | + raise_exception_err(EXCP0D_GPF, intno * 8 + 2); | ||
50 | + break; | ||
51 | + } | ||
52 | + dpl = (e2 >> DESC_DPL_SHIFT) & 3; | ||
53 | + cpl = env->segs[R_CS] & 3; | ||
54 | + /* check privledge if software int */ | ||
55 | + if (is_int && dpl < cpl) | ||
56 | + raise_exception_err(EXCP0D_GPF, intno * 8 + 2); | ||
57 | + /* check valid bit */ | ||
58 | + if (!(e2 & DESC_P_MASK)) | ||
59 | + raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2); | ||
60 | +} | ||
61 | + | ||
62 | +#else | ||
63 | + | ||
64 | +/* | ||
65 | + * is_int is TRUE if coming from the int instruction. next_eip is the | ||
66 | + * EIP value AFTER the interrupt instruction. It is only relevant if | ||
67 | + * is_int is TRUE. | ||
68 | + */ | ||
69 | +void raise_interrupt(int intno, int is_int, int error_code, | ||
70 | + unsigned int next_eip) | ||
71 | +{ | ||
72 | + SegmentDescriptorTable *dt; | ||
73 | + uint8_t *ptr; | ||
74 | + int dpl, cpl; | ||
75 | + uint32_t e2; | ||
76 | + | ||
77 | + dt = &env->idt; | ||
78 | + ptr = dt->base + (intno * 8); | ||
79 | + e2 = ldl(ptr + 4); | ||
80 | + | ||
81 | + dpl = (e2 >> DESC_DPL_SHIFT) & 3; | ||
82 | + cpl = 3; | ||
83 | + /* check privledge if software int */ | ||
84 | + if (is_int && dpl < cpl) | ||
85 | + raise_exception_err(EXCP0D_GPF, intno * 8 + 2); | ||
86 | + | ||
87 | + /* Since we emulate only user space, we cannot do more than | ||
88 | + exiting the emulation with the suitable exception and error | ||
89 | + code */ | ||
90 | + if (is_int) | ||
91 | + EIP = next_eip; | ||
92 | + env->exception_index = intno; | ||
93 | + env->error_code = error_code; | ||
94 | + | ||
95 | + cpu_loop_exit(); | ||
96 | +} | ||
97 | + | ||
98 | +#endif | ||
99 | + | ||
100 | +/* shortcuts to generate exceptions */ | ||
101 | +void raise_exception_err(int exception_index, int error_code) | ||
102 | +{ | ||
103 | + raise_interrupt(exception_index, 0, error_code, 0); | ||
104 | +} | ||
105 | + | ||
106 | +void raise_exception(int exception_index) | ||
107 | +{ | ||
108 | + raise_interrupt(exception_index, 0, 0, 0); | ||
109 | +} | ||
110 | + | ||
111 | +/* We simulate a pre-MMX pentium as in valgrind */ | ||
112 | +#define CPUID_FP87 (1 << 0) | ||
113 | +#define CPUID_VME (1 << 1) | ||
114 | +#define CPUID_DE (1 << 2) | ||
115 | +#define CPUID_PSE (1 << 3) | ||
116 | +#define CPUID_TSC (1 << 4) | ||
117 | +#define CPUID_MSR (1 << 5) | ||
118 | +#define CPUID_PAE (1 << 6) | ||
119 | +#define CPUID_MCE (1 << 7) | ||
120 | +#define CPUID_CX8 (1 << 8) | ||
121 | +#define CPUID_APIC (1 << 9) | ||
122 | +#define CPUID_SEP (1 << 11) /* sysenter/sysexit */ | ||
123 | +#define CPUID_MTRR (1 << 12) | ||
124 | +#define CPUID_PGE (1 << 13) | ||
125 | +#define CPUID_MCA (1 << 14) | ||
126 | +#define CPUID_CMOV (1 << 15) | ||
127 | +/* ... */ | ||
128 | +#define CPUID_MMX (1 << 23) | ||
129 | +#define CPUID_FXSR (1 << 24) | ||
130 | +#define CPUID_SSE (1 << 25) | ||
131 | +#define CPUID_SSE2 (1 << 26) | ||
132 | + | ||
133 | +void helper_cpuid(void) | ||
134 | +{ | ||
135 | + if (EAX == 0) { | ||
136 | + EAX = 1; /* max EAX index supported */ | ||
137 | + EBX = 0x756e6547; | ||
138 | + ECX = 0x6c65746e; | ||
139 | + EDX = 0x49656e69; | ||
140 | + } else if (EAX == 1) { | ||
141 | + /* EAX = 1 info */ | ||
142 | + EAX = 0x52b; | ||
143 | + EBX = 0; | ||
144 | + ECX = 0; | ||
145 | + EDX = CPUID_FP87 | CPUID_DE | CPUID_PSE | | ||
146 | + CPUID_TSC | CPUID_MSR | CPUID_MCE | | ||
147 | + CPUID_CX8; | ||
148 | + } | ||
149 | +} | ||
150 | + | ||
151 | +/* only works if protected mode and not VM86 */ | ||
152 | +void load_seg(int seg_reg, int selector, unsigned cur_eip) | ||
153 | +{ | ||
154 | + SegmentCache *sc; | ||
155 | + SegmentDescriptorTable *dt; | ||
156 | + int index; | ||
157 | + uint32_t e1, e2; | ||
158 | + uint8_t *ptr; | ||
159 | + | ||
160 | + sc = &env->seg_cache[seg_reg]; | ||
161 | + if ((selector & 0xfffc) == 0) { | ||
162 | + /* null selector case */ | ||
163 | + if (seg_reg == R_SS) { | ||
164 | + EIP = cur_eip; | ||
165 | + raise_exception_err(EXCP0D_GPF, selector & 0xfffc); | ||
166 | + } else { | ||
167 | + /* XXX: each access should trigger an exception */ | ||
168 | + sc->base = NULL; | ||
169 | + sc->limit = 0; | ||
170 | + sc->seg_32bit = 1; | ||
171 | + } | ||
172 | + } else { | ||
173 | + if (selector & 0x4) | ||
174 | + dt = &env->ldt; | ||
175 | + else | ||
176 | + dt = &env->gdt; | ||
177 | + index = selector & ~7; | ||
178 | + if ((index + 7) > dt->limit) { | ||
179 | + EIP = cur_eip; | ||
180 | + raise_exception_err(EXCP0D_GPF, selector & 0xfffc); | ||
181 | + } | ||
182 | + ptr = dt->base + index; | ||
183 | + e1 = ldl(ptr); | ||
184 | + e2 = ldl(ptr + 4); | ||
185 | + if (!(e2 & DESC_S_MASK) || | ||
186 | + (e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) { | ||
187 | + EIP = cur_eip; | ||
188 | + raise_exception_err(EXCP0D_GPF, selector & 0xfffc); | ||
189 | + } | ||
190 | + | ||
191 | + if (seg_reg == R_SS) { | ||
192 | + if ((e2 & (DESC_CS_MASK | DESC_W_MASK)) == 0) { | ||
193 | + EIP = cur_eip; | ||
194 | + raise_exception_err(EXCP0D_GPF, selector & 0xfffc); | ||
195 | + } | ||
196 | + } else { | ||
197 | + if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) { | ||
198 | + EIP = cur_eip; | ||
199 | + raise_exception_err(EXCP0D_GPF, selector & 0xfffc); | ||
200 | + } | ||
201 | + } | ||
202 | + | ||
203 | + if (!(e2 & DESC_P_MASK)) { | ||
204 | + EIP = cur_eip; | ||
205 | + if (seg_reg == R_SS) | ||
206 | + raise_exception_err(EXCP0C_STACK, selector & 0xfffc); | ||
207 | + else | ||
208 | + raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc); | ||
209 | + } | ||
210 | + | ||
211 | + sc->base = (void *)((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000)); | ||
212 | + sc->limit = (e1 & 0xffff) | (e2 & 0x000f0000); | ||
213 | + if (e2 & (1 << 23)) | ||
214 | + sc->limit = (sc->limit << 12) | 0xfff; | ||
215 | + sc->seg_32bit = (e2 >> 22) & 1; | ||
216 | +#if 0 | ||
217 | + fprintf(logfile, "load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx seg_32bit=%d\n", | ||
218 | + selector, (unsigned long)sc->base, sc->limit, sc->seg_32bit); | ||
219 | +#endif | ||
220 | + } | ||
221 | + env->segs[seg_reg] = selector; | ||
222 | +} | ||
223 | + | ||
224 | +void helper_lsl(void) | ||
225 | +{ | ||
226 | + unsigned int selector, limit; | ||
227 | + SegmentDescriptorTable *dt; | ||
228 | + int index; | ||
229 | + uint32_t e1, e2; | ||
230 | + uint8_t *ptr; | ||
231 | + | ||
232 | + CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; | ||
233 | + selector = T0 & 0xffff; | ||
234 | + if (selector & 0x4) | ||
235 | + dt = &env->ldt; | ||
236 | + else | ||
237 | + dt = &env->gdt; | ||
238 | + index = selector & ~7; | ||
239 | + if ((index + 7) > dt->limit) | ||
240 | + return; | ||
241 | + ptr = dt->base + index; | ||
242 | + e1 = ldl(ptr); | ||
243 | + e2 = ldl(ptr + 4); | ||
244 | + limit = (e1 & 0xffff) | (e2 & 0x000f0000); | ||
245 | + if (e2 & (1 << 23)) | ||
246 | + limit = (limit << 12) | 0xfff; | ||
247 | + T1 = limit; | ||
248 | + CC_SRC |= CC_Z; | ||
249 | +} | ||
250 | + | ||
251 | +void helper_lar(void) | ||
252 | +{ | ||
253 | + unsigned int selector; | ||
254 | + SegmentDescriptorTable *dt; | ||
255 | + int index; | ||
256 | + uint32_t e2; | ||
257 | + uint8_t *ptr; | ||
258 | + | ||
259 | + CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; | ||
260 | + selector = T0 & 0xffff; | ||
261 | + if (selector & 0x4) | ||
262 | + dt = &env->ldt; | ||
263 | + else | ||
264 | + dt = &env->gdt; | ||
265 | + index = selector & ~7; | ||
266 | + if ((index + 7) > dt->limit) | ||
267 | + return; | ||
268 | + ptr = dt->base + index; | ||
269 | + e2 = ldl(ptr + 4); | ||
270 | + T1 = e2 & 0x00f0ff00; | ||
271 | + CC_SRC |= CC_Z; | ||
272 | +} | ||
273 | + | ||
274 | +/* FPU helpers */ | ||
275 | + | ||
276 | +#ifndef USE_X86LDOUBLE | ||
277 | +void helper_fldt_ST0_A0(void) | ||
278 | +{ | ||
279 | + ST0 = helper_fldt((uint8_t *)A0); | ||
280 | +} | ||
281 | + | ||
282 | +void helper_fstt_ST0_A0(void) | ||
283 | +{ | ||
284 | + helper_fstt(ST0, (uint8_t *)A0); | ||
285 | +} | ||
286 | +#endif | ||
287 | + | ||
288 | +/* BCD ops */ | ||
289 | + | ||
290 | +#define MUL10(iv) ( iv + iv + (iv << 3) ) | ||
291 | + | ||
292 | +void helper_fbld_ST0_A0(void) | ||
293 | +{ | ||
294 | + uint8_t *seg; | ||
295 | + CPU86_LDouble fpsrcop; | ||
296 | + int m32i; | ||
297 | + unsigned int v; | ||
298 | + | ||
299 | + /* in this code, seg/m32i will be used as temporary ptr/int */ | ||
300 | + seg = (uint8_t *)A0 + 8; | ||
301 | + v = ldub(seg--); | ||
302 | + /* XXX: raise exception */ | ||
303 | + if (v != 0) | ||
304 | + return; | ||
305 | + v = ldub(seg--); | ||
306 | + /* XXX: raise exception */ | ||
307 | + if ((v & 0xf0) != 0) | ||
308 | + return; | ||
309 | + m32i = v; /* <-- d14 */ | ||
310 | + v = ldub(seg--); | ||
311 | + m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d13 */ | ||
312 | + m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d12 */ | ||
313 | + v = ldub(seg--); | ||
314 | + m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d11 */ | ||
315 | + m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d10 */ | ||
316 | + v = ldub(seg--); | ||
317 | + m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d9 */ | ||
318 | + m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d8 */ | ||
319 | + fpsrcop = ((CPU86_LDouble)m32i) * 100000000.0; | ||
320 | + | ||
321 | + v = ldub(seg--); | ||
322 | + m32i = (v >> 4); /* <-- d7 */ | ||
323 | + m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d6 */ | ||
324 | + v = ldub(seg--); | ||
325 | + m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d5 */ | ||
326 | + m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d4 */ | ||
327 | + v = ldub(seg--); | ||
328 | + m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d3 */ | ||
329 | + m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d2 */ | ||
330 | + v = ldub(seg); | ||
331 | + m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d1 */ | ||
332 | + m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d0 */ | ||
333 | + fpsrcop += ((CPU86_LDouble)m32i); | ||
334 | + if ( ldub(seg+9) & 0x80 ) | ||
335 | + fpsrcop = -fpsrcop; | ||
336 | + ST0 = fpsrcop; | ||
337 | +} | ||
338 | + | ||
339 | +void helper_fbst_ST0_A0(void) | ||
340 | +{ | ||
341 | + CPU86_LDouble fptemp; | ||
342 | + CPU86_LDouble fpsrcop; | ||
343 | + int v; | ||
344 | + uint8_t *mem_ref, *mem_end; | ||
345 | + | ||
346 | + fpsrcop = rint(ST0); | ||
347 | + mem_ref = (uint8_t *)A0; | ||
348 | + mem_end = mem_ref + 8; | ||
349 | + if ( fpsrcop < 0.0 ) { | ||
350 | + stw(mem_end, 0x8000); | ||
351 | + fpsrcop = -fpsrcop; | ||
352 | + } else { | ||
353 | + stw(mem_end, 0x0000); | ||
354 | + } | ||
355 | + while (mem_ref < mem_end) { | ||
356 | + if (fpsrcop == 0.0) | ||
357 | + break; | ||
358 | + fptemp = floor(fpsrcop/10.0); | ||
359 | + v = ((int)(fpsrcop - fptemp*10.0)); | ||
360 | + if (fptemp == 0.0) { | ||
361 | + stb(mem_ref++, v); | ||
362 | + break; | ||
363 | + } | ||
364 | + fpsrcop = fptemp; | ||
365 | + fptemp = floor(fpsrcop/10.0); | ||
366 | + v |= (((int)(fpsrcop - fptemp*10.0)) << 4); | ||
367 | + stb(mem_ref++, v); | ||
368 | + fpsrcop = fptemp; | ||
369 | + } | ||
370 | + while (mem_ref < mem_end) { | ||
371 | + stb(mem_ref++, 0); | ||
372 | + } | ||
373 | +} | ||
374 | + | ||
375 | +void helper_f2xm1(void) | ||
376 | +{ | ||
377 | + ST0 = pow(2.0,ST0) - 1.0; | ||
378 | +} | ||
379 | + | ||
380 | +void helper_fyl2x(void) | ||
381 | +{ | ||
382 | + CPU86_LDouble fptemp; | ||
383 | + | ||
384 | + fptemp = ST0; | ||
385 | + if (fptemp>0.0){ | ||
386 | + fptemp = log(fptemp)/log(2.0); /* log2(ST) */ | ||
387 | + ST1 *= fptemp; | ||
388 | + fpop(); | ||
389 | + } else { | ||
390 | + env->fpus &= (~0x4700); | ||
391 | + env->fpus |= 0x400; | ||
392 | + } | ||
393 | +} | ||
394 | + | ||
395 | +void helper_fptan(void) | ||
396 | +{ | ||
397 | + CPU86_LDouble fptemp; | ||
398 | + | ||
399 | + fptemp = ST0; | ||
400 | + if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { | ||
401 | + env->fpus |= 0x400; | ||
402 | + } else { | ||
403 | + ST0 = tan(fptemp); | ||
404 | + fpush(); | ||
405 | + ST0 = 1.0; | ||
406 | + env->fpus &= (~0x400); /* C2 <-- 0 */ | ||
407 | + /* the above code is for |arg| < 2**52 only */ | ||
408 | + } | ||
409 | +} | ||
410 | + | ||
411 | +void helper_fpatan(void) | ||
412 | +{ | ||
413 | + CPU86_LDouble fptemp, fpsrcop; | ||
414 | + | ||
415 | + fpsrcop = ST1; | ||
416 | + fptemp = ST0; | ||
417 | + ST1 = atan2(fpsrcop,fptemp); | ||
418 | + fpop(); | ||
419 | +} | ||
420 | + | ||
421 | +void helper_fxtract(void) | ||
422 | +{ | ||
423 | + CPU86_LDoubleU temp; | ||
424 | + unsigned int expdif; | ||
425 | + | ||
426 | + temp.d = ST0; | ||
427 | + expdif = EXPD(temp) - EXPBIAS; | ||
428 | + /*DP exponent bias*/ | ||
429 | + ST0 = expdif; | ||
430 | + fpush(); | ||
431 | + BIASEXPONENT(temp); | ||
432 | + ST0 = temp.d; | ||
433 | +} | ||
434 | + | ||
435 | +void helper_fprem1(void) | ||
436 | +{ | ||
437 | + CPU86_LDouble dblq, fpsrcop, fptemp; | ||
438 | + CPU86_LDoubleU fpsrcop1, fptemp1; | ||
439 | + int expdif; | ||
440 | + int q; | ||
441 | + | ||
442 | + fpsrcop = ST0; | ||
443 | + fptemp = ST1; | ||
444 | + fpsrcop1.d = fpsrcop; | ||
445 | + fptemp1.d = fptemp; | ||
446 | + expdif = EXPD(fpsrcop1) - EXPD(fptemp1); | ||
447 | + if (expdif < 53) { | ||
448 | + dblq = fpsrcop / fptemp; | ||
449 | + dblq = (dblq < 0.0)? ceil(dblq): floor(dblq); | ||
450 | + ST0 = fpsrcop - fptemp*dblq; | ||
451 | + q = (int)dblq; /* cutting off top bits is assumed here */ | ||
452 | + env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ | ||
453 | + /* (C0,C1,C3) <-- (q2,q1,q0) */ | ||
454 | + env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */ | ||
455 | + env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */ | ||
456 | + env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */ | ||
457 | + } else { | ||
458 | + env->fpus |= 0x400; /* C2 <-- 1 */ | ||
459 | + fptemp = pow(2.0, expdif-50); | ||
460 | + fpsrcop = (ST0 / ST1) / fptemp; | ||
461 | + /* fpsrcop = integer obtained by rounding to the nearest */ | ||
462 | + fpsrcop = (fpsrcop-floor(fpsrcop) < ceil(fpsrcop)-fpsrcop)? | ||
463 | + floor(fpsrcop): ceil(fpsrcop); | ||
464 | + ST0 -= (ST1 * fpsrcop * fptemp); | ||
465 | + } | ||
466 | +} | ||
467 | + | ||
468 | +void helper_fprem(void) | ||
469 | +{ | ||
470 | + CPU86_LDouble dblq, fpsrcop, fptemp; | ||
471 | + CPU86_LDoubleU fpsrcop1, fptemp1; | ||
472 | + int expdif; | ||
473 | + int q; | ||
474 | + | ||
475 | + fpsrcop = ST0; | ||
476 | + fptemp = ST1; | ||
477 | + fpsrcop1.d = fpsrcop; | ||
478 | + fptemp1.d = fptemp; | ||
479 | + expdif = EXPD(fpsrcop1) - EXPD(fptemp1); | ||
480 | + if ( expdif < 53 ) { | ||
481 | + dblq = fpsrcop / fptemp; | ||
482 | + dblq = (dblq < 0.0)? ceil(dblq): floor(dblq); | ||
483 | + ST0 = fpsrcop - fptemp*dblq; | ||
484 | + q = (int)dblq; /* cutting off top bits is assumed here */ | ||
485 | + env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ | ||
486 | + /* (C0,C1,C3) <-- (q2,q1,q0) */ | ||
487 | + env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */ | ||
488 | + env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */ | ||
489 | + env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */ | ||
490 | + } else { | ||
491 | + env->fpus |= 0x400; /* C2 <-- 1 */ | ||
492 | + fptemp = pow(2.0, expdif-50); | ||
493 | + fpsrcop = (ST0 / ST1) / fptemp; | ||
494 | + /* fpsrcop = integer obtained by chopping */ | ||
495 | + fpsrcop = (fpsrcop < 0.0)? | ||
496 | + -(floor(fabs(fpsrcop))): floor(fpsrcop); | ||
497 | + ST0 -= (ST1 * fpsrcop * fptemp); | ||
498 | + } | ||
499 | +} | ||
500 | + | ||
501 | +void helper_fyl2xp1(void) | ||
502 | +{ | ||
503 | + CPU86_LDouble fptemp; | ||
504 | + | ||
505 | + fptemp = ST0; | ||
506 | + if ((fptemp+1.0)>0.0) { | ||
507 | + fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */ | ||
508 | + ST1 *= fptemp; | ||
509 | + fpop(); | ||
510 | + } else { | ||
511 | + env->fpus &= (~0x4700); | ||
512 | + env->fpus |= 0x400; | ||
513 | + } | ||
514 | +} | ||
515 | + | ||
516 | +void helper_fsqrt(void) | ||
517 | +{ | ||
518 | + CPU86_LDouble fptemp; | ||
519 | + | ||
520 | + fptemp = ST0; | ||
521 | + if (fptemp<0.0) { | ||
522 | + env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ | ||
523 | + env->fpus |= 0x400; | ||
524 | + } | ||
525 | + ST0 = sqrt(fptemp); | ||
526 | +} | ||
527 | + | ||
528 | +void helper_fsincos(void) | ||
529 | +{ | ||
530 | + CPU86_LDouble fptemp; | ||
531 | + | ||
532 | + fptemp = ST0; | ||
533 | + if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { | ||
534 | + env->fpus |= 0x400; | ||
535 | + } else { | ||
536 | + ST0 = sin(fptemp); | ||
537 | + fpush(); | ||
538 | + ST0 = cos(fptemp); | ||
539 | + env->fpus &= (~0x400); /* C2 <-- 0 */ | ||
540 | + /* the above code is for |arg| < 2**63 only */ | ||
541 | + } | ||
542 | +} | ||
543 | + | ||
544 | +void helper_frndint(void) | ||
545 | +{ | ||
546 | + ST0 = rint(ST0); | ||
547 | +} | ||
548 | + | ||
549 | +void helper_fscale(void) | ||
550 | +{ | ||
551 | + CPU86_LDouble fpsrcop, fptemp; | ||
552 | + | ||
553 | + fpsrcop = 2.0; | ||
554 | + fptemp = pow(fpsrcop,ST1); | ||
555 | + ST0 *= fptemp; | ||
556 | +} | ||
557 | + | ||
558 | +void helper_fsin(void) | ||
559 | +{ | ||
560 | + CPU86_LDouble fptemp; | ||
561 | + | ||
562 | + fptemp = ST0; | ||
563 | + if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { | ||
564 | + env->fpus |= 0x400; | ||
565 | + } else { | ||
566 | + ST0 = sin(fptemp); | ||
567 | + env->fpus &= (~0x400); /* C2 <-- 0 */ | ||
568 | + /* the above code is for |arg| < 2**53 only */ | ||
569 | + } | ||
570 | +} | ||
571 | + | ||
572 | +void helper_fcos(void) | ||
573 | +{ | ||
574 | + CPU86_LDouble fptemp; | ||
575 | + | ||
576 | + fptemp = ST0; | ||
577 | + if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { | ||
578 | + env->fpus |= 0x400; | ||
579 | + } else { | ||
580 | + ST0 = cos(fptemp); | ||
581 | + env->fpus &= (~0x400); /* C2 <-- 0 */ | ||
582 | + /* the above code is for |arg5 < 2**63 only */ | ||
583 | + } | ||
584 | +} | ||
585 | + | ||
586 | +void helper_fxam_ST0(void) | ||
587 | +{ | ||
588 | + CPU86_LDoubleU temp; | ||
589 | + int expdif; | ||
590 | + | ||
591 | + temp.d = ST0; | ||
592 | + | ||
593 | + env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ | ||
594 | + if (SIGND(temp)) | ||
595 | + env->fpus |= 0x200; /* C1 <-- 1 */ | ||
596 | + | ||
597 | + expdif = EXPD(temp); | ||
598 | + if (expdif == MAXEXPD) { | ||
599 | + if (MANTD(temp) == 0) | ||
600 | + env->fpus |= 0x500 /*Infinity*/; | ||
601 | + else | ||
602 | + env->fpus |= 0x100 /*NaN*/; | ||
603 | + } else if (expdif == 0) { | ||
604 | + if (MANTD(temp) == 0) | ||
605 | + env->fpus |= 0x4000 /*Zero*/; | ||
606 | + else | ||
607 | + env->fpus |= 0x4400 /*Denormal*/; | ||
608 | + } else { | ||
609 | + env->fpus |= 0x400; | ||
610 | + } | ||
611 | +} | ||
612 | + | ||
613 | +void helper_fstenv(uint8_t *ptr, int data32) | ||
614 | +{ | ||
615 | + int fpus, fptag, exp, i; | ||
616 | + uint64_t mant; | ||
617 | + CPU86_LDoubleU tmp; | ||
618 | + | ||
619 | + fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; | ||
620 | + fptag = 0; | ||
621 | + for (i=7; i>=0; i--) { | ||
622 | + fptag <<= 2; | ||
623 | + if (env->fptags[i]) { | ||
624 | + fptag |= 3; | ||
625 | + } else { | ||
626 | + tmp.d = env->fpregs[i]; | ||
627 | + exp = EXPD(tmp); | ||
628 | + mant = MANTD(tmp); | ||
629 | + if (exp == 0 && mant == 0) { | ||
630 | + /* zero */ | ||
631 | + fptag |= 1; | ||
632 | + } else if (exp == 0 || exp == MAXEXPD | ||
633 | +#ifdef USE_X86LDOUBLE | ||
634 | + || (mant & (1LL << 63)) == 0 | ||
635 | +#endif | ||
636 | + ) { | ||
637 | + /* NaNs, infinity, denormal */ | ||
638 | + fptag |= 2; | ||
639 | + } | ||
640 | + } | ||
641 | + } | ||
642 | + if (data32) { | ||
643 | + /* 32 bit */ | ||
644 | + stl(ptr, env->fpuc); | ||
645 | + stl(ptr + 4, fpus); | ||
646 | + stl(ptr + 8, fptag); | ||
647 | + stl(ptr + 12, 0); | ||
648 | + stl(ptr + 16, 0); | ||
649 | + stl(ptr + 20, 0); | ||
650 | + stl(ptr + 24, 0); | ||
651 | + } else { | ||
652 | + /* 16 bit */ | ||
653 | + stw(ptr, env->fpuc); | ||
654 | + stw(ptr + 2, fpus); | ||
655 | + stw(ptr + 4, fptag); | ||
656 | + stw(ptr + 6, 0); | ||
657 | + stw(ptr + 8, 0); | ||
658 | + stw(ptr + 10, 0); | ||
659 | + stw(ptr + 12, 0); | ||
660 | + } | ||
661 | +} | ||
662 | + | ||
663 | +void helper_fldenv(uint8_t *ptr, int data32) | ||
664 | +{ | ||
665 | + int i, fpus, fptag; | ||
666 | + | ||
667 | + if (data32) { | ||
668 | + env->fpuc = lduw(ptr); | ||
669 | + fpus = lduw(ptr + 4); | ||
670 | + fptag = lduw(ptr + 8); | ||
671 | + } | ||
672 | + else { | ||
673 | + env->fpuc = lduw(ptr); | ||
674 | + fpus = lduw(ptr + 2); | ||
675 | + fptag = lduw(ptr + 4); | ||
676 | + } | ||
677 | + env->fpstt = (fpus >> 11) & 7; | ||
678 | + env->fpus = fpus & ~0x3800; | ||
679 | + for(i = 0;i < 7; i++) { | ||
680 | + env->fptags[i] = ((fptag & 3) == 3); | ||
681 | + fptag >>= 2; | ||
682 | + } | ||
683 | +} | ||
684 | + | ||
685 | +void helper_fsave(uint8_t *ptr, int data32) | ||
686 | +{ | ||
687 | + CPU86_LDouble tmp; | ||
688 | + int i; | ||
689 | + | ||
690 | + helper_fstenv(ptr, data32); | ||
691 | + | ||
692 | + ptr += (14 << data32); | ||
693 | + for(i = 0;i < 8; i++) { | ||
694 | + tmp = ST(i); | ||
695 | +#ifdef USE_X86LDOUBLE | ||
696 | + *(long double *)ptr = tmp; | ||
697 | +#else | ||
698 | + helper_fstt(tmp, ptr); | ||
699 | +#endif | ||
700 | + ptr += 10; | ||
701 | + } | ||
702 | + | ||
703 | + /* fninit */ | ||
704 | + env->fpus = 0; | ||
705 | + env->fpstt = 0; | ||
706 | + env->fpuc = 0x37f; | ||
707 | + env->fptags[0] = 1; | ||
708 | + env->fptags[1] = 1; | ||
709 | + env->fptags[2] = 1; | ||
710 | + env->fptags[3] = 1; | ||
711 | + env->fptags[4] = 1; | ||
712 | + env->fptags[5] = 1; | ||
713 | + env->fptags[6] = 1; | ||
714 | + env->fptags[7] = 1; | ||
715 | +} | ||
716 | + | ||
717 | +void helper_frstor(uint8_t *ptr, int data32) | ||
718 | +{ | ||
719 | + CPU86_LDouble tmp; | ||
720 | + int i; | ||
721 | + | ||
722 | + helper_fldenv(ptr, data32); | ||
723 | + ptr += (14 << data32); | ||
724 | + | ||
725 | + for(i = 0;i < 8; i++) { | ||
726 | +#ifdef USE_X86LDOUBLE | ||
727 | + tmp = *(long double *)ptr; | ||
728 | +#else | ||
729 | + tmp = helper_fldt(ptr); | ||
730 | +#endif | ||
731 | + ST(i) = tmp; | ||
732 | + ptr += 10; | ||
733 | + } | ||
734 | +} | ||
735 | + |
op-i386.c
@@ -626,95 +626,6 @@ void OPPROTO op_jmp_im(void) | @@ -626,95 +626,6 @@ void OPPROTO op_jmp_im(void) | ||
626 | EIP = PARAM1; | 626 | EIP = PARAM1; |
627 | } | 627 | } |
628 | 628 | ||
629 | -#if 0 | ||
630 | -/* full interrupt support (only useful for real CPU emulation, not | ||
631 | - finished) - I won't do it any time soon, finish it if you want ! */ | ||
632 | -void raise_interrupt(int intno, int is_int, int error_code, | ||
633 | - unsigned int next_eip) | ||
634 | -{ | ||
635 | - SegmentDescriptorTable *dt; | ||
636 | - uint8_t *ptr; | ||
637 | - int type, dpl, cpl; | ||
638 | - uint32_t e1, e2; | ||
639 | - | ||
640 | - dt = &env->idt; | ||
641 | - if (intno * 8 + 7 > dt->limit) | ||
642 | - raise_exception_err(EXCP0D_GPF, intno * 8 + 2); | ||
643 | - ptr = dt->base + intno * 8; | ||
644 | - e1 = ldl(ptr); | ||
645 | - e2 = ldl(ptr + 4); | ||
646 | - /* check gate type */ | ||
647 | - type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; | ||
648 | - switch(type) { | ||
649 | - case 5: /* task gate */ | ||
650 | - case 6: /* 286 interrupt gate */ | ||
651 | - case 7: /* 286 trap gate */ | ||
652 | - case 14: /* 386 interrupt gate */ | ||
653 | - case 15: /* 386 trap gate */ | ||
654 | - break; | ||
655 | - default: | ||
656 | - raise_exception_err(EXCP0D_GPF, intno * 8 + 2); | ||
657 | - break; | ||
658 | - } | ||
659 | - dpl = (e2 >> DESC_DPL_SHIFT) & 3; | ||
660 | - cpl = env->segs[R_CS] & 3; | ||
661 | - /* check privledge if software int */ | ||
662 | - if (is_int && dpl < cpl) | ||
663 | - raise_exception_err(EXCP0D_GPF, intno * 8 + 2); | ||
664 | - /* check valid bit */ | ||
665 | - if (!(e2 & DESC_P_MASK)) | ||
666 | - raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2); | ||
667 | -} | ||
668 | - | ||
669 | -#else | ||
670 | - | ||
671 | -/* | ||
672 | - * is_int is TRUE if coming from the int instruction. next_eip is the | ||
673 | - * EIP value AFTER the interrupt instruction. It is only relevant if | ||
674 | - * is_int is TRUE. | ||
675 | - */ | ||
676 | -void raise_interrupt(int intno, int is_int, int error_code, | ||
677 | - unsigned int next_eip) | ||
678 | -{ | ||
679 | - SegmentDescriptorTable *dt; | ||
680 | - uint8_t *ptr; | ||
681 | - int dpl, cpl; | ||
682 | - uint32_t e2; | ||
683 | - | ||
684 | - dt = &env->idt; | ||
685 | - ptr = dt->base + (intno * 8); | ||
686 | - e2 = ldl(ptr + 4); | ||
687 | - | ||
688 | - dpl = (e2 >> DESC_DPL_SHIFT) & 3; | ||
689 | - cpl = 3; | ||
690 | - /* check privledge if software int */ | ||
691 | - if (is_int && dpl < cpl) | ||
692 | - raise_exception_err(EXCP0D_GPF, intno * 8 + 2); | ||
693 | - | ||
694 | - /* Since we emulate only user space, we cannot do more than | ||
695 | - exiting the emulation with the suitable exception and error | ||
696 | - code */ | ||
697 | - if (is_int) | ||
698 | - EIP = next_eip; | ||
699 | - env->exception_index = intno; | ||
700 | - env->error_code = error_code; | ||
701 | - | ||
702 | - cpu_loop_exit(); | ||
703 | -} | ||
704 | - | ||
705 | -#endif | ||
706 | - | ||
707 | -/* shortcuts to generate exceptions */ | ||
708 | -void raise_exception_err(int exception_index, int error_code) | ||
709 | -{ | ||
710 | - raise_interrupt(exception_index, 0, error_code, 0); | ||
711 | -} | ||
712 | - | ||
713 | -void raise_exception(int exception_index) | ||
714 | -{ | ||
715 | - raise_interrupt(exception_index, 0, 0, 0); | ||
716 | -} | ||
717 | - | ||
718 | void OPPROTO op_raise_interrupt(void) | 629 | void OPPROTO op_raise_interrupt(void) |
719 | { | 630 | { |
720 | int intno; | 631 | int intno; |
@@ -833,7 +744,7 @@ label ## n:\ | @@ -833,7 +744,7 @@ label ## n:\ | ||
833 | #define JUMP_TB(tbparam, n, eip)\ | 744 | #define JUMP_TB(tbparam, n, eip)\ |
834 | do {\ | 745 | do {\ |
835 | static void __attribute__((unused)) *__op_label ## n = &&label ## n;\ | 746 | static void __attribute__((unused)) *__op_label ## n = &&label ## n;\ |
836 | - goto *((TranslationBlock *)tbparam)->tb_next[n];\ | 747 | + goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\ |
837 | label ## n:\ | 748 | label ## n:\ |
838 | T0 = (long)(tbparam) + (n);\ | 749 | T0 = (long)(tbparam) + (n);\ |
839 | EIP = eip;\ | 750 | EIP = eip;\ |
@@ -1044,46 +955,6 @@ void OPPROTO op_rdtsc(void) | @@ -1044,46 +955,6 @@ void OPPROTO op_rdtsc(void) | ||
1044 | EDX = val >> 32; | 955 | EDX = val >> 32; |
1045 | } | 956 | } |
1046 | 957 | ||
1047 | -/* We simulate a pre-MMX pentium as in valgrind */ | ||
1048 | -#define CPUID_FP87 (1 << 0) | ||
1049 | -#define CPUID_VME (1 << 1) | ||
1050 | -#define CPUID_DE (1 << 2) | ||
1051 | -#define CPUID_PSE (1 << 3) | ||
1052 | -#define CPUID_TSC (1 << 4) | ||
1053 | -#define CPUID_MSR (1 << 5) | ||
1054 | -#define CPUID_PAE (1 << 6) | ||
1055 | -#define CPUID_MCE (1 << 7) | ||
1056 | -#define CPUID_CX8 (1 << 8) | ||
1057 | -#define CPUID_APIC (1 << 9) | ||
1058 | -#define CPUID_SEP (1 << 11) /* sysenter/sysexit */ | ||
1059 | -#define CPUID_MTRR (1 << 12) | ||
1060 | -#define CPUID_PGE (1 << 13) | ||
1061 | -#define CPUID_MCA (1 << 14) | ||
1062 | -#define CPUID_CMOV (1 << 15) | ||
1063 | -/* ... */ | ||
1064 | -#define CPUID_MMX (1 << 23) | ||
1065 | -#define CPUID_FXSR (1 << 24) | ||
1066 | -#define CPUID_SSE (1 << 25) | ||
1067 | -#define CPUID_SSE2 (1 << 26) | ||
1068 | - | ||
1069 | -void helper_cpuid(void) | ||
1070 | -{ | ||
1071 | - if (EAX == 0) { | ||
1072 | - EAX = 1; /* max EAX index supported */ | ||
1073 | - EBX = 0x756e6547; | ||
1074 | - ECX = 0x6c65746e; | ||
1075 | - EDX = 0x49656e69; | ||
1076 | - } else if (EAX == 1) { | ||
1077 | - /* EAX = 1 info */ | ||
1078 | - EAX = 0x52b; | ||
1079 | - EBX = 0; | ||
1080 | - ECX = 0; | ||
1081 | - EDX = CPUID_FP87 | CPUID_DE | CPUID_PSE | | ||
1082 | - CPUID_TSC | CPUID_MSR | CPUID_MCE | | ||
1083 | - CPUID_CX8; | ||
1084 | - } | ||
1085 | -} | ||
1086 | - | ||
1087 | void OPPROTO op_cpuid(void) | 958 | void OPPROTO op_cpuid(void) |
1088 | { | 959 | { |
1089 | helper_cpuid(); | 960 | helper_cpuid(); |
@@ -1221,79 +1092,6 @@ void OPPROTO op_das(void) | @@ -1221,79 +1092,6 @@ void OPPROTO op_das(void) | ||
1221 | 1092 | ||
1222 | /* segment handling */ | 1093 | /* segment handling */ |
1223 | 1094 | ||
1224 | -/* only works if protected mode and not VM86 */ | ||
1225 | -void load_seg(int seg_reg, int selector, unsigned cur_eip) | ||
1226 | -{ | ||
1227 | - SegmentCache *sc; | ||
1228 | - SegmentDescriptorTable *dt; | ||
1229 | - int index; | ||
1230 | - uint32_t e1, e2; | ||
1231 | - uint8_t *ptr; | ||
1232 | - | ||
1233 | - sc = &env->seg_cache[seg_reg]; | ||
1234 | - if ((selector & 0xfffc) == 0) { | ||
1235 | - /* null selector case */ | ||
1236 | - if (seg_reg == R_SS) { | ||
1237 | - EIP = cur_eip; | ||
1238 | - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); | ||
1239 | - } else { | ||
1240 | - /* XXX: each access should trigger an exception */ | ||
1241 | - sc->base = NULL; | ||
1242 | - sc->limit = 0; | ||
1243 | - sc->seg_32bit = 1; | ||
1244 | - } | ||
1245 | - } else { | ||
1246 | - if (selector & 0x4) | ||
1247 | - dt = &env->ldt; | ||
1248 | - else | ||
1249 | - dt = &env->gdt; | ||
1250 | - index = selector & ~7; | ||
1251 | - if ((index + 7) > dt->limit) { | ||
1252 | - EIP = cur_eip; | ||
1253 | - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); | ||
1254 | - } | ||
1255 | - ptr = dt->base + index; | ||
1256 | - e1 = ldl(ptr); | ||
1257 | - e2 = ldl(ptr + 4); | ||
1258 | - if (!(e2 & DESC_S_MASK) || | ||
1259 | - (e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) { | ||
1260 | - EIP = cur_eip; | ||
1261 | - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); | ||
1262 | - } | ||
1263 | - | ||
1264 | - if (seg_reg == R_SS) { | ||
1265 | - if ((e2 & (DESC_CS_MASK | DESC_W_MASK)) == 0) { | ||
1266 | - EIP = cur_eip; | ||
1267 | - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); | ||
1268 | - } | ||
1269 | - } else { | ||
1270 | - if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) { | ||
1271 | - EIP = cur_eip; | ||
1272 | - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); | ||
1273 | - } | ||
1274 | - } | ||
1275 | - | ||
1276 | - if (!(e2 & DESC_P_MASK)) { | ||
1277 | - EIP = cur_eip; | ||
1278 | - if (seg_reg == R_SS) | ||
1279 | - raise_exception_err(EXCP0C_STACK, selector & 0xfffc); | ||
1280 | - else | ||
1281 | - raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc); | ||
1282 | - } | ||
1283 | - | ||
1284 | - sc->base = (void *)((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000)); | ||
1285 | - sc->limit = (e1 & 0xffff) | (e2 & 0x000f0000); | ||
1286 | - if (e2 & (1 << 23)) | ||
1287 | - sc->limit = (sc->limit << 12) | 0xfff; | ||
1288 | - sc->seg_32bit = (e2 >> 22) & 1; | ||
1289 | -#if 0 | ||
1290 | - fprintf(logfile, "load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx seg_32bit=%d\n", | ||
1291 | - selector, (unsigned long)sc->base, sc->limit, sc->seg_32bit); | ||
1292 | -#endif | ||
1293 | - } | ||
1294 | - env->segs[seg_reg] = selector; | ||
1295 | -} | ||
1296 | - | ||
1297 | void OPPROTO op_movl_seg_T0(void) | 1095 | void OPPROTO op_movl_seg_T0(void) |
1298 | { | 1096 | { |
1299 | load_seg(PARAM1, T0 & 0xffff, PARAM2); | 1097 | load_seg(PARAM1, T0 & 0xffff, PARAM2); |
@@ -1326,61 +1124,11 @@ void OPPROTO op_addl_A0_seg(void) | @@ -1326,61 +1124,11 @@ void OPPROTO op_addl_A0_seg(void) | ||
1326 | A0 += *(unsigned long *)((char *)env + PARAM1); | 1124 | A0 += *(unsigned long *)((char *)env + PARAM1); |
1327 | } | 1125 | } |
1328 | 1126 | ||
1329 | -void helper_lsl(void) | ||
1330 | -{ | ||
1331 | - unsigned int selector, limit; | ||
1332 | - SegmentDescriptorTable *dt; | ||
1333 | - int index; | ||
1334 | - uint32_t e1, e2; | ||
1335 | - uint8_t *ptr; | ||
1336 | - | ||
1337 | - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; | ||
1338 | - selector = T0 & 0xffff; | ||
1339 | - if (selector & 0x4) | ||
1340 | - dt = &env->ldt; | ||
1341 | - else | ||
1342 | - dt = &env->gdt; | ||
1343 | - index = selector & ~7; | ||
1344 | - if ((index + 7) > dt->limit) | ||
1345 | - return; | ||
1346 | - ptr = dt->base + index; | ||
1347 | - e1 = ldl(ptr); | ||
1348 | - e2 = ldl(ptr + 4); | ||
1349 | - limit = (e1 & 0xffff) | (e2 & 0x000f0000); | ||
1350 | - if (e2 & (1 << 23)) | ||
1351 | - limit = (limit << 12) | 0xfff; | ||
1352 | - T1 = limit; | ||
1353 | - CC_SRC |= CC_Z; | ||
1354 | -} | ||
1355 | - | ||
1356 | void OPPROTO op_lsl(void) | 1127 | void OPPROTO op_lsl(void) |
1357 | { | 1128 | { |
1358 | helper_lsl(); | 1129 | helper_lsl(); |
1359 | } | 1130 | } |
1360 | 1131 | ||
1361 | -void helper_lar(void) | ||
1362 | -{ | ||
1363 | - unsigned int selector; | ||
1364 | - SegmentDescriptorTable *dt; | ||
1365 | - int index; | ||
1366 | - uint32_t e2; | ||
1367 | - uint8_t *ptr; | ||
1368 | - | ||
1369 | - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; | ||
1370 | - selector = T0 & 0xffff; | ||
1371 | - if (selector & 0x4) | ||
1372 | - dt = &env->ldt; | ||
1373 | - else | ||
1374 | - dt = &env->gdt; | ||
1375 | - index = selector & ~7; | ||
1376 | - if ((index + 7) > dt->limit) | ||
1377 | - return; | ||
1378 | - ptr = dt->base + index; | ||
1379 | - e2 = ldl(ptr + 4); | ||
1380 | - T1 = e2 & 0x00f0ff00; | ||
1381 | - CC_SRC |= CC_Z; | ||
1382 | -} | ||
1383 | - | ||
1384 | void OPPROTO op_lar(void) | 1132 | void OPPROTO op_lar(void) |
1385 | { | 1133 | { |
1386 | helper_lar(); | 1134 | helper_lar(); |
@@ -1678,37 +1426,6 @@ CCTable cc_table[CC_OP_NB] = { | @@ -1678,37 +1426,6 @@ CCTable cc_table[CC_OP_NB] = { | ||
1678 | functions comes from the LGPL'ed x86 emulator found in the Willows | 1426 | functions comes from the LGPL'ed x86 emulator found in the Willows |
1679 | TWIN windows emulator. */ | 1427 | TWIN windows emulator. */ |
1680 | 1428 | ||
1681 | -#ifdef USE_X86LDOUBLE | ||
1682 | -/* use long double functions */ | ||
1683 | -#define lrint lrintl | ||
1684 | -#define llrint llrintl | ||
1685 | -#define fabs fabsl | ||
1686 | -#define sin sinl | ||
1687 | -#define cos cosl | ||
1688 | -#define sqrt sqrtl | ||
1689 | -#define pow powl | ||
1690 | -#define log logl | ||
1691 | -#define tan tanl | ||
1692 | -#define atan2 atan2l | ||
1693 | -#define floor floorl | ||
1694 | -#define ceil ceill | ||
1695 | -#define rint rintl | ||
1696 | -#endif | ||
1697 | - | ||
1698 | -extern int lrint(CPU86_LDouble x); | ||
1699 | -extern int64_t llrint(CPU86_LDouble x); | ||
1700 | -extern CPU86_LDouble fabs(CPU86_LDouble x); | ||
1701 | -extern CPU86_LDouble sin(CPU86_LDouble x); | ||
1702 | -extern CPU86_LDouble cos(CPU86_LDouble x); | ||
1703 | -extern CPU86_LDouble sqrt(CPU86_LDouble x); | ||
1704 | -extern CPU86_LDouble pow(CPU86_LDouble, CPU86_LDouble); | ||
1705 | -extern CPU86_LDouble log(CPU86_LDouble x); | ||
1706 | -extern CPU86_LDouble tan(CPU86_LDouble x); | ||
1707 | -extern CPU86_LDouble atan2(CPU86_LDouble, CPU86_LDouble); | ||
1708 | -extern CPU86_LDouble floor(CPU86_LDouble x); | ||
1709 | -extern CPU86_LDouble ceil(CPU86_LDouble x); | ||
1710 | -extern CPU86_LDouble rint(CPU86_LDouble x); | ||
1711 | - | ||
1712 | #if defined(__powerpc__) | 1429 | #if defined(__powerpc__) |
1713 | extern CPU86_LDouble copysign(CPU86_LDouble, CPU86_LDouble); | 1430 | extern CPU86_LDouble copysign(CPU86_LDouble, CPU86_LDouble); |
1714 | 1431 | ||
@@ -1729,60 +1446,6 @@ double qemu_rint(double x) | @@ -1729,60 +1446,6 @@ double qemu_rint(double x) | ||
1729 | #define rint qemu_rint | 1446 | #define rint qemu_rint |
1730 | #endif | 1447 | #endif |
1731 | 1448 | ||
1732 | -#define RC_MASK 0xc00 | ||
1733 | -#define RC_NEAR 0x000 | ||
1734 | -#define RC_DOWN 0x400 | ||
1735 | -#define RC_UP 0x800 | ||
1736 | -#define RC_CHOP 0xc00 | ||
1737 | - | ||
1738 | -#define MAXTAN 9223372036854775808.0 | ||
1739 | - | ||
1740 | -#ifdef USE_X86LDOUBLE | ||
1741 | - | ||
1742 | -/* only for x86 */ | ||
1743 | -typedef union { | ||
1744 | - long double d; | ||
1745 | - struct { | ||
1746 | - unsigned long long lower; | ||
1747 | - unsigned short upper; | ||
1748 | - } l; | ||
1749 | -} CPU86_LDoubleU; | ||
1750 | - | ||
1751 | -/* the following deal with x86 long double-precision numbers */ | ||
1752 | -#define MAXEXPD 0x7fff | ||
1753 | -#define EXPBIAS 16383 | ||
1754 | -#define EXPD(fp) (fp.l.upper & 0x7fff) | ||
1755 | -#define SIGND(fp) ((fp.l.upper) & 0x8000) | ||
1756 | -#define MANTD(fp) (fp.l.lower) | ||
1757 | -#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS | ||
1758 | - | ||
1759 | -#else | ||
1760 | - | ||
1761 | -typedef union { | ||
1762 | - double d; | ||
1763 | -#ifndef WORDS_BIGENDIAN | ||
1764 | - struct { | ||
1765 | - uint32_t lower; | ||
1766 | - int32_t upper; | ||
1767 | - } l; | ||
1768 | -#else | ||
1769 | - struct { | ||
1770 | - int32_t upper; | ||
1771 | - uint32_t lower; | ||
1772 | - } l; | ||
1773 | -#endif | ||
1774 | - int64_t ll; | ||
1775 | -} CPU86_LDoubleU; | ||
1776 | - | ||
1777 | -/* the following deal with IEEE double-precision numbers */ | ||
1778 | -#define MAXEXPD 0x7ff | ||
1779 | -#define EXPBIAS 1023 | ||
1780 | -#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) | ||
1781 | -#define SIGND(fp) ((fp.l.upper) & 0x80000000) | ||
1782 | -#define MANTD(fp) (fp.ll & ((1LL << 52) - 1)) | ||
1783 | -#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20) | ||
1784 | -#endif | ||
1785 | - | ||
1786 | /* fp load FT0 */ | 1449 | /* fp load FT0 */ |
1787 | 1450 | ||
1788 | void OPPROTO op_flds_FT0_A0(void) | 1451 | void OPPROTO op_flds_FT0_A0(void) |
@@ -1899,24 +1562,6 @@ void OPPROTO op_fldt_ST0_A0(void) | @@ -1899,24 +1562,6 @@ void OPPROTO op_fldt_ST0_A0(void) | ||
1899 | ST0 = *(long double *)A0; | 1562 | ST0 = *(long double *)A0; |
1900 | } | 1563 | } |
1901 | #else | 1564 | #else |
1902 | -static inline CPU86_LDouble helper_fldt(uint8_t *ptr) | ||
1903 | -{ | ||
1904 | - CPU86_LDoubleU temp; | ||
1905 | - int upper, e; | ||
1906 | - /* mantissa */ | ||
1907 | - upper = lduw(ptr + 8); | ||
1908 | - /* XXX: handle overflow ? */ | ||
1909 | - e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */ | ||
1910 | - e |= (upper >> 4) & 0x800; /* sign */ | ||
1911 | - temp.ll = ((ldq(ptr) >> 11) & ((1LL << 52) - 1)) | ((uint64_t)e << 52); | ||
1912 | - return temp.d; | ||
1913 | -} | ||
1914 | - | ||
1915 | -void helper_fldt_ST0_A0(void) | ||
1916 | -{ | ||
1917 | - ST0 = helper_fldt((uint8_t *)A0); | ||
1918 | -} | ||
1919 | - | ||
1920 | void OPPROTO op_fldt_ST0_A0(void) | 1565 | void OPPROTO op_fldt_ST0_A0(void) |
1921 | { | 1566 | { |
1922 | helper_fldt_ST0_A0(); | 1567 | helper_fldt_ST0_A0(); |
@@ -2013,25 +1658,6 @@ void OPPROTO op_fstt_ST0_A0(void) | @@ -2013,25 +1658,6 @@ void OPPROTO op_fstt_ST0_A0(void) | ||
2013 | *(long double *)A0 = ST0; | 1658 | *(long double *)A0 = ST0; |
2014 | } | 1659 | } |
2015 | #else | 1660 | #else |
2016 | - | ||
2017 | -static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) | ||
2018 | -{ | ||
2019 | - CPU86_LDoubleU temp; | ||
2020 | - int e; | ||
2021 | - temp.d = f; | ||
2022 | - /* mantissa */ | ||
2023 | - stq(ptr, (MANTD(temp) << 11) | (1LL << 63)); | ||
2024 | - /* exponent + sign */ | ||
2025 | - e = EXPD(temp) - EXPBIAS + 16383; | ||
2026 | - e |= SIGND(temp) >> 16; | ||
2027 | - stw(ptr + 8, e); | ||
2028 | -} | ||
2029 | - | ||
2030 | -void helper_fstt_ST0_A0(void) | ||
2031 | -{ | ||
2032 | - helper_fstt(ST0, (uint8_t *)A0); | ||
2033 | -} | ||
2034 | - | ||
2035 | void OPPROTO op_fstt_ST0_A0(void) | 1661 | void OPPROTO op_fstt_ST0_A0(void) |
2036 | { | 1662 | { |
2037 | helper_fstt_ST0_A0(); | 1663 | helper_fstt_ST0_A0(); |
@@ -2080,98 +1706,11 @@ void OPPROTO op_fistll_ST0_A0(void) | @@ -2080,98 +1706,11 @@ void OPPROTO op_fistll_ST0_A0(void) | ||
2080 | stq((void *)A0, val); | 1706 | stq((void *)A0, val); |
2081 | } | 1707 | } |
2082 | 1708 | ||
2083 | -/* BCD ops */ | ||
2084 | - | ||
2085 | -#define MUL10(iv) ( iv + iv + (iv << 3) ) | ||
2086 | - | ||
2087 | -void helper_fbld_ST0_A0(void) | ||
2088 | -{ | ||
2089 | - uint8_t *seg; | ||
2090 | - CPU86_LDouble fpsrcop; | ||
2091 | - int m32i; | ||
2092 | - unsigned int v; | ||
2093 | - | ||
2094 | - /* in this code, seg/m32i will be used as temporary ptr/int */ | ||
2095 | - seg = (uint8_t *)A0 + 8; | ||
2096 | - v = ldub(seg--); | ||
2097 | - /* XXX: raise exception */ | ||
2098 | - if (v != 0) | ||
2099 | - return; | ||
2100 | - v = ldub(seg--); | ||
2101 | - /* XXX: raise exception */ | ||
2102 | - if ((v & 0xf0) != 0) | ||
2103 | - return; | ||
2104 | - m32i = v; /* <-- d14 */ | ||
2105 | - v = ldub(seg--); | ||
2106 | - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d13 */ | ||
2107 | - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d12 */ | ||
2108 | - v = ldub(seg--); | ||
2109 | - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d11 */ | ||
2110 | - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d10 */ | ||
2111 | - v = ldub(seg--); | ||
2112 | - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d9 */ | ||
2113 | - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d8 */ | ||
2114 | - fpsrcop = ((CPU86_LDouble)m32i) * 100000000.0; | ||
2115 | - | ||
2116 | - v = ldub(seg--); | ||
2117 | - m32i = (v >> 4); /* <-- d7 */ | ||
2118 | - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d6 */ | ||
2119 | - v = ldub(seg--); | ||
2120 | - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d5 */ | ||
2121 | - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d4 */ | ||
2122 | - v = ldub(seg--); | ||
2123 | - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d3 */ | ||
2124 | - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d2 */ | ||
2125 | - v = ldub(seg); | ||
2126 | - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d1 */ | ||
2127 | - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d0 */ | ||
2128 | - fpsrcop += ((CPU86_LDouble)m32i); | ||
2129 | - if ( ldub(seg+9) & 0x80 ) | ||
2130 | - fpsrcop = -fpsrcop; | ||
2131 | - ST0 = fpsrcop; | ||
2132 | -} | ||
2133 | - | ||
2134 | void OPPROTO op_fbld_ST0_A0(void) | 1709 | void OPPROTO op_fbld_ST0_A0(void) |
2135 | { | 1710 | { |
2136 | helper_fbld_ST0_A0(); | 1711 | helper_fbld_ST0_A0(); |
2137 | } | 1712 | } |
2138 | 1713 | ||
2139 | -void helper_fbst_ST0_A0(void) | ||
2140 | -{ | ||
2141 | - CPU86_LDouble fptemp; | ||
2142 | - CPU86_LDouble fpsrcop; | ||
2143 | - int v; | ||
2144 | - uint8_t *mem_ref, *mem_end; | ||
2145 | - | ||
2146 | - fpsrcop = rint(ST0); | ||
2147 | - mem_ref = (uint8_t *)A0; | ||
2148 | - mem_end = mem_ref + 8; | ||
2149 | - if ( fpsrcop < 0.0 ) { | ||
2150 | - stw(mem_end, 0x8000); | ||
2151 | - fpsrcop = -fpsrcop; | ||
2152 | - } else { | ||
2153 | - stw(mem_end, 0x0000); | ||
2154 | - } | ||
2155 | - while (mem_ref < mem_end) { | ||
2156 | - if (fpsrcop == 0.0) | ||
2157 | - break; | ||
2158 | - fptemp = floor(fpsrcop/10.0); | ||
2159 | - v = ((int)(fpsrcop - fptemp*10.0)); | ||
2160 | - if (fptemp == 0.0) { | ||
2161 | - stb(mem_ref++, v); | ||
2162 | - break; | ||
2163 | - } | ||
2164 | - fpsrcop = fptemp; | ||
2165 | - fptemp = floor(fpsrcop/10.0); | ||
2166 | - v |= (((int)(fpsrcop - fptemp*10.0)) << 4); | ||
2167 | - stb(mem_ref++, v); | ||
2168 | - fpsrcop = fptemp; | ||
2169 | - } | ||
2170 | - while (mem_ref < mem_end) { | ||
2171 | - stb(mem_ref++, 0); | ||
2172 | - } | ||
2173 | -} | ||
2174 | - | ||
2175 | void OPPROTO op_fbst_ST0_A0(void) | 1714 | void OPPROTO op_fbst_ST0_A0(void) |
2176 | { | 1715 | { |
2177 | helper_fbst_ST0_A0(); | 1716 | helper_fbst_ST0_A0(); |
@@ -2179,18 +1718,6 @@ void OPPROTO op_fbst_ST0_A0(void) | @@ -2179,18 +1718,6 @@ void OPPROTO op_fbst_ST0_A0(void) | ||
2179 | 1718 | ||
2180 | /* FPU move */ | 1719 | /* FPU move */ |
2181 | 1720 | ||
2182 | -static inline void fpush(void) | ||
2183 | -{ | ||
2184 | - env->fpstt = (env->fpstt - 1) & 7; | ||
2185 | - env->fptags[env->fpstt] = 0; /* validate stack entry */ | ||
2186 | -} | ||
2187 | - | ||
2188 | -static inline void fpop(void) | ||
2189 | -{ | ||
2190 | - env->fptags[env->fpstt] = 1; /* invvalidate stack entry */ | ||
2191 | - env->fpstt = (env->fpstt + 1) & 7; | ||
2192 | -} | ||
2193 | - | ||
2194 | void OPPROTO op_fpush(void) | 1721 | void OPPROTO op_fpush(void) |
2195 | { | 1722 | { |
2196 | fpush(); | 1723 | fpush(); |
@@ -2370,33 +1897,6 @@ void OPPROTO op_fabs_ST0(void) | @@ -2370,33 +1897,6 @@ void OPPROTO op_fabs_ST0(void) | ||
2370 | ST0 = fabs(ST0); | 1897 | ST0 = fabs(ST0); |
2371 | } | 1898 | } |
2372 | 1899 | ||
2373 | -void helper_fxam_ST0(void) | ||
2374 | -{ | ||
2375 | - CPU86_LDoubleU temp; | ||
2376 | - int expdif; | ||
2377 | - | ||
2378 | - temp.d = ST0; | ||
2379 | - | ||
2380 | - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ | ||
2381 | - if (SIGND(temp)) | ||
2382 | - env->fpus |= 0x200; /* C1 <-- 1 */ | ||
2383 | - | ||
2384 | - expdif = EXPD(temp); | ||
2385 | - if (expdif == MAXEXPD) { | ||
2386 | - if (MANTD(temp) == 0) | ||
2387 | - env->fpus |= 0x500 /*Infinity*/; | ||
2388 | - else | ||
2389 | - env->fpus |= 0x100 /*NaN*/; | ||
2390 | - } else if (expdif == 0) { | ||
2391 | - if (MANTD(temp) == 0) | ||
2392 | - env->fpus |= 0x4000 /*Zero*/; | ||
2393 | - else | ||
2394 | - env->fpus |= 0x4400 /*Denormal*/; | ||
2395 | - } else { | ||
2396 | - env->fpus |= 0x400; | ||
2397 | - } | ||
2398 | -} | ||
2399 | - | ||
2400 | void OPPROTO op_fxam_ST0(void) | 1900 | void OPPROTO op_fxam_ST0(void) |
2401 | { | 1901 | { |
2402 | helper_fxam_ST0(); | 1902 | helper_fxam_ST0(); |
@@ -2442,217 +1942,6 @@ void OPPROTO op_fldz_FT0(void) | @@ -2442,217 +1942,6 @@ void OPPROTO op_fldz_FT0(void) | ||
2442 | ST0 = *(CPU86_LDouble *)&f15rk[0]; | 1942 | ST0 = *(CPU86_LDouble *)&f15rk[0]; |
2443 | } | 1943 | } |
2444 | 1944 | ||
2445 | -void helper_f2xm1(void) | ||
2446 | -{ | ||
2447 | - ST0 = pow(2.0,ST0) - 1.0; | ||
2448 | -} | ||
2449 | - | ||
2450 | -void helper_fyl2x(void) | ||
2451 | -{ | ||
2452 | - CPU86_LDouble fptemp; | ||
2453 | - | ||
2454 | - fptemp = ST0; | ||
2455 | - if (fptemp>0.0){ | ||
2456 | - fptemp = log(fptemp)/log(2.0); /* log2(ST) */ | ||
2457 | - ST1 *= fptemp; | ||
2458 | - fpop(); | ||
2459 | - } else { | ||
2460 | - env->fpus &= (~0x4700); | ||
2461 | - env->fpus |= 0x400; | ||
2462 | - } | ||
2463 | -} | ||
2464 | - | ||
2465 | -void helper_fptan(void) | ||
2466 | -{ | ||
2467 | - CPU86_LDouble fptemp; | ||
2468 | - | ||
2469 | - fptemp = ST0; | ||
2470 | - if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { | ||
2471 | - env->fpus |= 0x400; | ||
2472 | - } else { | ||
2473 | - ST0 = tan(fptemp); | ||
2474 | - fpush(); | ||
2475 | - ST0 = 1.0; | ||
2476 | - env->fpus &= (~0x400); /* C2 <-- 0 */ | ||
2477 | - /* the above code is for |arg| < 2**52 only */ | ||
2478 | - } | ||
2479 | -} | ||
2480 | - | ||
2481 | -void helper_fpatan(void) | ||
2482 | -{ | ||
2483 | - CPU86_LDouble fptemp, fpsrcop; | ||
2484 | - | ||
2485 | - fpsrcop = ST1; | ||
2486 | - fptemp = ST0; | ||
2487 | - ST1 = atan2(fpsrcop,fptemp); | ||
2488 | - fpop(); | ||
2489 | -} | ||
2490 | - | ||
2491 | -void helper_fxtract(void) | ||
2492 | -{ | ||
2493 | - CPU86_LDoubleU temp; | ||
2494 | - unsigned int expdif; | ||
2495 | - | ||
2496 | - temp.d = ST0; | ||
2497 | - expdif = EXPD(temp) - EXPBIAS; | ||
2498 | - /*DP exponent bias*/ | ||
2499 | - ST0 = expdif; | ||
2500 | - fpush(); | ||
2501 | - BIASEXPONENT(temp); | ||
2502 | - ST0 = temp.d; | ||
2503 | -} | ||
2504 | - | ||
2505 | -void helper_fprem1(void) | ||
2506 | -{ | ||
2507 | - CPU86_LDouble dblq, fpsrcop, fptemp; | ||
2508 | - CPU86_LDoubleU fpsrcop1, fptemp1; | ||
2509 | - int expdif; | ||
2510 | - int q; | ||
2511 | - | ||
2512 | - fpsrcop = ST0; | ||
2513 | - fptemp = ST1; | ||
2514 | - fpsrcop1.d = fpsrcop; | ||
2515 | - fptemp1.d = fptemp; | ||
2516 | - expdif = EXPD(fpsrcop1) - EXPD(fptemp1); | ||
2517 | - if (expdif < 53) { | ||
2518 | - dblq = fpsrcop / fptemp; | ||
2519 | - dblq = (dblq < 0.0)? ceil(dblq): floor(dblq); | ||
2520 | - ST0 = fpsrcop - fptemp*dblq; | ||
2521 | - q = (int)dblq; /* cutting off top bits is assumed here */ | ||
2522 | - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ | ||
2523 | - /* (C0,C1,C3) <-- (q2,q1,q0) */ | ||
2524 | - env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */ | ||
2525 | - env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */ | ||
2526 | - env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */ | ||
2527 | - } else { | ||
2528 | - env->fpus |= 0x400; /* C2 <-- 1 */ | ||
2529 | - fptemp = pow(2.0, expdif-50); | ||
2530 | - fpsrcop = (ST0 / ST1) / fptemp; | ||
2531 | - /* fpsrcop = integer obtained by rounding to the nearest */ | ||
2532 | - fpsrcop = (fpsrcop-floor(fpsrcop) < ceil(fpsrcop)-fpsrcop)? | ||
2533 | - floor(fpsrcop): ceil(fpsrcop); | ||
2534 | - ST0 -= (ST1 * fpsrcop * fptemp); | ||
2535 | - } | ||
2536 | -} | ||
2537 | - | ||
2538 | -void helper_fprem(void) | ||
2539 | -{ | ||
2540 | - CPU86_LDouble dblq, fpsrcop, fptemp; | ||
2541 | - CPU86_LDoubleU fpsrcop1, fptemp1; | ||
2542 | - int expdif; | ||
2543 | - int q; | ||
2544 | - | ||
2545 | - fpsrcop = ST0; | ||
2546 | - fptemp = ST1; | ||
2547 | - fpsrcop1.d = fpsrcop; | ||
2548 | - fptemp1.d = fptemp; | ||
2549 | - expdif = EXPD(fpsrcop1) - EXPD(fptemp1); | ||
2550 | - if ( expdif < 53 ) { | ||
2551 | - dblq = fpsrcop / fptemp; | ||
2552 | - dblq = (dblq < 0.0)? ceil(dblq): floor(dblq); | ||
2553 | - ST0 = fpsrcop - fptemp*dblq; | ||
2554 | - q = (int)dblq; /* cutting off top bits is assumed here */ | ||
2555 | - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ | ||
2556 | - /* (C0,C1,C3) <-- (q2,q1,q0) */ | ||
2557 | - env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */ | ||
2558 | - env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */ | ||
2559 | - env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */ | ||
2560 | - } else { | ||
2561 | - env->fpus |= 0x400; /* C2 <-- 1 */ | ||
2562 | - fptemp = pow(2.0, expdif-50); | ||
2563 | - fpsrcop = (ST0 / ST1) / fptemp; | ||
2564 | - /* fpsrcop = integer obtained by chopping */ | ||
2565 | - fpsrcop = (fpsrcop < 0.0)? | ||
2566 | - -(floor(fabs(fpsrcop))): floor(fpsrcop); | ||
2567 | - ST0 -= (ST1 * fpsrcop * fptemp); | ||
2568 | - } | ||
2569 | -} | ||
2570 | - | ||
2571 | -void helper_fyl2xp1(void) | ||
2572 | -{ | ||
2573 | - CPU86_LDouble fptemp; | ||
2574 | - | ||
2575 | - fptemp = ST0; | ||
2576 | - if ((fptemp+1.0)>0.0) { | ||
2577 | - fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */ | ||
2578 | - ST1 *= fptemp; | ||
2579 | - fpop(); | ||
2580 | - } else { | ||
2581 | - env->fpus &= (~0x4700); | ||
2582 | - env->fpus |= 0x400; | ||
2583 | - } | ||
2584 | -} | ||
2585 | - | ||
2586 | -void helper_fsqrt(void) | ||
2587 | -{ | ||
2588 | - CPU86_LDouble fptemp; | ||
2589 | - | ||
2590 | - fptemp = ST0; | ||
2591 | - if (fptemp<0.0) { | ||
2592 | - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */ | ||
2593 | - env->fpus |= 0x400; | ||
2594 | - } | ||
2595 | - ST0 = sqrt(fptemp); | ||
2596 | -} | ||
2597 | - | ||
2598 | -void helper_fsincos(void) | ||
2599 | -{ | ||
2600 | - CPU86_LDouble fptemp; | ||
2601 | - | ||
2602 | - fptemp = ST0; | ||
2603 | - if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { | ||
2604 | - env->fpus |= 0x400; | ||
2605 | - } else { | ||
2606 | - ST0 = sin(fptemp); | ||
2607 | - fpush(); | ||
2608 | - ST0 = cos(fptemp); | ||
2609 | - env->fpus &= (~0x400); /* C2 <-- 0 */ | ||
2610 | - /* the above code is for |arg| < 2**63 only */ | ||
2611 | - } | ||
2612 | -} | ||
2613 | - | ||
2614 | -void helper_frndint(void) | ||
2615 | -{ | ||
2616 | - ST0 = rint(ST0); | ||
2617 | -} | ||
2618 | - | ||
2619 | -void helper_fscale(void) | ||
2620 | -{ | ||
2621 | - CPU86_LDouble fpsrcop, fptemp; | ||
2622 | - | ||
2623 | - fpsrcop = 2.0; | ||
2624 | - fptemp = pow(fpsrcop,ST1); | ||
2625 | - ST0 *= fptemp; | ||
2626 | -} | ||
2627 | - | ||
2628 | -void helper_fsin(void) | ||
2629 | -{ | ||
2630 | - CPU86_LDouble fptemp; | ||
2631 | - | ||
2632 | - fptemp = ST0; | ||
2633 | - if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { | ||
2634 | - env->fpus |= 0x400; | ||
2635 | - } else { | ||
2636 | - ST0 = sin(fptemp); | ||
2637 | - env->fpus &= (~0x400); /* C2 <-- 0 */ | ||
2638 | - /* the above code is for |arg| < 2**53 only */ | ||
2639 | - } | ||
2640 | -} | ||
2641 | - | ||
2642 | -void helper_fcos(void) | ||
2643 | -{ | ||
2644 | - CPU86_LDouble fptemp; | ||
2645 | - | ||
2646 | - fptemp = ST0; | ||
2647 | - if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) { | ||
2648 | - env->fpus |= 0x400; | ||
2649 | - } else { | ||
2650 | - ST0 = cos(fptemp); | ||
2651 | - env->fpus &= (~0x400); /* C2 <-- 0 */ | ||
2652 | - /* the above code is for |arg5 < 2**63 only */ | ||
2653 | - } | ||
2654 | -} | ||
2655 | - | ||
2656 | /* associated heplers to reduce generated code length and to simplify | 1945 | /* associated heplers to reduce generated code length and to simplify |
2657 | relocation (FP constants are usually stored in .rodata section) */ | 1946 | relocation (FP constants are usually stored in .rodata section) */ |
2658 | 1947 | ||
@@ -2789,129 +2078,6 @@ void OPPROTO op_fninit(void) | @@ -2789,129 +2078,6 @@ void OPPROTO op_fninit(void) | ||
2789 | env->fptags[7] = 1; | 2078 | env->fptags[7] = 1; |
2790 | } | 2079 | } |
2791 | 2080 | ||
2792 | -void helper_fstenv(uint8_t *ptr, int data32) | ||
2793 | -{ | ||
2794 | - int fpus, fptag, exp, i; | ||
2795 | - uint64_t mant; | ||
2796 | - CPU86_LDoubleU tmp; | ||
2797 | - | ||
2798 | - fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; | ||
2799 | - fptag = 0; | ||
2800 | - for (i=7; i>=0; i--) { | ||
2801 | - fptag <<= 2; | ||
2802 | - if (env->fptags[i]) { | ||
2803 | - fptag |= 3; | ||
2804 | - } else { | ||
2805 | - tmp.d = env->fpregs[i]; | ||
2806 | - exp = EXPD(tmp); | ||
2807 | - mant = MANTD(tmp); | ||
2808 | - if (exp == 0 && mant == 0) { | ||
2809 | - /* zero */ | ||
2810 | - fptag |= 1; | ||
2811 | - } else if (exp == 0 || exp == MAXEXPD | ||
2812 | -#ifdef USE_X86LDOUBLE | ||
2813 | - || (mant & (1LL << 63)) == 0 | ||
2814 | -#endif | ||
2815 | - ) { | ||
2816 | - /* NaNs, infinity, denormal */ | ||
2817 | - fptag |= 2; | ||
2818 | - } | ||
2819 | - } | ||
2820 | - } | ||
2821 | - if (data32) { | ||
2822 | - /* 32 bit */ | ||
2823 | - stl(ptr, env->fpuc); | ||
2824 | - stl(ptr + 4, fpus); | ||
2825 | - stl(ptr + 8, fptag); | ||
2826 | - stl(ptr + 12, 0); | ||
2827 | - stl(ptr + 16, 0); | ||
2828 | - stl(ptr + 20, 0); | ||
2829 | - stl(ptr + 24, 0); | ||
2830 | - } else { | ||
2831 | - /* 16 bit */ | ||
2832 | - stw(ptr, env->fpuc); | ||
2833 | - stw(ptr + 2, fpus); | ||
2834 | - stw(ptr + 4, fptag); | ||
2835 | - stw(ptr + 6, 0); | ||
2836 | - stw(ptr + 8, 0); | ||
2837 | - stw(ptr + 10, 0); | ||
2838 | - stw(ptr + 12, 0); | ||
2839 | - } | ||
2840 | -} | ||
2841 | - | ||
2842 | -void helper_fldenv(uint8_t *ptr, int data32) | ||
2843 | -{ | ||
2844 | - int i, fpus, fptag; | ||
2845 | - | ||
2846 | - if (data32) { | ||
2847 | - env->fpuc = lduw(ptr); | ||
2848 | - fpus = lduw(ptr + 4); | ||
2849 | - fptag = lduw(ptr + 8); | ||
2850 | - } | ||
2851 | - else { | ||
2852 | - env->fpuc = lduw(ptr); | ||
2853 | - fpus = lduw(ptr + 2); | ||
2854 | - fptag = lduw(ptr + 4); | ||
2855 | - } | ||
2856 | - env->fpstt = (fpus >> 11) & 7; | ||
2857 | - env->fpus = fpus & ~0x3800; | ||
2858 | - for(i = 0;i < 7; i++) { | ||
2859 | - env->fptags[i] = ((fptag & 3) == 3); | ||
2860 | - fptag >>= 2; | ||
2861 | - } | ||
2862 | -} | ||
2863 | - | ||
2864 | -void helper_fsave(uint8_t *ptr, int data32) | ||
2865 | -{ | ||
2866 | - CPU86_LDouble tmp; | ||
2867 | - int i; | ||
2868 | - | ||
2869 | - helper_fstenv(ptr, data32); | ||
2870 | - | ||
2871 | - ptr += (14 << data32); | ||
2872 | - for(i = 0;i < 8; i++) { | ||
2873 | - tmp = ST(i); | ||
2874 | -#ifdef USE_X86LDOUBLE | ||
2875 | - *(long double *)ptr = tmp; | ||
2876 | -#else | ||
2877 | - helper_fstt(tmp, ptr); | ||
2878 | -#endif | ||
2879 | - ptr += 10; | ||
2880 | - } | ||
2881 | - | ||
2882 | - /* fninit */ | ||
2883 | - env->fpus = 0; | ||
2884 | - env->fpstt = 0; | ||
2885 | - env->fpuc = 0x37f; | ||
2886 | - env->fptags[0] = 1; | ||
2887 | - env->fptags[1] = 1; | ||
2888 | - env->fptags[2] = 1; | ||
2889 | - env->fptags[3] = 1; | ||
2890 | - env->fptags[4] = 1; | ||
2891 | - env->fptags[5] = 1; | ||
2892 | - env->fptags[6] = 1; | ||
2893 | - env->fptags[7] = 1; | ||
2894 | -} | ||
2895 | - | ||
2896 | -void helper_frstor(uint8_t *ptr, int data32) | ||
2897 | -{ | ||
2898 | - CPU86_LDouble tmp; | ||
2899 | - int i; | ||
2900 | - | ||
2901 | - helper_fldenv(ptr, data32); | ||
2902 | - ptr += (14 << data32); | ||
2903 | - | ||
2904 | - for(i = 0;i < 8; i++) { | ||
2905 | -#ifdef USE_X86LDOUBLE | ||
2906 | - tmp = *(long double *)ptr; | ||
2907 | -#else | ||
2908 | - tmp = helper_fldt(ptr); | ||
2909 | -#endif | ||
2910 | - ST(i) = tmp; | ||
2911 | - ptr += 10; | ||
2912 | - } | ||
2913 | -} | ||
2914 | - | ||
2915 | void OPPROTO op_fnstenv_A0(void) | 2081 | void OPPROTO op_fnstenv_A0(void) |
2916 | { | 2082 | { |
2917 | helper_fstenv((uint8_t *)A0, PARAM1); | 2083 | helper_fstenv((uint8_t *)A0, PARAM1); |
@@ -2942,3 +2108,4 @@ void OPPROTO op_unlock(void) | @@ -2942,3 +2108,4 @@ void OPPROTO op_unlock(void) | ||
2942 | { | 2108 | { |
2943 | cpu_unlock(); | 2109 | cpu_unlock(); |
2944 | } | 2110 | } |
2111 | + |