1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <linux/sched.h>
25#include <linux/debugfs.h>
26#include <linux/percpu-defs.h>
27#include <linux/perf_event.h>
28
29#include <asm/branch.h>
30#include <asm/inst.h>
31#include <asm/ptrace.h>
32#include <asm/signal.h>
33#include <linux/uaccess.h>
34
35#include <asm/cpu-info.h>
36#include <asm/processor.h>
37#include <asm/fpu_emulator.h>
38#include <asm/fpu.h>
39#include <asm/mips-r2-to-r6-emul.h>
40
41#include "ieee754.h"
42
43
44
45static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
46 mips_instruction);
47
48static int fpux_emu(struct pt_regs *,
49 struct mips_fpu_struct *, mips_instruction, void __user **);
50
51
52
53#define FPCREG_RID 0
54#define FPCREG_FCCR 25
55#define FPCREG_FEXR 26
56#define FPCREG_FENR 28
57#define FPCREG_CSR 31
58
59
60const unsigned int fpucondbit[8] = {
61 FPU_CSR_COND,
62 FPU_CSR_COND1,
63 FPU_CSR_COND2,
64 FPU_CSR_COND3,
65 FPU_CSR_COND4,
66 FPU_CSR_COND5,
67 FPU_CSR_COND6,
68 FPU_CSR_COND7
69};
70
71
72static const int sd_format[] = {16, 17, 0, 0, 0, 0, 0, 0};
73static const int sdps_format[] = {16, 17, 22, 0, 0, 0, 0, 0};
74static const int dwl_format[] = {17, 20, 21, 0, 0, 0, 0, 0};
75static const int swl_format[] = {16, 20, 21, 0, 0, 0, 0, 0};
76
77
78
79
80
81
82static int microMIPS32_to_MIPS32(union mips_instruction *insn_ptr)
83{
84 union mips_instruction insn = *insn_ptr;
85 union mips_instruction mips32_insn = insn;
86 int func, fmt, op;
87
88 switch (insn.mm_i_format.opcode) {
89 case mm_ldc132_op:
90 mips32_insn.mm_i_format.opcode = ldc1_op;
91 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
92 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
93 break;
94 case mm_lwc132_op:
95 mips32_insn.mm_i_format.opcode = lwc1_op;
96 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
97 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
98 break;
99 case mm_sdc132_op:
100 mips32_insn.mm_i_format.opcode = sdc1_op;
101 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
102 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
103 break;
104 case mm_swc132_op:
105 mips32_insn.mm_i_format.opcode = swc1_op;
106 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
107 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
108 break;
109 case mm_pool32i_op:
110
111 if ((insn.mm_i_format.rt == mm_bc1f_op) ||
112 (insn.mm_i_format.rt == mm_bc1t_op)) {
113 mips32_insn.fb_format.opcode = cop1_op;
114 mips32_insn.fb_format.bc = bc_op;
115 mips32_insn.fb_format.flag =
116 (insn.mm_i_format.rt == mm_bc1t_op) ? 1 : 0;
117 } else
118 return SIGILL;
119 break;
120 case mm_pool32f_op:
121 switch (insn.mm_fp0_format.func) {
122 case mm_32f_01_op:
123 case mm_32f_11_op:
124 case mm_32f_02_op:
125 case mm_32f_12_op:
126 case mm_32f_41_op:
127 case mm_32f_51_op:
128 case mm_32f_42_op:
129 case mm_32f_52_op:
130 op = insn.mm_fp0_format.func;
131 if (op == mm_32f_01_op)
132 func = madd_s_op;
133 else if (op == mm_32f_11_op)
134 func = madd_d_op;
135 else if (op == mm_32f_02_op)
136 func = nmadd_s_op;
137 else if (op == mm_32f_12_op)
138 func = nmadd_d_op;
139 else if (op == mm_32f_41_op)
140 func = msub_s_op;
141 else if (op == mm_32f_51_op)
142 func = msub_d_op;
143 else if (op == mm_32f_42_op)
144 func = nmsub_s_op;
145 else
146 func = nmsub_d_op;
147 mips32_insn.fp6_format.opcode = cop1x_op;
148 mips32_insn.fp6_format.fr = insn.mm_fp6_format.fr;
149 mips32_insn.fp6_format.ft = insn.mm_fp6_format.ft;
150 mips32_insn.fp6_format.fs = insn.mm_fp6_format.fs;
151 mips32_insn.fp6_format.fd = insn.mm_fp6_format.fd;
152 mips32_insn.fp6_format.func = func;
153 break;
154 case mm_32f_10_op:
155 func = -1;
156 op = insn.mm_fp5_format.op & 0x7;
157 if (op == mm_ldxc1_op)
158 func = ldxc1_op;
159 else if (op == mm_sdxc1_op)
160 func = sdxc1_op;
161 else if (op == mm_lwxc1_op)
162 func = lwxc1_op;
163 else if (op == mm_swxc1_op)
164 func = swxc1_op;
165
166 if (func != -1) {
167 mips32_insn.r_format.opcode = cop1x_op;
168 mips32_insn.r_format.rs =
169 insn.mm_fp5_format.base;
170 mips32_insn.r_format.rt =
171 insn.mm_fp5_format.index;
172 mips32_insn.r_format.rd = 0;
173 mips32_insn.r_format.re = insn.mm_fp5_format.fd;
174 mips32_insn.r_format.func = func;
175 } else
176 return SIGILL;
177 break;
178 case mm_32f_40_op:
179 op = -1;
180 if (insn.mm_fp2_format.op == mm_fmovt_op)
181 op = 1;
182 else if (insn.mm_fp2_format.op == mm_fmovf_op)
183 op = 0;
184 if (op != -1) {
185 mips32_insn.fp0_format.opcode = cop1_op;
186 mips32_insn.fp0_format.fmt =
187 sdps_format[insn.mm_fp2_format.fmt];
188 mips32_insn.fp0_format.ft =
189 (insn.mm_fp2_format.cc<<2) + op;
190 mips32_insn.fp0_format.fs =
191 insn.mm_fp2_format.fs;
192 mips32_insn.fp0_format.fd =
193 insn.mm_fp2_format.fd;
194 mips32_insn.fp0_format.func = fmovc_op;
195 } else
196 return SIGILL;
197 break;
198 case mm_32f_60_op:
199 func = -1;
200 if (insn.mm_fp0_format.op == mm_fadd_op)
201 func = fadd_op;
202 else if (insn.mm_fp0_format.op == mm_fsub_op)
203 func = fsub_op;
204 else if (insn.mm_fp0_format.op == mm_fmul_op)
205 func = fmul_op;
206 else if (insn.mm_fp0_format.op == mm_fdiv_op)
207 func = fdiv_op;
208 if (func != -1) {
209 mips32_insn.fp0_format.opcode = cop1_op;
210 mips32_insn.fp0_format.fmt =
211 sdps_format[insn.mm_fp0_format.fmt];
212 mips32_insn.fp0_format.ft =
213 insn.mm_fp0_format.ft;
214 mips32_insn.fp0_format.fs =
215 insn.mm_fp0_format.fs;
216 mips32_insn.fp0_format.fd =
217 insn.mm_fp0_format.fd;
218 mips32_insn.fp0_format.func = func;
219 } else
220 return SIGILL;
221 break;
222 case mm_32f_70_op:
223 func = -1;
224 if (insn.mm_fp0_format.op == mm_fmovn_op)
225 func = fmovn_op;
226 else if (insn.mm_fp0_format.op == mm_fmovz_op)
227 func = fmovz_op;
228 if (func != -1) {
229 mips32_insn.fp0_format.opcode = cop1_op;
230 mips32_insn.fp0_format.fmt =
231 sdps_format[insn.mm_fp0_format.fmt];
232 mips32_insn.fp0_format.ft =
233 insn.mm_fp0_format.ft;
234 mips32_insn.fp0_format.fs =
235 insn.mm_fp0_format.fs;
236 mips32_insn.fp0_format.fd =
237 insn.mm_fp0_format.fd;
238 mips32_insn.fp0_format.func = func;
239 } else
240 return SIGILL;
241 break;
242 case mm_32f_73_op:
243 switch (insn.mm_fp1_format.op) {
244 case mm_movf0_op:
245 case mm_movf1_op:
246 case mm_movt0_op:
247 case mm_movt1_op:
248 if ((insn.mm_fp1_format.op & 0x7f) ==
249 mm_movf0_op)
250 op = 0;
251 else
252 op = 1;
253 mips32_insn.r_format.opcode = spec_op;
254 mips32_insn.r_format.rs = insn.mm_fp4_format.fs;
255 mips32_insn.r_format.rt =
256 (insn.mm_fp4_format.cc << 2) + op;
257 mips32_insn.r_format.rd = insn.mm_fp4_format.rt;
258 mips32_insn.r_format.re = 0;
259 mips32_insn.r_format.func = movc_op;
260 break;
261 case mm_fcvtd0_op:
262 case mm_fcvtd1_op:
263 case mm_fcvts0_op:
264 case mm_fcvts1_op:
265 if ((insn.mm_fp1_format.op & 0x7f) ==
266 mm_fcvtd0_op) {
267 func = fcvtd_op;
268 fmt = swl_format[insn.mm_fp3_format.fmt];
269 } else {
270 func = fcvts_op;
271 fmt = dwl_format[insn.mm_fp3_format.fmt];
272 }
273 mips32_insn.fp0_format.opcode = cop1_op;
274 mips32_insn.fp0_format.fmt = fmt;
275 mips32_insn.fp0_format.ft = 0;
276 mips32_insn.fp0_format.fs =
277 insn.mm_fp3_format.fs;
278 mips32_insn.fp0_format.fd =
279 insn.mm_fp3_format.rt;
280 mips32_insn.fp0_format.func = func;
281 break;
282 case mm_fmov0_op:
283 case mm_fmov1_op:
284 case mm_fabs0_op:
285 case mm_fabs1_op:
286 case mm_fneg0_op:
287 case mm_fneg1_op:
288 if ((insn.mm_fp1_format.op & 0x7f) ==
289 mm_fmov0_op)
290 func = fmov_op;
291 else if ((insn.mm_fp1_format.op & 0x7f) ==
292 mm_fabs0_op)
293 func = fabs_op;
294 else
295 func = fneg_op;
296 mips32_insn.fp0_format.opcode = cop1_op;
297 mips32_insn.fp0_format.fmt =
298 sdps_format[insn.mm_fp3_format.fmt];
299 mips32_insn.fp0_format.ft = 0;
300 mips32_insn.fp0_format.fs =
301 insn.mm_fp3_format.fs;
302 mips32_insn.fp0_format.fd =
303 insn.mm_fp3_format.rt;
304 mips32_insn.fp0_format.func = func;
305 break;
306 case mm_ffloorl_op:
307 case mm_ffloorw_op:
308 case mm_fceill_op:
309 case mm_fceilw_op:
310 case mm_ftruncl_op:
311 case mm_ftruncw_op:
312 case mm_froundl_op:
313 case mm_froundw_op:
314 case mm_fcvtl_op:
315 case mm_fcvtw_op:
316 if (insn.mm_fp1_format.op == mm_ffloorl_op)
317 func = ffloorl_op;
318 else if (insn.mm_fp1_format.op == mm_ffloorw_op)
319 func = ffloor_op;
320 else if (insn.mm_fp1_format.op == mm_fceill_op)
321 func = fceill_op;
322 else if (insn.mm_fp1_format.op == mm_fceilw_op)
323 func = fceil_op;
324 else if (insn.mm_fp1_format.op == mm_ftruncl_op)
325 func = ftruncl_op;
326 else if (insn.mm_fp1_format.op == mm_ftruncw_op)
327 func = ftrunc_op;
328 else if (insn.mm_fp1_format.op == mm_froundl_op)
329 func = froundl_op;
330 else if (insn.mm_fp1_format.op == mm_froundw_op)
331 func = fround_op;
332 else if (insn.mm_fp1_format.op == mm_fcvtl_op)
333 func = fcvtl_op;
334 else
335 func = fcvtw_op;
336 mips32_insn.fp0_format.opcode = cop1_op;
337 mips32_insn.fp0_format.fmt =
338 sd_format[insn.mm_fp1_format.fmt];
339 mips32_insn.fp0_format.ft = 0;
340 mips32_insn.fp0_format.fs =
341 insn.mm_fp1_format.fs;
342 mips32_insn.fp0_format.fd =
343 insn.mm_fp1_format.rt;
344 mips32_insn.fp0_format.func = func;
345 break;
346 case mm_frsqrt_op:
347 case mm_fsqrt_op:
348 case mm_frecip_op:
349 if (insn.mm_fp1_format.op == mm_frsqrt_op)
350 func = frsqrt_op;
351 else if (insn.mm_fp1_format.op == mm_fsqrt_op)
352 func = fsqrt_op;
353 else
354 func = frecip_op;
355 mips32_insn.fp0_format.opcode = cop1_op;
356 mips32_insn.fp0_format.fmt =
357 sdps_format[insn.mm_fp1_format.fmt];
358 mips32_insn.fp0_format.ft = 0;
359 mips32_insn.fp0_format.fs =
360 insn.mm_fp1_format.fs;
361 mips32_insn.fp0_format.fd =
362 insn.mm_fp1_format.rt;
363 mips32_insn.fp0_format.func = func;
364 break;
365 case mm_mfc1_op:
366 case mm_mtc1_op:
367 case mm_cfc1_op:
368 case mm_ctc1_op:
369 case mm_mfhc1_op:
370 case mm_mthc1_op:
371 if (insn.mm_fp1_format.op == mm_mfc1_op)
372 op = mfc_op;
373 else if (insn.mm_fp1_format.op == mm_mtc1_op)
374 op = mtc_op;
375 else if (insn.mm_fp1_format.op == mm_cfc1_op)
376 op = cfc_op;
377 else if (insn.mm_fp1_format.op == mm_ctc1_op)
378 op = ctc_op;
379 else if (insn.mm_fp1_format.op == mm_mfhc1_op)
380 op = mfhc_op;
381 else
382 op = mthc_op;
383 mips32_insn.fp1_format.opcode = cop1_op;
384 mips32_insn.fp1_format.op = op;
385 mips32_insn.fp1_format.rt =
386 insn.mm_fp1_format.rt;
387 mips32_insn.fp1_format.fs =
388 insn.mm_fp1_format.fs;
389 mips32_insn.fp1_format.fd = 0;
390 mips32_insn.fp1_format.func = 0;
391 break;
392 default:
393 return SIGILL;
394 }
395 break;
396 case mm_32f_74_op:
397 mips32_insn.fp0_format.opcode = cop1_op;
398 mips32_insn.fp0_format.fmt =
399 sdps_format[insn.mm_fp4_format.fmt];
400 mips32_insn.fp0_format.ft = insn.mm_fp4_format.rt;
401 mips32_insn.fp0_format.fs = insn.mm_fp4_format.fs;
402 mips32_insn.fp0_format.fd = insn.mm_fp4_format.cc << 2;
403 mips32_insn.fp0_format.func =
404 insn.mm_fp4_format.cond | MM_MIPS32_COND_FC;
405 break;
406 default:
407 return SIGILL;
408 }
409 break;
410 default:
411 return SIGILL;
412 }
413
414 *insn_ptr = mips32_insn;
415 return 0;
416}
417
418
419
420
421
422
423
424int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
425 unsigned long *contpc)
426{
427 union mips_instruction insn = (union mips_instruction)dec_insn.insn;
428 unsigned int fcr31;
429 unsigned int bit = 0;
430 unsigned int bit0;
431 union fpureg *fpr;
432
433 switch (insn.i_format.opcode) {
434 case spec_op:
435 switch (insn.r_format.func) {
436 case jalr_op:
437 if (insn.r_format.rd != 0) {
438 regs->regs[insn.r_format.rd] =
439 regs->cp0_epc + dec_insn.pc_inc +
440 dec_insn.next_pc_inc;
441 }
442
443 case jr_op:
444
445 if (NO_R6EMU && insn.r_format.func == jr_op)
446 break;
447 *contpc = regs->regs[insn.r_format.rs];
448 return 1;
449 }
450 break;
451 case bcond_op:
452 switch (insn.i_format.rt) {
453 case bltzal_op:
454 case bltzall_op:
455 if (NO_R6EMU && (insn.i_format.rs ||
456 insn.i_format.rt == bltzall_op))
457 break;
458
459 regs->regs[31] = regs->cp0_epc +
460 dec_insn.pc_inc +
461 dec_insn.next_pc_inc;
462
463 case bltzl_op:
464 if (NO_R6EMU)
465 break;
466
467 case bltz_op:
468 if ((long)regs->regs[insn.i_format.rs] < 0)
469 *contpc = regs->cp0_epc +
470 dec_insn.pc_inc +
471 (insn.i_format.simmediate << 2);
472 else
473 *contpc = regs->cp0_epc +
474 dec_insn.pc_inc +
475 dec_insn.next_pc_inc;
476 return 1;
477 case bgezal_op:
478 case bgezall_op:
479 if (NO_R6EMU && (insn.i_format.rs ||
480 insn.i_format.rt == bgezall_op))
481 break;
482
483 regs->regs[31] = regs->cp0_epc +
484 dec_insn.pc_inc +
485 dec_insn.next_pc_inc;
486
487 case bgezl_op:
488 if (NO_R6EMU)
489 break;
490
491 case bgez_op:
492 if ((long)regs->regs[insn.i_format.rs] >= 0)
493 *contpc = regs->cp0_epc +
494 dec_insn.pc_inc +
495 (insn.i_format.simmediate << 2);
496 else
497 *contpc = regs->cp0_epc +
498 dec_insn.pc_inc +
499 dec_insn.next_pc_inc;
500 return 1;
501 }
502 break;
503 case jalx_op:
504 set_isa16_mode(bit);
505
506 case jal_op:
507 regs->regs[31] = regs->cp0_epc +
508 dec_insn.pc_inc +
509 dec_insn.next_pc_inc;
510
511 case j_op:
512 *contpc = regs->cp0_epc + dec_insn.pc_inc;
513 *contpc >>= 28;
514 *contpc <<= 28;
515 *contpc |= (insn.j_format.target << 2);
516
517 *contpc ^= bit;
518 return 1;
519 case beql_op:
520 if (NO_R6EMU)
521 break;
522
523 case beq_op:
524 if (regs->regs[insn.i_format.rs] ==
525 regs->regs[insn.i_format.rt])
526 *contpc = regs->cp0_epc +
527 dec_insn.pc_inc +
528 (insn.i_format.simmediate << 2);
529 else
530 *contpc = regs->cp0_epc +
531 dec_insn.pc_inc +
532 dec_insn.next_pc_inc;
533 return 1;
534 case bnel_op:
535 if (NO_R6EMU)
536 break;
537
538 case bne_op:
539 if (regs->regs[insn.i_format.rs] !=
540 regs->regs[insn.i_format.rt])
541 *contpc = regs->cp0_epc +
542 dec_insn.pc_inc +
543 (insn.i_format.simmediate << 2);
544 else
545 *contpc = regs->cp0_epc +
546 dec_insn.pc_inc +
547 dec_insn.next_pc_inc;
548 return 1;
549 case blezl_op:
550 if (!insn.i_format.rt && NO_R6EMU)
551 break;
552
553 case blez_op:
554
555
556
557
558
559
560
561
562
563
564
565
566
567 if (cpu_has_mips_r6 && insn.i_format.rt) {
568 if ((insn.i_format.opcode == blez_op) &&
569 ((!insn.i_format.rs && insn.i_format.rt) ||
570 (insn.i_format.rs == insn.i_format.rt)))
571 regs->regs[31] = regs->cp0_epc +
572 dec_insn.pc_inc;
573 *contpc = regs->cp0_epc + dec_insn.pc_inc +
574 dec_insn.next_pc_inc;
575
576 return 1;
577 }
578 if ((long)regs->regs[insn.i_format.rs] <= 0)
579 *contpc = regs->cp0_epc +
580 dec_insn.pc_inc +
581 (insn.i_format.simmediate << 2);
582 else
583 *contpc = regs->cp0_epc +
584 dec_insn.pc_inc +
585 dec_insn.next_pc_inc;
586 return 1;
587 case bgtzl_op:
588 if (!insn.i_format.rt && NO_R6EMU)
589 break;
590
591 case bgtz_op:
592
593
594
595
596
597
598
599
600
601
602
603
604
605 if (cpu_has_mips_r6 && insn.i_format.rt) {
606 if ((insn.i_format.opcode == blez_op) &&
607 ((!insn.i_format.rs && insn.i_format.rt) ||
608 (insn.i_format.rs == insn.i_format.rt)))
609 regs->regs[31] = regs->cp0_epc +
610 dec_insn.pc_inc;
611 *contpc = regs->cp0_epc + dec_insn.pc_inc +
612 dec_insn.next_pc_inc;
613
614 return 1;
615 }
616
617 if ((long)regs->regs[insn.i_format.rs] > 0)
618 *contpc = regs->cp0_epc +
619 dec_insn.pc_inc +
620 (insn.i_format.simmediate << 2);
621 else
622 *contpc = regs->cp0_epc +
623 dec_insn.pc_inc +
624 dec_insn.next_pc_inc;
625 return 1;
626 case pop10_op:
627 case pop30_op:
628 if (!cpu_has_mips_r6)
629 break;
630 if (insn.i_format.rt && !insn.i_format.rs)
631 regs->regs[31] = regs->cp0_epc + 4;
632 *contpc = regs->cp0_epc + dec_insn.pc_inc +
633 dec_insn.next_pc_inc;
634
635 return 1;
636#ifdef CONFIG_CPU_CAVIUM_OCTEON
637 case lwc2_op:
638 if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt)) == 0)
639 *contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
640 else
641 *contpc = regs->cp0_epc + 8;
642 return 1;
643 case ldc2_op:
644 if ((regs->regs[insn.i_format.rs] & (1ull<<(insn.i_format.rt + 32))) == 0)
645 *contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
646 else
647 *contpc = regs->cp0_epc + 8;
648 return 1;
649 case swc2_op:
650 if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
651 *contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
652 else
653 *contpc = regs->cp0_epc + 8;
654 return 1;
655 case sdc2_op:
656 if (regs->regs[insn.i_format.rs] & (1ull<<(insn.i_format.rt + 32)))
657 *contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
658 else
659 *contpc = regs->cp0_epc + 8;
660 return 1;
661#else
662 case bc6_op:
663
664
665
666
667
668 if (!cpu_has_mips_r6)
669 break;
670 *contpc = regs->cp0_epc + dec_insn.pc_inc +
671 dec_insn.next_pc_inc;
672
673 return 1;
674 case balc6_op:
675 if (!cpu_has_mips_r6)
676 break;
677 regs->regs[31] = regs->cp0_epc + 4;
678 *contpc = regs->cp0_epc + dec_insn.pc_inc +
679 dec_insn.next_pc_inc;
680
681 return 1;
682 case pop66_op:
683 if (!cpu_has_mips_r6)
684 break;
685 *contpc = regs->cp0_epc + dec_insn.pc_inc +
686 dec_insn.next_pc_inc;
687
688 return 1;
689 case pop76_op:
690 if (!cpu_has_mips_r6)
691 break;
692 if (!insn.i_format.rs)
693 regs->regs[31] = regs->cp0_epc + 4;
694 *contpc = regs->cp0_epc + dec_insn.pc_inc +
695 dec_insn.next_pc_inc;
696
697 return 1;
698#endif
699 case cop0_op:
700 case cop1_op:
701
702 if (cpu_has_mips_r6 &&
703 ((insn.i_format.rs == bc1eqz_op) ||
704 (insn.i_format.rs == bc1nez_op))) {
705 bit = 0;
706 fpr = ¤t->thread.fpu.fpr[insn.i_format.rt];
707 bit0 = get_fpr32(fpr, 0) & 0x1;
708 switch (insn.i_format.rs) {
709 case bc1eqz_op:
710 bit = bit0 == 0;
711 break;
712 case bc1nez_op:
713 bit = bit0 != 0;
714 break;
715 }
716 if (bit)
717 *contpc = regs->cp0_epc +
718 dec_insn.pc_inc +
719 (insn.i_format.simmediate << 2);
720 else
721 *contpc = regs->cp0_epc +
722 dec_insn.pc_inc +
723 dec_insn.next_pc_inc;
724
725 return 1;
726 }
727
728
729 case cop2_op:
730 case cop1x_op:
731 if (insn.i_format.rs == bc_op) {
732 preempt_disable();
733 if (is_fpu_owner())
734 fcr31 = read_32bit_cp1_register(CP1_STATUS);
735 else
736 fcr31 = current->thread.fpu.fcr31;
737 preempt_enable();
738
739 bit = (insn.i_format.rt >> 2);
740 bit += (bit != 0);
741 bit += 23;
742 switch (insn.i_format.rt & 3) {
743 case 0:
744 case 2:
745 if (~fcr31 & (1 << bit))
746 *contpc = regs->cp0_epc +
747 dec_insn.pc_inc +
748 (insn.i_format.simmediate << 2);
749 else
750 *contpc = regs->cp0_epc +
751 dec_insn.pc_inc +
752 dec_insn.next_pc_inc;
753 return 1;
754 case 1:
755 case 3:
756 if (fcr31 & (1 << bit))
757 *contpc = regs->cp0_epc +
758 dec_insn.pc_inc +
759 (insn.i_format.simmediate << 2);
760 else
761 *contpc = regs->cp0_epc +
762 dec_insn.pc_inc +
763 dec_insn.next_pc_inc;
764 return 1;
765 }
766 }
767 break;
768 }
769 return 0;
770}
771
772
773
774
775
776
777
778
779
780
781
782static inline int cop1_64bit(struct pt_regs *xcp)
783{
784 if (IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_MIPS32_O32))
785 return 1;
786 else if (IS_ENABLED(CONFIG_32BIT) &&
787 !IS_ENABLED(CONFIG_MIPS_O32_FP64_SUPPORT))
788 return 0;
789
790 return !test_thread_flag(TIF_32BIT_FPREGS);
791}
792
793static inline bool hybrid_fprs(void)
794{
795 return test_thread_flag(TIF_HYBRID_FPREGS);
796}
797
798#define SIFROMREG(si, x) \
799do { \
800 if (cop1_64bit(xcp) && !hybrid_fprs()) \
801 (si) = (int)get_fpr32(&ctx->fpr[x], 0); \
802 else \
803 (si) = (int)get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \
804} while (0)
805
806#define SITOREG(si, x) \
807do { \
808 if (cop1_64bit(xcp) && !hybrid_fprs()) { \
809 unsigned int i; \
810 set_fpr32(&ctx->fpr[x], 0, si); \
811 for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \
812 set_fpr32(&ctx->fpr[x], i, 0); \
813 } else { \
814 set_fpr32(&ctx->fpr[(x) & ~1], (x) & 1, si); \
815 } \
816} while (0)
817
818#define SIFROMHREG(si, x) ((si) = (int)get_fpr32(&ctx->fpr[x], 1))
819
820#define SITOHREG(si, x) \
821do { \
822 unsigned int i; \
823 set_fpr32(&ctx->fpr[x], 1, si); \
824 for (i = 2; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \
825 set_fpr32(&ctx->fpr[x], i, 0); \
826} while (0)
827
828#define DIFROMREG(di, x) \
829 ((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) ^ 1)], 0))
830
831#define DITOREG(di, x) \
832do { \
833 unsigned int fpr, i; \
834 fpr = (x) & ~(cop1_64bit(xcp) ^ 1); \
835 set_fpr64(&ctx->fpr[fpr], 0, di); \
836 for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val64); i++) \
837 set_fpr64(&ctx->fpr[fpr], i, 0); \
838} while (0)
839
840#define SPFROMREG(sp, x) SIFROMREG((sp).bits, x)
841#define SPTOREG(sp, x) SITOREG((sp).bits, x)
842#define DPFROMREG(dp, x) DIFROMREG((dp).bits, x)
843#define DPTOREG(dp, x) DITOREG((dp).bits, x)
844
845
846
847
848static inline void cop1_cfc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
849 mips_instruction ir)
850{
851 u32 fcr31 = ctx->fcr31;
852 u32 value = 0;
853
854 switch (MIPSInst_RD(ir)) {
855 case FPCREG_CSR:
856 value = fcr31;
857 pr_debug("%p gpr[%d]<-csr=%08x\n",
858 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
859 break;
860
861 case FPCREG_FENR:
862 if (!cpu_has_mips_r)
863 break;
864 value = (fcr31 >> (FPU_CSR_FS_S - MIPS_FENR_FS_S)) &
865 MIPS_FENR_FS;
866 value |= fcr31 & (FPU_CSR_ALL_E | FPU_CSR_RM);
867 pr_debug("%p gpr[%d]<-enr=%08x\n",
868 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
869 break;
870
871 case FPCREG_FEXR:
872 if (!cpu_has_mips_r)
873 break;
874 value = fcr31 & (FPU_CSR_ALL_X | FPU_CSR_ALL_S);
875 pr_debug("%p gpr[%d]<-exr=%08x\n",
876 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
877 break;
878
879 case FPCREG_FCCR:
880 if (!cpu_has_mips_r)
881 break;
882 value = (fcr31 >> (FPU_CSR_COND_S - MIPS_FCCR_COND0_S)) &
883 MIPS_FCCR_COND0;
884 value |= (fcr31 >> (FPU_CSR_COND1_S - MIPS_FCCR_COND1_S)) &
885 (MIPS_FCCR_CONDX & ~MIPS_FCCR_COND0);
886 pr_debug("%p gpr[%d]<-ccr=%08x\n",
887 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
888 break;
889
890 case FPCREG_RID:
891 value = boot_cpu_data.fpu_id;
892 break;
893
894 default:
895 break;
896 }
897
898 if (MIPSInst_RT(ir))
899 xcp->regs[MIPSInst_RT(ir)] = value;
900}
901
902
903
904
905static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
906 mips_instruction ir)
907{
908 u32 fcr31 = ctx->fcr31;
909 u32 value;
910 u32 mask;
911
912 if (MIPSInst_RT(ir) == 0)
913 value = 0;
914 else
915 value = xcp->regs[MIPSInst_RT(ir)];
916
917 switch (MIPSInst_RD(ir)) {
918 case FPCREG_CSR:
919 pr_debug("%p gpr[%d]->csr=%08x\n",
920 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
921
922
923 mask = boot_cpu_data.fpu_msk31;
924 fcr31 = (value & ~mask) | (fcr31 & mask);
925 break;
926
927 case FPCREG_FENR:
928 if (!cpu_has_mips_r)
929 break;
930 pr_debug("%p gpr[%d]->enr=%08x\n",
931 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
932 fcr31 &= ~(FPU_CSR_FS | FPU_CSR_ALL_E | FPU_CSR_RM);
933 fcr31 |= (value << (FPU_CSR_FS_S - MIPS_FENR_FS_S)) &
934 FPU_CSR_FS;
935 fcr31 |= value & (FPU_CSR_ALL_E | FPU_CSR_RM);
936 break;
937
938 case FPCREG_FEXR:
939 if (!cpu_has_mips_r)
940 break;
941 pr_debug("%p gpr[%d]->exr=%08x\n",
942 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
943 fcr31 &= ~(FPU_CSR_ALL_X | FPU_CSR_ALL_S);
944 fcr31 |= value & (FPU_CSR_ALL_X | FPU_CSR_ALL_S);
945 break;
946
947 case FPCREG_FCCR:
948 if (!cpu_has_mips_r)
949 break;
950 pr_debug("%p gpr[%d]->ccr=%08x\n",
951 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
952 fcr31 &= ~(FPU_CSR_CONDX | FPU_CSR_COND);
953 fcr31 |= (value << (FPU_CSR_COND_S - MIPS_FCCR_COND0_S)) &
954 FPU_CSR_COND;
955 fcr31 |= (value << (FPU_CSR_COND1_S - MIPS_FCCR_COND1_S)) &
956 FPU_CSR_CONDX;
957 break;
958
959 default:
960 break;
961 }
962
963 ctx->fcr31 = fcr31;
964}
965
966
967
968
969
970
971static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
972 struct mm_decoded_insn dec_insn, void __user **fault_addr)
973{
974 unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc;
975 unsigned int cond, cbit, bit0;
976 mips_instruction ir;
977 int likely, pc_inc;
978 union fpureg *fpr;
979 u32 __user *wva;
980 u64 __user *dva;
981 u32 wval;
982 u64 dval;
983 int sig;
984
985
986
987
988
989 if (!cpu_has_mmips && dec_insn.micro_mips_mode)
990 unreachable();
991
992
993 if (delay_slot(xcp)) {
994 if (dec_insn.micro_mips_mode) {
995 if (!mm_isBranchInstr(xcp, dec_insn, &contpc))
996 clear_delay_slot(xcp);
997 } else {
998 if (!isBranchInstr(xcp, dec_insn, &contpc))
999 clear_delay_slot(xcp);
1000 }
1001 }
1002
1003 if (delay_slot(xcp)) {
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016 ir = dec_insn.next_insn;
1017 pc_inc = dec_insn.next_pc_inc;
1018 } else {
1019 ir = dec_insn.insn;
1020 pc_inc = dec_insn.pc_inc;
1021 }
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033 if (dec_insn.micro_mips_mode) {
1034
1035
1036
1037
1038
1039 if ((pc_inc == 2) ||
1040 (microMIPS32_to_MIPS32((union mips_instruction *)&ir)
1041 == SIGILL))
1042 return SIGILL;
1043 }
1044
1045emul:
1046 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, xcp, 0);
1047 MIPS_FPU_EMU_INC_STATS(emulated);
1048 switch (MIPSInst_OPCODE(ir)) {
1049 case ldc1_op:
1050 dva = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1051 MIPSInst_SIMM(ir));
1052 MIPS_FPU_EMU_INC_STATS(loads);
1053
1054 if (!access_ok(dva, sizeof(u64))) {
1055 MIPS_FPU_EMU_INC_STATS(errors);
1056 *fault_addr = dva;
1057 return SIGBUS;
1058 }
1059 if (__get_user(dval, dva)) {
1060 MIPS_FPU_EMU_INC_STATS(errors);
1061 *fault_addr = dva;
1062 return SIGSEGV;
1063 }
1064 DITOREG(dval, MIPSInst_RT(ir));
1065 break;
1066
1067 case sdc1_op:
1068 dva = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1069 MIPSInst_SIMM(ir));
1070 MIPS_FPU_EMU_INC_STATS(stores);
1071 DIFROMREG(dval, MIPSInst_RT(ir));
1072 if (!access_ok(dva, sizeof(u64))) {
1073 MIPS_FPU_EMU_INC_STATS(errors);
1074 *fault_addr = dva;
1075 return SIGBUS;
1076 }
1077 if (__put_user(dval, dva)) {
1078 MIPS_FPU_EMU_INC_STATS(errors);
1079 *fault_addr = dva;
1080 return SIGSEGV;
1081 }
1082 break;
1083
1084 case lwc1_op:
1085 wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1086 MIPSInst_SIMM(ir));
1087 MIPS_FPU_EMU_INC_STATS(loads);
1088 if (!access_ok(wva, sizeof(u32))) {
1089 MIPS_FPU_EMU_INC_STATS(errors);
1090 *fault_addr = wva;
1091 return SIGBUS;
1092 }
1093 if (__get_user(wval, wva)) {
1094 MIPS_FPU_EMU_INC_STATS(errors);
1095 *fault_addr = wva;
1096 return SIGSEGV;
1097 }
1098 SITOREG(wval, MIPSInst_RT(ir));
1099 break;
1100
1101 case swc1_op:
1102 wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1103 MIPSInst_SIMM(ir));
1104 MIPS_FPU_EMU_INC_STATS(stores);
1105 SIFROMREG(wval, MIPSInst_RT(ir));
1106 if (!access_ok(wva, sizeof(u32))) {
1107 MIPS_FPU_EMU_INC_STATS(errors);
1108 *fault_addr = wva;
1109 return SIGBUS;
1110 }
1111 if (__put_user(wval, wva)) {
1112 MIPS_FPU_EMU_INC_STATS(errors);
1113 *fault_addr = wva;
1114 return SIGSEGV;
1115 }
1116 break;
1117
1118 case cop1_op:
1119 switch (MIPSInst_RS(ir)) {
1120 case dmfc_op:
1121 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1122 return SIGILL;
1123
1124
1125 if (MIPSInst_RT(ir) != 0) {
1126 DIFROMREG(xcp->regs[MIPSInst_RT(ir)],
1127 MIPSInst_RD(ir));
1128 }
1129 break;
1130
1131 case dmtc_op:
1132 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1133 return SIGILL;
1134
1135
1136 DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1137 break;
1138
1139 case mfhc_op:
1140 if (!cpu_has_mips_r2_r6)
1141 return SIGILL;
1142
1143
1144 if (MIPSInst_RT(ir) != 0) {
1145 SIFROMHREG(xcp->regs[MIPSInst_RT(ir)],
1146 MIPSInst_RD(ir));
1147 }
1148 break;
1149
1150 case mthc_op:
1151 if (!cpu_has_mips_r2_r6)
1152 return SIGILL;
1153
1154
1155 SITOHREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1156 break;
1157
1158 case mfc_op:
1159
1160 if (MIPSInst_RT(ir) != 0) {
1161 SIFROMREG(xcp->regs[MIPSInst_RT(ir)],
1162 MIPSInst_RD(ir));
1163 }
1164 break;
1165
1166 case mtc_op:
1167
1168 SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1169 break;
1170
1171 case cfc_op:
1172
1173 cop1_cfc(xcp, ctx, ir);
1174 break;
1175
1176 case ctc_op:
1177
1178 cop1_ctc(xcp, ctx, ir);
1179 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1180 return SIGFPE;
1181 }
1182 break;
1183
1184 case bc1eqz_op:
1185 case bc1nez_op:
1186 if (!cpu_has_mips_r6 || delay_slot(xcp))
1187 return SIGILL;
1188
1189 likely = 0;
1190 cond = 0;
1191 fpr = ¤t->thread.fpu.fpr[MIPSInst_RT(ir)];
1192 bit0 = get_fpr32(fpr, 0) & 0x1;
1193 switch (MIPSInst_RS(ir)) {
1194 case bc1eqz_op:
1195 MIPS_FPU_EMU_INC_STATS(bc1eqz);
1196 cond = bit0 == 0;
1197 break;
1198 case bc1nez_op:
1199 MIPS_FPU_EMU_INC_STATS(bc1nez);
1200 cond = bit0 != 0;
1201 break;
1202 }
1203 goto branch_common;
1204
1205 case bc_op:
1206 if (delay_slot(xcp))
1207 return SIGILL;
1208
1209 if (cpu_has_mips_4_5_r)
1210 cbit = fpucondbit[MIPSInst_RT(ir) >> 2];
1211 else
1212 cbit = FPU_CSR_COND;
1213 cond = ctx->fcr31 & cbit;
1214
1215 likely = 0;
1216 switch (MIPSInst_RT(ir) & 3) {
1217 case bcfl_op:
1218 if (cpu_has_mips_2_3_4_5_r)
1219 likely = 1;
1220
1221 case bcf_op:
1222 cond = !cond;
1223 break;
1224 case bctl_op:
1225 if (cpu_has_mips_2_3_4_5_r)
1226 likely = 1;
1227
1228 case bct_op:
1229 break;
1230 }
1231branch_common:
1232 MIPS_FPU_EMU_INC_STATS(branches);
1233 set_delay_slot(xcp);
1234 if (cond) {
1235
1236
1237
1238 unsigned long bcpc;
1239
1240
1241
1242
1243
1244
1245 bcpc = xcp->cp0_epc;
1246 xcp->cp0_epc += dec_insn.pc_inc;
1247
1248 contpc = MIPSInst_SIMM(ir);
1249 ir = dec_insn.next_insn;
1250 if (dec_insn.micro_mips_mode) {
1251 contpc = (xcp->cp0_epc + (contpc << 1));
1252
1253
1254 if ((dec_insn.next_pc_inc == 2) ||
1255 (microMIPS32_to_MIPS32((union mips_instruction *)&ir) == SIGILL)) {
1256
1257
1258
1259
1260
1261
1262
1263
1264 if (dec_insn.next_pc_inc == 2)
1265 ir = (ir & (~0xffff)) | MM_NOP16;
1266
1267
1268
1269
1270
1271 sig = mips_dsemul(xcp, ir,
1272 bcpc, contpc);
1273 if (sig < 0)
1274 break;
1275 if (sig)
1276 xcp->cp0_epc = bcpc;
1277
1278
1279
1280
1281 return sig ? sig : SIGILL;
1282 }
1283 } else
1284 contpc = (xcp->cp0_epc + (contpc << 2));
1285
1286 switch (MIPSInst_OPCODE(ir)) {
1287 case lwc1_op:
1288 case swc1_op:
1289 goto emul;
1290
1291 case ldc1_op:
1292 case sdc1_op:
1293 if (cpu_has_mips_2_3_4_5_r)
1294 goto emul;
1295
1296 goto bc_sigill;
1297
1298 case cop1_op:
1299 goto emul;
1300
1301 case cop1x_op:
1302 if (cpu_has_mips_4_5_64_r2_r6)
1303
1304 goto emul;
1305
1306 goto bc_sigill;
1307
1308 case spec_op:
1309 switch (MIPSInst_FUNC(ir)) {
1310 case movc_op:
1311 if (cpu_has_mips_4_5_r)
1312 goto emul;
1313
1314 goto bc_sigill;
1315 }
1316 break;
1317
1318 bc_sigill:
1319 xcp->cp0_epc = bcpc;
1320 return SIGILL;
1321 }
1322
1323
1324
1325
1326
1327 sig = mips_dsemul(xcp, ir, bcpc, contpc);
1328 if (sig < 0)
1329 break;
1330 if (sig)
1331 xcp->cp0_epc = bcpc;
1332
1333 return sig ? sig : SIGILL;
1334 } else if (likely) {
1335
1336
1337
1338
1339 xcp->cp0_epc += dec_insn.pc_inc;
1340 contpc += dec_insn.pc_inc;
1341
1342
1343
1344
1345 }
1346 break;
1347
1348 default:
1349 if (!(MIPSInst_RS(ir) & 0x10))
1350 return SIGILL;
1351
1352
1353 sig = fpu_emu(xcp, ctx, ir);
1354 if (sig)
1355 return sig;
1356 }
1357 break;
1358
1359 case cop1x_op:
1360 if (!cpu_has_mips_4_5_64_r2_r6)
1361 return SIGILL;
1362
1363 sig = fpux_emu(xcp, ctx, ir, fault_addr);
1364 if (sig)
1365 return sig;
1366 break;
1367
1368 case spec_op:
1369 if (!cpu_has_mips_4_5_r)
1370 return SIGILL;
1371
1372 if (MIPSInst_FUNC(ir) != movc_op)
1373 return SIGILL;
1374 cond = fpucondbit[MIPSInst_RT(ir) >> 2];
1375 if (((ctx->fcr31 & cond) != 0) == ((MIPSInst_RT(ir) & 1) != 0))
1376 xcp->regs[MIPSInst_RD(ir)] =
1377 xcp->regs[MIPSInst_RS(ir)];
1378 break;
1379 default:
1380 return SIGILL;
1381 }
1382
1383
1384 xcp->cp0_epc = contpc;
1385 clear_delay_slot(xcp);
1386
1387 return 0;
1388}
1389
1390
1391
1392
1393
1394static const unsigned char cmptab[8] = {
1395 0,
1396 IEEE754_CUN,
1397 IEEE754_CEQ,
1398 IEEE754_CEQ | IEEE754_CUN,
1399 IEEE754_CLT,
1400 IEEE754_CLT | IEEE754_CUN,
1401 IEEE754_CLT | IEEE754_CEQ,
1402 IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN,
1403};
1404
1405static const unsigned char negative_cmptab[8] = {
1406 0,
1407 IEEE754_CLT | IEEE754_CGT | IEEE754_CEQ,
1408 IEEE754_CLT | IEEE754_CGT | IEEE754_CUN,
1409 IEEE754_CLT | IEEE754_CGT,
1410
1411};
1412
1413
1414
1415
1416
1417
1418#define DEF3OP(name, p, f1, f2, f3) \
1419static union ieee754##p fpemu_##p##_##name(union ieee754##p r, \
1420 union ieee754##p s, union ieee754##p t) \
1421{ \
1422 struct _ieee754_csr ieee754_csr_save; \
1423 s = f1(s, t); \
1424 ieee754_csr_save = ieee754_csr; \
1425 s = f2(s, r); \
1426 ieee754_csr_save.cx |= ieee754_csr.cx; \
1427 ieee754_csr_save.sx |= ieee754_csr.sx; \
1428 s = f3(s); \
1429 ieee754_csr.cx |= ieee754_csr_save.cx; \
1430 ieee754_csr.sx |= ieee754_csr_save.sx; \
1431 return s; \
1432}
1433
1434static union ieee754dp fpemu_dp_recip(union ieee754dp d)
1435{
1436 return ieee754dp_div(ieee754dp_one(0), d);
1437}
1438
1439static union ieee754dp fpemu_dp_rsqrt(union ieee754dp d)
1440{
1441 return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d));
1442}
1443
1444static union ieee754sp fpemu_sp_recip(union ieee754sp s)
1445{
1446 return ieee754sp_div(ieee754sp_one(0), s);
1447}
1448
1449static union ieee754sp fpemu_sp_rsqrt(union ieee754sp s)
1450{
1451 return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
1452}
1453
1454DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add, );
1455DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub, );
1456DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg);
1457DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg);
1458DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add, );
1459DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub, );
1460DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
1461DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
1462
1463static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1464 mips_instruction ir, void __user **fault_addr)
1465{
1466 unsigned int rcsr = 0;
1467
1468 MIPS_FPU_EMU_INC_STATS(cp1xops);
1469
1470 switch (MIPSInst_FMA_FFMT(ir)) {
1471 case s_fmt:{
1472
1473 union ieee754sp(*handler) (union ieee754sp, union ieee754sp, union ieee754sp);
1474 union ieee754sp fd, fr, fs, ft;
1475 u32 __user *va;
1476 u32 val;
1477
1478 switch (MIPSInst_FUNC(ir)) {
1479 case lwxc1_op:
1480 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1481 xcp->regs[MIPSInst_FT(ir)]);
1482
1483 MIPS_FPU_EMU_INC_STATS(loads);
1484 if (!access_ok(va, sizeof(u32))) {
1485 MIPS_FPU_EMU_INC_STATS(errors);
1486 *fault_addr = va;
1487 return SIGBUS;
1488 }
1489 if (__get_user(val, va)) {
1490 MIPS_FPU_EMU_INC_STATS(errors);
1491 *fault_addr = va;
1492 return SIGSEGV;
1493 }
1494 SITOREG(val, MIPSInst_FD(ir));
1495 break;
1496
1497 case swxc1_op:
1498 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1499 xcp->regs[MIPSInst_FT(ir)]);
1500
1501 MIPS_FPU_EMU_INC_STATS(stores);
1502
1503 SIFROMREG(val, MIPSInst_FS(ir));
1504 if (!access_ok(va, sizeof(u32))) {
1505 MIPS_FPU_EMU_INC_STATS(errors);
1506 *fault_addr = va;
1507 return SIGBUS;
1508 }
1509 if (put_user(val, va)) {
1510 MIPS_FPU_EMU_INC_STATS(errors);
1511 *fault_addr = va;
1512 return SIGSEGV;
1513 }
1514 break;
1515
1516 case madd_s_op:
1517 handler = fpemu_sp_madd;
1518 goto scoptop;
1519 case msub_s_op:
1520 handler = fpemu_sp_msub;
1521 goto scoptop;
1522 case nmadd_s_op:
1523 handler = fpemu_sp_nmadd;
1524 goto scoptop;
1525 case nmsub_s_op:
1526 handler = fpemu_sp_nmsub;
1527 goto scoptop;
1528
1529 scoptop:
1530 SPFROMREG(fr, MIPSInst_FR(ir));
1531 SPFROMREG(fs, MIPSInst_FS(ir));
1532 SPFROMREG(ft, MIPSInst_FT(ir));
1533 fd = (*handler) (fr, fs, ft);
1534 SPTOREG(fd, MIPSInst_FD(ir));
1535
1536 copcsr:
1537 if (ieee754_cxtest(IEEE754_INEXACT)) {
1538 MIPS_FPU_EMU_INC_STATS(ieee754_inexact);
1539 rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
1540 }
1541 if (ieee754_cxtest(IEEE754_UNDERFLOW)) {
1542 MIPS_FPU_EMU_INC_STATS(ieee754_underflow);
1543 rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
1544 }
1545 if (ieee754_cxtest(IEEE754_OVERFLOW)) {
1546 MIPS_FPU_EMU_INC_STATS(ieee754_overflow);
1547 rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
1548 }
1549 if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) {
1550 MIPS_FPU_EMU_INC_STATS(ieee754_invalidop);
1551 rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
1552 }
1553
1554 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
1555 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1556
1557
1558 return SIGFPE;
1559 }
1560
1561 break;
1562
1563 default:
1564 return SIGILL;
1565 }
1566 break;
1567 }
1568
1569 case d_fmt:{
1570 union ieee754dp(*handler) (union ieee754dp, union ieee754dp, union ieee754dp);
1571 union ieee754dp fd, fr, fs, ft;
1572 u64 __user *va;
1573 u64 val;
1574
1575 switch (MIPSInst_FUNC(ir)) {
1576 case ldxc1_op:
1577 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1578 xcp->regs[MIPSInst_FT(ir)]);
1579
1580 MIPS_FPU_EMU_INC_STATS(loads);
1581 if (!access_ok(va, sizeof(u64))) {
1582 MIPS_FPU_EMU_INC_STATS(errors);
1583 *fault_addr = va;
1584 return SIGBUS;
1585 }
1586 if (__get_user(val, va)) {
1587 MIPS_FPU_EMU_INC_STATS(errors);
1588 *fault_addr = va;
1589 return SIGSEGV;
1590 }
1591 DITOREG(val, MIPSInst_FD(ir));
1592 break;
1593
1594 case sdxc1_op:
1595 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1596 xcp->regs[MIPSInst_FT(ir)]);
1597
1598 MIPS_FPU_EMU_INC_STATS(stores);
1599 DIFROMREG(val, MIPSInst_FS(ir));
1600 if (!access_ok(va, sizeof(u64))) {
1601 MIPS_FPU_EMU_INC_STATS(errors);
1602 *fault_addr = va;
1603 return SIGBUS;
1604 }
1605 if (__put_user(val, va)) {
1606 MIPS_FPU_EMU_INC_STATS(errors);
1607 *fault_addr = va;
1608 return SIGSEGV;
1609 }
1610 break;
1611
1612 case madd_d_op:
1613 handler = fpemu_dp_madd;
1614 goto dcoptop;
1615 case msub_d_op:
1616 handler = fpemu_dp_msub;
1617 goto dcoptop;
1618 case nmadd_d_op:
1619 handler = fpemu_dp_nmadd;
1620 goto dcoptop;
1621 case nmsub_d_op:
1622 handler = fpemu_dp_nmsub;
1623 goto dcoptop;
1624
1625 dcoptop:
1626 DPFROMREG(fr, MIPSInst_FR(ir));
1627 DPFROMREG(fs, MIPSInst_FS(ir));
1628 DPFROMREG(ft, MIPSInst_FT(ir));
1629 fd = (*handler) (fr, fs, ft);
1630 DPTOREG(fd, MIPSInst_FD(ir));
1631 goto copcsr;
1632
1633 default:
1634 return SIGILL;
1635 }
1636 break;
1637 }
1638
1639 case 0x3:
1640 if (MIPSInst_FUNC(ir) != pfetch_op)
1641 return SIGILL;
1642
1643
1644 break;
1645
1646 default:
1647 return SIGILL;
1648 }
1649
1650 return 0;
1651}
1652
1653
1654
1655
1656
1657
1658static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1659 mips_instruction ir)
1660{
1661 int rfmt;
1662 unsigned int rcsr = 0;
1663 unsigned int oldrm;
1664 unsigned int cbit;
1665 unsigned int cond;
1666 union {
1667 union ieee754dp d;
1668 union ieee754sp s;
1669 int w;
1670 s64 l;
1671 } rv;
1672 u64 bits;
1673
1674 MIPS_FPU_EMU_INC_STATS(cp1ops);
1675 switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
1676 case s_fmt: {
1677 union {
1678 union ieee754sp(*b) (union ieee754sp, union ieee754sp);
1679 union ieee754sp(*u) (union ieee754sp);
1680 } handler;
1681 union ieee754sp fd, fs, ft;
1682
1683 switch (MIPSInst_FUNC(ir)) {
1684
1685 case fadd_op:
1686 MIPS_FPU_EMU_INC_STATS(add_s);
1687 handler.b = ieee754sp_add;
1688 goto scopbop;
1689 case fsub_op:
1690 MIPS_FPU_EMU_INC_STATS(sub_s);
1691 handler.b = ieee754sp_sub;
1692 goto scopbop;
1693 case fmul_op:
1694 MIPS_FPU_EMU_INC_STATS(mul_s);
1695 handler.b = ieee754sp_mul;
1696 goto scopbop;
1697 case fdiv_op:
1698 MIPS_FPU_EMU_INC_STATS(div_s);
1699 handler.b = ieee754sp_div;
1700 goto scopbop;
1701
1702
1703 case fsqrt_op:
1704 if (!cpu_has_mips_2_3_4_5_r)
1705 return SIGILL;
1706
1707 MIPS_FPU_EMU_INC_STATS(sqrt_s);
1708 handler.u = ieee754sp_sqrt;
1709 goto scopuop;
1710
1711
1712
1713
1714
1715
1716 case frsqrt_op:
1717 if (!cpu_has_mips_4_5_64_r2_r6)
1718 return SIGILL;
1719
1720 MIPS_FPU_EMU_INC_STATS(rsqrt_s);
1721 handler.u = fpemu_sp_rsqrt;
1722 goto scopuop;
1723
1724 case frecip_op:
1725 if (!cpu_has_mips_4_5_64_r2_r6)
1726 return SIGILL;
1727
1728 MIPS_FPU_EMU_INC_STATS(recip_s);
1729 handler.u = fpemu_sp_recip;
1730 goto scopuop;
1731
1732 case fmovc_op:
1733 if (!cpu_has_mips_4_5_r)
1734 return SIGILL;
1735
1736 cond = fpucondbit[MIPSInst_FT(ir) >> 2];
1737 if (((ctx->fcr31 & cond) != 0) !=
1738 ((MIPSInst_FT(ir) & 1) != 0))
1739 return 0;
1740 SPFROMREG(rv.s, MIPSInst_FS(ir));
1741 break;
1742
1743 case fmovz_op:
1744 if (!cpu_has_mips_4_5_r)
1745 return SIGILL;
1746
1747 if (xcp->regs[MIPSInst_FT(ir)] != 0)
1748 return 0;
1749 SPFROMREG(rv.s, MIPSInst_FS(ir));
1750 break;
1751
1752 case fmovn_op:
1753 if (!cpu_has_mips_4_5_r)
1754 return SIGILL;
1755
1756 if (xcp->regs[MIPSInst_FT(ir)] == 0)
1757 return 0;
1758 SPFROMREG(rv.s, MIPSInst_FS(ir));
1759 break;
1760
1761 case fseleqz_op:
1762 if (!cpu_has_mips_r6)
1763 return SIGILL;
1764
1765 MIPS_FPU_EMU_INC_STATS(seleqz_s);
1766 SPFROMREG(rv.s, MIPSInst_FT(ir));
1767 if (rv.w & 0x1)
1768 rv.w = 0;
1769 else
1770 SPFROMREG(rv.s, MIPSInst_FS(ir));
1771 break;
1772
1773 case fselnez_op:
1774 if (!cpu_has_mips_r6)
1775 return SIGILL;
1776
1777 MIPS_FPU_EMU_INC_STATS(selnez_s);
1778 SPFROMREG(rv.s, MIPSInst_FT(ir));
1779 if (rv.w & 0x1)
1780 SPFROMREG(rv.s, MIPSInst_FS(ir));
1781 else
1782 rv.w = 0;
1783 break;
1784
1785 case fmaddf_op: {
1786 union ieee754sp ft, fs, fd;
1787
1788 if (!cpu_has_mips_r6)
1789 return SIGILL;
1790
1791 MIPS_FPU_EMU_INC_STATS(maddf_s);
1792 SPFROMREG(ft, MIPSInst_FT(ir));
1793 SPFROMREG(fs, MIPSInst_FS(ir));
1794 SPFROMREG(fd, MIPSInst_FD(ir));
1795 rv.s = ieee754sp_maddf(fd, fs, ft);
1796 goto copcsr;
1797 }
1798
1799 case fmsubf_op: {
1800 union ieee754sp ft, fs, fd;
1801
1802 if (!cpu_has_mips_r6)
1803 return SIGILL;
1804
1805 MIPS_FPU_EMU_INC_STATS(msubf_s);
1806 SPFROMREG(ft, MIPSInst_FT(ir));
1807 SPFROMREG(fs, MIPSInst_FS(ir));
1808 SPFROMREG(fd, MIPSInst_FD(ir));
1809 rv.s = ieee754sp_msubf(fd, fs, ft);
1810 goto copcsr;
1811 }
1812
1813 case frint_op: {
1814 union ieee754sp fs;
1815
1816 if (!cpu_has_mips_r6)
1817 return SIGILL;
1818
1819 MIPS_FPU_EMU_INC_STATS(rint_s);
1820 SPFROMREG(fs, MIPSInst_FS(ir));
1821 rv.s = ieee754sp_rint(fs);
1822 goto copcsr;
1823 }
1824
1825 case fclass_op: {
1826 union ieee754sp fs;
1827
1828 if (!cpu_has_mips_r6)
1829 return SIGILL;
1830
1831 MIPS_FPU_EMU_INC_STATS(class_s);
1832 SPFROMREG(fs, MIPSInst_FS(ir));
1833 rv.w = ieee754sp_2008class(fs);
1834 rfmt = w_fmt;
1835 goto copcsr;
1836 }
1837
1838 case fmin_op: {
1839 union ieee754sp fs, ft;
1840
1841 if (!cpu_has_mips_r6)
1842 return SIGILL;
1843
1844 MIPS_FPU_EMU_INC_STATS(min_s);
1845 SPFROMREG(ft, MIPSInst_FT(ir));
1846 SPFROMREG(fs, MIPSInst_FS(ir));
1847 rv.s = ieee754sp_fmin(fs, ft);
1848 goto copcsr;
1849 }
1850
1851 case fmina_op: {
1852 union ieee754sp fs, ft;
1853
1854 if (!cpu_has_mips_r6)
1855 return SIGILL;
1856
1857 MIPS_FPU_EMU_INC_STATS(mina_s);
1858 SPFROMREG(ft, MIPSInst_FT(ir));
1859 SPFROMREG(fs, MIPSInst_FS(ir));
1860 rv.s = ieee754sp_fmina(fs, ft);
1861 goto copcsr;
1862 }
1863
1864 case fmax_op: {
1865 union ieee754sp fs, ft;
1866
1867 if (!cpu_has_mips_r6)
1868 return SIGILL;
1869
1870 MIPS_FPU_EMU_INC_STATS(max_s);
1871 SPFROMREG(ft, MIPSInst_FT(ir));
1872 SPFROMREG(fs, MIPSInst_FS(ir));
1873 rv.s = ieee754sp_fmax(fs, ft);
1874 goto copcsr;
1875 }
1876
1877 case fmaxa_op: {
1878 union ieee754sp fs, ft;
1879
1880 if (!cpu_has_mips_r6)
1881 return SIGILL;
1882
1883 MIPS_FPU_EMU_INC_STATS(maxa_s);
1884 SPFROMREG(ft, MIPSInst_FT(ir));
1885 SPFROMREG(fs, MIPSInst_FS(ir));
1886 rv.s = ieee754sp_fmaxa(fs, ft);
1887 goto copcsr;
1888 }
1889
1890 case fabs_op:
1891 MIPS_FPU_EMU_INC_STATS(abs_s);
1892 handler.u = ieee754sp_abs;
1893 goto scopuop;
1894
1895 case fneg_op:
1896 MIPS_FPU_EMU_INC_STATS(neg_s);
1897 handler.u = ieee754sp_neg;
1898 goto scopuop;
1899
1900 case fmov_op:
1901
1902 MIPS_FPU_EMU_INC_STATS(mov_s);
1903 SPFROMREG(rv.s, MIPSInst_FS(ir));
1904 goto copcsr;
1905
1906
1907scopbop:
1908 SPFROMREG(fs, MIPSInst_FS(ir));
1909 SPFROMREG(ft, MIPSInst_FT(ir));
1910
1911 rv.s = (*handler.b) (fs, ft);
1912 goto copcsr;
1913scopuop:
1914 SPFROMREG(fs, MIPSInst_FS(ir));
1915 rv.s = (*handler.u) (fs);
1916 goto copcsr;
1917copcsr:
1918 if (ieee754_cxtest(IEEE754_INEXACT)) {
1919 MIPS_FPU_EMU_INC_STATS(ieee754_inexact);
1920 rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
1921 }
1922 if (ieee754_cxtest(IEEE754_UNDERFLOW)) {
1923 MIPS_FPU_EMU_INC_STATS(ieee754_underflow);
1924 rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
1925 }
1926 if (ieee754_cxtest(IEEE754_OVERFLOW)) {
1927 MIPS_FPU_EMU_INC_STATS(ieee754_overflow);
1928 rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
1929 }
1930 if (ieee754_cxtest(IEEE754_ZERO_DIVIDE)) {
1931 MIPS_FPU_EMU_INC_STATS(ieee754_zerodiv);
1932 rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
1933 }
1934 if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) {
1935 MIPS_FPU_EMU_INC_STATS(ieee754_invalidop);
1936 rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
1937 }
1938 break;
1939
1940
1941 case fcvts_op:
1942 return SIGILL;
1943
1944 case fcvtd_op:
1945 MIPS_FPU_EMU_INC_STATS(cvt_d_s);
1946 SPFROMREG(fs, MIPSInst_FS(ir));
1947 rv.d = ieee754dp_fsp(fs);
1948 rfmt = d_fmt;
1949 goto copcsr;
1950
1951 case fcvtw_op:
1952 MIPS_FPU_EMU_INC_STATS(cvt_w_s);
1953 SPFROMREG(fs, MIPSInst_FS(ir));
1954 rv.w = ieee754sp_tint(fs);
1955 rfmt = w_fmt;
1956 goto copcsr;
1957
1958 case fround_op:
1959 case ftrunc_op:
1960 case fceil_op:
1961 case ffloor_op:
1962 if (!cpu_has_mips_2_3_4_5_r)
1963 return SIGILL;
1964
1965 if (MIPSInst_FUNC(ir) == fceil_op)
1966 MIPS_FPU_EMU_INC_STATS(ceil_w_s);
1967 if (MIPSInst_FUNC(ir) == ffloor_op)
1968 MIPS_FPU_EMU_INC_STATS(floor_w_s);
1969 if (MIPSInst_FUNC(ir) == fround_op)
1970 MIPS_FPU_EMU_INC_STATS(round_w_s);
1971 if (MIPSInst_FUNC(ir) == ftrunc_op)
1972 MIPS_FPU_EMU_INC_STATS(trunc_w_s);
1973
1974 oldrm = ieee754_csr.rm;
1975 SPFROMREG(fs, MIPSInst_FS(ir));
1976 ieee754_csr.rm = MIPSInst_FUNC(ir);
1977 rv.w = ieee754sp_tint(fs);
1978 ieee754_csr.rm = oldrm;
1979 rfmt = w_fmt;
1980 goto copcsr;
1981
1982 case fsel_op:
1983 if (!cpu_has_mips_r6)
1984 return SIGILL;
1985
1986 MIPS_FPU_EMU_INC_STATS(sel_s);
1987 SPFROMREG(fd, MIPSInst_FD(ir));
1988 if (fd.bits & 0x1)
1989 SPFROMREG(rv.s, MIPSInst_FT(ir));
1990 else
1991 SPFROMREG(rv.s, MIPSInst_FS(ir));
1992 break;
1993
1994 case fcvtl_op:
1995 if (!cpu_has_mips_3_4_5_64_r2_r6)
1996 return SIGILL;
1997
1998 MIPS_FPU_EMU_INC_STATS(cvt_l_s);
1999 SPFROMREG(fs, MIPSInst_FS(ir));
2000 rv.l = ieee754sp_tlong(fs);
2001 rfmt = l_fmt;
2002 goto copcsr;
2003
2004 case froundl_op:
2005 case ftruncl_op:
2006 case fceill_op:
2007 case ffloorl_op:
2008 if (!cpu_has_mips_3_4_5_64_r2_r6)
2009 return SIGILL;
2010
2011 if (MIPSInst_FUNC(ir) == fceill_op)
2012 MIPS_FPU_EMU_INC_STATS(ceil_l_s);
2013 if (MIPSInst_FUNC(ir) == ffloorl_op)
2014 MIPS_FPU_EMU_INC_STATS(floor_l_s);
2015 if (MIPSInst_FUNC(ir) == froundl_op)
2016 MIPS_FPU_EMU_INC_STATS(round_l_s);
2017 if (MIPSInst_FUNC(ir) == ftruncl_op)
2018 MIPS_FPU_EMU_INC_STATS(trunc_l_s);
2019
2020 oldrm = ieee754_csr.rm;
2021 SPFROMREG(fs, MIPSInst_FS(ir));
2022 ieee754_csr.rm = MIPSInst_FUNC(ir);
2023 rv.l = ieee754sp_tlong(fs);
2024 ieee754_csr.rm = oldrm;
2025 rfmt = l_fmt;
2026 goto copcsr;
2027
2028 default:
2029 if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) {
2030 unsigned int cmpop;
2031 union ieee754sp fs, ft;
2032
2033 cmpop = MIPSInst_FUNC(ir) - fcmp_op;
2034 SPFROMREG(fs, MIPSInst_FS(ir));
2035 SPFROMREG(ft, MIPSInst_FT(ir));
2036 rv.w = ieee754sp_cmp(fs, ft,
2037 cmptab[cmpop & 0x7], cmpop & 0x8);
2038 rfmt = -1;
2039 if ((cmpop & 0x8) && ieee754_cxtest
2040 (IEEE754_INVALID_OPERATION))
2041 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2042 else
2043 goto copcsr;
2044
2045 } else
2046 return SIGILL;
2047 break;
2048 }
2049 break;
2050 }
2051
2052 case d_fmt: {
2053 union ieee754dp fd, fs, ft;
2054 union {
2055 union ieee754dp(*b) (union ieee754dp, union ieee754dp);
2056 union ieee754dp(*u) (union ieee754dp);
2057 } handler;
2058
2059 switch (MIPSInst_FUNC(ir)) {
2060
2061 case fadd_op:
2062 MIPS_FPU_EMU_INC_STATS(add_d);
2063 handler.b = ieee754dp_add;
2064 goto dcopbop;
2065 case fsub_op:
2066 MIPS_FPU_EMU_INC_STATS(sub_d);
2067 handler.b = ieee754dp_sub;
2068 goto dcopbop;
2069 case fmul_op:
2070 MIPS_FPU_EMU_INC_STATS(mul_d);
2071 handler.b = ieee754dp_mul;
2072 goto dcopbop;
2073 case fdiv_op:
2074 MIPS_FPU_EMU_INC_STATS(div_d);
2075 handler.b = ieee754dp_div;
2076 goto dcopbop;
2077
2078
2079 case fsqrt_op:
2080 if (!cpu_has_mips_2_3_4_5_r)
2081 return SIGILL;
2082
2083 MIPS_FPU_EMU_INC_STATS(sqrt_d);
2084 handler.u = ieee754dp_sqrt;
2085 goto dcopuop;
2086
2087
2088
2089
2090
2091 case frsqrt_op:
2092 if (!cpu_has_mips_4_5_64_r2_r6)
2093 return SIGILL;
2094
2095 MIPS_FPU_EMU_INC_STATS(rsqrt_d);
2096 handler.u = fpemu_dp_rsqrt;
2097 goto dcopuop;
2098 case frecip_op:
2099 if (!cpu_has_mips_4_5_64_r2_r6)
2100 return SIGILL;
2101
2102 MIPS_FPU_EMU_INC_STATS(recip_d);
2103 handler.u = fpemu_dp_recip;
2104 goto dcopuop;
2105 case fmovc_op:
2106 if (!cpu_has_mips_4_5_r)
2107 return SIGILL;
2108
2109 cond = fpucondbit[MIPSInst_FT(ir) >> 2];
2110 if (((ctx->fcr31 & cond) != 0) !=
2111 ((MIPSInst_FT(ir) & 1) != 0))
2112 return 0;
2113 DPFROMREG(rv.d, MIPSInst_FS(ir));
2114 break;
2115 case fmovz_op:
2116 if (!cpu_has_mips_4_5_r)
2117 return SIGILL;
2118
2119 if (xcp->regs[MIPSInst_FT(ir)] != 0)
2120 return 0;
2121 DPFROMREG(rv.d, MIPSInst_FS(ir));
2122 break;
2123 case fmovn_op:
2124 if (!cpu_has_mips_4_5_r)
2125 return SIGILL;
2126
2127 if (xcp->regs[MIPSInst_FT(ir)] == 0)
2128 return 0;
2129 DPFROMREG(rv.d, MIPSInst_FS(ir));
2130 break;
2131
2132 case fseleqz_op:
2133 if (!cpu_has_mips_r6)
2134 return SIGILL;
2135
2136 MIPS_FPU_EMU_INC_STATS(seleqz_d);
2137 DPFROMREG(rv.d, MIPSInst_FT(ir));
2138 if (rv.l & 0x1)
2139 rv.l = 0;
2140 else
2141 DPFROMREG(rv.d, MIPSInst_FS(ir));
2142 break;
2143
2144 case fselnez_op:
2145 if (!cpu_has_mips_r6)
2146 return SIGILL;
2147
2148 MIPS_FPU_EMU_INC_STATS(selnez_d);
2149 DPFROMREG(rv.d, MIPSInst_FT(ir));
2150 if (rv.l & 0x1)
2151 DPFROMREG(rv.d, MIPSInst_FS(ir));
2152 else
2153 rv.l = 0;
2154 break;
2155
2156 case fmaddf_op: {
2157 union ieee754dp ft, fs, fd;
2158
2159 if (!cpu_has_mips_r6)
2160 return SIGILL;
2161
2162 MIPS_FPU_EMU_INC_STATS(maddf_d);
2163 DPFROMREG(ft, MIPSInst_FT(ir));
2164 DPFROMREG(fs, MIPSInst_FS(ir));
2165 DPFROMREG(fd, MIPSInst_FD(ir));
2166 rv.d = ieee754dp_maddf(fd, fs, ft);
2167 goto copcsr;
2168 }
2169
2170 case fmsubf_op: {
2171 union ieee754dp ft, fs, fd;
2172
2173 if (!cpu_has_mips_r6)
2174 return SIGILL;
2175
2176 MIPS_FPU_EMU_INC_STATS(msubf_d);
2177 DPFROMREG(ft, MIPSInst_FT(ir));
2178 DPFROMREG(fs, MIPSInst_FS(ir));
2179 DPFROMREG(fd, MIPSInst_FD(ir));
2180 rv.d = ieee754dp_msubf(fd, fs, ft);
2181 goto copcsr;
2182 }
2183
2184 case frint_op: {
2185 union ieee754dp fs;
2186
2187 if (!cpu_has_mips_r6)
2188 return SIGILL;
2189
2190 MIPS_FPU_EMU_INC_STATS(rint_d);
2191 DPFROMREG(fs, MIPSInst_FS(ir));
2192 rv.d = ieee754dp_rint(fs);
2193 goto copcsr;
2194 }
2195
2196 case fclass_op: {
2197 union ieee754dp fs;
2198
2199 if (!cpu_has_mips_r6)
2200 return SIGILL;
2201
2202 MIPS_FPU_EMU_INC_STATS(class_d);
2203 DPFROMREG(fs, MIPSInst_FS(ir));
2204 rv.l = ieee754dp_2008class(fs);
2205 rfmt = l_fmt;
2206 goto copcsr;
2207 }
2208
2209 case fmin_op: {
2210 union ieee754dp fs, ft;
2211
2212 if (!cpu_has_mips_r6)
2213 return SIGILL;
2214
2215 MIPS_FPU_EMU_INC_STATS(min_d);
2216 DPFROMREG(ft, MIPSInst_FT(ir));
2217 DPFROMREG(fs, MIPSInst_FS(ir));
2218 rv.d = ieee754dp_fmin(fs, ft);
2219 goto copcsr;
2220 }
2221
2222 case fmina_op: {
2223 union ieee754dp fs, ft;
2224
2225 if (!cpu_has_mips_r6)
2226 return SIGILL;
2227
2228 MIPS_FPU_EMU_INC_STATS(mina_d);
2229 DPFROMREG(ft, MIPSInst_FT(ir));
2230 DPFROMREG(fs, MIPSInst_FS(ir));
2231 rv.d = ieee754dp_fmina(fs, ft);
2232 goto copcsr;
2233 }
2234
2235 case fmax_op: {
2236 union ieee754dp fs, ft;
2237
2238 if (!cpu_has_mips_r6)
2239 return SIGILL;
2240
2241 MIPS_FPU_EMU_INC_STATS(max_d);
2242 DPFROMREG(ft, MIPSInst_FT(ir));
2243 DPFROMREG(fs, MIPSInst_FS(ir));
2244 rv.d = ieee754dp_fmax(fs, ft);
2245 goto copcsr;
2246 }
2247
2248 case fmaxa_op: {
2249 union ieee754dp fs, ft;
2250
2251 if (!cpu_has_mips_r6)
2252 return SIGILL;
2253
2254 MIPS_FPU_EMU_INC_STATS(maxa_d);
2255 DPFROMREG(ft, MIPSInst_FT(ir));
2256 DPFROMREG(fs, MIPSInst_FS(ir));
2257 rv.d = ieee754dp_fmaxa(fs, ft);
2258 goto copcsr;
2259 }
2260
2261 case fabs_op:
2262 MIPS_FPU_EMU_INC_STATS(abs_d);
2263 handler.u = ieee754dp_abs;
2264 goto dcopuop;
2265
2266 case fneg_op:
2267 MIPS_FPU_EMU_INC_STATS(neg_d);
2268 handler.u = ieee754dp_neg;
2269 goto dcopuop;
2270
2271 case fmov_op:
2272
2273 MIPS_FPU_EMU_INC_STATS(mov_d);
2274 DPFROMREG(rv.d, MIPSInst_FS(ir));
2275 goto copcsr;
2276
2277
2278dcopbop:
2279 DPFROMREG(fs, MIPSInst_FS(ir));
2280 DPFROMREG(ft, MIPSInst_FT(ir));
2281
2282 rv.d = (*handler.b) (fs, ft);
2283 goto copcsr;
2284dcopuop:
2285 DPFROMREG(fs, MIPSInst_FS(ir));
2286 rv.d = (*handler.u) (fs);
2287 goto copcsr;
2288
2289
2290
2291
2292 case fcvts_op:
2293 MIPS_FPU_EMU_INC_STATS(cvt_s_d);
2294 DPFROMREG(fs, MIPSInst_FS(ir));
2295 rv.s = ieee754sp_fdp(fs);
2296 rfmt = s_fmt;
2297 goto copcsr;
2298
2299 case fcvtd_op:
2300 return SIGILL;
2301
2302 case fcvtw_op:
2303 MIPS_FPU_EMU_INC_STATS(cvt_w_d);
2304 DPFROMREG(fs, MIPSInst_FS(ir));
2305 rv.w = ieee754dp_tint(fs);
2306 rfmt = w_fmt;
2307 goto copcsr;
2308
2309 case fround_op:
2310 case ftrunc_op:
2311 case fceil_op:
2312 case ffloor_op:
2313 if (!cpu_has_mips_2_3_4_5_r)
2314 return SIGILL;
2315
2316 if (MIPSInst_FUNC(ir) == fceil_op)
2317 MIPS_FPU_EMU_INC_STATS(ceil_w_d);
2318 if (MIPSInst_FUNC(ir) == ffloor_op)
2319 MIPS_FPU_EMU_INC_STATS(floor_w_d);
2320 if (MIPSInst_FUNC(ir) == fround_op)
2321 MIPS_FPU_EMU_INC_STATS(round_w_d);
2322 if (MIPSInst_FUNC(ir) == ftrunc_op)
2323 MIPS_FPU_EMU_INC_STATS(trunc_w_d);
2324
2325 oldrm = ieee754_csr.rm;
2326 DPFROMREG(fs, MIPSInst_FS(ir));
2327 ieee754_csr.rm = MIPSInst_FUNC(ir);
2328 rv.w = ieee754dp_tint(fs);
2329 ieee754_csr.rm = oldrm;
2330 rfmt = w_fmt;
2331 goto copcsr;
2332
2333 case fsel_op:
2334 if (!cpu_has_mips_r6)
2335 return SIGILL;
2336
2337 MIPS_FPU_EMU_INC_STATS(sel_d);
2338 DPFROMREG(fd, MIPSInst_FD(ir));
2339 if (fd.bits & 0x1)
2340 DPFROMREG(rv.d, MIPSInst_FT(ir));
2341 else
2342 DPFROMREG(rv.d, MIPSInst_FS(ir));
2343 break;
2344
2345 case fcvtl_op:
2346 if (!cpu_has_mips_3_4_5_64_r2_r6)
2347 return SIGILL;
2348
2349 MIPS_FPU_EMU_INC_STATS(cvt_l_d);
2350 DPFROMREG(fs, MIPSInst_FS(ir));
2351 rv.l = ieee754dp_tlong(fs);
2352 rfmt = l_fmt;
2353 goto copcsr;
2354
2355 case froundl_op:
2356 case ftruncl_op:
2357 case fceill_op:
2358 case ffloorl_op:
2359 if (!cpu_has_mips_3_4_5_64_r2_r6)
2360 return SIGILL;
2361
2362 if (MIPSInst_FUNC(ir) == fceill_op)
2363 MIPS_FPU_EMU_INC_STATS(ceil_l_d);
2364 if (MIPSInst_FUNC(ir) == ffloorl_op)
2365 MIPS_FPU_EMU_INC_STATS(floor_l_d);
2366 if (MIPSInst_FUNC(ir) == froundl_op)
2367 MIPS_FPU_EMU_INC_STATS(round_l_d);
2368 if (MIPSInst_FUNC(ir) == ftruncl_op)
2369 MIPS_FPU_EMU_INC_STATS(trunc_l_d);
2370
2371 oldrm = ieee754_csr.rm;
2372 DPFROMREG(fs, MIPSInst_FS(ir));
2373 ieee754_csr.rm = MIPSInst_FUNC(ir);
2374 rv.l = ieee754dp_tlong(fs);
2375 ieee754_csr.rm = oldrm;
2376 rfmt = l_fmt;
2377 goto copcsr;
2378
2379 default:
2380 if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) {
2381 unsigned int cmpop;
2382 union ieee754dp fs, ft;
2383
2384 cmpop = MIPSInst_FUNC(ir) - fcmp_op;
2385 DPFROMREG(fs, MIPSInst_FS(ir));
2386 DPFROMREG(ft, MIPSInst_FT(ir));
2387 rv.w = ieee754dp_cmp(fs, ft,
2388 cmptab[cmpop & 0x7], cmpop & 0x8);
2389 rfmt = -1;
2390 if ((cmpop & 0x8)
2391 &&
2392 ieee754_cxtest
2393 (IEEE754_INVALID_OPERATION))
2394 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2395 else
2396 goto copcsr;
2397
2398 }
2399 else {
2400 return SIGILL;
2401 }
2402 break;
2403 }
2404 break;
2405 }
2406
2407 case w_fmt: {
2408 union ieee754dp fs;
2409
2410 switch (MIPSInst_FUNC(ir)) {
2411 case fcvts_op:
2412
2413 MIPS_FPU_EMU_INC_STATS(cvt_s_w);
2414 SPFROMREG(fs, MIPSInst_FS(ir));
2415 rv.s = ieee754sp_fint(fs.bits);
2416 rfmt = s_fmt;
2417 goto copcsr;
2418 case fcvtd_op:
2419
2420 MIPS_FPU_EMU_INC_STATS(cvt_d_w);
2421 SPFROMREG(fs, MIPSInst_FS(ir));
2422 rv.d = ieee754dp_fint(fs.bits);
2423 rfmt = d_fmt;
2424 goto copcsr;
2425 default: {
2426
2427#define CMPOP_MASK 0x7
2428#define SIGN_BIT (0x1 << 3)
2429#define PREDICATE_BIT (0x1 << 4)
2430
2431 int cmpop = MIPSInst_FUNC(ir) & CMPOP_MASK;
2432 int sig = MIPSInst_FUNC(ir) & SIGN_BIT;
2433 union ieee754sp fs, ft;
2434
2435
2436 if (!cpu_has_mips_r6 ||
2437 (MIPSInst_FUNC(ir) & 0x20))
2438 return SIGILL;
2439
2440 if (!sig) {
2441 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2442 switch (cmpop) {
2443 case 0:
2444 MIPS_FPU_EMU_INC_STATS(cmp_af_s);
2445 break;
2446 case 1:
2447 MIPS_FPU_EMU_INC_STATS(cmp_un_s);
2448 break;
2449 case 2:
2450 MIPS_FPU_EMU_INC_STATS(cmp_eq_s);
2451 break;
2452 case 3:
2453 MIPS_FPU_EMU_INC_STATS(cmp_ueq_s);
2454 break;
2455 case 4:
2456 MIPS_FPU_EMU_INC_STATS(cmp_lt_s);
2457 break;
2458 case 5:
2459 MIPS_FPU_EMU_INC_STATS(cmp_ult_s);
2460 break;
2461 case 6:
2462 MIPS_FPU_EMU_INC_STATS(cmp_le_s);
2463 break;
2464 case 7:
2465 MIPS_FPU_EMU_INC_STATS(cmp_ule_s);
2466 break;
2467 }
2468 } else {
2469 switch (cmpop) {
2470 case 1:
2471 MIPS_FPU_EMU_INC_STATS(cmp_or_s);
2472 break;
2473 case 2:
2474 MIPS_FPU_EMU_INC_STATS(cmp_une_s);
2475 break;
2476 case 3:
2477 MIPS_FPU_EMU_INC_STATS(cmp_ne_s);
2478 break;
2479 }
2480 }
2481 } else {
2482 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2483 switch (cmpop) {
2484 case 0:
2485 MIPS_FPU_EMU_INC_STATS(cmp_saf_s);
2486 break;
2487 case 1:
2488 MIPS_FPU_EMU_INC_STATS(cmp_sun_s);
2489 break;
2490 case 2:
2491 MIPS_FPU_EMU_INC_STATS(cmp_seq_s);
2492 break;
2493 case 3:
2494 MIPS_FPU_EMU_INC_STATS(cmp_sueq_s);
2495 break;
2496 case 4:
2497 MIPS_FPU_EMU_INC_STATS(cmp_slt_s);
2498 break;
2499 case 5:
2500 MIPS_FPU_EMU_INC_STATS(cmp_sult_s);
2501 break;
2502 case 6:
2503 MIPS_FPU_EMU_INC_STATS(cmp_sle_s);
2504 break;
2505 case 7:
2506 MIPS_FPU_EMU_INC_STATS(cmp_sule_s);
2507 break;
2508 }
2509 } else {
2510 switch (cmpop) {
2511 case 1:
2512 MIPS_FPU_EMU_INC_STATS(cmp_sor_s);
2513 break;
2514 case 2:
2515 MIPS_FPU_EMU_INC_STATS(cmp_sune_s);
2516 break;
2517 case 3:
2518 MIPS_FPU_EMU_INC_STATS(cmp_sne_s);
2519 break;
2520 }
2521 }
2522 }
2523
2524
2525 rfmt = s_fmt;
2526
2527 rv.w = 0;
2528
2529
2530 SPFROMREG(fs, MIPSInst_FS(ir));
2531 SPFROMREG(ft, MIPSInst_FT(ir));
2532
2533
2534 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2535 if (ieee754sp_cmp(fs, ft, cmptab[cmpop],
2536 sig))
2537 rv.w = -1;
2538 if ((sig) &&
2539 ieee754_cxtest(IEEE754_INVALID_OPERATION))
2540 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2541 else
2542 goto copcsr;
2543 } else {
2544
2545 switch (cmpop) {
2546 case 1:
2547 case 2:
2548 case 3:
2549 if (ieee754sp_cmp(fs, ft,
2550 negative_cmptab[cmpop],
2551 sig))
2552 rv.w = -1;
2553 if (sig &&
2554 ieee754_cxtest(IEEE754_INVALID_OPERATION))
2555 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2556 else
2557 goto copcsr;
2558 break;
2559 default:
2560
2561 return SIGILL;
2562 }
2563 }
2564 break;
2565 }
2566 }
2567 break;
2568 }
2569
2570 case l_fmt:
2571
2572 if (!cpu_has_mips_3_4_5_64_r2_r6)
2573 return SIGILL;
2574
2575 DIFROMREG(bits, MIPSInst_FS(ir));
2576
2577 switch (MIPSInst_FUNC(ir)) {
2578 case fcvts_op:
2579
2580 MIPS_FPU_EMU_INC_STATS(cvt_s_l);
2581 rv.s = ieee754sp_flong(bits);
2582 rfmt = s_fmt;
2583 goto copcsr;
2584 case fcvtd_op:
2585
2586 MIPS_FPU_EMU_INC_STATS(cvt_d_l);
2587 rv.d = ieee754dp_flong(bits);
2588 rfmt = d_fmt;
2589 goto copcsr;
2590 default: {
2591
2592 int cmpop = MIPSInst_FUNC(ir) & CMPOP_MASK;
2593 int sig = MIPSInst_FUNC(ir) & SIGN_BIT;
2594 union ieee754dp fs, ft;
2595
2596 if (!cpu_has_mips_r6 ||
2597 (MIPSInst_FUNC(ir) & 0x20))
2598 return SIGILL;
2599
2600 if (!sig) {
2601 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2602 switch (cmpop) {
2603 case 0:
2604 MIPS_FPU_EMU_INC_STATS(cmp_af_d);
2605 break;
2606 case 1:
2607 MIPS_FPU_EMU_INC_STATS(cmp_un_d);
2608 break;
2609 case 2:
2610 MIPS_FPU_EMU_INC_STATS(cmp_eq_d);
2611 break;
2612 case 3:
2613 MIPS_FPU_EMU_INC_STATS(cmp_ueq_d);
2614 break;
2615 case 4:
2616 MIPS_FPU_EMU_INC_STATS(cmp_lt_d);
2617 break;
2618 case 5:
2619 MIPS_FPU_EMU_INC_STATS(cmp_ult_d);
2620 break;
2621 case 6:
2622 MIPS_FPU_EMU_INC_STATS(cmp_le_d);
2623 break;
2624 case 7:
2625 MIPS_FPU_EMU_INC_STATS(cmp_ule_d);
2626 break;
2627 }
2628 } else {
2629 switch (cmpop) {
2630 case 1:
2631 MIPS_FPU_EMU_INC_STATS(cmp_or_d);
2632 break;
2633 case 2:
2634 MIPS_FPU_EMU_INC_STATS(cmp_une_d);
2635 break;
2636 case 3:
2637 MIPS_FPU_EMU_INC_STATS(cmp_ne_d);
2638 break;
2639 }
2640 }
2641 } else {
2642 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2643 switch (cmpop) {
2644 case 0:
2645 MIPS_FPU_EMU_INC_STATS(cmp_saf_d);
2646 break;
2647 case 1:
2648 MIPS_FPU_EMU_INC_STATS(cmp_sun_d);
2649 break;
2650 case 2:
2651 MIPS_FPU_EMU_INC_STATS(cmp_seq_d);
2652 break;
2653 case 3:
2654 MIPS_FPU_EMU_INC_STATS(cmp_sueq_d);
2655 break;
2656 case 4:
2657 MIPS_FPU_EMU_INC_STATS(cmp_slt_d);
2658 break;
2659 case 5:
2660 MIPS_FPU_EMU_INC_STATS(cmp_sult_d);
2661 break;
2662 case 6:
2663 MIPS_FPU_EMU_INC_STATS(cmp_sle_d);
2664 break;
2665 case 7:
2666 MIPS_FPU_EMU_INC_STATS(cmp_sule_d);
2667 break;
2668 }
2669 } else {
2670 switch (cmpop) {
2671 case 1:
2672 MIPS_FPU_EMU_INC_STATS(cmp_sor_d);
2673 break;
2674 case 2:
2675 MIPS_FPU_EMU_INC_STATS(cmp_sune_d);
2676 break;
2677 case 3:
2678 MIPS_FPU_EMU_INC_STATS(cmp_sne_d);
2679 break;
2680 }
2681 }
2682 }
2683
2684
2685 rfmt = d_fmt;
2686
2687 rv.l = 0;
2688
2689
2690 DPFROMREG(fs, MIPSInst_FS(ir));
2691 DPFROMREG(ft, MIPSInst_FT(ir));
2692
2693
2694 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2695 if (ieee754dp_cmp(fs, ft,
2696 cmptab[cmpop], sig))
2697 rv.l = -1LL;
2698 if (sig &&
2699 ieee754_cxtest(IEEE754_INVALID_OPERATION))
2700 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2701 else
2702 goto copcsr;
2703 } else {
2704
2705 switch (cmpop) {
2706 case 1:
2707 case 2:
2708 case 3:
2709 if (ieee754dp_cmp(fs, ft,
2710 negative_cmptab[cmpop],
2711 sig))
2712 rv.l = -1LL;
2713 if (sig &&
2714 ieee754_cxtest(IEEE754_INVALID_OPERATION))
2715 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2716 else
2717 goto copcsr;
2718 break;
2719 default:
2720
2721 return SIGILL;
2722 }
2723 }
2724 break;
2725 }
2726 }
2727 break;
2728
2729 default:
2730 return SIGILL;
2731 }
2732
2733
2734
2735
2736
2737
2738
2739
2740 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
2741 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
2742
2743 return SIGFPE;
2744 }
2745
2746
2747
2748
2749 switch (rfmt) {
2750 case -1:
2751
2752 if (cpu_has_mips_4_5_r)
2753 cbit = fpucondbit[MIPSInst_FD(ir) >> 2];
2754 else
2755 cbit = FPU_CSR_COND;
2756 if (rv.w)
2757 ctx->fcr31 |= cbit;
2758 else
2759 ctx->fcr31 &= ~cbit;
2760 break;
2761
2762 case d_fmt:
2763 DPTOREG(rv.d, MIPSInst_FD(ir));
2764 break;
2765 case s_fmt:
2766 SPTOREG(rv.s, MIPSInst_FD(ir));
2767 break;
2768 case w_fmt:
2769 SITOREG(rv.w, MIPSInst_FD(ir));
2770 break;
2771 case l_fmt:
2772 if (!cpu_has_mips_3_4_5_64_r2_r6)
2773 return SIGILL;
2774
2775 DITOREG(rv.l, MIPSInst_FD(ir));
2776 break;
2777 default:
2778 return SIGILL;
2779 }
2780
2781 return 0;
2782}
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
2814 int has_fpu, void __user **fault_addr)
2815{
2816 unsigned long oldepc, prevepc;
2817 struct mm_decoded_insn dec_insn;
2818 u16 instr[4];
2819 u16 *instr_ptr;
2820 int sig = 0;
2821
2822
2823
2824
2825
2826 if (!init_fp_ctx(current))
2827 lose_fpu(1);
2828
2829 oldepc = xcp->cp0_epc;
2830 do {
2831 prevepc = xcp->cp0_epc;
2832
2833 if (get_isa16_mode(prevepc) && cpu_has_mmips) {
2834
2835
2836
2837
2838 if ((get_user(instr[0], (u16 __user *)msk_isa16_mode(xcp->cp0_epc))) ||
2839 (get_user(instr[1], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 2))) ||
2840 (get_user(instr[2], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 4))) ||
2841 (get_user(instr[3], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 6)))) {
2842 MIPS_FPU_EMU_INC_STATS(errors);
2843 return SIGBUS;
2844 }
2845 instr_ptr = instr;
2846
2847
2848 if (mm_insn_16bit(*instr_ptr)) {
2849
2850 dec_insn.insn = (*instr_ptr << 16) |
2851 (*instr_ptr);
2852
2853 dec_insn.pc_inc = 2;
2854 instr_ptr += 1;
2855 } else {
2856 dec_insn.insn = (*instr_ptr << 16) |
2857 *(instr_ptr+1);
2858
2859 dec_insn.pc_inc = 4;
2860 instr_ptr += 2;
2861 }
2862
2863 if (mm_insn_16bit(*instr_ptr)) {
2864
2865 dec_insn.next_insn = (*instr_ptr << 16) |
2866 (*instr_ptr);
2867
2868 dec_insn.next_pc_inc = 2;
2869 } else {
2870 dec_insn.next_insn = (*instr_ptr << 16) |
2871 *(instr_ptr+1);
2872
2873 dec_insn.next_pc_inc = 4;
2874 }
2875 dec_insn.micro_mips_mode = 1;
2876 } else {
2877 if ((get_user(dec_insn.insn,
2878 (mips_instruction __user *) xcp->cp0_epc)) ||
2879 (get_user(dec_insn.next_insn,
2880 (mips_instruction __user *)(xcp->cp0_epc+4)))) {
2881 MIPS_FPU_EMU_INC_STATS(errors);
2882 return SIGBUS;
2883 }
2884 dec_insn.pc_inc = 4;
2885 dec_insn.next_pc_inc = 4;
2886 dec_insn.micro_mips_mode = 0;
2887 }
2888
2889 if ((dec_insn.insn == 0) ||
2890 ((dec_insn.pc_inc == 2) &&
2891 ((dec_insn.insn & 0xffff) == MM_NOP16)))
2892 xcp->cp0_epc += dec_insn.pc_inc;
2893 else {
2894
2895
2896
2897
2898 sig = cop1Emulate(xcp, ctx, dec_insn, fault_addr);
2899 }
2900
2901 if (has_fpu)
2902 break;
2903 if (sig)
2904 break;
2905
2906
2907
2908
2909
2910
2911
2912 if ((xcp->cp0_epc ^ prevepc) & 0x1)
2913 break;
2914
2915 cond_resched();
2916 } while (xcp->cp0_epc > prevepc);
2917
2918
2919 if (sig == SIGILL && xcp->cp0_epc != oldepc)
2920
2921 sig = 0;
2922
2923 return sig;
2924}
2925