powerpc/nvdimm: Pick nearby online node if the device node is not online
[linux-2.6-block.git] / arch / mips / math-emu / cp1emu.c
CommitLineData
9d5a6349 1// SPDX-License-Identifier: GPL-2.0-only
1da177e4 2/*
3f7cac41 3 * cp1emu.c: a MIPS coprocessor 1 (FPU) instruction emulator
1da177e4
LT
4 *
5 * MIPS floating point support
6 * Copyright (C) 1994-2000 Algorithmics Ltd.
1da177e4
LT
7 *
8 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
9 * Copyright (C) 2000 MIPS Technologies, Inc.
10 *
1da177e4
LT
11 * A complete emulator for MIPS coprocessor 1 instructions. This is
12 * required for #float(switch) or #float(trap), where it catches all
13 * COP1 instructions via the "CoProcessor Unusable" exception.
14 *
15 * More surprisingly it is also required for #float(ieee), to help out
3f7cac41 16 * the hardware FPU at the boundaries of the IEEE-754 representation
1da177e4
LT
17 * (denormalised values, infinities, underflow, etc). It is made
18 * quite nasty because emulation of some non-COP1 instructions is
19 * required, e.g. in branch delay slots.
20 *
3f7cac41 21 * Note if you know that you won't have an FPU, then you'll get much
1da177e4
LT
22 * better performance by compiling with -msoft-float!
23 */
24#include <linux/sched.h>
83fd38ca 25#include <linux/debugfs.h>
85c51c51 26#include <linux/percpu-defs.h>
7f788d2d 27#include <linux/perf_event.h>
1da177e4 28
cd8ee345 29#include <asm/branch.h>
1da177e4 30#include <asm/inst.h>
1da177e4
LT
31#include <asm/ptrace.h>
32#include <asm/signal.h>
7c0f6ba6 33#include <linux/uaccess.h>
cd8ee345 34
f6843626 35#include <asm/cpu-info.h>
cd8ee345 36#include <asm/processor.h>
1da177e4 37#include <asm/fpu_emulator.h>
102cedc3 38#include <asm/fpu.h>
b0a668fb 39#include <asm/mips-r2-to-r6-emul.h>
1da177e4
LT
40
41#include "ieee754.h"
1da177e4 42
1da177e4
LT
43/* Function which emulates a floating point instruction. */
44
eae89076 45static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
1da177e4
LT
46 mips_instruction);
47
1da177e4 48static int fpux_emu(struct pt_regs *,
445a58ce 49 struct mips_fpu_struct *, mips_instruction, void __user **);
1da177e4 50
1da177e4
LT
51/* Control registers */
52
53#define FPCREG_RID 0 /* $0 = revision id */
c491cfa2
MR
54#define FPCREG_FCCR 25 /* $25 = fccr */
55#define FPCREG_FEXR 26 /* $26 = fexr */
56#define FPCREG_FENR 28 /* $28 = fenr */
1da177e4
LT
57#define FPCREG_CSR 31 /* $31 = csr */
58
1da177e4 59/* convert condition code register number to csr bit */
b0a668fb 60const unsigned int fpucondbit[8] = {
c491cfa2 61 FPU_CSR_COND,
1da177e4
LT
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};
1da177e4 70
102cedc3
LY
71/* (microMIPS) Convert certain microMIPS instructions to MIPS32 format. */
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 * This functions translates a 32-bit microMIPS instruction
79 * into a 32-bit MIPS32 instruction. Returns 0 on success
80 * and SIGILL otherwise.
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 /* NOTE: offset is << by 1 if in microMIPS mode. */
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; /* Invalid */
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; /* Invalid */
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; /* Invalid */
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; /* Invalid */
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: /* POOL32FXF */
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:
9355e59c
SH
369 case mm_mfhc1_op:
370 case mm_mthc1_op:
102cedc3
LY
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;
9355e59c 377 else if (insn.mm_fp1_format.op == mm_ctc1_op)
102cedc3 378 op = ctc_op;
9355e59c
SH
379 else if (insn.mm_fp1_format.op == mm_mfhc1_op)
380 op = mfhc_op;
381 else
382 op = mthc_op;
102cedc3
LY
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;
102cedc3
LY
394 }
395 break;
396 case mm_32f_74_op: /* c.cond.fmt */
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;
102cedc3
LY
408 }
409 break;
410 default:
411 return SIGILL;
102cedc3
LY
412 }
413
414 *insn_ptr = mips32_insn;
415 return 0;
416}
417
1da177e4
LT
418/*
419 * Redundant with logic already in kernel/branch.c,
420 * embedded in compute_return_epc. At some point,
421 * a single subroutine should be used across both
422 * modules.
423 */
432c6bac
PB
424int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
425 unsigned long *contpc)
1da177e4 426{
102cedc3
LY
427 union mips_instruction insn = (union mips_instruction)dec_insn.insn;
428 unsigned int fcr31;
429 unsigned int bit = 0;
8bcd84a4
DL
430 unsigned int bit0;
431 union fpureg *fpr;
102cedc3
LY
432
433 switch (insn.i_format.opcode) {
1da177e4 434 case spec_op:
102cedc3 435 switch (insn.r_format.func) {
1da177e4 436 case jalr_op:
ab4a92e6
PB
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 }
2a14b21a 442 /* fall through */
1da177e4 443 case jr_op:
5f9f41c4 444 /* For R6, JR already emulated in jalr_op */
143fefc8 445 if (NO_R6EMU && insn.r_format.func == jr_op)
5f9f41c4 446 break;
102cedc3 447 *contpc = regs->regs[insn.r_format.rs];
1da177e4
LT
448 return 1;
449 }
450 break;
1da177e4 451 case bcond_op:
102cedc3
LY
452 switch (insn.i_format.rt) {
453 case bltzal_op:
454 case bltzall_op:
319824ea
MC
455 if (NO_R6EMU && (insn.i_format.rs ||
456 insn.i_format.rt == bltzall_op))
457 break;
458
102cedc3
LY
459 regs->regs[31] = regs->cp0_epc +
460 dec_insn.pc_inc +
461 dec_insn.next_pc_inc;
2a14b21a 462 /* fall through */
1da177e4 463 case bltzl_op:
319824ea
MC
464 if (NO_R6EMU)
465 break;
2a14b21a 466 /* fall through */
319824ea 467 case bltz_op:
102cedc3
LY
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;
1da177e4 477 case bgezal_op:
1da177e4 478 case bgezall_op:
319824ea
MC
479 if (NO_R6EMU && (insn.i_format.rs ||
480 insn.i_format.rt == bgezall_op))
481 break;
482
102cedc3
LY
483 regs->regs[31] = regs->cp0_epc +
484 dec_insn.pc_inc +
485 dec_insn.next_pc_inc;
2a14b21a 486 /* fall through */
102cedc3 487 case bgezl_op:
319824ea
MC
488 if (NO_R6EMU)
489 break;
2a14b21a 490 /* fall through */
319824ea 491 case bgez_op:
102cedc3
LY
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;
1da177e4
LT
500 return 1;
501 }
502 break;
1da177e4 503 case jalx_op:
102cedc3 504 set_isa16_mode(bit);
2a14b21a 505 /* fall through */
102cedc3
LY
506 case jal_op:
507 regs->regs[31] = regs->cp0_epc +
508 dec_insn.pc_inc +
509 dec_insn.next_pc_inc;
2a14b21a 510 /* fall through */
102cedc3
LY
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 /* Set microMIPS mode bit: XOR for jalx. */
517 *contpc ^= bit;
518 return 1;
1da177e4 519 case beql_op:
319824ea
MC
520 if (NO_R6EMU)
521 break;
2a14b21a 522 /* fall through */
319824ea 523 case beq_op:
102cedc3
LY
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;
1da177e4 534 case bnel_op:
319824ea
MC
535 if (NO_R6EMU)
536 break;
2a14b21a 537 /* fall through */
319824ea 538 case bne_op:
102cedc3
LY
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;
1da177e4 549 case blezl_op:
e9d92d22 550 if (!insn.i_format.rt && NO_R6EMU)
319824ea 551 break;
2a14b21a 552 /* fall through */
319824ea 553 case blez_op:
a8ff66f5
MC
554
555 /*
556 * Compact branches for R6 for the
557 * blez and blezl opcodes.
558 * BLEZ | rs = 0 | rt != 0 == BLEZALC
559 * BLEZ | rs = rt != 0 == BGEZALC
560 * BLEZ | rs != 0 | rt != 0 == BGEUC
561 * BLEZL | rs = 0 | rt != 0 == BLEZC
562 * BLEZL | rs = rt != 0 == BGEZC
563 * BLEZL | rs != 0 | rt != 0 == BGEC
564 *
565 * For real BLEZ{,L}, rt is always 0.
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 }
102cedc3
LY
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;
1da177e4 587 case bgtzl_op:
e9d92d22 588 if (!insn.i_format.rt && NO_R6EMU)
319824ea 589 break;
2a14b21a 590 /* fall through */
319824ea 591 case bgtz_op:
f1b44067
MC
592 /*
593 * Compact branches for R6 for the
594 * bgtz and bgtzl opcodes.
595 * BGTZ | rs = 0 | rt != 0 == BGTZALC
596 * BGTZ | rs = rt != 0 == BLTZALC
597 * BGTZ | rs != 0 | rt != 0 == BLTUC
598 * BGTZL | rs = 0 | rt != 0 == BGTZC
599 * BGTZL | rs = rt != 0 == BLTZC
600 * BGTZL | rs != 0 | rt != 0 == BLTC
601 *
602 * *ZALC varint for BGTZ &&& rt != 0
603 * For real GTZ{,L}, rt is always 0.
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
102cedc3
LY
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;
1da177e4 625 return 1;
1b492600
PB
626 case pop10_op:
627 case pop30_op:
c893ce38
MC
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;
c26d4219
DD
636#ifdef CONFIG_CPU_CAVIUM_OCTEON
637 case lwc2_op: /* This is bbit0 on Octeon */
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: /* This is bbit032 on Octeon */
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: /* This is bbit1 on Octeon */
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: /* This is bbit132 on Octeon */
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;
8467ca01
MC
661#else
662 case bc6_op:
663 /*
664 * Only valid for MIPS R6 but we can still end up
665 * here from a broken userland so just tell emulator
666 * this is not a branch and let it break later on.
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
84fef630
MC
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
69b9a2fd 681 return 1;
1c66b79b 682 case pop66_op:
69b9a2fd
MC
683 if (!cpu_has_mips_r6)
684 break;
685 *contpc = regs->cp0_epc + dec_insn.pc_inc +
686 dec_insn.next_pc_inc;
687
28d6f93d 688 return 1;
1c66b79b 689 case pop76_op:
28d6f93d
MC
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
8467ca01 697 return 1;
c26d4219 698#endif
1da177e4
LT
699 case cop0_op:
700 case cop1_op:
c8a34581
MC
701 /* Need to check for R6 bc1nez and bc1eqz branches */
702 if (cpu_has_mips_r6 &&
703 ((insn.i_format.rs == bc1eqz_op) ||
704 (insn.i_format.rs == bc1nez_op))) {
705 bit = 0;
8bcd84a4
DL
706 fpr = &current->thread.fpu.fpr[insn.i_format.rt];
707 bit0 = get_fpr32(fpr, 0) & 0x1;
c8a34581
MC
708 switch (insn.i_format.rs) {
709 case bc1eqz_op:
8bcd84a4 710 bit = bit0 == 0;
c8a34581
MC
711 break;
712 case bc1nez_op:
8bcd84a4 713 bit = bit0 != 0;
c8a34581
MC
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 }
2a14b21a
AM
727 /* R2/R6 compatible cop1 instruction */
728 /* fall through */
1da177e4
LT
729 case cop2_op:
730 case cop1x_op:
102cedc3
LY
731 if (insn.i_format.rs == bc_op) {
732 preempt_disable();
733 if (is_fpu_owner())
842dfc11 734 fcr31 = read_32bit_cp1_register(CP1_STATUS);
102cedc3
LY
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: /* bc1f */
744 case 2: /* bc1fl */
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;
102cedc3
LY
754 case 1: /* bc1t */
755 case 3: /* bc1tl */
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;
102cedc3
LY
765 }
766 }
1da177e4
LT
767 break;
768 }
1da177e4
LT
769 return 0;
770}
771
772/*
773 * In the Linux kernel, we support selection of FPR format on the
70342287 774 * basis of the Status.FR bit. If an FPU is not present, the FR bit
da0bac33 775 * is hardwired to zero, which would imply a 32-bit FPU even for
597ce172 776 * 64-bit CPUs so we rather look at TIF_32BIT_FPREGS.
51d943f0
RB
777 * FPU emu is slow and bulky and optimizing this function offers fairly
778 * sizeable benefits so we try to be clever and make this function return
779 * a constant whenever possible, that is on 64-bit kernels without O32
597ce172 780 * compatibility enabled and on 32-bit without 64-bit FPU support.
1da177e4 781 */
da0bac33
DD
782static inline int cop1_64bit(struct pt_regs *xcp)
783{
97f2645f 784 if (IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_MIPS32_O32))
08a07904 785 return 1;
97f2645f
MY
786 else if (IS_ENABLED(CONFIG_32BIT) &&
787 !IS_ENABLED(CONFIG_MIPS_O32_FP64_SUPPORT))
08a07904
RB
788 return 0;
789
597ce172 790 return !test_thread_flag(TIF_32BIT_FPREGS);
da0bac33
DD
791}
792
4227a2d4
PB
793static inline bool hybrid_fprs(void)
794{
795 return test_thread_flag(TIF_HYBRID_FPREGS);
796}
797
47fa0c02
RB
798#define SIFROMREG(si, x) \
799do { \
4227a2d4 800 if (cop1_64bit(xcp) && !hybrid_fprs()) \
c8c0da6b 801 (si) = (int)get_fpr32(&ctx->fpr[x], 0); \
bbd426f5 802 else \
c8c0da6b 803 (si) = (int)get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \
bbd426f5 804} while (0)
1da177e4 805
47fa0c02
RB
806#define SITOREG(si, x) \
807do { \
4227a2d4 808 if (cop1_64bit(xcp) && !hybrid_fprs()) { \
a58f85b5 809 unsigned int i; \
bbd426f5 810 set_fpr32(&ctx->fpr[x], 0, si); \
ef1c47af
PB
811 for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \
812 set_fpr32(&ctx->fpr[x], i, 0); \
813 } else { \
bbd426f5 814 set_fpr32(&ctx->fpr[(x) & ~1], (x) & 1, si); \
ef1c47af 815 } \
bbd426f5 816} while (0)
1da177e4 817
c8c0da6b 818#define SIFROMHREG(si, x) ((si) = (int)get_fpr32(&ctx->fpr[x], 1))
ef1c47af 819
47fa0c02
RB
820#define SITOHREG(si, x) \
821do { \
a58f85b5 822 unsigned int i; \
ef1c47af
PB
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)
1ac94400 827
47fa0c02 828#define DIFROMREG(di, x) \
8535f2ba 829 ((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) ^ 1)], 0))
bbd426f5 830
47fa0c02
RB
831#define DITOREG(di, x) \
832do { \
a58f85b5 833 unsigned int fpr, i; \
8535f2ba 834 fpr = (x) & ~(cop1_64bit(xcp) ^ 1); \
ef1c47af
PB
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)
1da177e4 839
21a151d8
RB
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)
1da177e4 844
d4f5b088
MR
845/*
846 * Emulate a CFC1 instruction.
847 */
848static inline void cop1_cfc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
849 mips_instruction ir)
850{
c491cfa2
MR
851 u32 fcr31 = ctx->fcr31;
852 u32 value = 0;
d4f5b088 853
c491cfa2
MR
854 switch (MIPSInst_RD(ir)) {
855 case FPCREG_CSR:
856 value = fcr31;
d4f5b088 857 pr_debug("%p gpr[%d]<-csr=%08x\n",
c491cfa2
MR
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:
03dce595 891 value = boot_cpu_data.fpu_id;
c491cfa2
MR
892 break;
893
894 default:
895 break;
896 }
897
d4f5b088
MR
898 if (MIPSInst_RT(ir))
899 xcp->regs[MIPSInst_RT(ir)] = value;
900}
901
902/*
903 * Emulate a CTC1 instruction.
904 */
905static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
906 mips_instruction ir)
907{
c491cfa2 908 u32 fcr31 = ctx->fcr31;
d4f5b088 909 u32 value;
9b26616c 910 u32 mask;
d4f5b088
MR
911
912 if (MIPSInst_RT(ir) == 0)
913 value = 0;
914 else
915 value = xcp->regs[MIPSInst_RT(ir)];
916
c491cfa2
MR
917 switch (MIPSInst_RD(ir)) {
918 case FPCREG_CSR:
d4f5b088 919 pr_debug("%p gpr[%d]->csr=%08x\n",
c491cfa2 920 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
d4f5b088 921
9b26616c 922 /* Preserve read-only bits. */
03dce595 923 mask = boot_cpu_data.fpu_msk31;
9b26616c 924 fcr31 = (value & ~mask) | (fcr31 & mask);
c491cfa2
MR
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;
d4f5b088 961 }
c491cfa2
MR
962
963 ctx->fcr31 = fcr31;
d4f5b088
MR
964}
965
1da177e4
LT
966/*
967 * Emulate the single floating point instruction pointed at by EPC.
968 * Two instructions if the instruction is in a branch delay slot.
969 */
970
515b029d 971static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
445a58ce 972 struct mm_decoded_insn dec_insn, void __user **fault_addr)
1da177e4 973{
102cedc3 974 unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc;
93583e17 975 unsigned int cond, cbit, bit0;
3f7cac41
RB
976 mips_instruction ir;
977 int likely, pc_inc;
93583e17 978 union fpureg *fpr;
3f7cac41
RB
979 u32 __user *wva;
980 u64 __user *dva;
3f7cac41
RB
981 u32 wval;
982 u64 dval;
983 int sig;
1da177e4 984
70e4c234
RB
985 /*
986 * These are giving gcc a gentle hint about what to expect in
987 * dec_inst in order to do better optimization.
988 */
989 if (!cpu_has_mmips && dec_insn.micro_mips_mode)
990 unreachable();
991
1da177e4 992 /* XXX NEC Vr54xx bug workaround */
e7e9cae5 993 if (delay_slot(xcp)) {
102cedc3
LY
994 if (dec_insn.micro_mips_mode) {
995 if (!mm_isBranchInstr(xcp, dec_insn, &contpc))
e7e9cae5 996 clear_delay_slot(xcp);
102cedc3
LY
997 } else {
998 if (!isBranchInstr(xcp, dec_insn, &contpc))
e7e9cae5 999 clear_delay_slot(xcp);
102cedc3
LY
1000 }
1001 }
1da177e4 1002
e7e9cae5 1003 if (delay_slot(xcp)) {
1da177e4
LT
1004 /*
1005 * The instruction to be emulated is in a branch delay slot
70342287 1006 * which means that we have to emulate the branch instruction
1da177e4
LT
1007 * BEFORE we do the cop1 instruction.
1008 *
1009 * This branch could be a COP1 branch, but in that case we
1010 * would have had a trap for that instruction, and would not
1011 * come through this route.
1012 *
1013 * Linux MIPS branch emulator operates on context, updating the
1014 * cp0_epc.
1015 */
102cedc3
LY
1016 ir = dec_insn.next_insn; /* process delay slot instr */
1017 pc_inc = dec_insn.next_pc_inc;
1018 } else {
1019 ir = dec_insn.insn; /* process current instr */
1020 pc_inc = dec_insn.pc_inc;
1021 }
1da177e4 1022
102cedc3
LY
1023 /*
1024 * Since microMIPS FPU instructios are a subset of MIPS32 FPU
1025 * instructions, we want to convert microMIPS FPU instructions
1026 * into MIPS32 instructions so that we could reuse all of the
1027 * FPU emulation code.
1028 *
1029 * NOTE: We cannot do this for branch instructions since they
1030 * are not a subset. Example: Cannot emulate a 16-bit
1031 * aligned target address with a MIPS32 instruction.
1032 */
1033 if (dec_insn.micro_mips_mode) {
1034 /*
1035 * If next instruction is a 16-bit instruction, then it
1036 * it cannot be a FPU instruction. This could happen
1037 * since we can be called for non-FPU instructions.
1038 */
1039 if ((pc_inc == 2) ||
1040 (microMIPS32_to_MIPS32((union mips_instruction *)&ir)
1041 == SIGILL))
1da177e4 1042 return SIGILL;
1da177e4
LT
1043 }
1044
3f7cac41 1045emul:
a8b0ca17 1046 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, xcp, 0);
b6ee75ed 1047 MIPS_FPU_EMU_INC_STATS(emulated);
1da177e4 1048 switch (MIPSInst_OPCODE(ir)) {
3f7cac41
RB
1049 case ldc1_op:
1050 dva = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1051 MIPSInst_SIMM(ir));
b6ee75ed 1052 MIPS_FPU_EMU_INC_STATS(loads);
515b029d 1053
96d4f267 1054 if (!access_ok(dva, sizeof(u64))) {
b6ee75ed 1055 MIPS_FPU_EMU_INC_STATS(errors);
3f7cac41 1056 *fault_addr = dva;
1da177e4
LT
1057 return SIGBUS;
1058 }
3f7cac41 1059 if (__get_user(dval, dva)) {
515b029d 1060 MIPS_FPU_EMU_INC_STATS(errors);
3f7cac41 1061 *fault_addr = dva;
515b029d
DD
1062 return SIGSEGV;
1063 }
3f7cac41 1064 DITOREG(dval, MIPSInst_RT(ir));
1da177e4 1065 break;
1da177e4 1066
3f7cac41
RB
1067 case sdc1_op:
1068 dva = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1069 MIPSInst_SIMM(ir));
b6ee75ed 1070 MIPS_FPU_EMU_INC_STATS(stores);
3f7cac41 1071 DIFROMREG(dval, MIPSInst_RT(ir));
96d4f267 1072 if (!access_ok(dva, sizeof(u64))) {
b6ee75ed 1073 MIPS_FPU_EMU_INC_STATS(errors);
3f7cac41 1074 *fault_addr = dva;
1da177e4
LT
1075 return SIGBUS;
1076 }
3f7cac41 1077 if (__put_user(dval, dva)) {
515b029d 1078 MIPS_FPU_EMU_INC_STATS(errors);
3f7cac41 1079 *fault_addr = dva;
515b029d
DD
1080 return SIGSEGV;
1081 }
1da177e4 1082 break;
1da177e4 1083
3f7cac41
RB
1084 case lwc1_op:
1085 wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1086 MIPSInst_SIMM(ir));
b6ee75ed 1087 MIPS_FPU_EMU_INC_STATS(loads);
96d4f267 1088 if (!access_ok(wva, sizeof(u32))) {
b6ee75ed 1089 MIPS_FPU_EMU_INC_STATS(errors);
3f7cac41 1090 *fault_addr = wva;
1da177e4
LT
1091 return SIGBUS;
1092 }
3f7cac41 1093 if (__get_user(wval, wva)) {
515b029d 1094 MIPS_FPU_EMU_INC_STATS(errors);
3f7cac41 1095 *fault_addr = wva;
515b029d
DD
1096 return SIGSEGV;
1097 }
3f7cac41 1098 SITOREG(wval, MIPSInst_RT(ir));
1da177e4 1099 break;
1da177e4 1100
3f7cac41
RB
1101 case swc1_op:
1102 wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1103 MIPSInst_SIMM(ir));
b6ee75ed 1104 MIPS_FPU_EMU_INC_STATS(stores);
3f7cac41 1105 SIFROMREG(wval, MIPSInst_RT(ir));
96d4f267 1106 if (!access_ok(wva, sizeof(u32))) {
b6ee75ed 1107 MIPS_FPU_EMU_INC_STATS(errors);
3f7cac41 1108 *fault_addr = wva;
1da177e4
LT
1109 return SIGBUS;
1110 }
3f7cac41 1111 if (__put_user(wval, wva)) {
515b029d 1112 MIPS_FPU_EMU_INC_STATS(errors);
3f7cac41 1113 *fault_addr = wva;
515b029d
DD
1114 return SIGSEGV;
1115 }
1da177e4 1116 break;
1da177e4
LT
1117
1118 case cop1_op:
1119 switch (MIPSInst_RS(ir)) {
1da177e4 1120 case dmfc_op:
08a07904
RB
1121 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1122 return SIGILL;
1123
1da177e4
LT
1124 /* copregister fs -> gpr[rt] */
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:
08a07904
RB
1132 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1133 return SIGILL;
1134
1da177e4
LT
1135 /* copregister fs <- rt */
1136 DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1137 break;
1da177e4 1138
1ac94400 1139 case mfhc_op:
e8f80cc1 1140 if (!cpu_has_mips_r2_r6)
70f743d1 1141 return SIGILL;
1ac94400
LY
1142
1143 /* copregister rd -> gpr[rt] */
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:
e8f80cc1 1151 if (!cpu_has_mips_r2_r6)
70f743d1 1152 return SIGILL;
1ac94400
LY
1153
1154 /* copregister rd <- gpr[rt] */
1155 SITOHREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1156 break;
1157
1da177e4
LT
1158 case mfc_op:
1159 /* copregister rd -> gpr[rt] */
1da177e4
LT
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 /* copregister rd <- rt */
1da177e4
LT
1168 SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1169 break;
1170
3f7cac41 1171 case cfc_op:
1da177e4 1172 /* cop control register rd -> gpr[rt] */
d4f5b088 1173 cop1_cfc(xcp, ctx, ir);
1da177e4 1174 break;
1da177e4 1175
3f7cac41 1176 case ctc_op:
1da177e4 1177 /* copregister rd <- rt */
d4f5b088 1178 cop1_ctc(xcp, ctx, ir);
1da177e4
LT
1179 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1180 return SIGFPE;
1181 }
1182 break;
1da177e4 1183
c909ca71
MC
1184 case bc1eqz_op:
1185 case bc1nez_op:
1186 if (!cpu_has_mips_r6 || delay_slot(xcp))
1187 return SIGILL;
1188
61100500
AM
1189 likely = 0;
1190 cond = 0;
93583e17
PB
1191 fpr = &current->thread.fpu.fpr[MIPSInst_RT(ir)];
1192 bit0 = get_fpr32(fpr, 0) & 0x1;
c909ca71
MC
1193 switch (MIPSInst_RS(ir)) {
1194 case bc1eqz_op:
454854ac 1195 MIPS_FPU_EMU_INC_STATS(bc1eqz);
93583e17 1196 cond = bit0 == 0;
c909ca71
MC
1197 break;
1198 case bc1nez_op:
454854ac 1199 MIPS_FPU_EMU_INC_STATS(bc1nez);
93583e17 1200 cond = bit0 != 0;
c909ca71
MC
1201 break;
1202 }
1203 goto branch_common;
1204
3f7cac41 1205 case bc_op:
e7e9cae5 1206 if (delay_slot(xcp))
1da177e4
LT
1207 return SIGILL;
1208
08a07904
RB
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
3f7cac41 1215 likely = 0;
1da177e4
LT
1216 switch (MIPSInst_RT(ir) & 3) {
1217 case bcfl_op:
2d83fea7
MR
1218 if (cpu_has_mips_2_3_4_5_r)
1219 likely = 1;
2a14b21a 1220 /* fall through */
1da177e4
LT
1221 case bcf_op:
1222 cond = !cond;
1223 break;
1224 case bctl_op:
2d83fea7
MR
1225 if (cpu_has_mips_2_3_4_5_r)
1226 likely = 1;
2a14b21a 1227 /* fall through */
1da177e4
LT
1228 case bct_op:
1229 break;
1da177e4 1230 }
c909ca71 1231branch_common:
ae5f3f5b 1232 MIPS_FPU_EMU_INC_STATS(branches);
e7e9cae5 1233 set_delay_slot(xcp);
1da177e4 1234 if (cond) {
3f7cac41
RB
1235 /*
1236 * Branch taken: emulate dslot instruction
1da177e4 1237 */
9ab4471c
MR
1238 unsigned long bcpc;
1239
1240 /*
1241 * Remember EPC at the branch to point back
1242 * at so that any delay-slot instruction
1243 * signal is not silently ignored.
1244 */
1245 bcpc = xcp->cp0_epc;
102cedc3
LY
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 /* If 16-bit instruction, not FPU. */
1254 if ((dec_insn.next_pc_inc == 2) ||
1255 (microMIPS32_to_MIPS32((union mips_instruction *)&ir) == SIGILL)) {
1256
1257 /*
1258 * Since this instruction will
1259 * be put on the stack with
1260 * 32-bit words, get around
1261 * this problem by putting a
1262 * NOP16 as the second one.
1263 */
1264 if (dec_insn.next_pc_inc == 2)
1265 ir = (ir & (~0xffff)) | MM_NOP16;
1266
1267 /*
1268 * Single step the non-CP1
1269 * instruction in the dslot.
1270 */
9ab4471c 1271 sig = mips_dsemul(xcp, ir,
432c6bac 1272 bcpc, contpc);
e4553573
MR
1273 if (sig < 0)
1274 break;
9ab4471c
MR
1275 if (sig)
1276 xcp->cp0_epc = bcpc;
1277 /*
1278 * SIGILL forces out of
1279 * the emulation loop.
1280 */
1281 return sig ? sig : SIGILL;
102cedc3
LY
1282 }
1283 } else
1284 contpc = (xcp->cp0_epc + (contpc << 2));
1da177e4
LT
1285
1286 switch (MIPSInst_OPCODE(ir)) {
1287 case lwc1_op:
1288 case swc1_op:
08a07904 1289 goto emul;
3f7cac41 1290
1da177e4
LT
1291 case ldc1_op:
1292 case sdc1_op:
2d83fea7 1293 if (cpu_has_mips_2_3_4_5_r)
08a07904
RB
1294 goto emul;
1295
9ab4471c 1296 goto bc_sigill;
3f7cac41 1297
1da177e4 1298 case cop1_op:
1da177e4 1299 goto emul;
3f7cac41 1300
08a07904 1301 case cop1x_op:
2d83fea7 1302 if (cpu_has_mips_4_5_64_r2_r6)
08a07904
RB
1303 /* its one of ours */
1304 goto emul;
1305
9ab4471c 1306 goto bc_sigill;
3f7cac41 1307
1da177e4 1308 case spec_op:
2d83fea7
MR
1309 switch (MIPSInst_FUNC(ir)) {
1310 case movc_op:
1311 if (cpu_has_mips_4_5_r)
1312 goto emul;
08a07904 1313
9ab4471c 1314 goto bc_sigill;
2d83fea7 1315 }
1da177e4 1316 break;
9ab4471c
MR
1317
1318 bc_sigill:
1319 xcp->cp0_epc = bcpc;
1320 return SIGILL;
1da177e4
LT
1321 }
1322
1323 /*
1324 * Single step the non-cp1
1325 * instruction in the dslot
1326 */
432c6bac 1327 sig = mips_dsemul(xcp, ir, bcpc, contpc);
e4553573
MR
1328 if (sig < 0)
1329 break;
9ab4471c
MR
1330 if (sig)
1331 xcp->cp0_epc = bcpc;
1332 /* SIGILL forces out of the emulation loop. */
1333 return sig ? sig : SIGILL;
3f7cac41 1334 } else if (likely) { /* branch not taken */
5d77cf28
MR
1335 /*
1336 * branch likely nullifies
1337 * dslot if not taken
1338 */
1339 xcp->cp0_epc += dec_insn.pc_inc;
1340 contpc += dec_insn.pc_inc;
1341 /*
1342 * else continue & execute
1343 * dslot as normal insn
1344 */
1345 }
1da177e4 1346 break;
1da177e4
LT
1347
1348 default:
1349 if (!(MIPSInst_RS(ir) & 0x10))
1350 return SIGILL;
1da177e4 1351
3f7cac41 1352 /* a real fpu computation instruction */
8904d5b1
AM
1353 sig = fpu_emu(xcp, ctx, ir);
1354 if (sig)
3f7cac41 1355 return sig;
1da177e4
LT
1356 }
1357 break;
1358
3f7cac41 1359 case cop1x_op:
2d83fea7 1360 if (!cpu_has_mips_4_5_64_r2_r6)
08a07904
RB
1361 return SIGILL;
1362
1363 sig = fpux_emu(xcp, ctx, ir, fault_addr);
515b029d 1364 if (sig)
1da177e4
LT
1365 return sig;
1366 break;
1da177e4 1367
1da177e4 1368 case spec_op:
08a07904
RB
1369 if (!cpu_has_mips_4_5_r)
1370 return SIGILL;
1371
1da177e4
LT
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;
1da177e4
LT
1379 default:
1380 return SIGILL;
1381 }
1382
1383 /* we did it !! */
e70dfc10 1384 xcp->cp0_epc = contpc;
e7e9cae5 1385 clear_delay_slot(xcp);
333d1f67 1386
1da177e4
LT
1387 return 0;
1388}
1389
1390/*
1391 * Conversion table from MIPS compare ops 48-63
1392 * cond = ieee754dp_cmp(x,y,IEEE754_UN,sig);
1393 */
1394static const unsigned char cmptab[8] = {
1395 0, /* cmp_0 (sig) cmp_sf */
1396 IEEE754_CUN, /* cmp_un (sig) cmp_ngle */
1397 IEEE754_CEQ, /* cmp_eq (sig) cmp_seq */
1398 IEEE754_CEQ | IEEE754_CUN, /* cmp_ueq (sig) cmp_ngl */
1399 IEEE754_CLT, /* cmp_olt (sig) cmp_lt */
1400 IEEE754_CLT | IEEE754_CUN, /* cmp_ult (sig) cmp_nge */
1401 IEEE754_CLT | IEEE754_CEQ, /* cmp_ole (sig) cmp_le */
1402 IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */
1403};
1404
f8c3c671
MC
1405static const unsigned char negative_cmptab[8] = {
1406 0, /* Reserved */
1407 IEEE754_CLT | IEEE754_CGT | IEEE754_CEQ,
1408 IEEE754_CLT | IEEE754_CGT | IEEE754_CUN,
1409 IEEE754_CLT | IEEE754_CGT,
1410 /* Reserved */
1411};
1412
1da177e4 1413
1da177e4
LT
1414/*
1415 * Additional MIPS4 instructions
1416 */
1417
47fa0c02
RB
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; \
1da177e4
LT
1432}
1433
2209bcb1 1434static union ieee754dp fpemu_dp_recip(union ieee754dp d)
1da177e4
LT
1435{
1436 return ieee754dp_div(ieee754dp_one(0), d);
1437}
1438
2209bcb1 1439static union ieee754dp fpemu_dp_rsqrt(union ieee754dp d)
1da177e4
LT
1440{
1441 return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d));
1442}
1443
2209bcb1 1444static union ieee754sp fpemu_sp_recip(union ieee754sp s)
1da177e4
LT
1445{
1446 return ieee754sp_div(ieee754sp_one(0), s);
1447}
1448
2209bcb1 1449static union ieee754sp fpemu_sp_rsqrt(union ieee754sp s)
1da177e4
LT
1450{
1451 return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
1452}
1453
21a151d8
RB
1454DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add, );
1455DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub, );
1da177e4
LT
1456DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg);
1457DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg);
21a151d8
RB
1458DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add, );
1459DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub, );
1da177e4
LT
1460DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
1461DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
1462
eae89076 1463static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
445a58ce 1464 mips_instruction ir, void __user **fault_addr)
1da177e4 1465{
a58f85b5 1466 unsigned int rcsr = 0; /* resulting csr */
1da177e4 1467
b6ee75ed 1468 MIPS_FPU_EMU_INC_STATS(cp1xops);
1da177e4
LT
1469
1470 switch (MIPSInst_FMA_FFMT(ir)) {
1471 case s_fmt:{ /* 0 */
1472
2209bcb1
RB
1473 union ieee754sp(*handler) (union ieee754sp, union ieee754sp, union ieee754sp);
1474 union ieee754sp fd, fr, fs, ft;
3fccc015 1475 u32 __user *va;
1da177e4
LT
1476 u32 val;
1477
1478 switch (MIPSInst_FUNC(ir)) {
1479 case lwxc1_op:
3fccc015 1480 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1da177e4
LT
1481 xcp->regs[MIPSInst_FT(ir)]);
1482
b6ee75ed 1483 MIPS_FPU_EMU_INC_STATS(loads);
96d4f267 1484 if (!access_ok(va, sizeof(u32))) {
b6ee75ed 1485 MIPS_FPU_EMU_INC_STATS(errors);
515b029d 1486 *fault_addr = va;
1da177e4
LT
1487 return SIGBUS;
1488 }
515b029d
DD
1489 if (__get_user(val, va)) {
1490 MIPS_FPU_EMU_INC_STATS(errors);
1491 *fault_addr = va;
1492 return SIGSEGV;
1493 }
1da177e4
LT
1494 SITOREG(val, MIPSInst_FD(ir));
1495 break;
1496
1497 case swxc1_op:
3fccc015 1498 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1da177e4
LT
1499 xcp->regs[MIPSInst_FT(ir)]);
1500
b6ee75ed 1501 MIPS_FPU_EMU_INC_STATS(stores);
1da177e4
LT
1502
1503 SIFROMREG(val, MIPSInst_FS(ir));
96d4f267 1504 if (!access_ok(va, sizeof(u32))) {
b6ee75ed 1505 MIPS_FPU_EMU_INC_STATS(errors);
515b029d 1506 *fault_addr = va;
1da177e4
LT
1507 return SIGBUS;
1508 }
515b029d
DD
1509 if (put_user(val, va)) {
1510 MIPS_FPU_EMU_INC_STATS(errors);
1511 *fault_addr = va;
1512 return SIGSEGV;
1513 }
1da177e4
LT
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:
c4103526
DCZ
1537 if (ieee754_cxtest(IEEE754_INEXACT)) {
1538 MIPS_FPU_EMU_INC_STATS(ieee754_inexact);
1da177e4 1539 rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
c4103526
DCZ
1540 }
1541 if (ieee754_cxtest(IEEE754_UNDERFLOW)) {
1542 MIPS_FPU_EMU_INC_STATS(ieee754_underflow);
1da177e4 1543 rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
c4103526
DCZ
1544 }
1545 if (ieee754_cxtest(IEEE754_OVERFLOW)) {
1546 MIPS_FPU_EMU_INC_STATS(ieee754_overflow);
1da177e4 1547 rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
c4103526
DCZ
1548 }
1549 if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) {
1550 MIPS_FPU_EMU_INC_STATS(ieee754_invalidop);
1da177e4 1551 rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
c4103526 1552 }
1da177e4
LT
1553
1554 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
1da177e4 1555 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
3f7cac41 1556 /*printk ("SIGFPE: FPU csr = %08x\n",
1da177e4
LT
1557 ctx->fcr31); */
1558 return SIGFPE;
1559 }
1560
1561 break;
1562
1563 default:
1564 return SIGILL;
1565 }
1566 break;
1567 }
1568
1da177e4 1569 case d_fmt:{ /* 1 */
2209bcb1
RB
1570 union ieee754dp(*handler) (union ieee754dp, union ieee754dp, union ieee754dp);
1571 union ieee754dp fd, fr, fs, ft;
3fccc015 1572 u64 __user *va;
1da177e4
LT
1573 u64 val;
1574
1575 switch (MIPSInst_FUNC(ir)) {
1576 case ldxc1_op:
3fccc015 1577 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1da177e4
LT
1578 xcp->regs[MIPSInst_FT(ir)]);
1579
b6ee75ed 1580 MIPS_FPU_EMU_INC_STATS(loads);
96d4f267 1581 if (!access_ok(va, sizeof(u64))) {
b6ee75ed 1582 MIPS_FPU_EMU_INC_STATS(errors);
515b029d 1583 *fault_addr = va;
1da177e4
LT
1584 return SIGBUS;
1585 }
515b029d
DD
1586 if (__get_user(val, va)) {
1587 MIPS_FPU_EMU_INC_STATS(errors);
1588 *fault_addr = va;
1589 return SIGSEGV;
1590 }
1da177e4
LT
1591 DITOREG(val, MIPSInst_FD(ir));
1592 break;
1593
1594 case sdxc1_op:
3fccc015 1595 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1da177e4
LT
1596 xcp->regs[MIPSInst_FT(ir)]);
1597
b6ee75ed 1598 MIPS_FPU_EMU_INC_STATS(stores);
1da177e4 1599 DIFROMREG(val, MIPSInst_FS(ir));
96d4f267 1600 if (!access_ok(va, sizeof(u64))) {
b6ee75ed 1601 MIPS_FPU_EMU_INC_STATS(errors);
515b029d 1602 *fault_addr = va;
1da177e4
LT
1603 return SIGBUS;
1604 }
515b029d
DD
1605 if (__put_user(val, va)) {
1606 MIPS_FPU_EMU_INC_STATS(errors);
1607 *fault_addr = va;
1608 return SIGSEGV;
1609 }
1da177e4
LT
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 }
1da177e4 1638
51061b88
DCZ
1639 case 0x3:
1640 if (MIPSInst_FUNC(ir) != pfetch_op)
1da177e4 1641 return SIGILL;
51061b88 1642
1da177e4
LT
1643 /* ignore prefx operation */
1644 break;
1645
1646 default:
1647 return SIGILL;
1648 }
1649
1650 return 0;
1651}
1da177e4
LT
1652
1653
1654
1655/*
1656 * Emulate a single COP1 arithmetic instruction.
1657 */
eae89076 1658static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1da177e4
LT
1659 mips_instruction ir)
1660{
1661 int rfmt; /* resulting format */
a58f85b5 1662 unsigned int rcsr = 0; /* resulting csr */
3f7cac41
RB
1663 unsigned int oldrm;
1664 unsigned int cbit;
a58f85b5 1665 unsigned int cond;
1da177e4 1666 union {
2209bcb1
RB
1667 union ieee754dp d;
1668 union ieee754sp s;
1da177e4 1669 int w;
1da177e4 1670 s64 l;
1da177e4 1671 } rv; /* resulting value */
3f7cac41 1672 u64 bits;
1da177e4 1673
b6ee75ed 1674 MIPS_FPU_EMU_INC_STATS(cp1ops);
1da177e4 1675 switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
3f7cac41 1676 case s_fmt: { /* 0 */
1da177e4 1677 union {
2209bcb1
RB
1678 union ieee754sp(*b) (union ieee754sp, union ieee754sp);
1679 union ieee754sp(*u) (union ieee754sp);
1da177e4 1680 } handler;
4b820d95 1681 union ieee754sp fd, fs, ft;
1da177e4
LT
1682
1683 switch (MIPSInst_FUNC(ir)) {
1684 /* binary ops */
1685 case fadd_op:
454854ac 1686 MIPS_FPU_EMU_INC_STATS(add_s);
1da177e4
LT
1687 handler.b = ieee754sp_add;
1688 goto scopbop;
1689 case fsub_op:
454854ac 1690 MIPS_FPU_EMU_INC_STATS(sub_s);
1da177e4
LT
1691 handler.b = ieee754sp_sub;
1692 goto scopbop;
1693 case fmul_op:
454854ac 1694 MIPS_FPU_EMU_INC_STATS(mul_s);
1da177e4
LT
1695 handler.b = ieee754sp_mul;
1696 goto scopbop;
1697 case fdiv_op:
454854ac 1698 MIPS_FPU_EMU_INC_STATS(div_s);
1da177e4
LT
1699 handler.b = ieee754sp_div;
1700 goto scopbop;
1701
1702 /* unary ops */
1da177e4 1703 case fsqrt_op:
2d83fea7 1704 if (!cpu_has_mips_2_3_4_5_r)
08a07904
RB
1705 return SIGILL;
1706
454854ac 1707 MIPS_FPU_EMU_INC_STATS(sqrt_s);
1da177e4
LT
1708 handler.u = ieee754sp_sqrt;
1709 goto scopuop;
3f7cac41 1710
08a07904
RB
1711 /*
1712 * Note that on some MIPS IV implementations such as the
1713 * R5000 and R8000 the FSQRT and FRECIP instructions do not
1714 * achieve full IEEE-754 accuracy - however this emulator does.
1715 */
1da177e4 1716 case frsqrt_op:
2d83fea7 1717 if (!cpu_has_mips_4_5_64_r2_r6)
08a07904
RB
1718 return SIGILL;
1719
454854ac 1720 MIPS_FPU_EMU_INC_STATS(rsqrt_s);
1da177e4
LT
1721 handler.u = fpemu_sp_rsqrt;
1722 goto scopuop;
3f7cac41 1723
1da177e4 1724 case frecip_op:
2d83fea7 1725 if (!cpu_has_mips_4_5_64_r2_r6)
08a07904
RB
1726 return SIGILL;
1727
454854ac 1728 MIPS_FPU_EMU_INC_STATS(recip_s);
1da177e4
LT
1729 handler.u = fpemu_sp_recip;
1730 goto scopuop;
08a07904 1731
1da177e4 1732 case fmovc_op:
08a07904
RB
1733 if (!cpu_has_mips_4_5_r)
1734 return SIGILL;
1735
1da177e4
LT
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;
3f7cac41 1742
1da177e4 1743 case fmovz_op:
08a07904
RB
1744 if (!cpu_has_mips_4_5_r)
1745 return SIGILL;
1746
1da177e4
LT
1747 if (xcp->regs[MIPSInst_FT(ir)] != 0)
1748 return 0;
1749 SPFROMREG(rv.s, MIPSInst_FS(ir));
1750 break;
3f7cac41 1751
1da177e4 1752 case fmovn_op:
08a07904
RB
1753 if (!cpu_has_mips_4_5_r)
1754 return SIGILL;
1755
1da177e4
LT
1756 if (xcp->regs[MIPSInst_FT(ir)] == 0)
1757 return 0;
1758 SPFROMREG(rv.s, MIPSInst_FS(ir));
1759 break;
3f7cac41 1760
67613f02
MC
1761 case fseleqz_op:
1762 if (!cpu_has_mips_r6)
1763 return SIGILL;
1764
454854ac 1765 MIPS_FPU_EMU_INC_STATS(seleqz_s);
67613f02
MC
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
130fe357
MC
1773 case fselnez_op:
1774 if (!cpu_has_mips_r6)
1775 return SIGILL;
1776
454854ac 1777 MIPS_FPU_EMU_INC_STATS(selnez_s);
130fe357
MC
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
e24c3bec
MC
1785 case fmaddf_op: {
1786 union ieee754sp ft, fs, fd;
1787
1788 if (!cpu_has_mips_r6)
1789 return SIGILL;
1790
454854ac 1791 MIPS_FPU_EMU_INC_STATS(maddf_s);
e24c3bec
MC
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);
409fcace 1796 goto copcsr;
e24c3bec
MC
1797 }
1798
83d43305
MC
1799 case fmsubf_op: {
1800 union ieee754sp ft, fs, fd;
1801
1802 if (!cpu_has_mips_r6)
1803 return SIGILL;
1804
454854ac 1805 MIPS_FPU_EMU_INC_STATS(msubf_s);
83d43305
MC
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);
409fcace 1810 goto copcsr;
83d43305
MC
1811 }
1812
400bd2e4
MC
1813 case frint_op: {
1814 union ieee754sp fs;
1815
1816 if (!cpu_has_mips_r6)
1817 return SIGILL;
1818
454854ac 1819 MIPS_FPU_EMU_INC_STATS(rint_s);
400bd2e4 1820 SPFROMREG(fs, MIPSInst_FS(ir));
3ec404d8 1821 rv.s = ieee754sp_rint(fs);
400bd2e4
MC
1822 goto copcsr;
1823 }
1824
38db37ba
MC
1825 case fclass_op: {
1826 union ieee754sp fs;
1827
1828 if (!cpu_has_mips_r6)
1829 return SIGILL;
1830
454854ac 1831 MIPS_FPU_EMU_INC_STATS(class_s);
38db37ba
MC
1832 SPFROMREG(fs, MIPSInst_FS(ir));
1833 rv.w = ieee754sp_2008class(fs);
1834 rfmt = w_fmt;
409fcace 1835 goto copcsr;
38db37ba
MC
1836 }
1837
4e9561b2
MC
1838 case fmin_op: {
1839 union ieee754sp fs, ft;
1840
1841 if (!cpu_has_mips_r6)
1842 return SIGILL;
1843
454854ac 1844 MIPS_FPU_EMU_INC_STATS(min_s);
4e9561b2
MC
1845 SPFROMREG(ft, MIPSInst_FT(ir));
1846 SPFROMREG(fs, MIPSInst_FS(ir));
1847 rv.s = ieee754sp_fmin(fs, ft);
409fcace 1848 goto copcsr;
4e9561b2
MC
1849 }
1850
1851 case fmina_op: {
1852 union ieee754sp fs, ft;
1853
1854 if (!cpu_has_mips_r6)
1855 return SIGILL;
1856
454854ac 1857 MIPS_FPU_EMU_INC_STATS(mina_s);
4e9561b2
MC
1858 SPFROMREG(ft, MIPSInst_FT(ir));
1859 SPFROMREG(fs, MIPSInst_FS(ir));
1860 rv.s = ieee754sp_fmina(fs, ft);
409fcace 1861 goto copcsr;
4e9561b2
MC
1862 }
1863
a79f5f9b
MC
1864 case fmax_op: {
1865 union ieee754sp fs, ft;
1866
1867 if (!cpu_has_mips_r6)
1868 return SIGILL;
1869
454854ac 1870 MIPS_FPU_EMU_INC_STATS(max_s);
a79f5f9b
MC
1871 SPFROMREG(ft, MIPSInst_FT(ir));
1872 SPFROMREG(fs, MIPSInst_FS(ir));
1873 rv.s = ieee754sp_fmax(fs, ft);
409fcace 1874 goto copcsr;
a79f5f9b
MC
1875 }
1876
1877 case fmaxa_op: {
1878 union ieee754sp fs, ft;
1879
1880 if (!cpu_has_mips_r6)
1881 return SIGILL;
1882
454854ac 1883 MIPS_FPU_EMU_INC_STATS(maxa_s);
a79f5f9b
MC
1884 SPFROMREG(ft, MIPSInst_FT(ir));
1885 SPFROMREG(fs, MIPSInst_FS(ir));
1886 rv.s = ieee754sp_fmaxa(fs, ft);
409fcace 1887 goto copcsr;
a79f5f9b
MC
1888 }
1889
1da177e4 1890 case fabs_op:
454854ac 1891 MIPS_FPU_EMU_INC_STATS(abs_s);
1da177e4
LT
1892 handler.u = ieee754sp_abs;
1893 goto scopuop;
3f7cac41 1894
1da177e4 1895 case fneg_op:
454854ac 1896 MIPS_FPU_EMU_INC_STATS(neg_s);
1da177e4
LT
1897 handler.u = ieee754sp_neg;
1898 goto scopuop;
3f7cac41 1899
1da177e4
LT
1900 case fmov_op:
1901 /* an easy one */
454854ac 1902 MIPS_FPU_EMU_INC_STATS(mov_s);
1da177e4
LT
1903 SPFROMREG(rv.s, MIPSInst_FS(ir));
1904 goto copcsr;
1905
1906 /* binary op on handler */
3f7cac41
RB
1907scopbop:
1908 SPFROMREG(fs, MIPSInst_FS(ir));
1909 SPFROMREG(ft, MIPSInst_FT(ir));
1da177e4 1910
3f7cac41
RB
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:
c4103526
DCZ
1918 if (ieee754_cxtest(IEEE754_INEXACT)) {
1919 MIPS_FPU_EMU_INC_STATS(ieee754_inexact);
1da177e4 1920 rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
c4103526
DCZ
1921 }
1922 if (ieee754_cxtest(IEEE754_UNDERFLOW)) {
1923 MIPS_FPU_EMU_INC_STATS(ieee754_underflow);
1da177e4 1924 rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
c4103526
DCZ
1925 }
1926 if (ieee754_cxtest(IEEE754_OVERFLOW)) {
1927 MIPS_FPU_EMU_INC_STATS(ieee754_overflow);
1da177e4 1928 rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
c4103526
DCZ
1929 }
1930 if (ieee754_cxtest(IEEE754_ZERO_DIVIDE)) {
1931 MIPS_FPU_EMU_INC_STATS(ieee754_zerodiv);
1da177e4 1932 rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
c4103526
DCZ
1933 }
1934 if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) {
1935 MIPS_FPU_EMU_INC_STATS(ieee754_invalidop);
1da177e4 1936 rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
c4103526 1937 }
1da177e4
LT
1938 break;
1939
1940 /* unary conv ops */
1941 case fcvts_op:
1942 return SIGILL; /* not defined */
1da177e4 1943
3f7cac41 1944 case fcvtd_op:
454854ac 1945 MIPS_FPU_EMU_INC_STATS(cvt_d_s);
1da177e4
LT
1946 SPFROMREG(fs, MIPSInst_FS(ir));
1947 rv.d = ieee754dp_fsp(fs);
1948 rfmt = d_fmt;
1949 goto copcsr;
1da177e4 1950
3f7cac41 1951 case fcvtw_op:
454854ac 1952 MIPS_FPU_EMU_INC_STATS(cvt_w_s);
1da177e4
LT
1953 SPFROMREG(fs, MIPSInst_FS(ir));
1954 rv.w = ieee754sp_tint(fs);
1955 rfmt = w_fmt;
1956 goto copcsr;
1da177e4 1957
1da177e4
LT
1958 case fround_op:
1959 case ftrunc_op:
1960 case fceil_op:
3f7cac41 1961 case ffloor_op:
2d83fea7 1962 if (!cpu_has_mips_2_3_4_5_r)
08a07904
RB
1963 return SIGILL;
1964
454854ac
AM
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
3f7cac41 1974 oldrm = ieee754_csr.rm;
1da177e4 1975 SPFROMREG(fs, MIPSInst_FS(ir));
2cfcf8a8 1976 ieee754_csr.rm = MIPSInst_FUNC(ir);
1da177e4
LT
1977 rv.w = ieee754sp_tint(fs);
1978 ieee754_csr.rm = oldrm;
1979 rfmt = w_fmt;
1980 goto copcsr;
1da177e4 1981
4b820d95
PB
1982 case fsel_op:
1983 if (!cpu_has_mips_r6)
1984 return SIGILL;
1985
454854ac 1986 MIPS_FPU_EMU_INC_STATS(sel_s);
4b820d95
PB
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
3f7cac41 1994 case fcvtl_op:
2d83fea7 1995 if (!cpu_has_mips_3_4_5_64_r2_r6)
08a07904
RB
1996 return SIGILL;
1997
454854ac 1998 MIPS_FPU_EMU_INC_STATS(cvt_l_s);
1da177e4
LT
1999 SPFROMREG(fs, MIPSInst_FS(ir));
2000 rv.l = ieee754sp_tlong(fs);
2001 rfmt = l_fmt;
2002 goto copcsr;
1da177e4
LT
2003
2004 case froundl_op:
2005 case ftruncl_op:
2006 case fceill_op:
3f7cac41 2007 case ffloorl_op:
2d83fea7 2008 if (!cpu_has_mips_3_4_5_64_r2_r6)
08a07904
RB
2009 return SIGILL;
2010
454854ac
AM
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
3f7cac41 2020 oldrm = ieee754_csr.rm;
1da177e4 2021 SPFROMREG(fs, MIPSInst_FS(ir));
2cfcf8a8 2022 ieee754_csr.rm = MIPSInst_FUNC(ir);
1da177e4
LT
2023 rv.l = ieee754sp_tlong(fs);
2024 ieee754_csr.rm = oldrm;
2025 rfmt = l_fmt;
2026 goto copcsr;
1da177e4
LT
2027
2028 default:
f8c3c671 2029 if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) {
a58f85b5 2030 unsigned int cmpop;
2209bcb1 2031 union ieee754sp fs, ft;
1da177e4 2032
a58f85b5 2033 cmpop = MIPSInst_FUNC(ir) - fcmp_op;
1da177e4
LT
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
3f7cac41 2045 } else
1da177e4 2046 return SIGILL;
1da177e4
LT
2047 break;
2048 }
2049 break;
2050 }
2051
3f7cac41 2052 case d_fmt: {
4b820d95 2053 union ieee754dp fd, fs, ft;
1da177e4 2054 union {
2209bcb1
RB
2055 union ieee754dp(*b) (union ieee754dp, union ieee754dp);
2056 union ieee754dp(*u) (union ieee754dp);
1da177e4
LT
2057 } handler;
2058
2059 switch (MIPSInst_FUNC(ir)) {
2060 /* binary ops */
2061 case fadd_op:
454854ac 2062 MIPS_FPU_EMU_INC_STATS(add_d);
1da177e4
LT
2063 handler.b = ieee754dp_add;
2064 goto dcopbop;
2065 case fsub_op:
454854ac 2066 MIPS_FPU_EMU_INC_STATS(sub_d);
1da177e4
LT
2067 handler.b = ieee754dp_sub;
2068 goto dcopbop;
2069 case fmul_op:
454854ac 2070 MIPS_FPU_EMU_INC_STATS(mul_d);
1da177e4
LT
2071 handler.b = ieee754dp_mul;
2072 goto dcopbop;
2073 case fdiv_op:
454854ac 2074 MIPS_FPU_EMU_INC_STATS(div_d);
1da177e4
LT
2075 handler.b = ieee754dp_div;
2076 goto dcopbop;
2077
2078 /* unary ops */
1da177e4 2079 case fsqrt_op:
08a07904
RB
2080 if (!cpu_has_mips_2_3_4_5_r)
2081 return SIGILL;
2082
454854ac 2083 MIPS_FPU_EMU_INC_STATS(sqrt_d);
1da177e4
LT
2084 handler.u = ieee754dp_sqrt;
2085 goto dcopuop;
08a07904
RB
2086 /*
2087 * Note that on some MIPS IV implementations such as the
2088 * R5000 and R8000 the FSQRT and FRECIP instructions do not
2089 * achieve full IEEE-754 accuracy - however this emulator does.
2090 */
1da177e4 2091 case frsqrt_op:
2d83fea7 2092 if (!cpu_has_mips_4_5_64_r2_r6)
08a07904
RB
2093 return SIGILL;
2094
454854ac 2095 MIPS_FPU_EMU_INC_STATS(rsqrt_d);
1da177e4
LT
2096 handler.u = fpemu_dp_rsqrt;
2097 goto dcopuop;
2098 case frecip_op:
2d83fea7 2099 if (!cpu_has_mips_4_5_64_r2_r6)
08a07904
RB
2100 return SIGILL;
2101
454854ac 2102 MIPS_FPU_EMU_INC_STATS(recip_d);
1da177e4
LT
2103 handler.u = fpemu_dp_recip;
2104 goto dcopuop;
1da177e4 2105 case fmovc_op:
08a07904
RB
2106 if (!cpu_has_mips_4_5_r)
2107 return SIGILL;
2108
1da177e4
LT
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:
08a07904
RB
2116 if (!cpu_has_mips_4_5_r)
2117 return SIGILL;
2118
1da177e4
LT
2119 if (xcp->regs[MIPSInst_FT(ir)] != 0)
2120 return 0;
2121 DPFROMREG(rv.d, MIPSInst_FS(ir));
2122 break;
2123 case fmovn_op:
08a07904
RB
2124 if (!cpu_has_mips_4_5_r)
2125 return SIGILL;
2126
1da177e4
LT
2127 if (xcp->regs[MIPSInst_FT(ir)] == 0)
2128 return 0;
2129 DPFROMREG(rv.d, MIPSInst_FS(ir));
2130 break;
67613f02
MC
2131
2132 case fseleqz_op:
2133 if (!cpu_has_mips_r6)
2134 return SIGILL;
2135
454854ac 2136 MIPS_FPU_EMU_INC_STATS(seleqz_d);
67613f02
MC
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
130fe357
MC
2144 case fselnez_op:
2145 if (!cpu_has_mips_r6)
2146 return SIGILL;
2147
454854ac 2148 MIPS_FPU_EMU_INC_STATS(selnez_d);
130fe357
MC
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
e24c3bec
MC
2156 case fmaddf_op: {
2157 union ieee754dp ft, fs, fd;
2158
2159 if (!cpu_has_mips_r6)
2160 return SIGILL;
2161
454854ac 2162 MIPS_FPU_EMU_INC_STATS(maddf_d);
e24c3bec
MC
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);
409fcace 2167 goto copcsr;
e24c3bec
MC
2168 }
2169
83d43305
MC
2170 case fmsubf_op: {
2171 union ieee754dp ft, fs, fd;
2172
2173 if (!cpu_has_mips_r6)
2174 return SIGILL;
2175
454854ac 2176 MIPS_FPU_EMU_INC_STATS(msubf_d);
83d43305
MC
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);
409fcace 2181 goto copcsr;
83d43305
MC
2182 }
2183
400bd2e4
MC
2184 case frint_op: {
2185 union ieee754dp fs;
2186
2187 if (!cpu_has_mips_r6)
2188 return SIGILL;
2189
454854ac 2190 MIPS_FPU_EMU_INC_STATS(rint_d);
400bd2e4 2191 DPFROMREG(fs, MIPSInst_FS(ir));
3ec404d8 2192 rv.d = ieee754dp_rint(fs);
400bd2e4
MC
2193 goto copcsr;
2194 }
2195
38db37ba
MC
2196 case fclass_op: {
2197 union ieee754dp fs;
2198
2199 if (!cpu_has_mips_r6)
2200 return SIGILL;
2201
454854ac 2202 MIPS_FPU_EMU_INC_STATS(class_d);
38db37ba 2203 DPFROMREG(fs, MIPSInst_FS(ir));
e1231dd6
AM
2204 rv.l = ieee754dp_2008class(fs);
2205 rfmt = l_fmt;
409fcace 2206 goto copcsr;
38db37ba
MC
2207 }
2208
4e9561b2
MC
2209 case fmin_op: {
2210 union ieee754dp fs, ft;
2211
2212 if (!cpu_has_mips_r6)
2213 return SIGILL;
2214
454854ac 2215 MIPS_FPU_EMU_INC_STATS(min_d);
4e9561b2
MC
2216 DPFROMREG(ft, MIPSInst_FT(ir));
2217 DPFROMREG(fs, MIPSInst_FS(ir));
2218 rv.d = ieee754dp_fmin(fs, ft);
409fcace 2219 goto copcsr;
4e9561b2
MC
2220 }
2221
2222 case fmina_op: {
2223 union ieee754dp fs, ft;
2224
2225 if (!cpu_has_mips_r6)
2226 return SIGILL;
2227
454854ac 2228 MIPS_FPU_EMU_INC_STATS(mina_d);
4e9561b2
MC
2229 DPFROMREG(ft, MIPSInst_FT(ir));
2230 DPFROMREG(fs, MIPSInst_FS(ir));
2231 rv.d = ieee754dp_fmina(fs, ft);
409fcace 2232 goto copcsr;
4e9561b2
MC
2233 }
2234
a79f5f9b
MC
2235 case fmax_op: {
2236 union ieee754dp fs, ft;
2237
2238 if (!cpu_has_mips_r6)
2239 return SIGILL;
2240
454854ac 2241 MIPS_FPU_EMU_INC_STATS(max_d);
a79f5f9b
MC
2242 DPFROMREG(ft, MIPSInst_FT(ir));
2243 DPFROMREG(fs, MIPSInst_FS(ir));
2244 rv.d = ieee754dp_fmax(fs, ft);
409fcace 2245 goto copcsr;
a79f5f9b
MC
2246 }
2247
2248 case fmaxa_op: {
2249 union ieee754dp fs, ft;
2250
2251 if (!cpu_has_mips_r6)
2252 return SIGILL;
2253
454854ac 2254 MIPS_FPU_EMU_INC_STATS(maxa_d);
a79f5f9b
MC
2255 DPFROMREG(ft, MIPSInst_FT(ir));
2256 DPFROMREG(fs, MIPSInst_FS(ir));
2257 rv.d = ieee754dp_fmaxa(fs, ft);
409fcace 2258 goto copcsr;
a79f5f9b
MC
2259 }
2260
1da177e4 2261 case fabs_op:
454854ac 2262 MIPS_FPU_EMU_INC_STATS(abs_d);
1da177e4
LT
2263 handler.u = ieee754dp_abs;
2264 goto dcopuop;
2265
2266 case fneg_op:
454854ac 2267 MIPS_FPU_EMU_INC_STATS(neg_d);
1da177e4
LT
2268 handler.u = ieee754dp_neg;
2269 goto dcopuop;
2270
2271 case fmov_op:
2272 /* an easy one */
454854ac 2273 MIPS_FPU_EMU_INC_STATS(mov_d);
1da177e4
LT
2274 DPFROMREG(rv.d, MIPSInst_FS(ir));
2275 goto copcsr;
2276
2277 /* binary op on handler */
3f7cac41
RB
2278dcopbop:
2279 DPFROMREG(fs, MIPSInst_FS(ir));
2280 DPFROMREG(ft, MIPSInst_FT(ir));
1da177e4 2281
3f7cac41
RB
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;
1da177e4 2288
3f7cac41
RB
2289 /*
2290 * unary conv ops
2291 */
2292 case fcvts_op:
454854ac 2293 MIPS_FPU_EMU_INC_STATS(cvt_s_d);
1da177e4
LT
2294 DPFROMREG(fs, MIPSInst_FS(ir));
2295 rv.s = ieee754sp_fdp(fs);
2296 rfmt = s_fmt;
2297 goto copcsr;
3f7cac41 2298
1da177e4
LT
2299 case fcvtd_op:
2300 return SIGILL; /* not defined */
2301
3f7cac41 2302 case fcvtw_op:
454854ac 2303 MIPS_FPU_EMU_INC_STATS(cvt_w_d);
1da177e4
LT
2304 DPFROMREG(fs, MIPSInst_FS(ir));
2305 rv.w = ieee754dp_tint(fs); /* wrong */
2306 rfmt = w_fmt;
2307 goto copcsr;
1da177e4 2308
1da177e4
LT
2309 case fround_op:
2310 case ftrunc_op:
2311 case fceil_op:
3f7cac41 2312 case ffloor_op:
08a07904
RB
2313 if (!cpu_has_mips_2_3_4_5_r)
2314 return SIGILL;
2315
454854ac
AM
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
3f7cac41 2325 oldrm = ieee754_csr.rm;
1da177e4 2326 DPFROMREG(fs, MIPSInst_FS(ir));
2cfcf8a8 2327 ieee754_csr.rm = MIPSInst_FUNC(ir);
1da177e4
LT
2328 rv.w = ieee754dp_tint(fs);
2329 ieee754_csr.rm = oldrm;
2330 rfmt = w_fmt;
2331 goto copcsr;
1da177e4 2332
4b820d95
PB
2333 case fsel_op:
2334 if (!cpu_has_mips_r6)
2335 return SIGILL;
2336
454854ac 2337 MIPS_FPU_EMU_INC_STATS(sel_d);
4b820d95
PB
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
3f7cac41 2345 case fcvtl_op:
2d83fea7 2346 if (!cpu_has_mips_3_4_5_64_r2_r6)
08a07904
RB
2347 return SIGILL;
2348
454854ac 2349 MIPS_FPU_EMU_INC_STATS(cvt_l_d);
1da177e4
LT
2350 DPFROMREG(fs, MIPSInst_FS(ir));
2351 rv.l = ieee754dp_tlong(fs);
2352 rfmt = l_fmt;
2353 goto copcsr;
1da177e4
LT
2354
2355 case froundl_op:
2356 case ftruncl_op:
2357 case fceill_op:
3f7cac41 2358 case ffloorl_op:
2d83fea7 2359 if (!cpu_has_mips_3_4_5_64_r2_r6)
08a07904
RB
2360 return SIGILL;
2361
454854ac
AM
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
3f7cac41 2371 oldrm = ieee754_csr.rm;
1da177e4 2372 DPFROMREG(fs, MIPSInst_FS(ir));
2cfcf8a8 2373 ieee754_csr.rm = MIPSInst_FUNC(ir);
1da177e4
LT
2374 rv.l = ieee754dp_tlong(fs);
2375 ieee754_csr.rm = oldrm;
2376 rfmt = l_fmt;
2377 goto copcsr;
1da177e4
LT
2378
2379 default:
f8c3c671 2380 if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) {
a58f85b5 2381 unsigned int cmpop;
2209bcb1 2382 union ieee754dp fs, ft;
1da177e4 2383
a58f85b5 2384 cmpop = MIPSInst_FUNC(ir) - fcmp_op;
1da177e4
LT
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;
bbdd8147
MC
2405 }
2406
2407 case w_fmt: {
2408 union ieee754dp fs;
1da177e4
LT
2409
2410 switch (MIPSInst_FUNC(ir)) {
2411 case fcvts_op:
2412 /* convert word to single precision real */
454854ac 2413 MIPS_FPU_EMU_INC_STATS(cvt_s_w);
1da177e4
LT
2414 SPFROMREG(fs, MIPSInst_FS(ir));
2415 rv.s = ieee754sp_fint(fs.bits);
2416 rfmt = s_fmt;
2417 goto copcsr;
1da177e4
LT
2418 case fcvtd_op:
2419 /* convert word to double precision real */
454854ac 2420 MIPS_FPU_EMU_INC_STATS(cvt_d_w);
1da177e4
LT
2421 SPFROMREG(fs, MIPSInst_FS(ir));
2422 rv.d = ieee754dp_fint(fs.bits);
2423 rfmt = d_fmt;
2424 goto copcsr;
f8c3c671
MC
2425 default: {
2426 /* Emulating the new CMP.condn.fmt R6 instruction */
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 /* This is an R6 only instruction */
2436 if (!cpu_has_mips_r6 ||
2437 (MIPSInst_FUNC(ir) & 0x20))
2438 return SIGILL;
2439
454854ac
AM
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
f8c3c671
MC
2524 /* fmt is w_fmt for single precision so fix it */
2525 rfmt = s_fmt;
2526 /* default to false */
2527 rv.w = 0;
2528
2529 /* CMP.condn.S */
2530 SPFROMREG(fs, MIPSInst_FS(ir));
2531 SPFROMREG(ft, MIPSInst_FT(ir));
2532
2533 /* positive predicates */
2534 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2535 if (ieee754sp_cmp(fs, ft, cmptab[cmpop],
2536 sig))
2537 rv.w = -1; /* true, all 1s */
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 /* negative predicates */
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; /* true, all 1s */
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 /* Reserved R6 ops */
f8c3c671
MC
2561 return SIGILL;
2562 }
2563 }
2564 break;
2565 }
1da177e4 2566 }
1ff8560a 2567 break;
1da177e4
LT
2568 }
2569
3f7cac41 2570 case l_fmt:
08a07904 2571
2d83fea7 2572 if (!cpu_has_mips_3_4_5_64_r2_r6)
08a07904
RB
2573 return SIGILL;
2574
bbd426f5
PB
2575 DIFROMREG(bits, MIPSInst_FS(ir));
2576
1da177e4
LT
2577 switch (MIPSInst_FUNC(ir)) {
2578 case fcvts_op:
2579 /* convert long to single precision real */
454854ac 2580 MIPS_FPU_EMU_INC_STATS(cvt_s_l);
bbd426f5 2581 rv.s = ieee754sp_flong(bits);
1da177e4
LT
2582 rfmt = s_fmt;
2583 goto copcsr;
2584 case fcvtd_op:
2585 /* convert long to double precision real */
454854ac 2586 MIPS_FPU_EMU_INC_STATS(cvt_d_l);
bbd426f5 2587 rv.d = ieee754dp_flong(bits);
1da177e4
LT
2588 rfmt = d_fmt;
2589 goto copcsr;
f8c3c671
MC
2590 default: {
2591 /* Emulating the new CMP.condn.fmt R6 instruction */
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
454854ac
AM
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
f8c3c671
MC
2684 /* fmt is l_fmt for double precision so fix it */
2685 rfmt = d_fmt;
2686 /* default to false */
2687 rv.l = 0;
2688
2689 /* CMP.condn.D */
2690 DPFROMREG(fs, MIPSInst_FS(ir));
2691 DPFROMREG(ft, MIPSInst_FT(ir));
1da177e4 2692
f8c3c671
MC
2693 /* positive predicates */
2694 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2695 if (ieee754dp_cmp(fs, ft,
2696 cmptab[cmpop], sig))
2697 rv.l = -1LL; /* true, all 1s */
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 /* negative predicates */
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; /* true, all 1s */
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 /* Reserved R6 ops */
f8c3c671
MC
2721 return SIGILL;
2722 }
2723 }
2724 break;
2725 }
2726 }
1ff8560a
AM
2727 break;
2728
1da177e4
LT
2729 default:
2730 return SIGILL;
2731 }
2732
2733 /*
2734 * Update the fpu CSR register for this operation.
2735 * If an exception is required, generate a tidy SIGFPE exception,
2736 * without updating the result register.
2737 * Note: cause exception bits do not accumulate, they are rewritten
2738 * for each op; only the flag/sticky bits accumulate.
2739 */
2740 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
2741 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
3f7cac41 2742 /*printk ("SIGFPE: FPU csr = %08x\n",ctx->fcr31); */
1da177e4
LT
2743 return SIGFPE;
2744 }
2745
2746 /*
2747 * Now we can safely write the result back to the register file.
2748 */
2749 switch (rfmt) {
08a07904
RB
2750 case -1:
2751
2752 if (cpu_has_mips_4_5_r)
c3b9b945 2753 cbit = fpucondbit[MIPSInst_FD(ir) >> 2];
08a07904
RB
2754 else
2755 cbit = FPU_CSR_COND;
1da177e4 2756 if (rv.w)
08a07904 2757 ctx->fcr31 |= cbit;
1da177e4 2758 else
08a07904 2759 ctx->fcr31 &= ~cbit;
1da177e4 2760 break;
08a07904 2761
1da177e4
LT
2762 case d_fmt:
2763 DPTOREG(rv.d, MIPSInst_FD(ir));
2764 break;
1da177e4
LT
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;
1da177e4 2771 case l_fmt:
2d83fea7 2772 if (!cpu_has_mips_3_4_5_64_r2_r6)
08a07904
RB
2773 return SIGILL;
2774
1da177e4
LT
2775 DITOREG(rv.l, MIPSInst_FD(ir));
2776 break;
1da177e4
LT
2777 default:
2778 return SIGILL;
2779 }
2780
2781 return 0;
2782}
2783
13769eba
MR
2784/*
2785 * Emulate FPU instructions.
2786 *
2787 * If we use FPU hardware, then we have been typically called to handle
2788 * an unimplemented operation, such as where an operand is a NaN or
2789 * denormalized. In that case exit the emulation loop after a single
2790 * iteration so as to let hardware execute any subsequent instructions.
2791 *
2792 * If we have no FPU hardware or it has been disabled, then continue
2793 * emulating floating-point instructions until one of these conditions
2794 * has occurred:
2795 *
2796 * - a non-FPU instruction has been encountered,
2797 *
2798 * - an attempt to emulate has ended with a signal,
2799 *
2800 * - the ISA mode has been switched.
2801 *
2802 * We need to terminate the emulation loop if we got switched to the
2803 * MIPS16 mode, whether supported or not, so that we do not attempt
2804 * to emulate a MIPS16 instruction as a regular MIPS FPU instruction.
2805 * Similarly if we got switched to the microMIPS mode and only the
2806 * regular MIPS mode is supported, so that we do not attempt to emulate
2807 * a microMIPS instruction as a regular MIPS FPU instruction. Or if
2808 * we got switched to the regular MIPS mode and only the microMIPS mode
2809 * is supported, so that we do not attempt to emulate a regular MIPS
2810 * instruction that should cause an Address Error exception instead.
2811 * For simplicity we always terminate upon an ISA mode switch.
2812 */
e04582b7 2813int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
445a58ce 2814 int has_fpu, void __user **fault_addr)
1da177e4 2815{
333d1f67 2816 unsigned long oldepc, prevepc;
102cedc3
LY
2817 struct mm_decoded_insn dec_insn;
2818 u16 instr[4];
2819 u16 *instr_ptr;
1da177e4
LT
2820 int sig = 0;
2821
1975ed43
PB
2822 /*
2823 * Initialize context if it hasn't been used already, otherwise ensure
2824 * it has been saved to struct thread_struct.
2825 */
2826 if (!init_fp_ctx(current))
2827 lose_fpu(1);
2828
1da177e4
LT
2829 oldepc = xcp->cp0_epc;
2830 do {
2831 prevepc = xcp->cp0_epc;
2832
102cedc3
LY
2833 if (get_isa16_mode(prevepc) && cpu_has_mmips) {
2834 /*
2835 * Get next 2 microMIPS instructions and convert them
2836 * into 32-bit instructions.
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 /* Get first instruction. */
2848 if (mm_insn_16bit(*instr_ptr)) {
2849 /* Duplicate the half-word. */
2850 dec_insn.insn = (*instr_ptr << 16) |
2851 (*instr_ptr);
2852 /* 16-bit instruction. */
2853 dec_insn.pc_inc = 2;
2854 instr_ptr += 1;
2855 } else {
2856 dec_insn.insn = (*instr_ptr << 16) |
2857 *(instr_ptr+1);
2858 /* 32-bit instruction. */
2859 dec_insn.pc_inc = 4;
2860 instr_ptr += 2;
2861 }
2862 /* Get second instruction. */
2863 if (mm_insn_16bit(*instr_ptr)) {
2864 /* Duplicate the half-word. */
2865 dec_insn.next_insn = (*instr_ptr << 16) |
2866 (*instr_ptr);
2867 /* 16-bit instruction. */
2868 dec_insn.next_pc_inc = 2;
2869 } else {
2870 dec_insn.next_insn = (*instr_ptr << 16) |
2871 *(instr_ptr+1);
2872 /* 32-bit instruction. */
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;
515b029d 2887 }
102cedc3
LY
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; /* Skip NOPs */
1da177e4 2893 else {
cd21dfcf 2894 /*
2cfcf8a8
MR
2895 * The 'ieee754_csr' is an alias of ctx->fcr31.
2896 * No need to copy ctx->fcr31 to ieee754_csr.
cd21dfcf 2897 */
102cedc3 2898 sig = cop1Emulate(xcp, ctx, dec_insn, fault_addr);
1da177e4
LT
2899 }
2900
e04582b7 2901 if (has_fpu)
1da177e4
LT
2902 break;
2903 if (sig)
2904 break;
13769eba
MR
2905 /*
2906 * We have to check for the ISA bit explicitly here,
2907 * because `get_isa16_mode' may return 0 if support
2908 * for code compression has been globally disabled,
2909 * or otherwise we may produce the wrong signal or
2910 * even proceed successfully where we must not.
2911 */
2912 if ((xcp->cp0_epc ^ prevepc) & 0x1)
2913 break;
1da177e4
LT
2914
2915 cond_resched();
2916 } while (xcp->cp0_epc > prevepc);
2917
2918 /* SIGILL indicates a non-fpu instruction */
2919 if (sig == SIGILL && xcp->cp0_epc != oldepc)
3f7cac41 2920 /* but if EPC has advanced, then ignore it */
1da177e4
LT
2921 sig = 0;
2922
2923 return sig;
2924}