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>
28 #include <linux/ptrace.h>
30 #include <asm/uaccess.h>
33 #include "fpu_system.h"
35 #include "exception.h"
36 #include "control_w.h"
39 #define __BAD__ FPU_illegal /* Illegal on an 80486, causes SIGILL */
41 #ifndef NO_UNDOC_CODE /* Un-documented FPU op-codes supported by default. */
43 /* WARNING: These codes are not documented by Intel in their 80486 manual
44 and may not work on FPU clones or later Intel FPUs. */
46 /* Changes to support the un-doc codes provided by Linus Torvalds. */
48 #define _d9_d8_ fstp_i /* unofficial code (19) */
49 #define _dc_d0_ fcom_st /* unofficial code (14) */
50 #define _dc_d8_ fcompst /* unofficial code (1c) */
51 #define _dd_c8_ fxch_i /* unofficial code (0d) */
52 #define _de_d0_ fcompst /* unofficial code (16) */
53 #define _df_c0_ ffreep /* unofficial code (07) ffree + pop */
54 #define _df_c8_ fxch_i /* unofficial code (0f) */
55 #define _df_d0_ fstp_i /* unofficial code (17) */
56 #define _df_d8_ fstp_i /* unofficial code (1f) */
58 static FUNC const st_instr_table[64] = {
59 fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, _df_c0_,
60 fmul__, fxch_i, __BAD__, __BAD__, fmul_i, _dd_c8_, fmulp_, _df_c8_,
61 fcom_st, fp_nop, __BAD__, __BAD__, _dc_d0_, fst_i_, _de_d0_, _df_d0_,
62 fcompst, _d9_d8_, __BAD__, __BAD__, _dc_d8_, fstp_i, fcompp, _df_d8_,
63 fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
64 fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
65 fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
66 fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
69 #else /* Support only documented FPU op-codes */
71 static FUNC const st_instr_table[64] = {
72 fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, __BAD__,
73 fmul__, fxch_i, __BAD__, __BAD__, fmul_i, __BAD__, fmulp_, __BAD__,
74 fcom_st, fp_nop, __BAD__, __BAD__, __BAD__, fst_i_, __BAD__, __BAD__,
75 fcompst, __BAD__, __BAD__, __BAD__, __BAD__, fstp_i, fcompp, __BAD__,
76 fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
77 fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
78 fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
79 fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
82 #endif /* NO_UNDOC_CODE */
85 #define _NONE_ 0 /* Take no special action */
86 #define _REG0_ 1 /* Need to check for not empty st(0) */
87 #define _REGI_ 2 /* Need to check for not empty st(0) and st(rm) */
88 #define _REGi_ 0 /* Uses st(rm) */
89 #define _PUSH_ 3 /* Need to check for space to push onto stack */
90 #define _null_ 4 /* Function illegal or not implemented */
91 #define _REGIi 5 /* Uses st(0) and st(rm), result to st(rm) */
92 #define _REGIp 6 /* Uses st(0) and st(rm), result to st(rm) then pop */
93 #define _REGIc 0 /* Compare st(0) and st(rm) */
94 #define _REGIn 0 /* Uses st(0) and st(rm), but handle checks later */
98 /* Un-documented FPU op-codes supported by default. (see above) */
100 static u_char const type_table[64] = {
101 _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _REGi_,
102 _REGI_, _REGIn, _null_, _null_, _REGIi, _REGI_, _REGIp, _REGI_,
103 _REGIc, _NONE_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
104 _REGIc, _REG0_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
105 _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
106 _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
107 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
108 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
111 #else /* Support only documented FPU op-codes */
113 static u_char const type_table[64] = {
114 _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _null_,
115 _REGI_, _REGIn, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
116 _REGIc, _NONE_, _null_, _null_, _null_, _REG0_, _null_, _null_,
117 _REGIc, _null_, _null_, _null_, _null_, _REG0_, _REGIc, _null_,
118 _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
119 _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
120 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
121 _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
124 #endif /* NO_UNDOC_CODE */
127 #ifdef RE_ENTRANT_CHECKING
129 #endif /* RE_ENTRANT_CHECKING */
131 static int valid_prefix(u_char *Byte, u_char **fpu_eip,
132 overrides *override);
134 asmlinkage void math_emulate(long arg)
136 u_char FPU_modrm, byte1;
138 fpu_addr_modes addr_modes;
142 u_char loaded_tag, st0_tag;
144 struct address data_sel_off;
145 struct address entry_sel_off;
146 unsigned long code_base = 0;
147 unsigned long code_limit = 0; /* Initialized to stop compiler warnings */
148 struct desc_struct code_descriptor;
150 #ifdef RE_ENTRANT_CHECKING
153 printk("ERROR: wm-FPU-emu is not RE-ENTRANT!\n");
156 #endif /* RE_ENTRANT_CHECKING */
158 if (!current->used_math)
161 current->used_math = 1;
164 SETUP_DATA_AREA(arg);
166 FPU_ORIG_EIP = FPU_EIP;
168 if ( (FPU_EFLAGS & 0x00020000) != 0 )
170 /* Virtual 8086 mode */
171 addr_modes.default_mode = VM86;
172 FPU_EIP += code_base = FPU_CS << 4;
173 code_limit = code_base + 0xffff; /* Assumes code_base <= 0xffff0000 */
175 else if ( FPU_CS == __USER_CS && FPU_DS == __USER_DS )
177 addr_modes.default_mode = 0;
179 else if ( FPU_CS == __KERNEL_CS )
181 printk("math_emulate: %04x:%08lx\n",FPU_CS,FPU_EIP);
182 panic("Math emulation needed in kernel");
187 if ( (FPU_CS & 4) != 4 ) /* Must be in the LDT */
189 /* Can only handle segmented addressing via the LDT
190 for now, and it must be 16 bit */
191 printk("FPU emulator: Unsupported addressing mode\n");
192 math_abort(FPU_info, SIGILL);
195 if ( SEG_D_SIZE(code_descriptor = LDT_DESCRIPTOR(FPU_CS)) )
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;
214 if (current->ptrace & PT_PTRACED)
217 if ( !valid_prefix(&byte1, (u_char **)&FPU_EIP,
218 &addr_modes.override) )
220 RE_ENTRANT_CHECK_OFF;
221 printk("FPU emulator: Unknown prefix byte 0x%02x, probably due to\n"
222 "FPU emulator: self-modifying code! (emulation impossible)\n",
225 EXCEPTION(EX_INTERNAL|0x126);
226 math_abort(FPU_info,SIGILL);
229 do_another_FPU_instruction:
233 FPU_EIP++; /* We have fetched the prefix and first code bytes. */
235 if ( addr_modes.default_mode )
237 /* This checks for the minimum instruction bytes.
238 We also need to check any extra (address mode) code access. */
239 if ( FPU_EIP > code_limit )
240 math_abort(FPU_info,SIGSEGV);
243 if ( (byte1 & 0xf8) != 0xd8 )
245 if ( byte1 == FWAIT_OPCODE )
247 if (partial_status & SW_Summary)
248 goto do_the_FPU_interrupt;
253 EXCEPTION(EX_INTERNAL|0x128);
254 math_abort(FPU_info,SIGILL);
255 #endif /* PARANOID */
258 RE_ENTRANT_CHECK_OFF;
259 FPU_code_verify_area(1);
260 FPU_get_user(FPU_modrm, (u_char *) FPU_EIP);
264 if (partial_status & SW_Summary)
266 /* Ignore the error for now if the current instruction is a no-wait
267 control instruction */
268 /* The 80486 manual contradicts itself on this topic,
269 but a real 80486 uses the following instructions:
270 fninit, fnstenv, fnsave, fnstsw, fnstenv, fnclex.
272 code = (FPU_modrm << 8) | byte1;
273 if ( ! ( (((code & 0xf803) == 0xe003) || /* fnclex, fninit, fnstsw */
274 (((code & 0x3003) == 0x3001) && /* fnsave, fnstcw, fnstenv,
276 ((code & 0xc000) != 0xc000))) ) )
279 * We need to simulate the action of the kernel to FPU
282 do_the_FPU_interrupt:
284 FPU_EIP = FPU_ORIG_EIP; /* Point to current FPU instruction. */
286 RE_ENTRANT_CHECK_OFF;
287 current->thread.trap_no = 16;
288 current->thread.error_code = 0;
289 send_sig(SIGFPE, current, 1);
294 entry_sel_off.offset = FPU_ORIG_EIP;
295 entry_sel_off.selector = FPU_CS;
296 entry_sel_off.opcode = (byte1 << 8) | FPU_modrm;
298 FPU_rm = FPU_modrm & 7;
300 if ( FPU_modrm < 0300 )
302 /* All of these instructions use the mod/rm byte to get a data address */
304 if ( (addr_modes.default_mode & SIXTEEN)
305 ^ (addr_modes.override.address_size == ADDR_SIZE_PREFIX) )
306 data_address = FPU_get_address_16(FPU_modrm, &FPU_EIP, &data_sel_off,
309 data_address = FPU_get_address(FPU_modrm, &FPU_EIP, &data_sel_off,
312 if ( addr_modes.default_mode )
314 if ( FPU_EIP-1 > code_limit )
315 math_abort(FPU_info,SIGSEGV);
320 unsigned short status1 = partial_status;
323 st0_tag = FPU_gettag0();
325 /* Stack underflow has priority */
328 if ( addr_modes.default_mode & PROTECTED )
330 /* This table works for 16 and 32 bit protected mode */
331 if ( access_limit < data_sizes_16[(byte1 >> 1) & 3] )
332 math_abort(FPU_info,SIGSEGV);
335 unmasked = 0; /* Do this here to stop compiler warnings. */
336 switch ( (byte1 >> 1) & 3 )
339 unmasked = FPU_load_single((float *)data_address,
341 loaded_tag = unmasked & 0xff;
345 loaded_tag = FPU_load_int32((long *)data_address, &loaded_data);
348 unmasked = FPU_load_double((double *)data_address,
350 loaded_tag = unmasked & 0xff;
354 default: /* Used here to suppress gcc warnings. */
355 loaded_tag = FPU_load_int16((short *)data_address, &loaded_data);
359 /* No more access to user memory, it is safe
360 to use static data now */
362 /* NaN operands have the next priority. */
363 /* We have to delay looking at st(0) until after
364 loading the data, because that data might contain an SNaN */
365 if ( ((st0_tag == TAG_Special) && isNaN(st0_ptr)) ||
366 ((loaded_tag == TAG_Special) && isNaN(&loaded_data)) )
368 /* Restore the status word; we might have loaded a
370 partial_status = status1;
371 if ( (FPU_modrm & 0x30) == 0x10 )
374 EXCEPTION(EX_Invalid);
375 setcc(SW_C3 | SW_C2 | SW_C0);
376 if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
377 FPU_pop(); /* fcomp, masked, so we pop. */
381 if ( loaded_tag == TAG_Special )
382 loaded_tag = FPU_Special(&loaded_data);
384 /* This is not really needed, but gives behaviour
385 identical to an 80486 */
386 if ( (FPU_modrm & 0x28) == 0x20 )
388 real_2op_NaN(&loaded_data, loaded_tag, 0, &loaded_data);
390 #endif /* PECULIAR_486 */
391 /* fadd, fdivr, fmul, or fsubr */
392 real_2op_NaN(&loaded_data, loaded_tag, 0, st0_ptr);
394 goto reg_mem_instr_done;
397 if ( unmasked && !((FPU_modrm & 0x30) == 0x10) )
399 /* Is not a comparison instruction. */
400 if ( (FPU_modrm & 0x38) == 0x38 )
403 if ( (st0_tag == TAG_Zero) &&
404 ((loaded_tag == TAG_Valid)
405 || (loaded_tag == TAG_Special
406 && isdenormal(&loaded_data))) )
408 if ( FPU_divide_by_zero(0, getsign(&loaded_data))
411 /* We use the fact here that the unmasked
412 exception in the loaded data was for a
414 /* Restore the state of the denormal op bit */
415 partial_status &= ~SW_Denorm_Op;
416 partial_status |= status1 & SW_Denorm_Op;
419 setsign(st0_ptr, getsign(&loaded_data));
422 goto reg_mem_instr_done;
425 switch ( (FPU_modrm >> 3) & 7 )
429 FPU_add(&loaded_data, loaded_tag, 0, control_word);
433 FPU_mul(&loaded_data, loaded_tag, 0, control_word);
436 FPU_compare_st_data(&loaded_data, loaded_tag);
439 if ( !FPU_compare_st_data(&loaded_data, loaded_tag)
445 FPU_sub(LOADED|loaded_tag, (int)&loaded_data, control_word);
449 FPU_sub(REV|LOADED|loaded_tag, (int)&loaded_data, control_word);
453 FPU_div(LOADED|loaded_tag, (int)&loaded_data, control_word);
457 if ( st0_tag == TAG_Zero )
458 partial_status = status1; /* Undo any denorm tag,
459 zero-divide has priority. */
460 FPU_div(REV|LOADED|loaded_tag, (int)&loaded_data, control_word);
466 if ( (FPU_modrm & 0x30) == 0x10 )
468 /* The instruction is fcom or fcomp */
469 EXCEPTION(EX_StackUnder);
470 setcc(SW_C3 | SW_C2 | SW_C0);
471 if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
472 FPU_pop(); /* fcomp */
475 FPU_stack_underflow();
478 operand_address = data_sel_off;
482 if ( !(no_ip_update =
483 FPU_load_store(((FPU_modrm & 0x38) | (byte1 & 6)) >> 1,
484 addr_modes, data_address)) )
486 operand_address = data_sel_off;
493 /* None of these instructions access user memory */
494 u_char instr_index = (FPU_modrm & 0x38) | (byte1 & 7);
497 /* This is supposed to be undefined, but a real 80486 seems
499 operand_address.offset = 0;
500 operand_address.selector = FPU_DS;
501 #endif /* PECULIAR_486 */
504 st0_tag = FPU_gettag0();
505 switch ( type_table[(int) instr_index] )
507 case _NONE_: /* also _REGIc: _REGIn */
510 if ( !NOT_EMPTY_ST0 )
512 FPU_stack_underflow();
513 goto FPU_instruction_done;
517 if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
519 FPU_stack_underflow_i(FPU_rm);
520 goto FPU_instruction_done;
524 if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
526 FPU_stack_underflow_pop(FPU_rm);
527 goto FPU_instruction_done;
531 if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
533 FPU_stack_underflow();
534 goto FPU_instruction_done;
537 case _PUSH_: /* Only used by the fld st(i) instruction */
541 goto FPU_instruction_done;
543 EXCEPTION(EX_INTERNAL|0x111);
544 goto FPU_instruction_done;
546 (*st_instr_table[(int) instr_index])();
548 FPU_instruction_done:
552 if ( ! no_ip_update )
553 instruction_address = entry_sel_off;
558 RE_ENTRANT_CHECK_OFF;
563 if (FPU_lookahead && !need_resched())
565 FPU_ORIG_EIP = FPU_EIP - code_base;
566 if ( valid_prefix(&byte1, (u_char **)&FPU_EIP,
567 &addr_modes.override) )
568 goto do_another_FPU_instruction;
571 if ( addr_modes.default_mode )
572 FPU_EIP -= code_base;
574 RE_ENTRANT_CHECK_OFF;
578 /* Support for prefix bytes is not yet complete. To properly handle
579 all prefix bytes, further changes are needed in the emulator code
580 which accesses user address space. Access to separate segments is
581 important for msdos emulation. */
582 static int valid_prefix(u_char *Byte, u_char **fpu_eip,
586 u_char *ip = *fpu_eip;
588 *override = (overrides) { 0, 0, PREFIX_DEFAULT }; /* defaults */
590 RE_ENTRANT_CHECK_OFF;
591 FPU_code_verify_area(1);
592 FPU_get_user(byte, ip);
599 case ADDR_SIZE_PREFIX:
600 override->address_size = ADDR_SIZE_PREFIX;
604 override->operand_size = OP_SIZE_PREFIX;
608 override->segment = PREFIX_CS_;
611 override->segment = PREFIX_ES_;
614 override->segment = PREFIX_SS_;
617 override->segment = PREFIX_FS_;
620 override->segment = PREFIX_GS_;
623 override->segment = PREFIX_DS_;
626 /* lock is not a valid prefix for FPU instructions,
627 let the cpu handle it to generate a SIGILL. */
628 /* case PREFIX_LOCK: */
630 /* rep.. prefixes have no meaning for FPU instructions */
636 RE_ENTRANT_CHECK_OFF;
637 FPU_code_verify_area(1);
638 FPU_get_user(byte, ip);
645 if ( (byte & 0xf8) == 0xd8 )
653 /* Not a valid sequence of prefix bytes followed by
654 an FPU instruction. */
655 *Byte = byte; /* Needed for error message. */
663 void math_abort(struct info * info, unsigned int signal)
665 FPU_EIP = FPU_ORIG_EIP;
666 current->thread.trap_no = 16;
667 current->thread.error_code = 0;
668 send_sig(signal,current,1);
669 RE_ENTRANT_CHECK_OFF;
670 __asm__("movl %0,%%esp ; ret": :"g" (((long) info)-4));
672 printk("ERROR: wm-FPU-emu math_abort failed!\n");
673 #endif /* PARANOID */
678 #define S387 ((struct i387_soft_struct *)s387)
679 #define sstatus_word() \
680 ((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top))
682 int restore_i387_soft(void *s387, struct _fpstate *buf)
684 u_char *d = (u_char *)buf;
685 int offset, other, i, tags, regnr, tag, newtop;
687 RE_ENTRANT_CHECK_OFF;
688 FPU_verify_area(VERIFY_READ, d, 7*4 + 8*10);
689 if (__copy_from_user(&S387->cwd, d, 7*4))
695 S387->ftop = (S387->swd >> SW_Top_Shift) & 7;
696 offset = (S387->ftop & 7) * 10;
699 RE_ENTRANT_CHECK_OFF;
700 /* Copy all registers in stack order. */
701 if (__copy_from_user(((u_char *)&S387->st_space)+offset, d, other))
704 if (__copy_from_user((u_char *)&S387->st_space, d+other, offset))
708 /* The tags may need to be corrected now. */
711 for ( i = 0; i < 8; i++ )
713 regnr = (i+newtop) & 7;
714 if ( ((tags >> ((regnr & 7)*2)) & 3) != TAG_Empty )
716 /* The loaded data over-rides all other cases. */
717 tag = FPU_tagof((FPU_REG *)((u_char *)S387->st_space + 10*regnr));
718 tags &= ~(3 << (regnr*2));
719 tags |= (tag & 3) << (regnr*2);
728 int save_i387_soft(void *s387, struct _fpstate * buf)
730 u_char *d = (u_char *)buf;
731 int offset = (S387->ftop & 7) * 10, other = 80 - offset;
733 RE_ENTRANT_CHECK_OFF;
734 FPU_verify_area(VERIFY_WRITE, d, 7*4 + 8*10);
736 S387->cwd &= ~0xe080;
737 /* An 80486 sets nearly all of the reserved bits to 1. */
738 S387->cwd |= 0xffff0040;
739 S387->swd = sstatus_word() | 0xffff0000;
740 S387->twd |= 0xffff0000;
741 S387->fcs &= ~0xf8000000;
742 S387->fos |= 0xffff0000;
743 #endif /* PECULIAR_486 */
744 __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))