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