1 /*---------------------------------------------------------------------------+
4 | The entry functions for wm-FPU-emu |
6 | Copyright (C) 1992,1993,1994,1996,1997 |
7 | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
8 | E-mail billm@suburbia.net |
10 | See the files "README" and "COPYING" for further copyright and warranty |
13 +---------------------------------------------------------------------------*/
15 /*---------------------------------------------------------------------------+
17 | The file contains code which accesses user memory. |
18 | Emulator static data may change when user memory is accessed, due to |
19 | other processes using the emulator while swapping is in progress. |
20 +---------------------------------------------------------------------------*/
22 /*---------------------------------------------------------------------------+
23 | math_emulate(), restore_i387_soft() and save_i387_soft() are the only |
24 | entry points for wm-FPU-emu. |
25 +---------------------------------------------------------------------------*/
27 #include <linux/signal.h>
29 #include <asm/uaccess.h>
32 #include "fpu_system.h"
34 #include "exception.h"
35 #include "control_w.h"
38 #define __BAD__ FPU_illegal /* Illegal on an 80486, causes SIGILL */
40 #ifndef NO_UNDOC_CODE /* Un-documented FPU op-codes supported by default. */
42 /* WARNING: These codes are not documented by Intel in their 80486 manual
43 and may not work on FPU clones or later Intel FPUs. */
45 /* Changes to support the un-doc codes provided by Linus Torvalds. */
47 #define _d9_d8_ fstp_i /* unofficial code (19) */
48 #define _dc_d0_ fcom_st /* unofficial code (14) */
49 #define _dc_d8_ fcompst /* unofficial code (1c) */
50 #define _dd_c8_ fxch_i /* unofficial code (0d) */
51 #define _de_d0_ fcompst /* unofficial code (16) */
52 #define _df_c0_ ffreep /* unofficial code (07) ffree + pop */
53 #define _df_c8_ fxch_i /* unofficial code (0f) */
54 #define _df_d0_ fstp_i /* unofficial code (17) */
55 #define _df_d8_ fstp_i /* unofficial code (1f) */
57 static FUNC const st_instr_table[64] = {
58 fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, _df_c0_,
59 fmul__, fxch_i, __BAD__, __BAD__, fmul_i, _dd_c8_, fmulp_, _df_c8_,
60 fcom_st, fp_nop, __BAD__, __BAD__, _dc_d0_, fst_i_, _de_d0_, _df_d0_,
61 fcompst, _d9_d8_, __BAD__, __BAD__, _dc_d8_, fstp_i, fcompp, _df_d8_,
62 fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
63 fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
64 fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
65 fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
68 #else /* Support only documented FPU op-codes */
70 static FUNC const st_instr_table[64] = {
71 fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, __BAD__,
72 fmul__, fxch_i, __BAD__, __BAD__, fmul_i, __BAD__, fmulp_, __BAD__,
73 fcom_st, fp_nop, __BAD__, __BAD__, __BAD__, fst_i_, __BAD__, __BAD__,
74 fcompst, __BAD__, __BAD__, __BAD__, __BAD__, fstp_i, fcompp, __BAD__,
75 fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
76 fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
77 fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
78 fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
81 #endif /* NO_UNDOC_CODE */
84 #define _NONE_ 0 /* Take no special action */
85 #define _REG0_ 1 /* Need to check for not empty st(0) */
86 #define _REGI_ 2 /* Need to check for not empty st(0) and st(rm) */
87 #define _REGi_ 0 /* Uses st(rm) */
88 #define _PUSH_ 3 /* Need to check for space to push onto stack */
89 #define _null_ 4 /* Function illegal or not implemented */
90 #define _REGIi 5 /* Uses st(0) and st(rm), result to st(rm) */
91 #define _REGIp 6 /* Uses st(0) and st(rm), result to st(rm) then pop */
92 #define _REGIc 0 /* Compare st(0) and st(rm) */
93 #define _REGIn 0 /* Uses st(0) and st(rm), but handle checks later */
97 /* Un-documented FPU op-codes supported by default. (see above) */
99 static u_char const type_table[64] = {
100 _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _REGi_,
101 _REGI_, _REGIn, _null_, _null_, _REGIi, _REGI_, _REGIp, _REGI_,
102 _REGIc, _NONE_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
103 _REGIc, _REG0_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
104 _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
105 _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
106 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
107 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
110 #else /* Support only documented FPU op-codes */
112 static u_char const type_table[64] = {
113 _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _null_,
114 _REGI_, _REGIn, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
115 _REGIc, _NONE_, _null_, _null_, _null_, _REG0_, _null_, _null_,
116 _REGIc, _null_, _null_, _null_, _null_, _REG0_, _REGIc, _null_,
117 _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
118 _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
119 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
120 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
123 #endif /* NO_UNDOC_CODE */
126 #ifdef RE_ENTRANT_CHECKING
128 #endif /* RE_ENTRANT_CHECKING */
130 static int valid_prefix(u_char *Byte, u_char __user **fpu_eip,
131 overrides *override);
133 asmlinkage void math_emulate(long arg)
135 u_char FPU_modrm, byte1;
137 fpu_addr_modes addr_modes;
141 u_char loaded_tag, st0_tag;
142 void __user *data_address;
143 struct address data_sel_off;
144 struct address entry_sel_off;
145 unsigned long code_base = 0;
146 unsigned long code_limit = 0; /* Initialized to stop compiler warnings */
147 struct desc_struct code_descriptor;
149 #ifdef RE_ENTRANT_CHECKING
152 printk("ERROR: wm-FPU-emu is not RE-ENTRANT!\n");
155 #endif /* RE_ENTRANT_CHECKING */
163 SETUP_DATA_AREA(arg);
165 FPU_ORIG_EIP = FPU_EIP;
167 if ( (FPU_EFLAGS & 0x00020000) != 0 )
169 /* Virtual 8086 mode */
170 addr_modes.default_mode = VM86;
171 FPU_EIP += code_base = FPU_CS << 4;
172 code_limit = code_base + 0xffff; /* Assumes code_base <= 0xffff0000 */
174 else if ( FPU_CS == __USER_CS && FPU_DS == __USER_DS )
176 addr_modes.default_mode = 0;
178 else if ( FPU_CS == __KERNEL_CS )
180 printk("math_emulate: %04x:%08lx\n",FPU_CS,FPU_EIP);
181 panic("Math emulation needed in kernel");
186 if ( (FPU_CS & 4) != 4 ) /* Must be in the LDT */
188 /* Can only handle segmented addressing via the LDT
189 for now, and it must be 16 bit */
190 printk("FPU emulator: Unsupported addressing mode\n");
191 math_abort(FPU_info, SIGILL);
194 code_descriptor = LDT_DESCRIPTOR(FPU_CS);
195 if ( SEG_D_SIZE(code_descriptor) )
197 /* The above test may be wrong, the book is not clear */
198 /* Segmented 32 bit protected mode */
199 addr_modes.default_mode = SEG32;
203 /* 16 bit protected mode */
204 addr_modes.default_mode = PM16;
206 FPU_EIP += code_base = SEG_BASE_ADDR(code_descriptor);
207 code_limit = code_base
208 + (SEG_LIMIT(code_descriptor)+1) * SEG_GRANULARITY(code_descriptor)
210 if ( code_limit < code_base ) code_limit = 0xffffffff;
213 /* Don't run ahead if single-stepping. */
214 FPU_lookahead = (FPU_EFLAGS & X86_EFLAGS_TF) == 0;
216 if ( !valid_prefix(&byte1, (u_char __user **)&FPU_EIP,
217 &addr_modes.override) )
219 RE_ENTRANT_CHECK_OFF;
220 printk("FPU emulator: Unknown prefix byte 0x%02x, probably due to\n"
221 "FPU emulator: self-modifying code! (emulation impossible)\n",
224 EXCEPTION(EX_INTERNAL|0x126);
225 math_abort(FPU_info,SIGILL);
228 do_another_FPU_instruction:
232 FPU_EIP++; /* We have fetched the prefix and first code bytes. */
234 if ( addr_modes.default_mode )
236 /* This checks for the minimum instruction bytes.
237 We also need to check any extra (address mode) code access. */
238 if ( FPU_EIP > code_limit )
239 math_abort(FPU_info,SIGSEGV);
242 if ( (byte1 & 0xf8) != 0xd8 )
244 if ( byte1 == FWAIT_OPCODE )
246 if (partial_status & SW_Summary)
247 goto do_the_FPU_interrupt;
252 EXCEPTION(EX_INTERNAL|0x128);
253 math_abort(FPU_info,SIGILL);
254 #endif /* PARANOID */
257 RE_ENTRANT_CHECK_OFF;
258 FPU_code_access_ok(1);
259 FPU_get_user(FPU_modrm, (u_char __user *) FPU_EIP);
263 if (partial_status & SW_Summary)
265 /* Ignore the error for now if the current instruction is a no-wait
266 control instruction */
267 /* The 80486 manual contradicts itself on this topic,
268 but a real 80486 uses the following instructions:
269 fninit, fnstenv, fnsave, fnstsw, fnstenv, fnclex.
271 code = (FPU_modrm << 8) | byte1;
272 if ( ! ( (((code & 0xf803) == 0xe003) || /* fnclex, fninit, fnstsw */
273 (((code & 0x3003) == 0x3001) && /* fnsave, fnstcw, fnstenv,
275 ((code & 0xc000) != 0xc000))) ) )
278 * We need to simulate the action of the kernel to FPU
281 do_the_FPU_interrupt:
283 FPU_EIP = FPU_ORIG_EIP; /* Point to current FPU instruction. */
285 RE_ENTRANT_CHECK_OFF;
286 current->thread.trap_no = 16;
287 current->thread.error_code = 0;
288 send_sig(SIGFPE, current, 1);
293 entry_sel_off.offset = FPU_ORIG_EIP;
294 entry_sel_off.selector = FPU_CS;
295 entry_sel_off.opcode = (byte1 << 8) | FPU_modrm;
297 FPU_rm = FPU_modrm & 7;
299 if ( FPU_modrm < 0300 )
301 /* All of these instructions use the mod/rm byte to get a data address */
303 if ( (addr_modes.default_mode & SIXTEEN)
304 ^ (addr_modes.override.address_size == ADDR_SIZE_PREFIX) )
305 data_address = FPU_get_address_16(FPU_modrm, &FPU_EIP, &data_sel_off,
308 data_address = FPU_get_address(FPU_modrm, &FPU_EIP, &data_sel_off,
311 if ( addr_modes.default_mode )
313 if ( FPU_EIP-1 > code_limit )
314 math_abort(FPU_info,SIGSEGV);
319 unsigned short status1 = partial_status;
322 st0_tag = FPU_gettag0();
324 /* Stack underflow has priority */
327 if ( addr_modes.default_mode & PROTECTED )
329 /* This table works for 16 and 32 bit protected mode */
330 if ( access_limit < data_sizes_16[(byte1 >> 1) & 3] )
331 math_abort(FPU_info,SIGSEGV);
334 unmasked = 0; /* Do this here to stop compiler warnings. */
335 switch ( (byte1 >> 1) & 3 )
338 unmasked = FPU_load_single((float __user *)data_address,
340 loaded_tag = unmasked & 0xff;
344 loaded_tag = FPU_load_int32((long __user *)data_address, &loaded_data);
347 unmasked = FPU_load_double((double __user *)data_address,
349 loaded_tag = unmasked & 0xff;
353 default: /* Used here to suppress gcc warnings. */
354 loaded_tag = FPU_load_int16((short __user *)data_address, &loaded_data);
358 /* No more access to user memory, it is safe
359 to use static data now */
361 /* NaN operands have the next priority. */
362 /* We have to delay looking at st(0) until after
363 loading the data, because that data might contain an SNaN */
364 if ( ((st0_tag == TAG_Special) && isNaN(st0_ptr)) ||
365 ((loaded_tag == TAG_Special) && isNaN(&loaded_data)) )
367 /* Restore the status word; we might have loaded a
369 partial_status = status1;
370 if ( (FPU_modrm & 0x30) == 0x10 )
373 EXCEPTION(EX_Invalid);
374 setcc(SW_C3 | SW_C2 | SW_C0);
375 if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
376 FPU_pop(); /* fcomp, masked, so we pop. */
380 if ( loaded_tag == TAG_Special )
381 loaded_tag = FPU_Special(&loaded_data);
383 /* This is not really needed, but gives behaviour
384 identical to an 80486 */
385 if ( (FPU_modrm & 0x28) == 0x20 )
387 real_2op_NaN(&loaded_data, loaded_tag, 0, &loaded_data);
389 #endif /* PECULIAR_486 */
390 /* fadd, fdivr, fmul, or fsubr */
391 real_2op_NaN(&loaded_data, loaded_tag, 0, st0_ptr);
393 goto reg_mem_instr_done;
396 if ( unmasked && !((FPU_modrm & 0x30) == 0x10) )
398 /* Is not a comparison instruction. */
399 if ( (FPU_modrm & 0x38) == 0x38 )
402 if ( (st0_tag == TAG_Zero) &&
403 ((loaded_tag == TAG_Valid)
404 || (loaded_tag == TAG_Special
405 && isdenormal(&loaded_data))) )
407 if ( FPU_divide_by_zero(0, getsign(&loaded_data))
410 /* We use the fact here that the unmasked
411 exception in the loaded data was for a
413 /* Restore the state of the denormal op bit */
414 partial_status &= ~SW_Denorm_Op;
415 partial_status |= status1 & SW_Denorm_Op;
418 setsign(st0_ptr, getsign(&loaded_data));
421 goto reg_mem_instr_done;
424 switch ( (FPU_modrm >> 3) & 7 )
428 FPU_add(&loaded_data, loaded_tag, 0, control_word);
432 FPU_mul(&loaded_data, loaded_tag, 0, control_word);
435 FPU_compare_st_data(&loaded_data, loaded_tag);
438 if ( !FPU_compare_st_data(&loaded_data, loaded_tag)
444 FPU_sub(LOADED|loaded_tag, (int)&loaded_data, control_word);
448 FPU_sub(REV|LOADED|loaded_tag, (int)&loaded_data, control_word);
452 FPU_div(LOADED|loaded_tag, (int)&loaded_data, control_word);
456 if ( st0_tag == TAG_Zero )
457 partial_status = status1; /* Undo any denorm tag,
458 zero-divide has priority. */
459 FPU_div(REV|LOADED|loaded_tag, (int)&loaded_data, control_word);
465 if ( (FPU_modrm & 0x30) == 0x10 )
467 /* The instruction is fcom or fcomp */
468 EXCEPTION(EX_StackUnder);
469 setcc(SW_C3 | SW_C2 | SW_C0);
470 if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
471 FPU_pop(); /* fcomp */
474 FPU_stack_underflow();
477 operand_address = data_sel_off;
481 if ( !(no_ip_update =
482 FPU_load_store(((FPU_modrm & 0x38) | (byte1 & 6)) >> 1,
483 addr_modes, data_address)) )
485 operand_address = data_sel_off;
492 /* None of these instructions access user memory */
493 u_char instr_index = (FPU_modrm & 0x38) | (byte1 & 7);
496 /* This is supposed to be undefined, but a real 80486 seems
498 operand_address.offset = 0;
499 operand_address.selector = FPU_DS;
500 #endif /* PECULIAR_486 */
503 st0_tag = FPU_gettag0();
504 switch ( type_table[(int) instr_index] )
506 case _NONE_: /* also _REGIc: _REGIn */
509 if ( !NOT_EMPTY_ST0 )
511 FPU_stack_underflow();
512 goto FPU_instruction_done;
516 if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
518 FPU_stack_underflow_i(FPU_rm);
519 goto FPU_instruction_done;
523 if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
525 FPU_stack_underflow_pop(FPU_rm);
526 goto FPU_instruction_done;
530 if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
532 FPU_stack_underflow();
533 goto FPU_instruction_done;
536 case _PUSH_: /* Only used by the fld st(i) instruction */
540 goto FPU_instruction_done;
542 EXCEPTION(EX_INTERNAL|0x111);
543 goto FPU_instruction_done;
545 (*st_instr_table[(int) instr_index])();
547 FPU_instruction_done:
551 if ( ! no_ip_update )
552 instruction_address = entry_sel_off;
557 RE_ENTRANT_CHECK_OFF;
562 if (FPU_lookahead && !need_resched())
564 FPU_ORIG_EIP = FPU_EIP - code_base;
565 if ( valid_prefix(&byte1, (u_char __user **)&FPU_EIP,
566 &addr_modes.override) )
567 goto do_another_FPU_instruction;
570 if ( addr_modes.default_mode )
571 FPU_EIP -= code_base;
573 RE_ENTRANT_CHECK_OFF;
577 /* Support for prefix bytes is not yet complete. To properly handle
578 all prefix bytes, further changes are needed in the emulator code
579 which accesses user address space. Access to separate segments is
580 important for msdos emulation. */
581 static int valid_prefix(u_char *Byte, u_char __user **fpu_eip,
585 u_char __user *ip = *fpu_eip;
587 *override = (overrides) { 0, 0, PREFIX_DEFAULT }; /* defaults */
589 RE_ENTRANT_CHECK_OFF;
590 FPU_code_access_ok(1);
591 FPU_get_user(byte, ip);
598 case ADDR_SIZE_PREFIX:
599 override->address_size = ADDR_SIZE_PREFIX;
603 override->operand_size = OP_SIZE_PREFIX;
607 override->segment = PREFIX_CS_;
610 override->segment = PREFIX_ES_;
613 override->segment = PREFIX_SS_;
616 override->segment = PREFIX_FS_;
619 override->segment = PREFIX_GS_;
622 override->segment = PREFIX_DS_;
625 /* lock is not a valid prefix for FPU instructions,
626 let the cpu handle it to generate a SIGILL. */
627 /* case PREFIX_LOCK: */
629 /* rep.. prefixes have no meaning for FPU instructions */
635 RE_ENTRANT_CHECK_OFF;
636 FPU_code_access_ok(1);
637 FPU_get_user(byte, ip);
644 if ( (byte & 0xf8) == 0xd8 )
652 /* Not a valid sequence of prefix bytes followed by
653 an FPU instruction. */
654 *Byte = byte; /* Needed for error message. */
662 void math_abort(struct info * info, unsigned int signal)
664 FPU_EIP = FPU_ORIG_EIP;
665 current->thread.trap_no = 16;
666 current->thread.error_code = 0;
667 send_sig(signal,current,1);
668 RE_ENTRANT_CHECK_OFF;
669 __asm__("movl %0,%%esp ; ret": :"g" (((long) info)-4));
671 printk("ERROR: wm-FPU-emu math_abort failed!\n");
672 #endif /* PARANOID */
677 #define S387 ((struct i387_soft_struct *)s387)
678 #define sstatus_word() \
679 ((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top))
681 int restore_i387_soft(void *s387, struct _fpstate __user *buf)
683 u_char __user *d = (u_char __user *)buf;
684 int offset, other, i, tags, regnr, tag, newtop;
686 RE_ENTRANT_CHECK_OFF;
687 FPU_access_ok(VERIFY_READ, d, 7*4 + 8*10);
688 if (__copy_from_user(&S387->cwd, d, 7*4))
694 S387->ftop = (S387->swd >> SW_Top_Shift) & 7;
695 offset = (S387->ftop & 7) * 10;
698 RE_ENTRANT_CHECK_OFF;
699 /* Copy all registers in stack order. */
700 if (__copy_from_user(((u_char *)&S387->st_space)+offset, d, other))
703 if (__copy_from_user((u_char *)&S387->st_space, d+other, offset))
707 /* The tags may need to be corrected now. */
710 for ( i = 0; i < 8; i++ )
712 regnr = (i+newtop) & 7;
713 if ( ((tags >> ((regnr & 7)*2)) & 3) != TAG_Empty )
715 /* The loaded data over-rides all other cases. */
716 tag = FPU_tagof((FPU_REG *)((u_char *)S387->st_space + 10*regnr));
717 tags &= ~(3 << (regnr*2));
718 tags |= (tag & 3) << (regnr*2);
727 int save_i387_soft(void *s387, struct _fpstate __user * buf)
729 u_char __user *d = (u_char __user *)buf;
730 int offset = (S387->ftop & 7) * 10, other = 80 - offset;
732 RE_ENTRANT_CHECK_OFF;
733 FPU_access_ok(VERIFY_WRITE, d, 7*4 + 8*10);
735 S387->cwd &= ~0xe080;
736 /* An 80486 sets nearly all of the reserved bits to 1. */
737 S387->cwd |= 0xffff0040;
738 S387->swd = sstatus_word() | 0xffff0000;
739 S387->twd |= 0xffff0000;
740 S387->fcs &= ~0xf8000000;
741 S387->fos |= 0xffff0000;
742 #endif /* PECULIAR_486 */
743 if (__copy_to_user(d, &S387->cwd, 7*4))
749 RE_ENTRANT_CHECK_OFF;
750 /* Copy all registers in stack order. */
751 if (__copy_to_user(d, ((u_char *)&S387->st_space)+offset, other))
754 if (__copy_to_user(d+other, (u_char *)&S387->st_space, offset))