File: /usr/src/linux/arch/mips/math-emu/cp1emu.c

1     /*
2      * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator
3      * 
4      * MIPS floating point support
5      * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
6      * http://www.algor.co.uk
7      *
8      * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
9      * Copyright (C) 2000  MIPS Technologies, Inc.
10      *
11      *  This program is free software; you can distribute it and/or modify it
12      *  under the terms of the GNU General Public License (Version 2) as
13      *  published by the Free Software Foundation.
14      *
15      *  This program is distributed in the hope it will be useful, but WITHOUT
16      *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17      *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18      *  for more details.
19      *
20      *  You should have received a copy of the GNU General Public License along
21      *  with this program; if not, write to the Free Software Foundation, Inc.,
22      *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
23      *
24      * A complete emulator for MIPS coprocessor 1 instructions.  This is
25      * required for #float(switch) or #float(trap), where it catches all
26      * COP1 instructions via the "CoProcessor Unusable" exception.  
27      *
28      * More surprisingly it is also required for #float(ieee), to help out
29      * the hardware fpu at the boundaries of the IEEE-754 representation
30      * (denormalised values, infinities, underflow, etc).  It is made
31      * quite nasty because emulation of some non-COP1 instructions is
32      * required, e.g. in branch delay slots.
33      * 
34      * Note if you know that you won't have an fpu, then you'll get much 
35      * better performance by compiling with -msoft-float!
36      */
37     #include <linux/mm.h>
38     #include <linux/signal.h>
39     #include <linux/smp.h>
40     #include <linux/smp_lock.h>
41     
42     #include <asm/asm.h>
43     #include <asm/branch.h>
44     #include <asm/bootinfo.h>
45     #include <asm/byteorder.h>
46     #include <asm/cpu.h>
47     #include <asm/inst.h>
48     #include <asm/uaccess.h>
49     #include <asm/processor.h>
50     #include <asm/mipsregs.h>
51     #include <asm/system.h>
52     #include <asm/pgtable.h>
53     
54     #include <asm/fpu_emulator.h>
55     
56     #include "ieee754.h"
57     
58     /* Strap kernel emulator for full MIPS IV emulation */
59     
60     #ifdef __mips
61     #undef __mips
62     #endif
63     #define __mips 4
64     
65     typedef void *vaddr_t;
66     
67     /* Function which emulates the instruction in a branch delay slot. */
68     
69     static int mips_dsemul(struct pt_regs *, mips_instruction, vaddr_t);
70     
71     /* Function which emulates a floating point instruction. */
72     
73     static int fpu_emu(struct pt_regs *, struct mips_fpu_soft_struct *,
74     	 mips_instruction);
75     
76     #if __mips >= 4 && __mips != 32
77     static int fpux_emu(struct pt_regs *,
78     		    struct mips_fpu_soft_struct *, mips_instruction);
79     #endif
80     
81     /* Further private data for which no space exists in mips_fpu_soft_struct */
82     
83     struct mips_fpu_emulator_private fpuemuprivate;
84     
85     /* Control registers */
86     
87     #define FPCREG_RID	0	/* $0  = revision id */
88     #define FPCREG_CSR	31	/* $31 = csr */
89     
90     /* Convert Mips rounding mode (0..3) to IEEE library modes. */
91     static const unsigned char ieee_rm[4] = {
92     	IEEE754_RN, IEEE754_RZ, IEEE754_RU, IEEE754_RD
93     };
94     
95     #if __mips >= 4
96     /* convert condition code register number to csr bit */
97     static const unsigned int fpucondbit[8] = {
98     	FPU_CSR_COND0,
99     	FPU_CSR_COND1,
100     	FPU_CSR_COND2,
101     	FPU_CSR_COND3,
102     	FPU_CSR_COND4,
103     	FPU_CSR_COND5,
104     	FPU_CSR_COND6,
105     	FPU_CSR_COND7
106     };
107     #endif
108     
109     
110     
111     /* 
112      * Redundant with logic already in kernel/branch.c,
113      * embedded in compute_return_epc.  At some point,
114      * a single subroutine should be used across both
115      * modules.
116      */
117     static int isBranchInstr(mips_instruction * i)
118     {
119     	switch (MIPSInst_OPCODE(*i)) {
120     	case spec_op:
121     		switch (MIPSInst_FUNC(*i)) {
122     		case jalr_op:
123     		case jr_op:
124     			return 1;
125     		}
126     		break;
127     
128     	case bcond_op:
129     		switch (MIPSInst_RT(*i)) {
130     		case bltz_op:
131     		case bgez_op:
132     		case bltzl_op:
133     		case bgezl_op:
134     		case bltzal_op:
135     		case bgezal_op:
136     		case bltzall_op:
137     		case bgezall_op:
138     			return 1;
139     		}
140     		break;
141     
142     	case j_op:
143     	case jal_op:
144     	case jalx_op:
145     	case beq_op:
146     	case bne_op:
147     	case blez_op:
148     	case bgtz_op:
149     	case beql_op:
150     	case bnel_op:
151     	case blezl_op:
152     	case bgtzl_op:
153     		return 1;
154     
155     	case cop0_op:
156     	case cop1_op:
157     	case cop2_op:
158     	case cop1x_op:
159     		if (MIPSInst_RS(*i) == bc_op)
160     			return 1;
161     		break;
162     	}
163     
164     	return 0;
165     }
166     
167     #define REG_TO_VA (vaddr_t)
168     #define VA_TO_REG (unsigned long)
169     
170     static unsigned long mips_get_word(struct pt_regs *xcp, void *va, int *perr)
171     {
172     	unsigned long temp;
173     
174     	if (!user_mode(xcp)) {
175     		*perr = 0;
176     		return (*(unsigned long *) va);
177     	}
178     
179     	*perr = (int) get_user(temp, (unsigned long *) va);
180     	return temp;
181     }
182     
183     static unsigned long long
184     mips_get_dword(struct pt_regs *xcp, void *va, int *perr)
185     {
186     	unsigned long long temp;
187     
188     	if (!user_mode(xcp)) {
189     		*perr = 0;
190     		return (*(unsigned long long *) va);
191     	}
192     
193     	*perr = (int) get_user(temp, (unsigned long long *) va);
194     	return temp;
195     }
196     
197     static int mips_put_word(struct pt_regs *xcp, void *va, unsigned long val)
198     {
199     	if (!user_mode(xcp)) {
200     		*(unsigned long *) va = val;
201     		return 0;
202     	}
203     
204     	return put_user(val, (unsigned long *) va);
205     }
206     
207     static int mips_put_dword(struct pt_regs *xcp, void *va, long long val)
208     {
209     	if (!user_mode(xcp)) {
210     		*(unsigned long long *) va = val;
211     		return 0;
212     	}
213     
214     	return put_user(val, (unsigned long long *) va);
215     }
216     
217     
218     /*
219      * In the Linux kernel, we support selection of FPR format on the
220      * basis of the Status.FR bit.  This does imply that, if a full 32
221      * FPRs are desired, there needs to be a flip-flop that can be written
222      * to one at that bit position.  In any case, normal MIPS ABI uses
223      * only the even FPRs (Status.FR = 0).
224      */
225     
226     #define CP0_STATUS_FR_SUPPORT
227     
228     /*
229      * Emulate the single floating point instruction pointed at by EPC.
230      * Two instructions if the instruction is in a branch delay slot.
231      */
232     
233     static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
234     {
235     	mips_instruction ir;
236     	vaddr_t emulpc;
237     	vaddr_t contpc;
238     	unsigned int cond;
239     	int err = 0;
240     
241     	ir = mips_get_word(xcp, REG_TO_VA xcp->cp0_epc, &err);
242     	if (err) {
243     		fpuemuprivate.stats.errors++;
244     		return SIGBUS;
245     	}
246     
247     	/* XXX NEC Vr54xx bug workaround */
248     	if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
249     		xcp->cp0_cause &= ~CAUSEF_BD;
250     
251     	if (xcp->cp0_cause & CAUSEF_BD) {
252     		/*
253     		 * The instruction to be emulated is in a branch delay slot
254     		 * which means that we have to  emulate the branch instruction
255     		 * BEFORE we do the cop1 instruction. 
256     		 *
257     		 * This branch could be a COP1 branch, but in that case we
258     		 * would have had a trap for that instruction, and would not
259     		 * come through this route.
260     		 *
261     		 * Linux MIPS branch emulator operates on context, updating the
262     		 * cp0_epc.
263     		 */
264     		emulpc = REG_TO_VA(xcp->cp0_epc + 4);	/* Snapshot emulation target */
265     
266     		if (__compute_return_epc(xcp)) {
267     #ifdef CP1DBG
268     			printk("failed to emulate branch at %p\n",
269     				    REG_TO_VA(xcp->cp0_epc));
270     #endif
271     			return SIGILL;;
272     		}
273     		ir = mips_get_word(xcp, emulpc, &err);
274     		if (err) {
275     			fpuemuprivate.stats.errors++;
276     			return SIGBUS;
277     		}
278     		contpc = REG_TO_VA xcp->cp0_epc;
279     	} else {
280     		emulpc = REG_TO_VA xcp->cp0_epc;
281     		contpc = REG_TO_VA xcp->cp0_epc + 4;
282     	}
283     
284     emul:
285     	fpuemuprivate.stats.emulated++;
286     	switch (MIPSInst_OPCODE(ir)) {
287     #ifdef CP0_STATUS_FR_SUPPORT
288     		/* R4000+ 64-bit fpu registers */
289     #ifndef SINGLE_ONLY_FPU
290     	case ldc1_op:
291     		{
292     			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
293     			    + MIPSInst_SIMM(ir);
294     			int ft = MIPSInst_RT(ir);
295     			if (!(xcp->cp0_status & ST0_FR))
296     				ft &= ~1;
297     			ctx->regs[ft] = mips_get_dword(xcp, va, &err);
298     			fpuemuprivate.stats.loads++;
299     			if (err) {
300     				fpuemuprivate.stats.errors++;
301     				return SIGBUS;
302     			}
303     		}
304     		break;
305     
306     	case sdc1_op:
307     		{
308     			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
309     			    + MIPSInst_SIMM(ir);
310     			int ft = MIPSInst_RT(ir);
311     			if (!(xcp->cp0_status & ST0_FR))
312     				ft &= ~1;
313     			fpuemuprivate.stats.stores++;
314     			if (mips_put_dword(xcp, va, ctx->regs[ft])) {
315     				fpuemuprivate.stats.errors++;
316     				return SIGBUS;
317     			}
318     		}
319     		break;
320     #endif
321     
322     	case lwc1_op:
323     		{
324     			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
325     			    + MIPSInst_SIMM(ir);
326     			fpureg_t val;
327     			int ft = MIPSInst_RT(ir);
328     			fpuemuprivate.stats.loads++;
329     			val = mips_get_word(xcp, va, &err);
330     			if (err) {
331     				fpuemuprivate.stats.errors++;
332     				return SIGBUS;
333     			}
334     			if (xcp->cp0_status & ST0_FR) {
335     				/* load whole register */
336     				ctx->regs[ft] = val;
337     			} else if (ft & 1) {
338     				/* load to m.s. 32 bits */
339     #ifdef SINGLE_ONLY_FPU
340     				/* illegal register in single-float mode */
341     				return SIGILL;
342     #else
343     				ctx->regs[(ft & ~1)] &= 0xffffffff;
344     				ctx->regs[(ft & ~1)] |= val << 32;
345     #endif
346     			} else {
347     				/* load to l.s. 32 bits */
348     				ctx->regs[ft] &= ~0xffffffffLL;
349     				ctx->regs[ft] |= val;
350     			}
351     		}
352     		break;
353     
354     	case swc1_op:
355     		{
356     			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
357     			    + MIPSInst_SIMM(ir);
358     			unsigned int val;
359     			int ft = MIPSInst_RT(ir);
360     			fpuemuprivate.stats.stores++;
361     			if (xcp->cp0_status & ST0_FR) {
362     				/* store whole register */
363     				val = ctx->regs[ft];
364     			} else if (ft & 1) {
365     #ifdef SINGLE_ONLY_FPU
366     				/* illegal register in single-float mode */
367     				return SIGILL;
368     #else
369     				/* store from m.s. 32 bits */
370     				val = ctx->regs[(ft & ~1)] >> 32;
371     #endif
372     			} else {
373     				/* store from l.s. 32 bits */
374     				val = ctx->regs[ft];
375     			}
376     			if (mips_put_word(xcp, va, val)) {
377     				fpuemuprivate.stats.errors++;
378     				return SIGBUS;
379     			}
380     		}
381     		break;
382     #else				/* old 32-bit fpu registers */
383     	case lwc1_op:
384     		{
385     			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
386     			    + MIPSInst_SIMM(ir);
387     			ctx->regs[MIPSInst_RT(ir)] =
388     			    mips_get_word(xcp, va, &err);
389     			fpuemuprivate.stats.loads++;
390     			if (err) {
391     				fpuemuprivate.stats.errors++;
392     				return SIGBUS;
393     			}
394     		}
395     		break;
396     
397     	case swc1_op:
398     		{
399     			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
400     			    + MIPSInst_SIMM(ir);
401     			fpuemuprivate.stats.stores++;
402     			if (mips_put_word
403     			    (xcp, va, ctx->regs[MIPSInst_RT(ir)])) {
404     				fpuemuprivate.stats.errors++;
405     				return SIGBUS;
406     			}
407     		}
408     		break;
409     	case ldc1_op:
410     		{
411     			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
412     			    + MIPSInst_SIMM(ir);
413     			unsigned int rt = MIPSInst_RT(ir) & ~1;
414     			int errs = 0;
415     			fpuemuprivate.stats.loads++;
416     #if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
417     			ctx->regs[rt + 1] =
418     			    mips_get_word(xcp, va + 0, &err);
419     			errs += err;
420     			ctx->regs[rt + 0] =
421     			    mips_get_word(xcp, va + 4, &err);
422     			errs += err;
423     #else
424     			ctx->regs[rt + 0] =
425     			    mips_get_word(xcp, va + 0, &err);
426     			errs += err;
427     			ctx->regs[rt + 1] =
428     			    mips_get_word(xcp, va + 4, &err);
429     			errs += err;
430     #endif
431     			if (err)
432     				return SIGBUS;
433     		}
434     		break;
435     
436     	case sdc1_op:
437     		{
438     			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
439     			    + MIPSInst_SIMM(ir);
440     			unsigned int rt = MIPSInst_RT(ir) & ~1;
441     			fpuemuprivate.stats.stores++;
442     #if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
443     			if (mips_put_word(xcp, va + 0, ctx->regs[rt + 1]))
444     				return SIGBUS;
445     			if (mips_put_word(xcp, va + 4, ctx->regs[rt + 0]))
446     				return SIGBUS;
447     #else
448     			if (mips_put_word(xcp, va + 0, ctx->regs[rt + 0]))
449     				return SIGBUS;
450     			if (mips_put_word(xcp, va + 4, ctx->regs[rt + 1]))
451     				return SIGBUS;
452     #endif
453     		}
454     		break;
455     #endif
456     
457     	case cop1_op:
458     		switch (MIPSInst_RS(ir)) {
459     
460     #ifdef CP0_STATUS_FR_SUPPORT
461     #if __mips64 && !defined(SINGLE_ONLY_FPU)
462     		case dmfc_op:
463     			/* copregister fs -> gpr[rt] */
464     			if (MIPSInst_RT(ir) != 0) {
465     				int fs = MIPSInst_RD(ir);
466     				if (!(xcp->cp0_status & ST0_FR))
467     					fs &= ~1;
468     				xcp->regs[MIPSInst_RT(ir)] = ctx->regs[fs];
469     			}
470     			break;
471     
472     		case dmtc_op: {
473     			/* copregister fs <- rt */
474     				fpureg_t value;
475     				int fs = MIPSInst_RD(ir);
476     				if (!(xcp->cp0_status & ST0_FR))
477     					fs &= ~1;
478     				value =
479     				    (MIPSInst_RT(ir) ==
480     				     0) ? 0 : xcp->regs[MIPSInst_RT(ir)];
481     				ctx->regs[fs] = value;
482     			break;
483     		}
484     #endif
485     
486     		case mfc_op:
487     			/* copregister rd -> gpr[rt] */
488     			if (MIPSInst_RT(ir) != 0) {
489     				/* default value from l.s. 32 bits */
490     				int value = ctx->regs[MIPSInst_RD(ir)];
491     				if (MIPSInst_RD(ir) & 1) {
492     #ifdef SINGLE_ONLY_FPU
493     					/* illegal register in single-float mode */
494     					return SIGILL;
495     #else
496     					if (!(xcp->cp0_status & ST0_FR)) {
497     						/* move from m.s. 32 bits */
498     						value =
499     						    ctx->
500     						    regs[MIPSInst_RD(ir) &
501     							 ~1] >> 32;
502     					}
503     #endif
504     				}
505     				xcp->regs[MIPSInst_RT(ir)] = value;
506     			}
507     			break;
508     
509     		case mtc_op:
510     			/* copregister rd <- rt */
511     			{
512     				fpureg_t value;
513     				if (MIPSInst_RT(ir) == 0)
514     					value = 0;
515     				else
516     					value =
517     					    (unsigned int) xcp->
518     					    regs[MIPSInst_RT(ir)];
519     				if (MIPSInst_RD(ir) & 1) {
520     #ifdef SINGLE_ONLY_FPU
521     					/* illegal register in single-float mode */
522     					return SIGILL;
523     #else
524     					if (!(xcp->cp0_status & ST0_FR)) {
525     						/* move to m.s. 32 bits */
526     						ctx->
527     						    regs[
528     							 (MIPSInst_RD(ir) &
529     							  ~1)] &=
530     						    0xffffffff;
531     						ctx->
532     						    regs[
533     							 (MIPSInst_RD(ir) &
534     							  ~1)] |=
535     						    value << 32;
536     						break;
537     					}
538     #endif
539     				}
540     				/* move to l.s. 32 bits */
541     				ctx->regs[MIPSInst_RD(ir)] &=
542     				    ~0xffffffffLL;
543     				ctx->regs[MIPSInst_RD(ir)] |= value;
544     			}
545     			break;
546     #else
547     
548     		case mfc_op:
549     			/* copregister rd -> gpr[rt] */
550     			if (MIPSInst_RT(ir) != 0) {
551     				unsigned value =
552     				    ctx->regs[MIPSInst_RD(ir)];
553     				xcp->regs[MIPSInst_RT(ir)] = value;
554     			}
555     			break;
556     
557     		case mtc_op:
558     			/* copregister rd <- rt */
559     			{
560     				unsigned value;
561     				value =
562     				    (MIPSInst_RT(ir) ==
563     				     0) ? 0 : xcp->regs[MIPSInst_RT(ir)];
564     				ctx->regs[MIPSInst_RD(ir)] = value;
565     			}
566     			break;
567     #endif
568     
569     		case cfc_op:
570     			/* cop control register rd -> gpr[rt] */
571     			{
572     				unsigned value;
573     
574     				if (MIPSInst_RD(ir) == FPCREG_CSR) {
575     					value = ctx->sr;
576     #ifdef CSRTRACE
577     					printk
578     					    ("%p gpr[%d]<-csr=%08x\n",
579     					     REG_TO_VA(xcp->cp0_epc),
580     					     MIPSInst_RT(ir), value);
581     #endif
582     				} else if (MIPSInst_RD(ir) == FPCREG_RID)
583     					value = 0;
584     				else
585     					value = 0;
586     				if (MIPSInst_RT(ir))
587     					xcp->regs[MIPSInst_RT(ir)] = value;
588     			}
589     			break;
590     
591     		case ctc_op:
592     			/* copregister rd <- rt */
593     			{
594     				unsigned value;
595     
596     				if (MIPSInst_RT(ir) == 0)
597     					value = 0;
598     				else
599     					value = xcp->regs[MIPSInst_RT(ir)];
600     
601     				/* we only have one writable control reg
602     				 */
603     				if (MIPSInst_RD(ir) == FPCREG_CSR) {
604     #ifdef CSRTRACE
605     					printk
606     					    ("%p gpr[%d]->csr=%08x\n",
607     					     REG_TO_VA(xcp->cp0_epc),
608     					     MIPSInst_RT(ir), value);
609     #endif
610     					ctx->sr = value;
611     					/* copy new rounding mode to ieee library state! */
612     					ieee754_csr.rm =
613     					    ieee_rm[value & 0x3];
614     				}
615     			}
616     			break;
617     
618     		case bc_op: {
619     			int likely = 0;
620     
621     			if (xcp->cp0_cause & CAUSEF_BD)
622     				return SIGILL;
623     
624     #if __mips >= 4
625     			cond = ctx-> sr & fpucondbit[MIPSInst_RT(ir) >> 2];
626     #else
627     			cond = ctx->sr & FPU_CSR_COND;
628     #endif
629     			switch (MIPSInst_RT(ir) & 3) {
630     			case bcfl_op:
631     				likely = 1;
632     			case bcf_op:
633     				cond = !cond;
634     				break;
635     			case bctl_op:
636     				likely = 1;
637     			case bct_op:
638     				break;
639     			default:
640     				/* thats an illegal instruction */
641     				return SIGILL;
642     			}
643     
644     			xcp->cp0_cause |= CAUSEF_BD;
645     			if (cond) {
646     				/* branch taken: emulate dslot instruction */
647     				xcp->cp0_epc += 4;
648     				contpc = REG_TO_VA xcp->cp0_epc +
649     				         (MIPSInst_SIMM(ir) << 2);
650     
651     				ir = mips_get_word(xcp, REG_TO_VA(xcp->cp0_epc),
652     				      &err);
653     				if (err) {
654     					fpuemuprivate.stats.errors++;
655     					return SIGBUS;
656     				}
657     
658     				switch (MIPSInst_OPCODE(ir)) {
659     				case lwc1_op:
660     				case swc1_op:
661     #if (__mips >= 2 || __mips64) && !defined(SINGLE_ONLY_FPU)
662     				case ldc1_op:
663     				case sdc1_op:
664     #endif
665     				case cop1_op:
666     #if __mips >= 4 && __mips != 32
667     				case cop1x_op:
668     #endif
669     					/* its one of ours */
670     					goto emul;
671     #if __mips >= 4
672     				case spec_op:
673     					if (MIPSInst_FUNC(ir) == movc_op)
674     						goto emul;
675     					break;
676     #endif
677     				}
678     
679     				/*
680     				 * Single step the non-cp1 instruction in the
681     				 * dslot
682     				 */
683     				return mips_dsemul(xcp, ir, contpc);
684     			} else {
685     				/* branch not taken */
686     				if (likely)
687     					/*
688     					 * branch likely nullifies dslot if not
689     					 * taken
690     					 */
691     					xcp->cp0_epc += 4;
692     					/* else continue & execute dslot as normal insn */
693     			}
694     			break;
695     		}
696     
697     		default: {
698     			int sig;
699     
700     			if (!(MIPSInst_RS(ir) & 0x10))
701     				return SIGILL;
702     
703     			/* a real fpu computation instruction */
704     				if ((sig = fpu_emu(xcp, ctx, ir)))
705     					return sig;
706     			}
707     		}
708     		break;
709     
710     #if __mips >= 4 && __mips != 32
711     	case cop1x_op:
712     		{
713     			int sig;
714     			if ((sig = fpux_emu(xcp, ctx, ir)))
715     				return sig;
716     		}
717     		break;
718     #endif
719     
720     #if __mips >= 4
721     	case spec_op:
722     		if (MIPSInst_FUNC(ir) != movc_op)
723     			return SIGILL;
724     		cond = fpucondbit[MIPSInst_RT(ir) >> 2];
725     		if (((ctx->sr & cond) != 0) !=
726     		    ((MIPSInst_RT(ir) & 1) != 0)) return 0;
727     		xcp->regs[MIPSInst_RD(ir)] = xcp->regs[MIPSInst_RS(ir)];
728     		break;
729     #endif
730     
731     	default:
732     		return SIGILL;
733     	}
734     
735     	/* we did it !! */
736     	xcp->cp0_epc = VA_TO_REG(contpc);
737     	xcp->cp0_cause &= ~CAUSEF_BD;
738     	return 0;
739     }
740     
741     /*
742      * Emulate the arbritrary instruction ir at xcp->cp0_epc.  Required when
743      * we have to emulate the instruction in a COP1 branch delay slot.  Do
744      * not change cp0_epc due to the instruction
745      *
746      * According to the spec:
747      * 1) it shouldnt be a branch :-)
748      * 2) it can be a COP instruction :-(
749      * 3) if we are tring to run a protected memory space we must take
750      *    special care on memory access instructions :-(
751      */
752     
753     /*
754      * "Trampoline" return routine to catch exception following
755      *  execution of delay-slot instruction execution.
756      */
757     
758     int do_dsemulret(struct pt_regs *xcp)
759     {
760     #ifdef DSEMUL_TRACE
761     	printk("desemulret\n");
762     #endif
763     	/* Set EPC to return to post-branch instruction */
764     	xcp->cp0_epc = current->thread.dsemul_epc;
765     	/*
766     	 * Clear the state that got us here.
767     	 */
768     	current->thread.dsemul_aerpc = (unsigned long) 0;
769     
770     	return 0;
771     }
772     
773     
774     #define AdELOAD 0x8c000001	/* lw $0,1($0) */
775     
776     static int
777     mips_dsemul(struct pt_regs *xcp, mips_instruction ir, vaddr_t cpc)
778     {
779     	mips_instruction *dsemul_insns;
780     	mips_instruction forcetrap;
781     	extern asmlinkage void handle_dsemulret(void);
782     
783     	if (ir == 0) {		/* a nop is easy */
784     		xcp->cp0_epc = VA_TO_REG(cpc);
785     		return 0;
786     	}
787     #ifdef DSEMUL_TRACE
788     	printk("desemul %p %p\n", REG_TO_VA(xcp->cp0_epc), cpc);
789     #endif
790     
791     	/* 
792     	 * The strategy is to push the instruction onto the user stack 
793     	 * and put a trap after it which we can catch and jump to 
794     	 * the required address any alternative apart from full 
795     	 * instruction emulation!!.
796     	 */
797     	dsemul_insns = (mips_instruction *) (xcp->regs[29] & ~3);
798     	dsemul_insns -= 3;	/* Two instructions, plus one for luck ;-) */
799     
800     	/* Verify that the stack pointer is not competely insane */
801     	if (verify_area(VERIFY_WRITE, dsemul_insns,
802     	                sizeof(mips_instruction) * 2))
803     		return SIGBUS;
804     
805     	if (mips_put_word(xcp, &dsemul_insns[0], ir)) {
806     		fpuemuprivate.stats.errors++;
807     		return SIGBUS;
808     	}
809     
810     	/* 
811     	 * Algorithmics used a system call instruction, and
812     	 * borrowed that vector.  MIPS/Linux version is a bit
813     	 * more heavyweight in the interests of portability and
814     	 * multiprocessor support.  We flag the thread for special
815     	 * handling in the unaligned access handler and force an
816     	 * address error excpetion.
817     	 */
818     
819     	/* If one is *really* paranoid, one tests for a bad stack pointer */
820     	if ((xcp->regs[29] & 0x3) == 0x3)
821     		forcetrap = AdELOAD - 1;
822     	else
823     		forcetrap = AdELOAD;
824     
825     	if (mips_put_word(xcp, &dsemul_insns[1], forcetrap)) {
826     		fpuemuprivate.stats.errors++;
827     		return (SIGBUS);
828     	}
829     
830     	/* Set thread state to catch and handle the exception */
831     	current->thread.dsemul_epc = (unsigned long) cpc;
832     	current->thread.dsemul_aerpc = (unsigned long) &dsemul_insns[1];
833     	xcp->cp0_epc = VA_TO_REG & dsemul_insns[0];
834     	flush_cache_sigtramp((unsigned long) dsemul_insns);
835     
836     	return SIGILL;		/* force out of emulation loop */
837     }
838     
839     /* 
840      * Conversion table from MIPS compare ops 48-63
841      * cond = ieee754dp_cmp(x,y,IEEE754_UN);
842      */
843     static const unsigned char cmptab[8] = {
844     	0,					/* cmp_0 (sig) cmp_sf */
845     	IEEE754_CUN,				/* cmp_un (sig) cmp_ngle */
846     	IEEE754_CEQ,				/* cmp_eq (sig) cmp_seq */
847     	IEEE754_CEQ | IEEE754_CUN,		/* cmp_ueq (sig) cmp_ngl  */
848     	IEEE754_CLT,				/* cmp_olt (sig) cmp_lt */
849     	IEEE754_CLT | IEEE754_CUN,		/* cmp_ult (sig) cmp_nge */
850     	IEEE754_CLT | IEEE754_CEQ,		/* cmp_ole (sig) cmp_le */
851     	IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */
852     };
853     
854     #define SIFROMREG(si,x)	((si) = ctx->regs[x])
855     #define SITOREG(si,x)	(ctx->regs[x] = (int)(si))
856     
857     #if __mips64 && !defined(SINGLE_ONLY_FPU)
858     #define DIFROMREG(di,x)	((di) = ctx->regs[x])
859     #define DITOREG(di,x)	(ctx->regs[x] = (di))
860     #endif
861     
862     #define SPFROMREG(sp,x)	((sp).bits = ctx->regs[x])
863     #define SPTOREG(sp,x)	(ctx->regs[x] = (sp).bits)
864     
865     #ifdef CP0_STATUS_FR_SUPPORT
866     #define DPFROMREG(dp,x)	((dp).bits = \
867     			ctx->regs[(xcp->cp0_status & ST0_FR) ? x : (x & ~1)])
868     #define DPTOREG(dp,x)	(ctx->regs[(xcp->cp0_status & ST0_FR) ? x : (x & ~1)]\
869     			= (dp).bits)
870     #else
871     /* Beware: MIPS COP1 doubles are always little_word endian in registers */
872     #define DPFROMREG(dp,x)	\
873       ((dp).bits = ((unsigned long long)ctx->regs[(x)+1] << 32) | ctx->regs[x])
874     #define DPTOREG(dp,x) \
875       (ctx->regs[x] = (dp).bits, ctx->regs[(x)+1] = (dp).bits >> 32)
876     #endif
877     
878     #if __mips >= 4 && __mips != 32
879     
880     /*
881      * Additional MIPS4 instructions
882      */
883     
884     static ieee754dp fpemu_dp_recip(ieee754dp d)
885     {
886     	return ieee754dp_div(ieee754dp_one(0), d);
887     }
888     
889     static ieee754dp fpemu_dp_rsqrt(ieee754dp d)
890     {
891     	return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d));
892     }
893     
894     static ieee754sp fpemu_sp_recip(ieee754sp s)
895     {
896     	return ieee754sp_div(ieee754sp_one(0), s);
897     }
898     
899     static ieee754sp fpemu_sp_rsqrt(ieee754sp s)
900     {
901     	return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
902     }
903     
904     
905     static ieee754dp fpemu_dp_madd(ieee754dp r, ieee754dp s, ieee754dp t)
906     {
907     	return ieee754dp_add(ieee754dp_mul(s, t), r);
908     }
909     
910     static ieee754dp fpemu_dp_msub(ieee754dp r, ieee754dp s, ieee754dp t)
911     {
912     	return ieee754dp_sub(ieee754dp_mul(s, t), r);
913     }
914     
915     static ieee754dp fpemu_dp_nmadd(ieee754dp r, ieee754dp s, ieee754dp t)
916     {
917     	return ieee754dp_neg(ieee754dp_add(ieee754dp_mul(s, t), r));
918     }
919     
920     static ieee754dp fpemu_dp_nmsub(ieee754dp r, ieee754dp s, ieee754dp t)
921     {
922     	return ieee754dp_neg(ieee754dp_sub(ieee754dp_mul(s, t), r));
923     }
924     
925     
926     static ieee754sp fpemu_sp_madd(ieee754sp r, ieee754sp s, ieee754sp t)
927     {
928     	return ieee754sp_add(ieee754sp_mul(s, t), r);
929     }
930     
931     static ieee754sp fpemu_sp_msub(ieee754sp r, ieee754sp s, ieee754sp t)
932     {
933     	return ieee754sp_sub(ieee754sp_mul(s, t), r);
934     }
935     
936     static ieee754sp fpemu_sp_nmadd(ieee754sp r, ieee754sp s, ieee754sp t)
937     {
938     	return ieee754sp_neg(ieee754sp_add(ieee754sp_mul(s, t), r));
939     }
940     
941     static ieee754sp fpemu_sp_nmsub(ieee754sp r, ieee754sp s, ieee754sp t)
942     {
943     	return ieee754sp_neg(ieee754sp_sub(ieee754sp_mul(s, t), r));
944     }
945     
946     static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
947                         mips_instruction ir)
948     {
949     	unsigned rcsr = 0;	/* resulting csr */
950     
951     	fpuemuprivate.stats.cp1xops++;
952     
953     	switch (MIPSInst_FMA_FFMT(ir)) {
954     	case s_fmt:		/* 0 */
955     		{
956     			ieee754sp(*handler) (ieee754sp, ieee754sp,
957     					     ieee754sp);
958     			ieee754sp fd, fr, fs, ft;
959     
960     			switch (MIPSInst_FUNC(ir)) {
961     			case lwxc1_op:
962     				{
963     					void *va =
964     					    REG_TO_VA(xcp->
965     						      regs[MIPSInst_FR(ir)]
966     						      +
967     						      xcp->
968     						      regs[MIPSInst_FT
969     							   (ir)]);
970     					fpureg_t val;
971     					int err = 0;
972     					val = mips_get_word(xcp, va, &err);
973     					if (err) {
974     						fpuemuprivate.stats.
975     						    errors++;
976     						return SIGBUS;
977     					}
978     					if (xcp->cp0_status & ST0_FR) {
979     						/* load whole register */
980     						ctx->
981     						    regs[MIPSInst_FD(ir)] =
982     						    val;
983     					} else if (MIPSInst_FD(ir) & 1) {
984     						/* load to m.s. 32 bits */
985     #if defined(SINGLE_ONLY_FPU)
986     						/* illegal register in single-float mode */
987     						return SIGILL;
988     #else
989     						ctx->
990     						    regs[
991     							 (MIPSInst_FD(ir) &
992     							  ~1)] &=
993     						    0xffffffff;
994     						ctx->
995     						    regs[
996     							 (MIPSInst_FD(ir) &
997     							  ~1)] |=
998     						    val << 32;
999     #endif
1000     					} else {
1001     						/* load to l.s. 32 bits */
1002     						ctx->
1003     						    regs[MIPSInst_FD(ir)]
1004     						    &= ~0xffffffffLL;
1005     						ctx->
1006     						    regs[MIPSInst_FD(ir)]
1007     						    |= val;
1008     					}
1009     				}
1010     				break;
1011     
1012     			case swxc1_op:
1013     				{
1014     					void *va =
1015     					    REG_TO_VA(xcp->
1016     						      regs[MIPSInst_FR(ir)]
1017     						      +
1018     						      xcp->
1019     						      regs[MIPSInst_FT
1020     							   (ir)]);
1021     					unsigned int val;
1022     					if (xcp->cp0_status & ST0_FR) {
1023     						/* store whole register */
1024     						val =
1025     						    ctx->
1026     						    regs[MIPSInst_FS(ir)];
1027     					} else if (MIPSInst_FS(ir) & 1) {
1028     #if defined(SINGLE_ONLY_FPU)
1029     						/* illegal register in single-float mode */
1030     						return SIGILL;
1031     #else
1032     						/* store from m.s. 32 bits */
1033     						val =
1034     						    ctx->
1035     						    regs[
1036     							 (MIPSInst_FS(ir) &
1037     							  ~1)] >> 32;
1038     #endif
1039     					} else {
1040     						/* store from l.s. 32 bits */
1041     						val =
1042     						    ctx->
1043     						    regs[MIPSInst_FS(ir)];
1044     					}
1045     					if (mips_put_word(xcp, va, val)) {
1046     						fpuemuprivate.stats.
1047     						    errors++;
1048     						return SIGBUS;
1049     					}
1050     				}
1051     				break;
1052     
1053     			case madd_s_op:
1054     				handler = fpemu_sp_madd;
1055     				goto scoptop;
1056     			case msub_s_op:
1057     				handler = fpemu_sp_msub;
1058     				goto scoptop;
1059     			case nmadd_s_op:
1060     				handler = fpemu_sp_nmadd;
1061     				goto scoptop;
1062     			case nmsub_s_op:
1063     				handler = fpemu_sp_nmsub;
1064     				goto scoptop;
1065     
1066     			      scoptop:
1067     				SPFROMREG(fr, MIPSInst_FR(ir));
1068     				SPFROMREG(fs, MIPSInst_FS(ir));
1069     				SPFROMREG(ft, MIPSInst_FT(ir));
1070     				fd = (*handler) (fr, fs, ft);
1071     				SPTOREG(fd, MIPSInst_FD(ir));
1072     
1073     			      copcsr:
1074     				if (ieee754_cxtest(IEEE754_INEXACT))
1075     					rcsr |=
1076     					    FPU_CSR_INE_X | FPU_CSR_INE_S;
1077     				if (ieee754_cxtest(IEEE754_UNDERFLOW))
1078     					rcsr |=
1079     					    FPU_CSR_UDF_X | FPU_CSR_UDF_S;
1080     				if (ieee754_cxtest(IEEE754_OVERFLOW))
1081     					rcsr |=
1082     					    FPU_CSR_OVF_X | FPU_CSR_OVF_S;
1083     				if (ieee754_cxtest
1084     				    (IEEE754_INVALID_OPERATION)) rcsr |=
1085     					    FPU_CSR_INV_X | FPU_CSR_INV_S;
1086     
1087     				ctx->sr =
1088     				    (ctx->sr & ~FPU_CSR_ALL_X) | rcsr;
1089     				if ((ctx->sr >> 5) & ctx->
1090     				    sr & FPU_CSR_ALL_E) {
1091     		/*printk ("SIGFPE: fpu csr = %08x\n",ctx->sr); */
1092     					return SIGFPE;
1093     				}
1094     
1095     				break;
1096     
1097     			default:
1098     				return SIGILL;
1099     			}
1100     		}
1101     		break;
1102     
1103     #if !defined(SINGLE_ONLY_FPU)
1104     	case d_fmt:		/* 1 */
1105     		{
1106     			ieee754dp(*handler) (ieee754dp, ieee754dp,
1107     					     ieee754dp);
1108     			ieee754dp fd, fr, fs, ft;
1109     
1110     			switch (MIPSInst_FUNC(ir)) {
1111     			case ldxc1_op:
1112     				{
1113     					void *va =
1114     					    REG_TO_VA(xcp->
1115     						      regs[MIPSInst_FR(ir)]
1116     						      +
1117     						      xcp->
1118     						      regs[MIPSInst_FT
1119     							   (ir)]);
1120     					int err = 0;
1121     					ctx->regs[MIPSInst_FD(ir)] =
1122     					    mips_get_dword(xcp, va, &err);
1123     					if (err) {
1124     						fpuemuprivate.stats.
1125     						    errors++;
1126     						return SIGBUS;
1127     					}
1128     				}
1129     				break;
1130     
1131     			case sdxc1_op:
1132     				{
1133     					void *va =
1134     					    REG_TO_VA(xcp->
1135     						      regs[MIPSInst_FR(ir)]
1136     						      +
1137     						      xcp->
1138     						      regs[MIPSInst_FT
1139     							   (ir)]);
1140     					if (mips_put_dword
1141     					    (xcp, va,
1142     					     ctx->regs[MIPSInst_FS(ir)])) {
1143     						fpuemuprivate.stats.
1144     						    errors++;
1145     						return SIGBUS;
1146     					}
1147     				}
1148     				break;
1149     
1150     			case madd_d_op:
1151     				handler = fpemu_dp_madd;
1152     				goto dcoptop;
1153     			case msub_d_op:
1154     				handler = fpemu_dp_msub;
1155     				goto dcoptop;
1156     			case nmadd_d_op:
1157     				handler = fpemu_dp_nmadd;
1158     				goto dcoptop;
1159     			case nmsub_d_op:
1160     				handler = fpemu_dp_nmsub;
1161     				goto dcoptop;
1162     
1163     			      dcoptop:
1164     				DPFROMREG(fr, MIPSInst_FR(ir));
1165     				DPFROMREG(fs, MIPSInst_FS(ir));
1166     				DPFROMREG(ft, MIPSInst_FT(ir));
1167     				fd = (*handler) (fr, fs, ft);
1168     				DPTOREG(fd, MIPSInst_FD(ir));
1169     				goto copcsr;
1170     
1171     			default:
1172     				return SIGILL;
1173     			}
1174     		}
1175     		break;
1176     #endif
1177     
1178     	case 0x7:		/* 7 */
1179     		{
1180     			if (MIPSInst_FUNC(ir) != pfetch_op) {
1181     				return SIGILL;
1182     			}
1183     			/* ignore prefx operation */
1184     		}
1185     		break;
1186     
1187     	default:
1188     		return SIGILL;
1189     	}
1190     
1191     	return 0;
1192     }
1193     #endif
1194     
1195     
1196     
1197     /*
1198      * Emulate a single COP1 arithmetic instruction.
1199      */
1200     static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
1201                        mips_instruction ir)
1202     {
1203     	int rfmt;		/* resulting format */
1204     	unsigned rcsr = 0;	/* resulting csr */
1205     	unsigned cond;
1206     	union {
1207     		ieee754dp d;
1208     		ieee754sp s;
1209     		int w;
1210     #if __mips64
1211     		long long l;
1212     #endif
1213     	} rv;			/* resulting value */
1214     
1215     	fpuemuprivate.stats.cp1ops++;
1216     	switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
1217     	case s_fmt: {		/* 0 */
1218     		ieee754sp(*handler) ();
1219     
1220     		switch (MIPSInst_FUNC(ir)) {
1221     			/* binary ops */
1222     		case fadd_op:
1223     			handler = ieee754sp_add;
1224     			goto scopbop;
1225     		case fsub_op:
1226     			handler = ieee754sp_sub;
1227     			goto scopbop;
1228     		case fmul_op:
1229     			handler = ieee754sp_mul;
1230     			goto scopbop;
1231     		case fdiv_op:
1232     			handler = ieee754sp_div;
1233     			goto scopbop;
1234     
1235     			/* unary  ops */
1236     #if __mips >= 2 || __mips64
1237     		case fsqrt_op:
1238     			handler = ieee754sp_sqrt;
1239     			goto scopuop;
1240     #endif
1241     #if __mips >= 4 && __mips != 32
1242     		case frsqrt_op:
1243     			handler = fpemu_sp_rsqrt;
1244     			goto scopuop;
1245     		case frecip_op:
1246     			handler = fpemu_sp_recip;
1247     			goto scopuop;
1248     #endif
1249     #if __mips >= 4
1250     		case fmovc_op:
1251     			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
1252     			if (((ctx->sr & cond) != 0) !=
1253     			    ((MIPSInst_FT(ir) & 1) != 0))
1254     				return 0;
1255     			SPFROMREG(rv.s, MIPSInst_FS(ir));
1256     			break;
1257     		case fmovz_op:
1258     			if (xcp->regs[MIPSInst_FT(ir)] != 0)
1259     				return 0;
1260     			SPFROMREG(rv.s, MIPSInst_FS(ir));
1261     			break;
1262     		case fmovn_op:
1263     			if (xcp->regs[MIPSInst_FT(ir)] == 0)
1264     				return 0;
1265     			SPFROMREG(rv.s, MIPSInst_FS(ir));
1266     			break;
1267     #endif
1268     		case fabs_op:
1269     			handler = ieee754sp_abs;
1270     			goto scopuop;
1271     		case fneg_op:
1272     			handler = ieee754sp_neg;
1273     			goto scopuop;
1274     		case fmov_op:
1275     			/* an easy one */
1276     			SPFROMREG(rv.s, MIPSInst_FS(ir));
1277     			break;
1278     			/* binary op on handler */
1279     scopbop:
1280     			{
1281     				ieee754sp fs, ft;
1282     
1283     				SPFROMREG(fs, MIPSInst_FS(ir));
1284     				SPFROMREG(ft, MIPSInst_FT(ir));
1285     
1286     				rv.s = (*handler) (fs, ft);
1287     				goto copcsr;
1288     			}
1289     scopuop:
1290     			{
1291     				ieee754sp fs;
1292     
1293     				SPFROMREG(fs, MIPSInst_FS(ir));
1294     				rv.s = (*handler) (fs);
1295     				goto copcsr;
1296     			}
1297     copcsr:
1298     			if (ieee754_cxtest(IEEE754_INEXACT))
1299     				rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
1300     			if (ieee754_cxtest(IEEE754_UNDERFLOW))
1301     				rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
1302     			if (ieee754_cxtest(IEEE754_OVERFLOW))
1303     				rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
1304     			if (ieee754_cxtest(IEEE754_ZERO_DIVIDE))
1305     				rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
1306     			if (ieee754_cxtest
1307     				(IEEE754_INVALID_OPERATION)) rcsr |=
1308     					    FPU_CSR_INV_X | FPU_CSR_INV_S;
1309     				break;
1310     
1311     				/* unary conv ops */
1312     		case fcvts_op:
1313     			return SIGILL;	/* not defined */
1314     		case fcvtd_op: {
1315     #ifdef SINGLE_ONLY_FPU
1316     			return SIGILL;	/* not defined */
1317     #else
1318     			ieee754sp fs;
1319     
1320     			SPFROMREG(fs, MIPSInst_FS(ir));
1321     			rv.d = ieee754dp_fsp(fs);
1322     			rfmt = d_fmt;
1323     			goto copcsr;
1324     		}
1325     #endif
1326     		case fcvtw_op: {
1327     			ieee754sp fs;
1328     
1329     			SPFROMREG(fs, MIPSInst_FS(ir));
1330     			rv.w = ieee754sp_tint(fs);
1331     			rfmt = w_fmt;
1332     			goto copcsr;
1333     		}
1334     
1335     #if __mips >= 2 || __mips64
1336     		case fround_op:
1337     		case ftrunc_op:
1338     		case fceil_op:
1339     		case ffloor_op: {
1340     			unsigned int oldrm = ieee754_csr.rm;
1341     			ieee754sp fs;
1342     
1343     			SPFROMREG(fs, MIPSInst_FS(ir));
1344     			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
1345     			rv.w = ieee754sp_tint(fs);
1346     			ieee754_csr.rm = oldrm;
1347     			rfmt = w_fmt;
1348     			goto copcsr;
1349     		}
1350     #endif /* __mips >= 2 */
1351     
1352     #if __mips64 && !defined(SINGLE_ONLY_FPU)
1353     		case fcvtl_op: {
1354     			ieee754sp fs;
1355     
1356     			SPFROMREG(fs, MIPSInst_FS(ir));
1357     			rv.l = ieee754sp_tlong(fs);
1358     			rfmt = l_fmt;
1359     			goto copcsr;
1360     		}
1361     
1362     		case froundl_op:
1363     		case ftruncl_op:
1364     		case fceill_op:
1365     		case ffloorl_op: {
1366     			unsigned int oldrm = ieee754_csr.rm;
1367     			ieee754sp fs;
1368     
1369     			SPFROMREG(fs, MIPSInst_FS(ir));
1370     			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
1371     			rv.l = ieee754sp_tlong(fs);
1372     			ieee754_csr.rm = oldrm;
1373     			rfmt = l_fmt;
1374     			goto copcsr;
1375     		}
1376     #endif /* __mips64 && !fpu(single) */
1377     
1378     		default:
1379     			if (MIPSInst_FUNC(ir) >= fcmp_op) {
1380     				unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
1381     				ieee754sp fs, ft;
1382     
1383     				SPFROMREG(fs, MIPSInst_FS(ir));
1384     				SPFROMREG(ft, MIPSInst_FT(ir));
1385     				rv.w = ieee754sp_cmp(fs, ft, cmptab[cmpop & 0x7]);
1386     				rfmt = -1;
1387     				if ((cmpop & 0x8) && ieee754_cxtest(IEEE754_INVALID_OPERATION))
1388     					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
1389     				} else {
1390     					return SIGILL;
1391     				}
1392     				break;
1393     			}
1394     			break;
1395     		}
1396     
1397     #if !defined(SINGLE_ONLY_FPU)
1398     	case d_fmt: {
1399     		ieee754dp(*handler) ();
1400     
1401     		switch (MIPSInst_FUNC(ir)) {
1402     			/* binary ops */
1403     		case fadd_op:
1404     			handler = ieee754dp_add;
1405     			goto dcopbop;
1406     		case fsub_op:
1407     			handler = ieee754dp_sub;
1408     			goto dcopbop;
1409     		case fmul_op:
1410     			handler = ieee754dp_mul;
1411     			goto dcopbop;
1412     		case fdiv_op:
1413     			handler = ieee754dp_div;
1414     			goto dcopbop;
1415     
1416     			/* unary  ops */
1417     #if __mips >= 2 || __mips64
1418     		case fsqrt_op:
1419     			handler = ieee754dp_sqrt;
1420     			goto dcopuop;
1421     #endif
1422     #if __mips >= 4 && __mips != 32
1423     		case frsqrt_op:
1424     			handler = fpemu_dp_rsqrt;
1425     			goto dcopuop;
1426     		case frecip_op:
1427     			handler = fpemu_dp_recip;
1428     			goto dcopuop;
1429     #endif
1430     #if __mips >= 4
1431     		case fmovc_op:
1432     			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
1433     			if (((ctx->sr & cond) != 0) != ((MIPSInst_FT(ir) & 1) != 0))
1434     				return 0;
1435     			DPFROMREG(rv.d, MIPSInst_FS(ir));
1436     			break;
1437     		case fmovz_op:
1438     			if (xcp->regs[MIPSInst_FT(ir)] != 0)
1439     				return 0;
1440     			DPFROMREG(rv.d, MIPSInst_FS(ir));
1441     			break;
1442     		case fmovn_op:
1443     			if (xcp->regs[MIPSInst_FT(ir)] == 0)
1444     				return 0;
1445     			DPFROMREG(rv.d, MIPSInst_FS(ir));
1446     			break;
1447     #endif
1448     		case fabs_op:
1449     			handler = ieee754dp_abs;
1450     			goto dcopuop;
1451     
1452     		case fneg_op:
1453     			handler = ieee754dp_neg;
1454     			goto dcopuop;
1455     
1456     		case fmov_op:
1457     			/* an easy one */
1458     			DPFROMREG(rv.d, MIPSInst_FS(ir));
1459     			break;
1460     
1461     			/* binary op on handler */
1462     dcopbop:
1463     			{
1464     				ieee754dp fs, ft;
1465     
1466     				DPFROMREG(fs, MIPSInst_FS(ir));
1467     				DPFROMREG(ft, MIPSInst_FT(ir));
1468     
1469     				rv.d = (*handler) (fs, ft);
1470     				goto copcsr;
1471     			}
1472     dcopuop:
1473     			{
1474     				ieee754dp fs;
1475     
1476     				DPFROMREG(fs, MIPSInst_FS(ir));
1477     				rv.d = (*handler) (fs);
1478     				goto copcsr;
1479     			}
1480     
1481     		/* unary conv ops */
1482     		case fcvts_op: {
1483     			ieee754dp fs;
1484     
1485     			DPFROMREG(fs, MIPSInst_FS(ir));
1486     			rv.s = ieee754sp_fdp(fs);
1487     			rfmt = s_fmt;
1488     			goto copcsr;
1489     		}
1490     		case fcvtd_op:
1491     			return SIGILL;	/* not defined */
1492     
1493     		case fcvtw_op: {
1494     			ieee754dp fs;
1495     
1496     			DPFROMREG(fs, MIPSInst_FS(ir));
1497     			rv.w = ieee754dp_tint(fs);	/* wrong */
1498     			rfmt = w_fmt;
1499     			goto copcsr;
1500     		}
1501     
1502     #if __mips >= 2 || __mips64
1503     		case fround_op:
1504     		case ftrunc_op:
1505     		case fceil_op:
1506     		case ffloor_op: {
1507     			unsigned int oldrm = ieee754_csr.rm;
1508     			ieee754dp fs;
1509     
1510     			DPFROMREG(fs, MIPSInst_FS(ir));
1511     			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
1512     			rv.w = ieee754dp_tint(fs);
1513     			ieee754_csr.rm = oldrm;
1514     			rfmt = w_fmt;
1515     			goto copcsr;
1516     		}
1517     #endif
1518     
1519     #if __mips64 && !defined(SINGLE_ONLY_FPU)
1520     		case fcvtl_op: {
1521     			ieee754dp fs;
1522     
1523     			DPFROMREG(fs, MIPSInst_FS(ir));
1524     			rv.l = ieee754dp_tlong(fs);
1525     			rfmt = l_fmt;
1526     			goto copcsr;
1527     		}
1528     
1529     		case froundl_op:
1530     		case ftruncl_op:
1531     		case fceill_op:
1532     		case ffloorl_op: {
1533     			unsigned int oldrm = ieee754_csr.rm;
1534     			ieee754dp fs;
1535     
1536     			DPFROMREG(fs, MIPSInst_FS(ir));
1537     			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
1538     			rv.l = ieee754dp_tlong(fs);
1539     			ieee754_csr.rm = oldrm;
1540     			rfmt = l_fmt;
1541     			goto copcsr;
1542     		}
1543     #endif /* __mips >= 3 && !fpu(single) */
1544     
1545     		default:
1546     			if (MIPSInst_FUNC(ir) >= fcmp_op) {
1547     				unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
1548     				ieee754dp fs, ft;
1549     
1550     				DPFROMREG(fs, MIPSInst_FS(ir));
1551     				DPFROMREG(ft, MIPSInst_FT(ir));
1552     				rv.w = ieee754dp_cmp(fs, ft, cmptab[cmpop & 0x7]);
1553     				rfmt = -1;
1554     				if ((cmpop & 0x8) && ieee754_cxtest (IEEE754_INVALID_OPERATION))
1555     					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
1556     			} else {
1557     				return SIGILL;
1558     			}
1559     			break;
1560     		}
1561     		break;
1562     	}
1563     #endif /* !defined(SINGLE_ONLY_FPU) */
1564     
1565     	case w_fmt: {
1566     		switch (MIPSInst_FUNC(ir)) {
1567     		case fcvts_op:
1568     			/* convert word to single precision real */
1569     			rv.s = ieee754sp_fint(ctx-> regs[MIPSInst_FS(ir)]);
1570     			rfmt = s_fmt;
1571     			goto copcsr;
1572     #if !defined(SINGLE_ONLY_FPU)
1573     		case fcvtd_op:
1574     			/* convert word to double precision real */
1575     			rv.d = ieee754dp_fint(ctx-> regs[MIPSInst_FS(ir)]);
1576     			rfmt = d_fmt;
1577     			goto copcsr;
1578     #endif
1579     		default:
1580     			return SIGILL;
1581     		}
1582     		break;
1583     	}
1584     
1585     #if __mips64 && !defined(SINGLE_ONLY_FPU)
1586     	case l_fmt: {
1587     		switch (MIPSInst_FUNC(ir)) {
1588     		case fcvts_op:
1589     			/* convert long to single precision real */
1590     			rv.s = ieee754sp_flong(ctx-> regs[MIPSInst_FS(ir)]);
1591     			rfmt = s_fmt;
1592     			goto copcsr;
1593     		case fcvtd_op:
1594     			/* convert long to double precision real */
1595     			rv.d = ieee754dp_flong(ctx-> regs[MIPSInst_FS(ir)]);
1596     			rfmt = d_fmt;
1597     			goto copcsr;
1598     		default:
1599     			return SIGILL;
1600     		}
1601     		break;
1602     	}
1603     #endif
1604     
1605     	default:
1606     		return SIGILL;
1607     	}
1608     
1609     	/*
1610     	 * Update the fpu CSR register for this operation.
1611     	 * If an exception is required, generate a tidy SIGFPE exception,
1612     	 * without updating the result register.
1613     	 * Note: cause exception bits do not accumulate, they are rewritten
1614     	 * for each op; only the flag/sticky bits accumulate.
1615     	 */
1616     	ctx->sr = (ctx->sr & ~FPU_CSR_ALL_X) | rcsr;
1617     	if ((ctx->sr >> 5) & ctx->sr & FPU_CSR_ALL_E) {
1618     		/*printk ("SIGFPE: fpu csr = %08x\n",ctx->sr); */
1619     		return SIGFPE;
1620     	}
1621     
1622     	/* 
1623     	 * Now we can safely write the result back to the register file.
1624     	 */
1625     	switch (rfmt) {
1626     	case -1: {
1627     #if __mips >= 4
1628     		cond = fpucondbit[MIPSInst_FD(ir) >> 2];
1629     #else
1630     		cond = FPU_CSR_COND;
1631     #endif
1632     		if (rv.w)
1633     			ctx->sr |= cond;
1634     		else
1635     			ctx->sr &= ~cond;
1636     		break;
1637     	}
1638     #if !defined(SINGLE_ONLY_FPU)
1639     	case d_fmt:
1640     		DPTOREG(rv.d, MIPSInst_FD(ir));
1641     		break;
1642     #endif
1643     	case s_fmt:
1644     		SPTOREG(rv.s, MIPSInst_FD(ir));
1645     		break;
1646     	case w_fmt:
1647     		SITOREG(rv.w, MIPSInst_FD(ir));
1648     		break;
1649     #if __mips64 && !defined(SINGLE_ONLY_FPU)
1650     	case l_fmt:
1651     		DITOREG(rv.l, MIPSInst_FD(ir));
1652     		break;
1653     #endif
1654     	default:
1655     		return SIGILL;
1656     	}
1657     
1658     	return 0;
1659     }
1660     
1661     
1662     /*
1663      * Emulate the floating point instruction at EPC, and continue to run until we
1664      * hit a non-fp instruction, or a backward branch.  This cuts down dramatically
1665      * on the per instruction exception overhead.
1666      */
1667     int fpu_emulator_cop1Handler(struct pt_regs *xcp)
1668     {
1669     	struct mips_fpu_soft_struct *ctx = &current->thread.fpu.soft;
1670     	unsigned long oldepc, prevepc;
1671     	unsigned int insn;
1672     	int sig = 0;
1673     	int err = 0;
1674     
1675     	oldepc = xcp->cp0_epc;
1676     	do {
1677     		if (current->need_resched)
1678     			schedule();
1679     
1680     		prevepc = xcp->cp0_epc;
1681     		insn = mips_get_word(xcp, REG_TO_VA(xcp->cp0_epc), &err);
1682     		if (err) {
1683     			fpuemuprivate.stats.errors++;
1684     			return SIGBUS;
1685     		}
1686     		if (insn != 0)
1687     			sig = cop1Emulate(xcp, ctx);
1688     		else
1689     			xcp->cp0_epc += 4;	/* skip nops */
1690     
1691     		if (mips_cpu.options & MIPS_CPU_FPU)
1692     			break;
1693     	} while (xcp->cp0_epc > prevepc && sig == 0);
1694     
1695     	/* SIGILL indicates a non-fpu instruction */
1696     	if (sig == SIGILL && xcp->cp0_epc != oldepc)
1697     		/* but if epc has advanced, then ignore it */
1698     		sig = 0;
1699     
1700     	return sig;
1701     }
1702     
1703     
1704     #ifdef NOTDEF
1705     /*
1706      * Patch up the hardware fpu state when an f.p. exception occurs.  
1707      */
1708     static int cop1Patcher(int xcptno, struct pt_regs *xcp)
1709     {
1710     	struct mips_fpu_soft_struct *ctx = &current->thread.fpu.soft;
1711     	unsigned sr;
1712     	int sig;
1713     
1714     	/* reenable Cp1, else fpe_save() will get nested exception */
1715     	sr = mips_bissr(ST0_CU1);
1716     
1717     	/* get fpu registers and status, then clear pending exceptions */
1718     	fpe_save(ctx);
1719     	fpe_setsr(ctx->sr &= ~FPU_CSR_ALL_X);
1720     
1721     	/* get current rounding mode for IEEE library, and emulate insn */
1722     	ieee754_csr.rm = ieee_rm[ctx->sr & 0x3];
1723     	sig = cop1Emulate(xcp, ctx);
1724     
1725     	/* don't return with f.p. exceptions pending */
1726     	ctx->sr &= ~FPU_CSR_ALL_X;
1727     	fpe_restore(ctx);
1728     
1729     	mips_setsr(sr);
1730     	return sig;
1731     }
1732     
1733     void _cop1_init(int emulate)
1734     {
1735     	extern int _nofpu;
1736     
1737     	if (emulate) {
1738     		/* 
1739     		 * Install cop1 emulator to handle "coprocessor unusable" exception
1740     		 */
1741     		xcption(XCPTCPU, cop1Handler);
1742     		fpuemuactive = 1;	/* tell dbg.c that we are in charge */
1743     		_nofpu = 0;	/* tell setjmp() it "has" an fpu */
1744     	} else {
1745     		/* 
1746     		 * Install cop1 emulator for floating point exceptions only,
1747     		 * i.e. denormalised results, underflow, overflow etc, which
1748     		 * must be emulated in s/w.
1749     		 */
1750     #ifdef 1
1751     		/* r4000 or above use dedicate exception */
1752     		xcption(XCPTFPE, cop1Patcher);
1753     #else
1754     		/* r3000 et al use interrupt */
1755     		extern int _sbd_getfpuintr(void);
1756     		int intno = _sbd_getfpuintr();
1757     		intrupt(intno, cop1Patcher, 0);
1758     		mips_bissr(SR_IM0 << intno);
1759     #endif
1760     
1761     #if (#cpu(r4640) || #cpu(r4650)) && !defined(SINGLE_ONLY_FPU)
1762     		/* For R4640/R4650 compiled *without* the -msingle-float flag,
1763     		   then we share responsibility: the h/w handles the single
1764     		   precision operations, and the trap emulator handles the
1765     		   double precision. We set fpuemuactive so that dbg.c first
1766     		   fetches the s/w state before saving the h/w state. */
1767     		fpuemuactive = 1;
1768     		{
1769     			int i;
1770     			/* initialise the unused d.p high order words to be NaN */
1771     			for (i = 0; i < 32; i++)
1772     				current->thread.fpu.soft.regs[i] =
1773     				    0x7ff80bad00000000LL;
1774     		}
1775     #endif				/* (r4640 || r4650) && !fpu(single) */
1776     	}
1777     }
1778     #endif
1779