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