Linux Audio

Check our new training course

Loading...
v3.1
 
  1/*---------------------------------------------------------------------------+
  2 |  fpu_entry.c                                                              |
  3 |                                                                           |
  4 | The entry functions for wm-FPU-emu                                        |
  5 |                                                                           |
  6 | Copyright (C) 1992,1993,1994,1996,1997                                    |
  7 |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
  8 |                  E-mail   billm@suburbia.net                              |
  9 |                                                                           |
 10 | See the files "README" and "COPYING" for further copyright and warranty   |
 11 | information.                                                              |
 12 |                                                                           |
 13 +---------------------------------------------------------------------------*/
 14
 15/*---------------------------------------------------------------------------+
 16 | Note:                                                                     |
 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 +---------------------------------------------------------------------------*/
 21
 22/*---------------------------------------------------------------------------+
 23 | math_emulate(), restore_i387_soft() and save_i387_soft() are the only     |
 24 | entry points for wm-FPU-emu.                                              |
 25 +---------------------------------------------------------------------------*/
 26
 27#include <linux/signal.h>
 28#include <linux/regset.h>
 29
 30#include <asm/uaccess.h>
 31#include <asm/desc.h>
 32#include <asm/user.h>
 33#include <asm/i387.h>
 34
 35#include "fpu_system.h"
 36#include "fpu_emu.h"
 37#include "exception.h"
 38#include "control_w.h"
 39#include "status_w.h"
 40
 41#define __BAD__ FPU_illegal	/* Illegal on an 80486, causes SIGILL */
 42
 43#ifndef NO_UNDOC_CODE		/* Un-documented FPU op-codes supported by default. */
 44
 45/* WARNING: These codes are not documented by Intel in their 80486 manual
 46   and may not work on FPU clones or later Intel FPUs. */
 47
 48/* Changes to support the un-doc codes provided by Linus Torvalds. */
 49
 50#define _d9_d8_ fstp_i		/* unofficial code (19) */
 51#define _dc_d0_ fcom_st		/* unofficial code (14) */
 52#define _dc_d8_ fcompst		/* unofficial code (1c) */
 53#define _dd_c8_ fxch_i		/* unofficial code (0d) */
 54#define _de_d0_ fcompst		/* unofficial code (16) */
 55#define _df_c0_ ffreep		/* unofficial code (07) ffree + pop */
 56#define _df_c8_ fxch_i		/* unofficial code (0f) */
 57#define _df_d0_ fstp_i		/* unofficial code (17) */
 58#define _df_d8_ fstp_i		/* unofficial code (1f) */
 59
 60static FUNC const st_instr_table[64] = {
 61	fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, _df_c0_,
 62	fmul__, fxch_i, __BAD__, __BAD__, fmul_i, _dd_c8_, fmulp_, _df_c8_,
 63	fcom_st, fp_nop, __BAD__, __BAD__, _dc_d0_, fst_i_, _de_d0_, _df_d0_,
 64	fcompst, _d9_d8_, __BAD__, __BAD__, _dc_d8_, fstp_i, fcompp, _df_d8_,
 65	fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
 66	fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
 67	fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
 68	fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
 69};
 70
 71#else /* Support only documented FPU op-codes */
 72
 73static FUNC const st_instr_table[64] = {
 74	fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, __BAD__,
 75	fmul__, fxch_i, __BAD__, __BAD__, fmul_i, __BAD__, fmulp_, __BAD__,
 76	fcom_st, fp_nop, __BAD__, __BAD__, __BAD__, fst_i_, __BAD__, __BAD__,
 77	fcompst, __BAD__, __BAD__, __BAD__, __BAD__, fstp_i, fcompp, __BAD__,
 78	fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
 79	fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
 80	fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
 81	fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
 
 
 
 
 
 
 
 
 
 
 82};
 83
 84#endif /* NO_UNDOC_CODE */
 85
 86#define _NONE_ 0		/* Take no special action */
 87#define _REG0_ 1		/* Need to check for not empty st(0) */
 88#define _REGI_ 2		/* Need to check for not empty st(0) and st(rm) */
 89#define _REGi_ 0		/* Uses st(rm) */
 90#define _PUSH_ 3		/* Need to check for space to push onto stack */
 91#define _null_ 4		/* Function illegal or not implemented */
 92#define _REGIi 5		/* Uses st(0) and st(rm), result to st(rm) */
 93#define _REGIp 6		/* Uses st(0) and st(rm), result to st(rm) then pop */
 94#define _REGIc 0		/* Compare st(0) and st(rm) */
 95#define _REGIn 0		/* Uses st(0) and st(rm), but handle checks later */
 96
 97#ifndef NO_UNDOC_CODE
 98
 99/* Un-documented FPU op-codes supported by default. (see above) */
100
101static u_char const type_table[64] = {
102	_REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _REGi_,
103	_REGI_, _REGIn, _null_, _null_, _REGIi, _REGI_, _REGIp, _REGI_,
104	_REGIc, _NONE_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
105	_REGIc, _REG0_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
106	_REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
107	_REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
108	_REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
109	_REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
 
110};
111
112#else /* Support only documented FPU op-codes */
113
114static u_char const type_table[64] = {
115	_REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _null_,
116	_REGI_, _REGIn, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
117	_REGIc, _NONE_, _null_, _null_, _null_, _REG0_, _null_, _null_,
118	_REGIc, _null_, _null_, _null_, _null_, _REG0_, _REGIc, _null_,
119	_REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
120	_REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
121	_REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
122	_REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
123};
124
125#endif /* NO_UNDOC_CODE */
126
127#ifdef RE_ENTRANT_CHECKING
128u_char emulating = 0;
129#endif /* RE_ENTRANT_CHECKING */
130
131static int valid_prefix(u_char *Byte, u_char __user ** fpu_eip,
132			overrides * override);
133
134void math_emulate(struct math_emu_info *info)
135{
136	u_char FPU_modrm, byte1;
137	unsigned short code;
138	fpu_addr_modes addr_modes;
139	int unmasked;
140	FPU_REG loaded_data;
141	FPU_REG *st0_ptr;
142	u_char loaded_tag, st0_tag;
143	void __user *data_address;
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;
149
150	if (!used_math()) {
151		if (init_fpu(current)) {
152			do_group_exit(SIGKILL);
153			return;
154		}
155	}
156
157#ifdef RE_ENTRANT_CHECKING
158	if (emulating) {
159		printk("ERROR: wm-FPU-emu is not RE-ENTRANT!\n");
160	}
161	RE_ENTRANT_CHECK_ON;
162#endif /* RE_ENTRANT_CHECKING */
163
164	FPU_info = info;
165
166	FPU_ORIG_EIP = FPU_EIP;
167
168	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 */
173	} else if (FPU_CS == __USER_CS && FPU_DS == __USER_DS) {
174		addr_modes.default_mode = 0;
175	} else if (FPU_CS == __KERNEL_CS) {
176		printk("math_emulate: %04x:%08lx\n", FPU_CS, FPU_EIP);
177		panic("Math emulation needed in kernel");
178	} else {
179
180		if ((FPU_CS & 4) != 4) {	/* Must be in the LDT */
181			/* Can only handle segmented addressing via the LDT
182			   for now, and it must be 16 bit */
183			printk("FPU emulator: Unsupported addressing mode\n");
184			math_abort(FPU_info, SIGILL);
185		}
186
187		code_descriptor = LDT_DESCRIPTOR(FPU_CS);
188		if (SEG_D_SIZE(code_descriptor)) {
189			/* The above test may be wrong, the book is not clear */
190			/* Segmented 32 bit protected mode */
191			addr_modes.default_mode = SEG32;
192		} else {
193			/* 16 bit protected mode */
194			addr_modes.default_mode = PM16;
195		}
196		FPU_EIP += code_base = SEG_BASE_ADDR(code_descriptor);
197		code_limit = code_base
198		    + (SEG_LIMIT(code_descriptor) +
199		       1) * SEG_GRANULARITY(code_descriptor)
200		    - 1;
201		if (code_limit < code_base)
202			code_limit = 0xffffffff;
203	}
204
205	FPU_lookahead = !(FPU_EFLAGS & X86_EFLAGS_TF);
206
207	if (!valid_prefix(&byte1, (u_char __user **) & FPU_EIP,
208			  &addr_modes.override)) {
209		RE_ENTRANT_CHECK_OFF;
210		printk
211		    ("FPU emulator: Unknown prefix byte 0x%02x, probably due to\n"
212		     "FPU emulator: self-modifying code! (emulation impossible)\n",
213		     byte1);
214		RE_ENTRANT_CHECK_ON;
215		EXCEPTION(EX_INTERNAL | 0x126);
216		math_abort(FPU_info, SIGILL);
217	}
218
219      do_another_FPU_instruction:
220
221	no_ip_update = 0;
222
223	FPU_EIP++;		/* We have fetched the prefix and first code bytes. */
224
225	if (addr_modes.default_mode) {
226		/* This checks for the minimum instruction bytes.
227		   We also need to check any extra (address mode) code access. */
228		if (FPU_EIP > code_limit)
229			math_abort(FPU_info, SIGSEGV);
230	}
231
232	if ((byte1 & 0xf8) != 0xd8) {
233		if (byte1 == FWAIT_OPCODE) {
234			if (partial_status & SW_Summary)
235				goto do_the_FPU_interrupt;
236			else
237				goto FPU_fwait_done;
238		}
239#ifdef PARANOID
240		EXCEPTION(EX_INTERNAL | 0x128);
241		math_abort(FPU_info, SIGILL);
242#endif /* PARANOID */
243	}
244
245	RE_ENTRANT_CHECK_OFF;
246	FPU_code_access_ok(1);
247	FPU_get_user(FPU_modrm, (u_char __user *) FPU_EIP);
248	RE_ENTRANT_CHECK_ON;
249	FPU_EIP++;
250
251	if (partial_status & SW_Summary) {
252		/* Ignore the error for now if the current instruction is a no-wait
253		   control instruction */
254		/* The 80486 manual contradicts itself on this topic,
255		   but a real 80486 uses the following instructions:
256		   fninit, fnstenv, fnsave, fnstsw, fnstenv, fnclex.
257		 */
258		code = (FPU_modrm << 8) | byte1;
259		if (!((((code & 0xf803) == 0xe003) ||	/* fnclex, fninit, fnstsw */
260		       (((code & 0x3003) == 0x3001) &&	/* fnsave, fnstcw, fnstenv,
261							   fnstsw */
262			((code & 0xc000) != 0xc000))))) {
263			/*
264			 *  We need to simulate the action of the kernel to FPU
265			 *  interrupts here.
266			 */
267		      do_the_FPU_interrupt:
268
269			FPU_EIP = FPU_ORIG_EIP;	/* Point to current FPU instruction. */
270
271			RE_ENTRANT_CHECK_OFF;
272			current->thread.trap_no = 16;
273			current->thread.error_code = 0;
274			send_sig(SIGFPE, current, 1);
275			return;
276		}
277	}
278
279	entry_sel_off.offset = FPU_ORIG_EIP;
280	entry_sel_off.selector = FPU_CS;
281	entry_sel_off.opcode = (byte1 << 8) | FPU_modrm;
282	entry_sel_off.empty = 0;
283
284	FPU_rm = FPU_modrm & 7;
285
286	if (FPU_modrm < 0300) {
287		/* All of these instructions use the mod/rm byte to get a data address */
288
289		if ((addr_modes.default_mode & SIXTEEN)
290		    ^ (addr_modes.override.address_size == ADDR_SIZE_PREFIX))
291			data_address =
292			    FPU_get_address_16(FPU_modrm, &FPU_EIP,
293					       &data_sel_off, addr_modes);
294		else
295			data_address =
296			    FPU_get_address(FPU_modrm, &FPU_EIP, &data_sel_off,
297					    addr_modes);
298
299		if (addr_modes.default_mode) {
300			if (FPU_EIP - 1 > code_limit)
301				math_abort(FPU_info, SIGSEGV);
302		}
303
304		if (!(byte1 & 1)) {
305			unsigned short status1 = partial_status;
306
307			st0_ptr = &st(0);
308			st0_tag = FPU_gettag0();
309
310			/* Stack underflow has priority */
311			if (NOT_EMPTY_ST0) {
312				if (addr_modes.default_mode & PROTECTED) {
313					/* This table works for 16 and 32 bit protected mode */
314					if (access_limit <
315					    data_sizes_16[(byte1 >> 1) & 3])
316						math_abort(FPU_info, SIGSEGV);
317				}
318
319				unmasked = 0;	/* Do this here to stop compiler warnings. */
320				switch ((byte1 >> 1) & 3) {
321				case 0:
322					unmasked =
323					    FPU_load_single((float __user *)
324							    data_address,
325							    &loaded_data);
326					loaded_tag = unmasked & 0xff;
327					unmasked &= ~0xff;
328					break;
329				case 1:
330					loaded_tag =
331					    FPU_load_int32((long __user *)
332							   data_address,
333							   &loaded_data);
334					break;
335				case 2:
336					unmasked =
337					    FPU_load_double((double __user *)
338							    data_address,
339							    &loaded_data);
340					loaded_tag = unmasked & 0xff;
341					unmasked &= ~0xff;
342					break;
343				case 3:
344				default:	/* Used here to suppress gcc warnings. */
345					loaded_tag =
346					    FPU_load_int16((short __user *)
347							   data_address,
348							   &loaded_data);
349					break;
350				}
351
352				/* No more access to user memory, it is safe
353				   to use static data now */
354
355				/* NaN operands have the next priority. */
356				/* We have to delay looking at st(0) until after
357				   loading the data, because that data might contain an SNaN */
358				if (((st0_tag == TAG_Special) && isNaN(st0_ptr))
359				    || ((loaded_tag == TAG_Special)
360					&& isNaN(&loaded_data))) {
361					/* Restore the status word; we might have loaded a
362					   denormal. */
363					partial_status = status1;
364					if ((FPU_modrm & 0x30) == 0x10) {
365						/* fcom or fcomp */
366						EXCEPTION(EX_Invalid);
367						setcc(SW_C3 | SW_C2 | SW_C0);
368						if ((FPU_modrm & 0x08)
369						    && (control_word &
370							CW_Invalid))
371							FPU_pop();	/* fcomp, masked, so we pop. */
372					} else {
373						if (loaded_tag == TAG_Special)
374							loaded_tag =
375							    FPU_Special
376							    (&loaded_data);
377#ifdef PECULIAR_486
378						/* This is not really needed, but gives behaviour
379						   identical to an 80486 */
380						if ((FPU_modrm & 0x28) == 0x20)
381							/* fdiv or fsub */
382							real_2op_NaN
383							    (&loaded_data,
384							     loaded_tag, 0,
385							     &loaded_data);
386						else
387#endif /* PECULIAR_486 */
388							/* fadd, fdivr, fmul, or fsubr */
389							real_2op_NaN
390							    (&loaded_data,
391							     loaded_tag, 0,
392							     st0_ptr);
393					}
394					goto reg_mem_instr_done;
395				}
396
397				if (unmasked && !((FPU_modrm & 0x30) == 0x10)) {
398					/* Is not a comparison instruction. */
399					if ((FPU_modrm & 0x38) == 0x38) {
400						/* fdivr */
401						if ((st0_tag == TAG_Zero) &&
402						    ((loaded_tag == TAG_Valid)
403						     || (loaded_tag ==
404							 TAG_Special
405							 &&
406							 isdenormal
407							 (&loaded_data)))) {
408							if (FPU_divide_by_zero
409							    (0,
410							     getsign
411							     (&loaded_data))
412							    < 0) {
413								/* We use the fact here that the unmasked
414								   exception in the loaded data was for a
415								   denormal operand */
416								/* Restore the state of the denormal op bit */
417								partial_status
418								    &=
419								    ~SW_Denorm_Op;
420								partial_status
421								    |=
422								    status1 &
423								    SW_Denorm_Op;
424							} else
425								setsign(st0_ptr,
426									getsign
427									(&loaded_data));
428						}
429					}
430					goto reg_mem_instr_done;
431				}
432
433				switch ((FPU_modrm >> 3) & 7) {
434				case 0:	/* fadd */
435					clear_C1();
436					FPU_add(&loaded_data, loaded_tag, 0,
437						control_word);
438					break;
439				case 1:	/* fmul */
440					clear_C1();
441					FPU_mul(&loaded_data, loaded_tag, 0,
442						control_word);
443					break;
444				case 2:	/* fcom */
445					FPU_compare_st_data(&loaded_data,
446							    loaded_tag);
447					break;
448				case 3:	/* fcomp */
449					if (!FPU_compare_st_data
450					    (&loaded_data, loaded_tag)
451					    && !unmasked)
452						FPU_pop();
453					break;
454				case 4:	/* fsub */
455					clear_C1();
456					FPU_sub(LOADED | loaded_tag,
457						(int)&loaded_data,
458						control_word);
459					break;
460				case 5:	/* fsubr */
461					clear_C1();
462					FPU_sub(REV | LOADED | loaded_tag,
463						(int)&loaded_data,
464						control_word);
465					break;
466				case 6:	/* fdiv */
467					clear_C1();
468					FPU_div(LOADED | loaded_tag,
469						(int)&loaded_data,
470						control_word);
471					break;
472				case 7:	/* fdivr */
473					clear_C1();
474					if (st0_tag == TAG_Zero)
475						partial_status = status1;	/* Undo any denorm tag,
476										   zero-divide has priority. */
477					FPU_div(REV | LOADED | loaded_tag,
478						(int)&loaded_data,
479						control_word);
480					break;
481				}
482			} else {
483				if ((FPU_modrm & 0x30) == 0x10) {
484					/* The instruction is fcom or fcomp */
485					EXCEPTION(EX_StackUnder);
486					setcc(SW_C3 | SW_C2 | SW_C0);
487					if ((FPU_modrm & 0x08)
488					    && (control_word & CW_Invalid))
489						FPU_pop();	/* fcomp */
490				} else
491					FPU_stack_underflow();
492			}
493		      reg_mem_instr_done:
494			operand_address = data_sel_off;
495		} else {
496			if (!(no_ip_update =
497			      FPU_load_store(((FPU_modrm & 0x38) | (byte1 & 6))
498					     >> 1, addr_modes, data_address))) {
499				operand_address = data_sel_off;
500			}
501		}
502
503	} else {
504		/* None of these instructions access user memory */
505		u_char instr_index = (FPU_modrm & 0x38) | (byte1 & 7);
506
507#ifdef PECULIAR_486
508		/* This is supposed to be undefined, but a real 80486 seems
509		   to do this: */
510		operand_address.offset = 0;
511		operand_address.selector = FPU_DS;
512#endif /* PECULIAR_486 */
513
514		st0_ptr = &st(0);
515		st0_tag = FPU_gettag0();
516		switch (type_table[(int)instr_index]) {
517		case _NONE_:	/* also _REGIc: _REGIn */
518			break;
519		case _REG0_:
520			if (!NOT_EMPTY_ST0) {
521				FPU_stack_underflow();
522				goto FPU_instruction_done;
523			}
524			break;
525		case _REGIi:
526			if (!NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm)) {
527				FPU_stack_underflow_i(FPU_rm);
528				goto FPU_instruction_done;
529			}
530			break;
531		case _REGIp:
532			if (!NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm)) {
533				FPU_stack_underflow_pop(FPU_rm);
534				goto FPU_instruction_done;
535			}
536			break;
537		case _REGI_:
538			if (!NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm)) {
539				FPU_stack_underflow();
540				goto FPU_instruction_done;
541			}
542			break;
543		case _PUSH_:	/* Only used by the fld st(i) instruction */
544			break;
545		case _null_:
546			FPU_illegal();
547			goto FPU_instruction_done;
548		default:
549			EXCEPTION(EX_INTERNAL | 0x111);
550			goto FPU_instruction_done;
551		}
552		(*st_instr_table[(int)instr_index]) ();
553
554	      FPU_instruction_done:
555		;
556	}
557
558	if (!no_ip_update)
559		instruction_address = entry_sel_off;
560
561      FPU_fwait_done:
562
563#ifdef DEBUG
564	RE_ENTRANT_CHECK_OFF;
565	FPU_printall();
566	RE_ENTRANT_CHECK_ON;
567#endif /* DEBUG */
568
569	if (FPU_lookahead && !need_resched()) {
570		FPU_ORIG_EIP = FPU_EIP - code_base;
571		if (valid_prefix(&byte1, (u_char __user **) & FPU_EIP,
572				 &addr_modes.override))
573			goto do_another_FPU_instruction;
574	}
575
576	if (addr_modes.default_mode)
577		FPU_EIP -= code_base;
578
579	RE_ENTRANT_CHECK_OFF;
580}
581
582/* Support for prefix bytes is not yet complete. To properly handle
583   all prefix bytes, further changes are needed in the emulator code
584   which accesses user address space. Access to separate segments is
585   important for msdos emulation. */
586static int valid_prefix(u_char *Byte, u_char __user **fpu_eip,
587			overrides * override)
588{
589	u_char byte;
590	u_char __user *ip = *fpu_eip;
591
592	*override = (overrides) {
593	0, 0, PREFIX_DEFAULT};	/* defaults */
594
595	RE_ENTRANT_CHECK_OFF;
596	FPU_code_access_ok(1);
597	FPU_get_user(byte, ip);
598	RE_ENTRANT_CHECK_ON;
599
600	while (1) {
601		switch (byte) {
602		case ADDR_SIZE_PREFIX:
603			override->address_size = ADDR_SIZE_PREFIX;
604			goto do_next_byte;
605
606		case OP_SIZE_PREFIX:
607			override->operand_size = OP_SIZE_PREFIX;
608			goto do_next_byte;
609
610		case PREFIX_CS:
611			override->segment = PREFIX_CS_;
612			goto do_next_byte;
613		case PREFIX_ES:
614			override->segment = PREFIX_ES_;
615			goto do_next_byte;
616		case PREFIX_SS:
617			override->segment = PREFIX_SS_;
618			goto do_next_byte;
619		case PREFIX_FS:
620			override->segment = PREFIX_FS_;
621			goto do_next_byte;
622		case PREFIX_GS:
623			override->segment = PREFIX_GS_;
624			goto do_next_byte;
625		case PREFIX_DS:
626			override->segment = PREFIX_DS_;
627			goto do_next_byte;
628
629/* lock is not a valid prefix for FPU instructions,
630   let the cpu handle it to generate a SIGILL. */
631/*	case PREFIX_LOCK: */
632
633			/* rep.. prefixes have no meaning for FPU instructions */
634		case PREFIX_REPE:
635		case PREFIX_REPNE:
636
637		      do_next_byte:
638			ip++;
639			RE_ENTRANT_CHECK_OFF;
640			FPU_code_access_ok(1);
641			FPU_get_user(byte, ip);
642			RE_ENTRANT_CHECK_ON;
643			break;
644		case FWAIT_OPCODE:
645			*Byte = byte;
646			return 1;
647		default:
648			if ((byte & 0xf8) == 0xd8) {
649				*Byte = byte;
650				*fpu_eip = ip;
651				return 1;
652			} else {
653				/* Not a valid sequence of prefix bytes followed by
654				   an FPU instruction. */
655				*Byte = byte;	/* Needed for error message. */
656				return 0;
657			}
658		}
659	}
660}
661
662void math_abort(struct math_emu_info *info, unsigned int signal)
663{
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));
670#ifdef PARANOID
671	printk("ERROR: wm-FPU-emu math_abort failed!\n");
672#endif /* PARANOID */
673}
674
675#define S387 ((struct i387_soft_struct *)s387)
676#define sstatus_word() \
677  ((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top))
678
679int fpregs_soft_set(struct task_struct *target,
680		    const struct user_regset *regset,
681		    unsigned int pos, unsigned int count,
682		    const void *kbuf, const void __user *ubuf)
683{
684	struct i387_soft_struct *s387 = &target->thread.fpu.state->soft;
685	void *space = s387->st_space;
686	int ret;
687	int offset, other, i, tags, regnr, tag, newtop;
688
689	RE_ENTRANT_CHECK_OFF;
690	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, s387, 0,
691				 offsetof(struct i387_soft_struct, st_space));
692	RE_ENTRANT_CHECK_ON;
693
694	if (ret)
695		return ret;
696
697	S387->ftop = (S387->swd >> SW_Top_Shift) & 7;
698	offset = (S387->ftop & 7) * 10;
699	other = 80 - offset;
700
701	RE_ENTRANT_CHECK_OFF;
702
703	/* Copy all registers in stack order. */
704	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
705				 space + offset, 0, other);
706	if (!ret && offset)
707		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
708					 space, 0, offset);
709
710	RE_ENTRANT_CHECK_ON;
711
712	/* The tags may need to be corrected now. */
713	tags = S387->twd;
714	newtop = S387->ftop;
715	for (i = 0; i < 8; i++) {
716		regnr = (i + newtop) & 7;
717		if (((tags >> ((regnr & 7) * 2)) & 3) != TAG_Empty) {
718			/* The loaded data over-rides all other cases. */
719			tag =
720			    FPU_tagof((FPU_REG *) ((u_char *) S387->st_space +
721						   10 * regnr));
722			tags &= ~(3 << (regnr * 2));
723			tags |= (tag & 3) << (regnr * 2);
724		}
725	}
726	S387->twd = tags;
727
728	return ret;
729}
730
731int fpregs_soft_get(struct task_struct *target,
732		    const struct user_regset *regset,
733		    unsigned int pos, unsigned int count,
734		    void *kbuf, void __user *ubuf)
735{
736	struct i387_soft_struct *s387 = &target->thread.fpu.state->soft;
737	const void *space = s387->st_space;
738	int ret;
739	int offset = (S387->ftop & 7) * 10, other = 80 - offset;
740
741	RE_ENTRANT_CHECK_OFF;
742
743#ifdef PECULIAR_486
744	S387->cwd &= ~0xe080;
745	/* An 80486 sets nearly all of the reserved bits to 1. */
746	S387->cwd |= 0xffff0040;
747	S387->swd = sstatus_word() | 0xffff0000;
748	S387->twd |= 0xffff0000;
749	S387->fcs &= ~0xf8000000;
750	S387->fos |= 0xffff0000;
751#endif /* PECULIAR_486 */
752
753	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, s387, 0,
754				  offsetof(struct i387_soft_struct, st_space));
755
756	/* Copy all registers in stack order. */
757	if (!ret)
758		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
759					  space + offset, 0, other);
760	if (!ret)
761		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
762					  space, 0, offset);
763
764	RE_ENTRANT_CHECK_ON;
765
766	return ret;
767}
v5.9
  1// SPDX-License-Identifier: GPL-2.0
  2/*---------------------------------------------------------------------------+
  3 |  fpu_entry.c                                                              |
  4 |                                                                           |
  5 | The entry functions for wm-FPU-emu                                        |
  6 |                                                                           |
  7 | Copyright (C) 1992,1993,1994,1996,1997                                    |
  8 |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
  9 |                  E-mail   billm@suburbia.net                              |
 10 |                                                                           |
 11 | See the files "README" and "COPYING" for further copyright and warranty   |
 12 | information.                                                              |
 13 |                                                                           |
 14 +---------------------------------------------------------------------------*/
 15
 16/*---------------------------------------------------------------------------+
 17 | Note:                                                                     |
 18 |    The file contains code which accesses user memory.                     |
 19 |    Emulator static data may change when user memory is accessed, due to   |
 20 |    other processes using the emulator while swapping is in progress.      |
 21 +---------------------------------------------------------------------------*/
 22
 23/*---------------------------------------------------------------------------+
 24 | math_emulate(), restore_i387_soft() and save_i387_soft() are the only     |
 25 | entry points for wm-FPU-emu.                                              |
 26 +---------------------------------------------------------------------------*/
 27
 28#include <linux/signal.h>
 29#include <linux/regset.h>
 30
 31#include <linux/uaccess.h>
 32#include <asm/traps.h>
 33#include <asm/user.h>
 34#include <asm/fpu/internal.h>
 35
 36#include "fpu_system.h"
 37#include "fpu_emu.h"
 38#include "exception.h"
 39#include "control_w.h"
 40#include "status_w.h"
 41
 42#define __BAD__ FPU_illegal	/* Illegal on an 80486, causes SIGILL */
 43
 44/* fcmovCC and f(u)comi(p) are enabled if CPUID(1).EDX(15) "cmov" is set */
 45
 46/* WARNING: "u" entries are not documented by Intel in their 80486 manual
 47   and may not work on FPU clones or later Intel FPUs.
 48   Changes to support them provided by Linus Torvalds. */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 49
 50static FUNC const st_instr_table[64] = {
 51/* Opcode:	d8		d9		da		db */
 52/*		dc		dd		de		df */
 53/* c0..7 */	fadd__,		fld_i_,		fcmovb,		fcmovnb,
 54/* c0..7 */	fadd_i,		ffree_,		faddp_,		ffreep,/*u*/
 55/* c8..f */	fmul__,		fxch_i,		fcmove,		fcmovne,
 56/* c8..f */	fmul_i,		fxch_i,/*u*/	fmulp_,		fxch_i,/*u*/
 57/* d0..7 */	fcom_st,	fp_nop,		fcmovbe,	fcmovnbe,
 58/* d0..7 */	fcom_st,/*u*/	fst_i_,		fcompst,/*u*/	fstp_i,/*u*/
 59/* d8..f */	fcompst,	fstp_i,/*u*/	fcmovu,		fcmovnu,
 60/* d8..f */	fcompst,/*u*/	fstp_i,		fcompp,		fstp_i,/*u*/
 61/* e0..7 */	fsub__,		FPU_etc,	__BAD__,	finit_,
 62/* e0..7 */	fsubri,		fucom_,		fsubrp,		fstsw_,
 63/* e8..f */	fsubr_,		fconst,		fucompp,	fucomi_,
 64/* e8..f */	fsub_i,		fucomp,		fsubp_,		fucomip,
 65/* f0..7 */	fdiv__,		FPU_triga,	__BAD__,	fcomi_,
 66/* f0..7 */	fdivri,		__BAD__,	fdivrp,		fcomip,
 67/* f8..f */	fdivr_,		FPU_trigb,	__BAD__,	__BAD__,
 68/* f8..f */	fdiv_i,		__BAD__,	fdivp_,		__BAD__,
 69};
 70
 
 
 71#define _NONE_ 0		/* Take no special action */
 72#define _REG0_ 1		/* Need to check for not empty st(0) */
 73#define _REGI_ 2		/* Need to check for not empty st(0) and st(rm) */
 74#define _REGi_ 0		/* Uses st(rm) */
 75#define _PUSH_ 3		/* Need to check for space to push onto stack */
 76#define _null_ 4		/* Function illegal or not implemented */
 77#define _REGIi 5		/* Uses st(0) and st(rm), result to st(rm) */
 78#define _REGIp 6		/* Uses st(0) and st(rm), result to st(rm) then pop */
 79#define _REGIc 0		/* Compare st(0) and st(rm) */
 80#define _REGIn 0		/* Uses st(0) and st(rm), but handle checks later */
 81
 
 
 
 
 82static u_char const type_table[64] = {
 83/* Opcode:	d8	d9	da	db	dc	dd	de	df */
 84/* c0..7 */	_REGI_, _NONE_, _REGIn, _REGIn, _REGIi, _REGi_, _REGIp, _REGi_,
 85/* c8..f */	_REGI_, _REGIn, _REGIn, _REGIn, _REGIi, _REGI_, _REGIp, _REGI_,
 86/* d0..7 */	_REGIc, _NONE_, _REGIn, _REGIn, _REGIc, _REG0_, _REGIc, _REG0_,
 87/* d8..f */	_REGIc, _REG0_, _REGIn, _REGIn, _REGIc, _REG0_, _REGIc, _REG0_,
 88/* e0..7 */	_REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
 89/* e8..f */	_REGI_, _NONE_, _REGIc, _REGIc, _REGIi, _REGIc, _REGIp, _REGIc,
 90/* f0..7 */	_REGI_, _NONE_, _null_, _REGIc, _REGIi, _null_, _REGIp, _REGIc,
 91/* f8..f */	_REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
 92};
 93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 94#ifdef RE_ENTRANT_CHECKING
 95u_char emulating = 0;
 96#endif /* RE_ENTRANT_CHECKING */
 97
 98static int valid_prefix(u_char *Byte, u_char __user ** fpu_eip,
 99			overrides * override);
100
101void math_emulate(struct math_emu_info *info)
102{
103	u_char FPU_modrm, byte1;
104	unsigned short code;
105	fpu_addr_modes addr_modes;
106	int unmasked;
107	FPU_REG loaded_data;
108	FPU_REG *st0_ptr;
109	u_char loaded_tag, st0_tag;
110	void __user *data_address;
111	struct address data_sel_off;
112	struct address entry_sel_off;
113	unsigned long code_base = 0;
114	unsigned long code_limit = 0;	/* Initialized to stop compiler warnings */
115	struct desc_struct code_descriptor;
116
 
 
 
 
 
 
 
117#ifdef RE_ENTRANT_CHECKING
118	if (emulating) {
119		printk("ERROR: wm-FPU-emu is not RE-ENTRANT!\n");
120	}
121	RE_ENTRANT_CHECK_ON;
122#endif /* RE_ENTRANT_CHECKING */
123
124	FPU_info = info;
125
126	FPU_ORIG_EIP = FPU_EIP;
127
128	if ((FPU_EFLAGS & 0x00020000) != 0) {
129		/* Virtual 8086 mode */
130		addr_modes.default_mode = VM86;
131		FPU_EIP += code_base = FPU_CS << 4;
132		code_limit = code_base + 0xffff;	/* Assumes code_base <= 0xffff0000 */
133	} else if (FPU_CS == __USER_CS && FPU_DS == __USER_DS) {
134		addr_modes.default_mode = 0;
135	} else if (FPU_CS == __KERNEL_CS) {
136		printk("math_emulate: %04x:%08lx\n", FPU_CS, FPU_EIP);
137		panic("Math emulation needed in kernel");
138	} else {
139
140		if ((FPU_CS & 4) != 4) {	/* Must be in the LDT */
141			/* Can only handle segmented addressing via the LDT
142			   for now, and it must be 16 bit */
143			printk("FPU emulator: Unsupported addressing mode\n");
144			math_abort(FPU_info, SIGILL);
145		}
146
147		code_descriptor = FPU_get_ldt_descriptor(FPU_CS);
148		if (code_descriptor.d) {
149			/* The above test may be wrong, the book is not clear */
150			/* Segmented 32 bit protected mode */
151			addr_modes.default_mode = SEG32;
152		} else {
153			/* 16 bit protected mode */
154			addr_modes.default_mode = PM16;
155		}
156		FPU_EIP += code_base = seg_get_base(&code_descriptor);
157		code_limit = seg_get_limit(&code_descriptor) + 1;
158		code_limit *= seg_get_granularity(&code_descriptor);
159		code_limit += code_base - 1;
 
160		if (code_limit < code_base)
161			code_limit = 0xffffffff;
162	}
163
164	FPU_lookahead = !(FPU_EFLAGS & X86_EFLAGS_TF);
165
166	if (!valid_prefix(&byte1, (u_char __user **) & FPU_EIP,
167			  &addr_modes.override)) {
168		RE_ENTRANT_CHECK_OFF;
169		printk
170		    ("FPU emulator: Unknown prefix byte 0x%02x, probably due to\n"
171		     "FPU emulator: self-modifying code! (emulation impossible)\n",
172		     byte1);
173		RE_ENTRANT_CHECK_ON;
174		EXCEPTION(EX_INTERNAL | 0x126);
175		math_abort(FPU_info, SIGILL);
176	}
177
178      do_another_FPU_instruction:
179
180	no_ip_update = 0;
181
182	FPU_EIP++;		/* We have fetched the prefix and first code bytes. */
183
184	if (addr_modes.default_mode) {
185		/* This checks for the minimum instruction bytes.
186		   We also need to check any extra (address mode) code access. */
187		if (FPU_EIP > code_limit)
188			math_abort(FPU_info, SIGSEGV);
189	}
190
191	if ((byte1 & 0xf8) != 0xd8) {
192		if (byte1 == FWAIT_OPCODE) {
193			if (partial_status & SW_Summary)
194				goto do_the_FPU_interrupt;
195			else
196				goto FPU_fwait_done;
197		}
198#ifdef PARANOID
199		EXCEPTION(EX_INTERNAL | 0x128);
200		math_abort(FPU_info, SIGILL);
201#endif /* PARANOID */
202	}
203
204	RE_ENTRANT_CHECK_OFF;
205	FPU_code_access_ok(1);
206	FPU_get_user(FPU_modrm, (u_char __user *) FPU_EIP);
207	RE_ENTRANT_CHECK_ON;
208	FPU_EIP++;
209
210	if (partial_status & SW_Summary) {
211		/* Ignore the error for now if the current instruction is a no-wait
212		   control instruction */
213		/* The 80486 manual contradicts itself on this topic,
214		   but a real 80486 uses the following instructions:
215		   fninit, fnstenv, fnsave, fnstsw, fnstenv, fnclex.
216		 */
217		code = (FPU_modrm << 8) | byte1;
218		if (!((((code & 0xf803) == 0xe003) ||	/* fnclex, fninit, fnstsw */
219		       (((code & 0x3003) == 0x3001) &&	/* fnsave, fnstcw, fnstenv,
220							   fnstsw */
221			((code & 0xc000) != 0xc000))))) {
222			/*
223			 *  We need to simulate the action of the kernel to FPU
224			 *  interrupts here.
225			 */
226		      do_the_FPU_interrupt:
227
228			FPU_EIP = FPU_ORIG_EIP;	/* Point to current FPU instruction. */
229
230			RE_ENTRANT_CHECK_OFF;
231			current->thread.trap_nr = X86_TRAP_MF;
232			current->thread.error_code = 0;
233			send_sig(SIGFPE, current, 1);
234			return;
235		}
236	}
237
238	entry_sel_off.offset = FPU_ORIG_EIP;
239	entry_sel_off.selector = FPU_CS;
240	entry_sel_off.opcode = (byte1 << 8) | FPU_modrm;
241	entry_sel_off.empty = 0;
242
243	FPU_rm = FPU_modrm & 7;
244
245	if (FPU_modrm < 0300) {
246		/* All of these instructions use the mod/rm byte to get a data address */
247
248		if ((addr_modes.default_mode & SIXTEEN)
249		    ^ (addr_modes.override.address_size == ADDR_SIZE_PREFIX))
250			data_address =
251			    FPU_get_address_16(FPU_modrm, &FPU_EIP,
252					       &data_sel_off, addr_modes);
253		else
254			data_address =
255			    FPU_get_address(FPU_modrm, &FPU_EIP, &data_sel_off,
256					    addr_modes);
257
258		if (addr_modes.default_mode) {
259			if (FPU_EIP - 1 > code_limit)
260				math_abort(FPU_info, SIGSEGV);
261		}
262
263		if (!(byte1 & 1)) {
264			unsigned short status1 = partial_status;
265
266			st0_ptr = &st(0);
267			st0_tag = FPU_gettag0();
268
269			/* Stack underflow has priority */
270			if (NOT_EMPTY_ST0) {
271				if (addr_modes.default_mode & PROTECTED) {
272					/* This table works for 16 and 32 bit protected mode */
273					if (access_limit <
274					    data_sizes_16[(byte1 >> 1) & 3])
275						math_abort(FPU_info, SIGSEGV);
276				}
277
278				unmasked = 0;	/* Do this here to stop compiler warnings. */
279				switch ((byte1 >> 1) & 3) {
280				case 0:
281					unmasked =
282					    FPU_load_single((float __user *)
283							    data_address,
284							    &loaded_data);
285					loaded_tag = unmasked & 0xff;
286					unmasked &= ~0xff;
287					break;
288				case 1:
289					loaded_tag =
290					    FPU_load_int32((long __user *)
291							   data_address,
292							   &loaded_data);
293					break;
294				case 2:
295					unmasked =
296					    FPU_load_double((double __user *)
297							    data_address,
298							    &loaded_data);
299					loaded_tag = unmasked & 0xff;
300					unmasked &= ~0xff;
301					break;
302				case 3:
303				default:	/* Used here to suppress gcc warnings. */
304					loaded_tag =
305					    FPU_load_int16((short __user *)
306							   data_address,
307							   &loaded_data);
308					break;
309				}
310
311				/* No more access to user memory, it is safe
312				   to use static data now */
313
314				/* NaN operands have the next priority. */
315				/* We have to delay looking at st(0) until after
316				   loading the data, because that data might contain an SNaN */
317				if (((st0_tag == TAG_Special) && isNaN(st0_ptr))
318				    || ((loaded_tag == TAG_Special)
319					&& isNaN(&loaded_data))) {
320					/* Restore the status word; we might have loaded a
321					   denormal. */
322					partial_status = status1;
323					if ((FPU_modrm & 0x30) == 0x10) {
324						/* fcom or fcomp */
325						EXCEPTION(EX_Invalid);
326						setcc(SW_C3 | SW_C2 | SW_C0);
327						if ((FPU_modrm & 0x08)
328						    && (control_word &
329							CW_Invalid))
330							FPU_pop();	/* fcomp, masked, so we pop. */
331					} else {
332						if (loaded_tag == TAG_Special)
333							loaded_tag =
334							    FPU_Special
335							    (&loaded_data);
336#ifdef PECULIAR_486
337						/* This is not really needed, but gives behaviour
338						   identical to an 80486 */
339						if ((FPU_modrm & 0x28) == 0x20)
340							/* fdiv or fsub */
341							real_2op_NaN
342							    (&loaded_data,
343							     loaded_tag, 0,
344							     &loaded_data);
345						else
346#endif /* PECULIAR_486 */
347							/* fadd, fdivr, fmul, or fsubr */
348							real_2op_NaN
349							    (&loaded_data,
350							     loaded_tag, 0,
351							     st0_ptr);
352					}
353					goto reg_mem_instr_done;
354				}
355
356				if (unmasked && !((FPU_modrm & 0x30) == 0x10)) {
357					/* Is not a comparison instruction. */
358					if ((FPU_modrm & 0x38) == 0x38) {
359						/* fdivr */
360						if ((st0_tag == TAG_Zero) &&
361						    ((loaded_tag == TAG_Valid)
362						     || (loaded_tag ==
363							 TAG_Special
364							 &&
365							 isdenormal
366							 (&loaded_data)))) {
367							if (FPU_divide_by_zero
368							    (0,
369							     getsign
370							     (&loaded_data))
371							    < 0) {
372								/* We use the fact here that the unmasked
373								   exception in the loaded data was for a
374								   denormal operand */
375								/* Restore the state of the denormal op bit */
376								partial_status
377								    &=
378								    ~SW_Denorm_Op;
379								partial_status
380								    |=
381								    status1 &
382								    SW_Denorm_Op;
383							} else
384								setsign(st0_ptr,
385									getsign
386									(&loaded_data));
387						}
388					}
389					goto reg_mem_instr_done;
390				}
391
392				switch ((FPU_modrm >> 3) & 7) {
393				case 0:	/* fadd */
394					clear_C1();
395					FPU_add(&loaded_data, loaded_tag, 0,
396						control_word);
397					break;
398				case 1:	/* fmul */
399					clear_C1();
400					FPU_mul(&loaded_data, loaded_tag, 0,
401						control_word);
402					break;
403				case 2:	/* fcom */
404					FPU_compare_st_data(&loaded_data,
405							    loaded_tag);
406					break;
407				case 3:	/* fcomp */
408					if (!FPU_compare_st_data
409					    (&loaded_data, loaded_tag)
410					    && !unmasked)
411						FPU_pop();
412					break;
413				case 4:	/* fsub */
414					clear_C1();
415					FPU_sub(LOADED | loaded_tag,
416						(int)&loaded_data,
417						control_word);
418					break;
419				case 5:	/* fsubr */
420					clear_C1();
421					FPU_sub(REV | LOADED | loaded_tag,
422						(int)&loaded_data,
423						control_word);
424					break;
425				case 6:	/* fdiv */
426					clear_C1();
427					FPU_div(LOADED | loaded_tag,
428						(int)&loaded_data,
429						control_word);
430					break;
431				case 7:	/* fdivr */
432					clear_C1();
433					if (st0_tag == TAG_Zero)
434						partial_status = status1;	/* Undo any denorm tag,
435										   zero-divide has priority. */
436					FPU_div(REV | LOADED | loaded_tag,
437						(int)&loaded_data,
438						control_word);
439					break;
440				}
441			} else {
442				if ((FPU_modrm & 0x30) == 0x10) {
443					/* The instruction is fcom or fcomp */
444					EXCEPTION(EX_StackUnder);
445					setcc(SW_C3 | SW_C2 | SW_C0);
446					if ((FPU_modrm & 0x08)
447					    && (control_word & CW_Invalid))
448						FPU_pop();	/* fcomp */
449				} else
450					FPU_stack_underflow();
451			}
452		      reg_mem_instr_done:
453			operand_address = data_sel_off;
454		} else {
455			if (!(no_ip_update =
456			      FPU_load_store(((FPU_modrm & 0x38) | (byte1 & 6))
457					     >> 1, addr_modes, data_address))) {
458				operand_address = data_sel_off;
459			}
460		}
461
462	} else {
463		/* None of these instructions access user memory */
464		u_char instr_index = (FPU_modrm & 0x38) | (byte1 & 7);
465
466#ifdef PECULIAR_486
467		/* This is supposed to be undefined, but a real 80486 seems
468		   to do this: */
469		operand_address.offset = 0;
470		operand_address.selector = FPU_DS;
471#endif /* PECULIAR_486 */
472
473		st0_ptr = &st(0);
474		st0_tag = FPU_gettag0();
475		switch (type_table[(int)instr_index]) {
476		case _NONE_:	/* also _REGIc: _REGIn */
477			break;
478		case _REG0_:
479			if (!NOT_EMPTY_ST0) {
480				FPU_stack_underflow();
481				goto FPU_instruction_done;
482			}
483			break;
484		case _REGIi:
485			if (!NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm)) {
486				FPU_stack_underflow_i(FPU_rm);
487				goto FPU_instruction_done;
488			}
489			break;
490		case _REGIp:
491			if (!NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm)) {
492				FPU_stack_underflow_pop(FPU_rm);
493				goto FPU_instruction_done;
494			}
495			break;
496		case _REGI_:
497			if (!NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm)) {
498				FPU_stack_underflow();
499				goto FPU_instruction_done;
500			}
501			break;
502		case _PUSH_:	/* Only used by the fld st(i) instruction */
503			break;
504		case _null_:
505			FPU_illegal();
506			goto FPU_instruction_done;
507		default:
508			EXCEPTION(EX_INTERNAL | 0x111);
509			goto FPU_instruction_done;
510		}
511		(*st_instr_table[(int)instr_index]) ();
512
513	      FPU_instruction_done:
514		;
515	}
516
517	if (!no_ip_update)
518		instruction_address = entry_sel_off;
519
520      FPU_fwait_done:
521
522#ifdef DEBUG
523	RE_ENTRANT_CHECK_OFF;
524	FPU_printall();
525	RE_ENTRANT_CHECK_ON;
526#endif /* DEBUG */
527
528	if (FPU_lookahead && !need_resched()) {
529		FPU_ORIG_EIP = FPU_EIP - code_base;
530		if (valid_prefix(&byte1, (u_char __user **) & FPU_EIP,
531				 &addr_modes.override))
532			goto do_another_FPU_instruction;
533	}
534
535	if (addr_modes.default_mode)
536		FPU_EIP -= code_base;
537
538	RE_ENTRANT_CHECK_OFF;
539}
540
541/* Support for prefix bytes is not yet complete. To properly handle
542   all prefix bytes, further changes are needed in the emulator code
543   which accesses user address space. Access to separate segments is
544   important for msdos emulation. */
545static int valid_prefix(u_char *Byte, u_char __user **fpu_eip,
546			overrides * override)
547{
548	u_char byte;
549	u_char __user *ip = *fpu_eip;
550
551	*override = (overrides) {
552	0, 0, PREFIX_DEFAULT};	/* defaults */
553
554	RE_ENTRANT_CHECK_OFF;
555	FPU_code_access_ok(1);
556	FPU_get_user(byte, ip);
557	RE_ENTRANT_CHECK_ON;
558
559	while (1) {
560		switch (byte) {
561		case ADDR_SIZE_PREFIX:
562			override->address_size = ADDR_SIZE_PREFIX;
563			goto do_next_byte;
564
565		case OP_SIZE_PREFIX:
566			override->operand_size = OP_SIZE_PREFIX;
567			goto do_next_byte;
568
569		case PREFIX_CS:
570			override->segment = PREFIX_CS_;
571			goto do_next_byte;
572		case PREFIX_ES:
573			override->segment = PREFIX_ES_;
574			goto do_next_byte;
575		case PREFIX_SS:
576			override->segment = PREFIX_SS_;
577			goto do_next_byte;
578		case PREFIX_FS:
579			override->segment = PREFIX_FS_;
580			goto do_next_byte;
581		case PREFIX_GS:
582			override->segment = PREFIX_GS_;
583			goto do_next_byte;
584		case PREFIX_DS:
585			override->segment = PREFIX_DS_;
586			goto do_next_byte;
587
588/* lock is not a valid prefix for FPU instructions,
589   let the cpu handle it to generate a SIGILL. */
590/*	case PREFIX_LOCK: */
591
592			/* rep.. prefixes have no meaning for FPU instructions */
593		case PREFIX_REPE:
594		case PREFIX_REPNE:
595
596		      do_next_byte:
597			ip++;
598			RE_ENTRANT_CHECK_OFF;
599			FPU_code_access_ok(1);
600			FPU_get_user(byte, ip);
601			RE_ENTRANT_CHECK_ON;
602			break;
603		case FWAIT_OPCODE:
604			*Byte = byte;
605			return 1;
606		default:
607			if ((byte & 0xf8) == 0xd8) {
608				*Byte = byte;
609				*fpu_eip = ip;
610				return 1;
611			} else {
612				/* Not a valid sequence of prefix bytes followed by
613				   an FPU instruction. */
614				*Byte = byte;	/* Needed for error message. */
615				return 0;
616			}
617		}
618	}
619}
620
621void math_abort(struct math_emu_info *info, unsigned int signal)
622{
623	FPU_EIP = FPU_ORIG_EIP;
624	current->thread.trap_nr = X86_TRAP_MF;
625	current->thread.error_code = 0;
626	send_sig(signal, current, 1);
627	RE_ENTRANT_CHECK_OFF;
628      __asm__("movl %0,%%esp ; ret": :"g"(((long)info) - 4));
629#ifdef PARANOID
630	printk("ERROR: wm-FPU-emu math_abort failed!\n");
631#endif /* PARANOID */
632}
633
634#define S387 ((struct swregs_state *)s387)
635#define sstatus_word() \
636  ((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top))
637
638int fpregs_soft_set(struct task_struct *target,
639		    const struct user_regset *regset,
640		    unsigned int pos, unsigned int count,
641		    const void *kbuf, const void __user *ubuf)
642{
643	struct swregs_state *s387 = &target->thread.fpu.state.soft;
644	void *space = s387->st_space;
645	int ret;
646	int offset, other, i, tags, regnr, tag, newtop;
647
648	RE_ENTRANT_CHECK_OFF;
649	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, s387, 0,
650				 offsetof(struct swregs_state, st_space));
651	RE_ENTRANT_CHECK_ON;
652
653	if (ret)
654		return ret;
655
656	S387->ftop = (S387->swd >> SW_Top_Shift) & 7;
657	offset = (S387->ftop & 7) * 10;
658	other = 80 - offset;
659
660	RE_ENTRANT_CHECK_OFF;
661
662	/* Copy all registers in stack order. */
663	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
664				 space + offset, 0, other);
665	if (!ret && offset)
666		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
667					 space, 0, offset);
668
669	RE_ENTRANT_CHECK_ON;
670
671	/* The tags may need to be corrected now. */
672	tags = S387->twd;
673	newtop = S387->ftop;
674	for (i = 0; i < 8; i++) {
675		regnr = (i + newtop) & 7;
676		if (((tags >> ((regnr & 7) * 2)) & 3) != TAG_Empty) {
677			/* The loaded data over-rides all other cases. */
678			tag =
679			    FPU_tagof((FPU_REG *) ((u_char *) S387->st_space +
680						   10 * regnr));
681			tags &= ~(3 << (regnr * 2));
682			tags |= (tag & 3) << (regnr * 2);
683		}
684	}
685	S387->twd = tags;
686
687	return ret;
688}
689
690int fpregs_soft_get(struct task_struct *target,
691		    const struct user_regset *regset,
692		    struct membuf to)
 
693{
694	struct swregs_state *s387 = &target->thread.fpu.state.soft;
695	const void *space = s387->st_space;
 
696	int offset = (S387->ftop & 7) * 10, other = 80 - offset;
697
698	RE_ENTRANT_CHECK_OFF;
699
700#ifdef PECULIAR_486
701	S387->cwd &= ~0xe080;
702	/* An 80486 sets nearly all of the reserved bits to 1. */
703	S387->cwd |= 0xffff0040;
704	S387->swd = sstatus_word() | 0xffff0000;
705	S387->twd |= 0xffff0000;
706	S387->fcs &= ~0xf8000000;
707	S387->fos |= 0xffff0000;
708#endif /* PECULIAR_486 */
709
710	membuf_write(&to, s387, offsetof(struct swregs_state, st_space));
711	membuf_write(&to, space + offset, other);
712	membuf_write(&to, space, offset);
 
 
 
 
 
 
 
713
714	RE_ENTRANT_CHECK_ON;
715
716	return 0;
717}