Merge tag 'v3.10.108' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / mips / math-emu / cp1emu.c
CommitLineData
1da177e4
LT
1/*
2 * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator
3 *
4 * MIPS floating point support
5 * Copyright (C) 1994-2000 Algorithmics Ltd.
1da177e4
LT
6 *
7 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
8 * Copyright (C) 2000 MIPS Technologies, Inc.
9 *
10 * This program is free software; you can distribute it and/or modify it
11 * under the terms of the GNU General Public License (Version 2) as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 * for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * A complete emulator for MIPS coprocessor 1 instructions. This is
24 * required for #float(switch) or #float(trap), where it catches all
25 * COP1 instructions via the "CoProcessor Unusable" exception.
26 *
27 * More surprisingly it is also required for #float(ieee), to help out
28 * the hardware fpu at the boundaries of the IEEE-754 representation
29 * (denormalised values, infinities, underflow, etc). It is made
30 * quite nasty because emulation of some non-COP1 instructions is
31 * required, e.g. in branch delay slots.
32 *
33 * Note if you know that you won't have an fpu, then you'll get much
34 * better performance by compiling with -msoft-float!
35 */
36#include <linux/sched.h>
b6ee75ed 37#include <linux/module.h>
83fd38ca 38#include <linux/debugfs.h>
7f788d2d 39#include <linux/perf_event.h>
1da177e4
LT
40
41#include <asm/inst.h>
42#include <asm/bootinfo.h>
1da177e4
LT
43#include <asm/processor.h>
44#include <asm/ptrace.h>
45#include <asm/signal.h>
46#include <asm/mipsregs.h>
47#include <asm/fpu_emulator.h>
102cedc3 48#include <asm/fpu.h>
1da177e4
LT
49#include <asm/uaccess.h>
50#include <asm/branch.h>
51
52#include "ieee754.h"
1da177e4
LT
53
54/* Strap kernel emulator for full MIPS IV emulation */
55
56#ifdef __mips
57#undef __mips
58#endif
59#define __mips 4
60
61/* Function which emulates a floating point instruction. */
62
eae89076 63static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
1da177e4
LT
64 mips_instruction);
65
66#if __mips >= 4 && __mips != 32
67static int fpux_emu(struct pt_regs *,
515b029d 68 struct mips_fpu_struct *, mips_instruction, void *__user *);
1da177e4
LT
69#endif
70
eae89076 71/* Further private data for which no space exists in mips_fpu_struct */
1da177e4 72
b6ee75ed
DD
73#ifdef CONFIG_DEBUG_FS
74DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
75#endif
1da177e4
LT
76
77/* Control registers */
78
79#define FPCREG_RID 0 /* $0 = revision id */
80#define FPCREG_CSR 31 /* $31 = csr */
81
95e8f634
SM
82/* Determine rounding mode from the RM bits of the FCSR */
83#define modeindex(v) ((v) & FPU_CSR_RM)
84
102cedc3
LY
85/* microMIPS bitfields */
86#define MM_POOL32A_MINOR_MASK 0x3f
87#define MM_POOL32A_MINOR_SHIFT 0x6
88#define MM_MIPS32_COND_FC 0x30
89
1da177e4
LT
90/* Convert Mips rounding mode (0..3) to IEEE library modes. */
91static const unsigned char ieee_rm[4] = {
cd21dfcf
RB
92 [FPU_CSR_RN] = IEEE754_RN,
93 [FPU_CSR_RZ] = IEEE754_RZ,
94 [FPU_CSR_RU] = IEEE754_RU,
95 [FPU_CSR_RD] = IEEE754_RD,
96};
97/* Convert IEEE library modes to Mips rounding mode (0..3). */
98static const unsigned char mips_rm[4] = {
99 [IEEE754_RN] = FPU_CSR_RN,
100 [IEEE754_RZ] = FPU_CSR_RZ,
101 [IEEE754_RD] = FPU_CSR_RD,
102 [IEEE754_RU] = FPU_CSR_RU,
1da177e4
LT
103};
104
105#if __mips >= 4
106/* convert condition code register number to csr bit */
107static const unsigned int fpucondbit[8] = {
108 FPU_CSR_COND0,
109 FPU_CSR_COND1,
110 FPU_CSR_COND2,
111 FPU_CSR_COND3,
112 FPU_CSR_COND4,
113 FPU_CSR_COND5,
114 FPU_CSR_COND6,
115 FPU_CSR_COND7
116};
117#endif
118
102cedc3
LY
119/* (microMIPS) Convert 16-bit register encoding to 32-bit register encoding. */
120static const unsigned int reg16to32map[8] = {16, 17, 2, 3, 4, 5, 6, 7};
121
122/* (microMIPS) Convert certain microMIPS instructions to MIPS32 format. */
123static const int sd_format[] = {16, 17, 0, 0, 0, 0, 0, 0};
124static const int sdps_format[] = {16, 17, 22, 0, 0, 0, 0, 0};
125static const int dwl_format[] = {17, 20, 21, 0, 0, 0, 0, 0};
126static const int swl_format[] = {16, 20, 21, 0, 0, 0, 0, 0};
127
128/*
129 * This functions translates a 32-bit microMIPS instruction
130 * into a 32-bit MIPS32 instruction. Returns 0 on success
131 * and SIGILL otherwise.
132 */
133static int microMIPS32_to_MIPS32(union mips_instruction *insn_ptr)
134{
135 union mips_instruction insn = *insn_ptr;
136 union mips_instruction mips32_insn = insn;
137 int func, fmt, op;
138
139 switch (insn.mm_i_format.opcode) {
140 case mm_ldc132_op:
141 mips32_insn.mm_i_format.opcode = ldc1_op;
142 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
143 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
144 break;
145 case mm_lwc132_op:
146 mips32_insn.mm_i_format.opcode = lwc1_op;
147 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
148 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
149 break;
150 case mm_sdc132_op:
151 mips32_insn.mm_i_format.opcode = sdc1_op;
152 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
153 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
154 break;
155 case mm_swc132_op:
156 mips32_insn.mm_i_format.opcode = swc1_op;
157 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
158 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
159 break;
160 case mm_pool32i_op:
161 /* NOTE: offset is << by 1 if in microMIPS mode. */
162 if ((insn.mm_i_format.rt == mm_bc1f_op) ||
163 (insn.mm_i_format.rt == mm_bc1t_op)) {
164 mips32_insn.fb_format.opcode = cop1_op;
165 mips32_insn.fb_format.bc = bc_op;
166 mips32_insn.fb_format.flag =
167 (insn.mm_i_format.rt == mm_bc1t_op) ? 1 : 0;
168 } else
169 return SIGILL;
170 break;
171 case mm_pool32f_op:
172 switch (insn.mm_fp0_format.func) {
173 case mm_32f_01_op:
174 case mm_32f_11_op:
175 case mm_32f_02_op:
176 case mm_32f_12_op:
177 case mm_32f_41_op:
178 case mm_32f_51_op:
179 case mm_32f_42_op:
180 case mm_32f_52_op:
181 op = insn.mm_fp0_format.func;
182 if (op == mm_32f_01_op)
183 func = madd_s_op;
184 else if (op == mm_32f_11_op)
185 func = madd_d_op;
186 else if (op == mm_32f_02_op)
187 func = nmadd_s_op;
188 else if (op == mm_32f_12_op)
189 func = nmadd_d_op;
190 else if (op == mm_32f_41_op)
191 func = msub_s_op;
192 else if (op == mm_32f_51_op)
193 func = msub_d_op;
194 else if (op == mm_32f_42_op)
195 func = nmsub_s_op;
196 else
197 func = nmsub_d_op;
198 mips32_insn.fp6_format.opcode = cop1x_op;
199 mips32_insn.fp6_format.fr = insn.mm_fp6_format.fr;
200 mips32_insn.fp6_format.ft = insn.mm_fp6_format.ft;
201 mips32_insn.fp6_format.fs = insn.mm_fp6_format.fs;
202 mips32_insn.fp6_format.fd = insn.mm_fp6_format.fd;
203 mips32_insn.fp6_format.func = func;
204 break;
205 case mm_32f_10_op:
206 func = -1; /* Invalid */
207 op = insn.mm_fp5_format.op & 0x7;
208 if (op == mm_ldxc1_op)
209 func = ldxc1_op;
210 else if (op == mm_sdxc1_op)
211 func = sdxc1_op;
212 else if (op == mm_lwxc1_op)
213 func = lwxc1_op;
214 else if (op == mm_swxc1_op)
215 func = swxc1_op;
216
217 if (func != -1) {
218 mips32_insn.r_format.opcode = cop1x_op;
219 mips32_insn.r_format.rs =
220 insn.mm_fp5_format.base;
221 mips32_insn.r_format.rt =
222 insn.mm_fp5_format.index;
223 mips32_insn.r_format.rd = 0;
224 mips32_insn.r_format.re = insn.mm_fp5_format.fd;
225 mips32_insn.r_format.func = func;
226 } else
227 return SIGILL;
228 break;
229 case mm_32f_40_op:
230 op = -1; /* Invalid */
231 if (insn.mm_fp2_format.op == mm_fmovt_op)
232 op = 1;
233 else if (insn.mm_fp2_format.op == mm_fmovf_op)
234 op = 0;
235 if (op != -1) {
236 mips32_insn.fp0_format.opcode = cop1_op;
237 mips32_insn.fp0_format.fmt =
238 sdps_format[insn.mm_fp2_format.fmt];
239 mips32_insn.fp0_format.ft =
240 (insn.mm_fp2_format.cc<<2) + op;
241 mips32_insn.fp0_format.fs =
242 insn.mm_fp2_format.fs;
243 mips32_insn.fp0_format.fd =
244 insn.mm_fp2_format.fd;
245 mips32_insn.fp0_format.func = fmovc_op;
246 } else
247 return SIGILL;
248 break;
249 case mm_32f_60_op:
250 func = -1; /* Invalid */
251 if (insn.mm_fp0_format.op == mm_fadd_op)
252 func = fadd_op;
253 else if (insn.mm_fp0_format.op == mm_fsub_op)
254 func = fsub_op;
255 else if (insn.mm_fp0_format.op == mm_fmul_op)
256 func = fmul_op;
257 else if (insn.mm_fp0_format.op == mm_fdiv_op)
258 func = fdiv_op;
259 if (func != -1) {
260 mips32_insn.fp0_format.opcode = cop1_op;
261 mips32_insn.fp0_format.fmt =
262 sdps_format[insn.mm_fp0_format.fmt];
263 mips32_insn.fp0_format.ft =
264 insn.mm_fp0_format.ft;
265 mips32_insn.fp0_format.fs =
266 insn.mm_fp0_format.fs;
267 mips32_insn.fp0_format.fd =
268 insn.mm_fp0_format.fd;
269 mips32_insn.fp0_format.func = func;
270 } else
271 return SIGILL;
272 break;
273 case mm_32f_70_op:
274 func = -1; /* Invalid */
275 if (insn.mm_fp0_format.op == mm_fmovn_op)
276 func = fmovn_op;
277 else if (insn.mm_fp0_format.op == mm_fmovz_op)
278 func = fmovz_op;
279 if (func != -1) {
280 mips32_insn.fp0_format.opcode = cop1_op;
281 mips32_insn.fp0_format.fmt =
282 sdps_format[insn.mm_fp0_format.fmt];
283 mips32_insn.fp0_format.ft =
284 insn.mm_fp0_format.ft;
285 mips32_insn.fp0_format.fs =
286 insn.mm_fp0_format.fs;
287 mips32_insn.fp0_format.fd =
288 insn.mm_fp0_format.fd;
289 mips32_insn.fp0_format.func = func;
290 } else
291 return SIGILL;
292 break;
293 case mm_32f_73_op: /* POOL32FXF */
294 switch (insn.mm_fp1_format.op) {
295 case mm_movf0_op:
296 case mm_movf1_op:
297 case mm_movt0_op:
298 case mm_movt1_op:
299 if ((insn.mm_fp1_format.op & 0x7f) ==
300 mm_movf0_op)
301 op = 0;
302 else
303 op = 1;
304 mips32_insn.r_format.opcode = spec_op;
305 mips32_insn.r_format.rs = insn.mm_fp4_format.fs;
306 mips32_insn.r_format.rt =
307 (insn.mm_fp4_format.cc << 2) + op;
308 mips32_insn.r_format.rd = insn.mm_fp4_format.rt;
309 mips32_insn.r_format.re = 0;
310 mips32_insn.r_format.func = movc_op;
311 break;
312 case mm_fcvtd0_op:
313 case mm_fcvtd1_op:
314 case mm_fcvts0_op:
315 case mm_fcvts1_op:
316 if ((insn.mm_fp1_format.op & 0x7f) ==
317 mm_fcvtd0_op) {
318 func = fcvtd_op;
319 fmt = swl_format[insn.mm_fp3_format.fmt];
320 } else {
321 func = fcvts_op;
322 fmt = dwl_format[insn.mm_fp3_format.fmt];
323 }
324 mips32_insn.fp0_format.opcode = cop1_op;
325 mips32_insn.fp0_format.fmt = fmt;
326 mips32_insn.fp0_format.ft = 0;
327 mips32_insn.fp0_format.fs =
328 insn.mm_fp3_format.fs;
329 mips32_insn.fp0_format.fd =
330 insn.mm_fp3_format.rt;
331 mips32_insn.fp0_format.func = func;
332 break;
333 case mm_fmov0_op:
334 case mm_fmov1_op:
335 case mm_fabs0_op:
336 case mm_fabs1_op:
337 case mm_fneg0_op:
338 case mm_fneg1_op:
339 if ((insn.mm_fp1_format.op & 0x7f) ==
340 mm_fmov0_op)
341 func = fmov_op;
342 else if ((insn.mm_fp1_format.op & 0x7f) ==
343 mm_fabs0_op)
344 func = fabs_op;
345 else
346 func = fneg_op;
347 mips32_insn.fp0_format.opcode = cop1_op;
348 mips32_insn.fp0_format.fmt =
349 sdps_format[insn.mm_fp3_format.fmt];
350 mips32_insn.fp0_format.ft = 0;
351 mips32_insn.fp0_format.fs =
352 insn.mm_fp3_format.fs;
353 mips32_insn.fp0_format.fd =
354 insn.mm_fp3_format.rt;
355 mips32_insn.fp0_format.func = func;
356 break;
357 case mm_ffloorl_op:
358 case mm_ffloorw_op:
359 case mm_fceill_op:
360 case mm_fceilw_op:
361 case mm_ftruncl_op:
362 case mm_ftruncw_op:
363 case mm_froundl_op:
364 case mm_froundw_op:
365 case mm_fcvtl_op:
366 case mm_fcvtw_op:
367 if (insn.mm_fp1_format.op == mm_ffloorl_op)
368 func = ffloorl_op;
369 else if (insn.mm_fp1_format.op == mm_ffloorw_op)
370 func = ffloor_op;
371 else if (insn.mm_fp1_format.op == mm_fceill_op)
372 func = fceill_op;
373 else if (insn.mm_fp1_format.op == mm_fceilw_op)
374 func = fceil_op;
375 else if (insn.mm_fp1_format.op == mm_ftruncl_op)
376 func = ftruncl_op;
377 else if (insn.mm_fp1_format.op == mm_ftruncw_op)
378 func = ftrunc_op;
379 else if (insn.mm_fp1_format.op == mm_froundl_op)
380 func = froundl_op;
381 else if (insn.mm_fp1_format.op == mm_froundw_op)
382 func = fround_op;
383 else if (insn.mm_fp1_format.op == mm_fcvtl_op)
384 func = fcvtl_op;
385 else
386 func = fcvtw_op;
387 mips32_insn.fp0_format.opcode = cop1_op;
388 mips32_insn.fp0_format.fmt =
389 sd_format[insn.mm_fp1_format.fmt];
390 mips32_insn.fp0_format.ft = 0;
391 mips32_insn.fp0_format.fs =
392 insn.mm_fp1_format.fs;
393 mips32_insn.fp0_format.fd =
394 insn.mm_fp1_format.rt;
395 mips32_insn.fp0_format.func = func;
396 break;
397 case mm_frsqrt_op:
398 case mm_fsqrt_op:
399 case mm_frecip_op:
400 if (insn.mm_fp1_format.op == mm_frsqrt_op)
401 func = frsqrt_op;
402 else if (insn.mm_fp1_format.op == mm_fsqrt_op)
403 func = fsqrt_op;
404 else
405 func = frecip_op;
406 mips32_insn.fp0_format.opcode = cop1_op;
407 mips32_insn.fp0_format.fmt =
408 sdps_format[insn.mm_fp1_format.fmt];
409 mips32_insn.fp0_format.ft = 0;
410 mips32_insn.fp0_format.fs =
411 insn.mm_fp1_format.fs;
412 mips32_insn.fp0_format.fd =
413 insn.mm_fp1_format.rt;
414 mips32_insn.fp0_format.func = func;
415 break;
416 case mm_mfc1_op:
417 case mm_mtc1_op:
418 case mm_cfc1_op:
419 case mm_ctc1_op:
420 if (insn.mm_fp1_format.op == mm_mfc1_op)
421 op = mfc_op;
422 else if (insn.mm_fp1_format.op == mm_mtc1_op)
423 op = mtc_op;
424 else if (insn.mm_fp1_format.op == mm_cfc1_op)
425 op = cfc_op;
426 else
427 op = ctc_op;
428 mips32_insn.fp1_format.opcode = cop1_op;
429 mips32_insn.fp1_format.op = op;
430 mips32_insn.fp1_format.rt =
431 insn.mm_fp1_format.rt;
432 mips32_insn.fp1_format.fs =
433 insn.mm_fp1_format.fs;
434 mips32_insn.fp1_format.fd = 0;
435 mips32_insn.fp1_format.func = 0;
436 break;
437 default:
438 return SIGILL;
439 break;
440 }
441 break;
442 case mm_32f_74_op: /* c.cond.fmt */
443 mips32_insn.fp0_format.opcode = cop1_op;
444 mips32_insn.fp0_format.fmt =
445 sdps_format[insn.mm_fp4_format.fmt];
446 mips32_insn.fp0_format.ft = insn.mm_fp4_format.rt;
447 mips32_insn.fp0_format.fs = insn.mm_fp4_format.fs;
448 mips32_insn.fp0_format.fd = insn.mm_fp4_format.cc << 2;
449 mips32_insn.fp0_format.func =
450 insn.mm_fp4_format.cond | MM_MIPS32_COND_FC;
451 break;
452 default:
453 return SIGILL;
454 break;
455 }
456 break;
457 default:
458 return SIGILL;
459 break;
460 }
461
462 *insn_ptr = mips32_insn;
463 return 0;
464}
465
466int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
467 unsigned long *contpc)
468{
469 union mips_instruction insn = (union mips_instruction)dec_insn.insn;
470 int bc_false = 0;
471 unsigned int fcr31;
472 unsigned int bit;
473
474 switch (insn.mm_i_format.opcode) {
475 case mm_pool32a_op:
476 if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MASK) ==
477 mm_pool32axf_op) {
478 switch (insn.mm_i_format.simmediate >>
479 MM_POOL32A_MINOR_SHIFT) {
480 case mm_jalr_op:
481 case mm_jalrhb_op:
482 case mm_jalrs_op:
483 case mm_jalrshb_op:
484 if (insn.mm_i_format.rt != 0) /* Not mm_jr */
485 regs->regs[insn.mm_i_format.rt] =
486 regs->cp0_epc +
487 dec_insn.pc_inc +
488 dec_insn.next_pc_inc;
489 *contpc = regs->regs[insn.mm_i_format.rs];
490 return 1;
491 break;
492 }
493 }
494 break;
495 case mm_pool32i_op:
496 switch (insn.mm_i_format.rt) {
497 case mm_bltzals_op:
498 case mm_bltzal_op:
499 regs->regs[31] = regs->cp0_epc +
500 dec_insn.pc_inc +
501 dec_insn.next_pc_inc;
502 /* Fall through */
503 case mm_bltz_op:
504 if ((long)regs->regs[insn.mm_i_format.rs] < 0)
505 *contpc = regs->cp0_epc +
506 dec_insn.pc_inc +
507 (insn.mm_i_format.simmediate << 1);
508 else
509 *contpc = regs->cp0_epc +
510 dec_insn.pc_inc +
511 dec_insn.next_pc_inc;
512 return 1;
513 break;
514 case mm_bgezals_op:
515 case mm_bgezal_op:
516 regs->regs[31] = regs->cp0_epc +
517 dec_insn.pc_inc +
518 dec_insn.next_pc_inc;
519 /* Fall through */
520 case mm_bgez_op:
521 if ((long)regs->regs[insn.mm_i_format.rs] >= 0)
522 *contpc = regs->cp0_epc +
523 dec_insn.pc_inc +
524 (insn.mm_i_format.simmediate << 1);
525 else
526 *contpc = regs->cp0_epc +
527 dec_insn.pc_inc +
528 dec_insn.next_pc_inc;
529 return 1;
530 break;
531 case mm_blez_op:
532 if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
533 *contpc = regs->cp0_epc +
534 dec_insn.pc_inc +
535 (insn.mm_i_format.simmediate << 1);
536 else
537 *contpc = regs->cp0_epc +
538 dec_insn.pc_inc +
539 dec_insn.next_pc_inc;
540 return 1;
541 break;
542 case mm_bgtz_op:
543 if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
544 *contpc = regs->cp0_epc +
545 dec_insn.pc_inc +
546 (insn.mm_i_format.simmediate << 1);
547 else
548 *contpc = regs->cp0_epc +
549 dec_insn.pc_inc +
550 dec_insn.next_pc_inc;
551 return 1;
552 break;
553 case mm_bc2f_op:
554 case mm_bc1f_op:
555 bc_false = 1;
556 /* Fall through */
557 case mm_bc2t_op:
558 case mm_bc1t_op:
559 preempt_disable();
560 if (is_fpu_owner())
561 asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
562 else
563 fcr31 = current->thread.fpu.fcr31;
564 preempt_enable();
565
566 if (bc_false)
567 fcr31 = ~fcr31;
568
569 bit = (insn.mm_i_format.rs >> 2);
570 bit += (bit != 0);
571 bit += 23;
572 if (fcr31 & (1 << bit))
573 *contpc = regs->cp0_epc +
574 dec_insn.pc_inc +
575 (insn.mm_i_format.simmediate << 1);
576 else
577 *contpc = regs->cp0_epc +
578 dec_insn.pc_inc + dec_insn.next_pc_inc;
579 return 1;
580 break;
581 }
582 break;
583 case mm_pool16c_op:
584 switch (insn.mm_i_format.rt) {
585 case mm_jalr16_op:
586 case mm_jalrs16_op:
587 regs->regs[31] = regs->cp0_epc +
588 dec_insn.pc_inc + dec_insn.next_pc_inc;
589 /* Fall through */
590 case mm_jr16_op:
591 *contpc = regs->regs[insn.mm_i_format.rs];
592 return 1;
593 break;
594 }
595 break;
596 case mm_beqz16_op:
597 if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] == 0)
598 *contpc = regs->cp0_epc +
599 dec_insn.pc_inc +
600 (insn.mm_b1_format.simmediate << 1);
601 else
602 *contpc = regs->cp0_epc +
603 dec_insn.pc_inc + dec_insn.next_pc_inc;
604 return 1;
605 break;
606 case mm_bnez16_op:
607 if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] != 0)
608 *contpc = regs->cp0_epc +
609 dec_insn.pc_inc +
610 (insn.mm_b1_format.simmediate << 1);
611 else
612 *contpc = regs->cp0_epc +
613 dec_insn.pc_inc + dec_insn.next_pc_inc;
614 return 1;
615 break;
616 case mm_b16_op:
617 *contpc = regs->cp0_epc + dec_insn.pc_inc +
618 (insn.mm_b0_format.simmediate << 1);
619 return 1;
620 break;
621 case mm_beq32_op:
622 if (regs->regs[insn.mm_i_format.rs] ==
623 regs->regs[insn.mm_i_format.rt])
624 *contpc = regs->cp0_epc +
625 dec_insn.pc_inc +
626 (insn.mm_i_format.simmediate << 1);
627 else
628 *contpc = regs->cp0_epc +
629 dec_insn.pc_inc +
630 dec_insn.next_pc_inc;
631 return 1;
632 break;
633 case mm_bne32_op:
634 if (regs->regs[insn.mm_i_format.rs] !=
635 regs->regs[insn.mm_i_format.rt])
636 *contpc = regs->cp0_epc +
637 dec_insn.pc_inc +
638 (insn.mm_i_format.simmediate << 1);
639 else
640 *contpc = regs->cp0_epc +
641 dec_insn.pc_inc + dec_insn.next_pc_inc;
642 return 1;
643 break;
644 case mm_jalx32_op:
645 regs->regs[31] = regs->cp0_epc +
646 dec_insn.pc_inc + dec_insn.next_pc_inc;
647 *contpc = regs->cp0_epc + dec_insn.pc_inc;
648 *contpc >>= 28;
649 *contpc <<= 28;
650 *contpc |= (insn.j_format.target << 2);
651 return 1;
652 break;
653 case mm_jals32_op:
654 case mm_jal32_op:
655 regs->regs[31] = regs->cp0_epc +
656 dec_insn.pc_inc + dec_insn.next_pc_inc;
657 /* Fall through */
658 case mm_j32_op:
659 *contpc = regs->cp0_epc + dec_insn.pc_inc;
660 *contpc >>= 27;
661 *contpc <<= 27;
662 *contpc |= (insn.j_format.target << 1);
663 set_isa16_mode(*contpc);
664 return 1;
665 break;
666 }
667 return 0;
668}
1da177e4
LT
669
670/*
671 * Redundant with logic already in kernel/branch.c,
672 * embedded in compute_return_epc. At some point,
673 * a single subroutine should be used across both
674 * modules.
675 */
102cedc3
LY
676static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
677 unsigned long *contpc)
1da177e4 678{
102cedc3
LY
679 union mips_instruction insn = (union mips_instruction)dec_insn.insn;
680 unsigned int fcr31;
681 unsigned int bit = 0;
682
683 switch (insn.i_format.opcode) {
1da177e4 684 case spec_op:
102cedc3 685 switch (insn.r_format.func) {
1da177e4 686 case jalr_op:
2c767dae
PB
687 if (insn.r_format.rd != 0) {
688 regs->regs[insn.r_format.rd] =
689 regs->cp0_epc + dec_insn.pc_inc +
690 dec_insn.next_pc_inc;
691 }
102cedc3 692 /* Fall through */
1da177e4 693 case jr_op:
102cedc3 694 *contpc = regs->regs[insn.r_format.rs];
1da177e4 695 return 1;
102cedc3 696 break;
1da177e4
LT
697 }
698 break;
1da177e4 699 case bcond_op:
102cedc3
LY
700 switch (insn.i_format.rt) {
701 case bltzal_op:
702 case bltzall_op:
703 regs->regs[31] = regs->cp0_epc +
704 dec_insn.pc_inc +
705 dec_insn.next_pc_inc;
706 /* Fall through */
1da177e4 707 case bltz_op:
1da177e4 708 case bltzl_op:
102cedc3
LY
709 if ((long)regs->regs[insn.i_format.rs] < 0)
710 *contpc = regs->cp0_epc +
711 dec_insn.pc_inc +
712 (insn.i_format.simmediate << 2);
713 else
714 *contpc = regs->cp0_epc +
715 dec_insn.pc_inc +
716 dec_insn.next_pc_inc;
717 return 1;
718 break;
1da177e4 719 case bgezal_op:
1da177e4 720 case bgezall_op:
102cedc3
LY
721 regs->regs[31] = regs->cp0_epc +
722 dec_insn.pc_inc +
723 dec_insn.next_pc_inc;
724 /* Fall through */
725 case bgez_op:
726 case bgezl_op:
727 if ((long)regs->regs[insn.i_format.rs] >= 0)
728 *contpc = regs->cp0_epc +
729 dec_insn.pc_inc +
730 (insn.i_format.simmediate << 2);
731 else
732 *contpc = regs->cp0_epc +
733 dec_insn.pc_inc +
734 dec_insn.next_pc_inc;
1da177e4 735 return 1;
102cedc3 736 break;
1da177e4
LT
737 }
738 break;
1da177e4 739 case jalx_op:
102cedc3
LY
740 set_isa16_mode(bit);
741 case jal_op:
742 regs->regs[31] = regs->cp0_epc +
743 dec_insn.pc_inc +
744 dec_insn.next_pc_inc;
745 /* Fall through */
746 case j_op:
747 *contpc = regs->cp0_epc + dec_insn.pc_inc;
748 *contpc >>= 28;
749 *contpc <<= 28;
750 *contpc |= (insn.j_format.target << 2);
751 /* Set microMIPS mode bit: XOR for jalx. */
752 *contpc ^= bit;
753 return 1;
754 break;
1da177e4 755 case beq_op:
1da177e4 756 case beql_op:
102cedc3
LY
757 if (regs->regs[insn.i_format.rs] ==
758 regs->regs[insn.i_format.rt])
759 *contpc = regs->cp0_epc +
760 dec_insn.pc_inc +
761 (insn.i_format.simmediate << 2);
762 else
763 *contpc = regs->cp0_epc +
764 dec_insn.pc_inc +
765 dec_insn.next_pc_inc;
766 return 1;
767 break;
768 case bne_op:
1da177e4 769 case bnel_op:
102cedc3
LY
770 if (regs->regs[insn.i_format.rs] !=
771 regs->regs[insn.i_format.rt])
772 *contpc = regs->cp0_epc +
773 dec_insn.pc_inc +
774 (insn.i_format.simmediate << 2);
775 else
776 *contpc = regs->cp0_epc +
777 dec_insn.pc_inc +
778 dec_insn.next_pc_inc;
779 return 1;
780 break;
781 case blez_op:
1da177e4 782 case blezl_op:
102cedc3
LY
783 if ((long)regs->regs[insn.i_format.rs] <= 0)
784 *contpc = regs->cp0_epc +
785 dec_insn.pc_inc +
786 (insn.i_format.simmediate << 2);
787 else
788 *contpc = regs->cp0_epc +
789 dec_insn.pc_inc +
790 dec_insn.next_pc_inc;
791 return 1;
792 break;
793 case bgtz_op:
1da177e4 794 case bgtzl_op:
102cedc3
LY
795 if ((long)regs->regs[insn.i_format.rs] > 0)
796 *contpc = regs->cp0_epc +
797 dec_insn.pc_inc +
798 (insn.i_format.simmediate << 2);
799 else
800 *contpc = regs->cp0_epc +
801 dec_insn.pc_inc +
802 dec_insn.next_pc_inc;
1da177e4 803 return 1;
102cedc3 804 break;
1da177e4
LT
805 case cop0_op:
806 case cop1_op:
807 case cop2_op:
808 case cop1x_op:
102cedc3
LY
809 if (insn.i_format.rs == bc_op) {
810 preempt_disable();
811 if (is_fpu_owner())
812 asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
813 else
814 fcr31 = current->thread.fpu.fcr31;
815 preempt_enable();
816
817 bit = (insn.i_format.rt >> 2);
818 bit += (bit != 0);
819 bit += 23;
820 switch (insn.i_format.rt & 3) {
821 case 0: /* bc1f */
822 case 2: /* bc1fl */
823 if (~fcr31 & (1 << bit))
824 *contpc = regs->cp0_epc +
825 dec_insn.pc_inc +
826 (insn.i_format.simmediate << 2);
827 else
828 *contpc = regs->cp0_epc +
829 dec_insn.pc_inc +
830 dec_insn.next_pc_inc;
831 return 1;
832 break;
833 case 1: /* bc1t */
834 case 3: /* bc1tl */
835 if (fcr31 & (1 << bit))
836 *contpc = regs->cp0_epc +
837 dec_insn.pc_inc +
838 (insn.i_format.simmediate << 2);
839 else
840 *contpc = regs->cp0_epc +
841 dec_insn.pc_inc +
842 dec_insn.next_pc_inc;
843 return 1;
844 break;
845 }
846 }
1da177e4
LT
847 break;
848 }
1da177e4
LT
849 return 0;
850}
851
852/*
853 * In the Linux kernel, we support selection of FPR format on the
70342287 854 * basis of the Status.FR bit. If an FPU is not present, the FR bit
da0bac33 855 * is hardwired to zero, which would imply a 32-bit FPU even for
51d943f0
RB
856 * 64-bit CPUs so we rather look at TIF_32BIT_REGS.
857 * FPU emu is slow and bulky and optimizing this function offers fairly
858 * sizeable benefits so we try to be clever and make this function return
859 * a constant whenever possible, that is on 64-bit kernels without O32
860 * compatibility enabled and on 32-bit kernels.
1da177e4 861 */
da0bac33
DD
862static inline int cop1_64bit(struct pt_regs *xcp)
863{
51d943f0
RB
864#if defined(CONFIG_64BIT) && !defined(CONFIG_MIPS32_O32)
865 return 1;
866#elif defined(CONFIG_64BIT) && defined(CONFIG_MIPS32_O32)
da0bac33 867 return !test_thread_flag(TIF_32BIT_REGS);
1da177e4 868#else
da0bac33 869 return 0;
1da177e4 870#endif
da0bac33
DD
871}
872
873#define SIFROMREG(si, x) ((si) = cop1_64bit(xcp) || !(x & 1) ? \
874 (int)ctx->fpr[x] : (int)(ctx->fpr[x & ~1] >> 32))
1da177e4 875
da0bac33
DD
876#define SITOREG(si, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = \
877 cop1_64bit(xcp) || !(x & 1) ? \
1da177e4
LT
878 ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \
879 ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32)
880
da0bac33
DD
881#define DIFROMREG(di, x) ((di) = ctx->fpr[x & ~(cop1_64bit(xcp) == 0)])
882#define DITOREG(di, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = (di))
1da177e4 883
21a151d8
RB
884#define SPFROMREG(sp, x) SIFROMREG((sp).bits, x)
885#define SPTOREG(sp, x) SITOREG((sp).bits, x)
886#define DPFROMREG(dp, x) DIFROMREG((dp).bits, x)
887#define DPTOREG(dp, x) DITOREG((dp).bits, x)
1da177e4
LT
888
889/*
890 * Emulate the single floating point instruction pointed at by EPC.
891 * Two instructions if the instruction is in a branch delay slot.
892 */
893
515b029d 894static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
102cedc3 895 struct mm_decoded_insn dec_insn, void *__user *fault_addr)
1da177e4
LT
896{
897 mips_instruction ir;
102cedc3 898 unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc;
1da177e4 899 unsigned int cond;
102cedc3 900 int pc_inc;
1da177e4
LT
901
902 /* XXX NEC Vr54xx bug workaround */
102cedc3
LY
903 if (xcp->cp0_cause & CAUSEF_BD) {
904 if (dec_insn.micro_mips_mode) {
905 if (!mm_isBranchInstr(xcp, dec_insn, &contpc))
906 xcp->cp0_cause &= ~CAUSEF_BD;
907 } else {
908 if (!isBranchInstr(xcp, dec_insn, &contpc))
909 xcp->cp0_cause &= ~CAUSEF_BD;
910 }
911 }
1da177e4
LT
912
913 if (xcp->cp0_cause & CAUSEF_BD) {
914 /*
915 * The instruction to be emulated is in a branch delay slot
70342287 916 * which means that we have to emulate the branch instruction
1da177e4
LT
917 * BEFORE we do the cop1 instruction.
918 *
919 * This branch could be a COP1 branch, but in that case we
920 * would have had a trap for that instruction, and would not
921 * come through this route.
922 *
923 * Linux MIPS branch emulator operates on context, updating the
924 * cp0_epc.
925 */
102cedc3
LY
926 ir = dec_insn.next_insn; /* process delay slot instr */
927 pc_inc = dec_insn.next_pc_inc;
928 } else {
929 ir = dec_insn.insn; /* process current instr */
930 pc_inc = dec_insn.pc_inc;
931 }
1da177e4 932
102cedc3
LY
933 /*
934 * Since microMIPS FPU instructios are a subset of MIPS32 FPU
935 * instructions, we want to convert microMIPS FPU instructions
936 * into MIPS32 instructions so that we could reuse all of the
937 * FPU emulation code.
938 *
939 * NOTE: We cannot do this for branch instructions since they
940 * are not a subset. Example: Cannot emulate a 16-bit
941 * aligned target address with a MIPS32 instruction.
942 */
943 if (dec_insn.micro_mips_mode) {
944 /*
945 * If next instruction is a 16-bit instruction, then it
946 * it cannot be a FPU instruction. This could happen
947 * since we can be called for non-FPU instructions.
948 */
949 if ((pc_inc == 2) ||
950 (microMIPS32_to_MIPS32((union mips_instruction *)&ir)
951 == SIGILL))
1da177e4 952 return SIGILL;
1da177e4
LT
953 }
954
955 emul:
a8b0ca17 956 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, xcp, 0);
b6ee75ed 957 MIPS_FPU_EMU_INC_STATS(emulated);
1da177e4 958 switch (MIPSInst_OPCODE(ir)) {
1da177e4 959 case ldc1_op:{
3fccc015 960 u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1da177e4
LT
961 MIPSInst_SIMM(ir));
962 u64 val;
963
b6ee75ed 964 MIPS_FPU_EMU_INC_STATS(loads);
515b029d
DD
965
966 if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
b6ee75ed 967 MIPS_FPU_EMU_INC_STATS(errors);
515b029d 968 *fault_addr = va;
1da177e4
LT
969 return SIGBUS;
970 }
515b029d
DD
971 if (__get_user(val, va)) {
972 MIPS_FPU_EMU_INC_STATS(errors);
973 *fault_addr = va;
974 return SIGSEGV;
975 }
1da177e4
LT
976 DITOREG(val, MIPSInst_RT(ir));
977 break;
978 }
979
980 case sdc1_op:{
3fccc015 981 u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1da177e4
LT
982 MIPSInst_SIMM(ir));
983 u64 val;
984
b6ee75ed 985 MIPS_FPU_EMU_INC_STATS(stores);
1da177e4 986 DIFROMREG(val, MIPSInst_RT(ir));
515b029d 987 if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
b6ee75ed 988 MIPS_FPU_EMU_INC_STATS(errors);
515b029d 989 *fault_addr = va;
1da177e4
LT
990 return SIGBUS;
991 }
515b029d
DD
992 if (__put_user(val, va)) {
993 MIPS_FPU_EMU_INC_STATS(errors);
994 *fault_addr = va;
995 return SIGSEGV;
996 }
1da177e4
LT
997 break;
998 }
1da177e4
LT
999
1000 case lwc1_op:{
3fccc015 1001 u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1da177e4
LT
1002 MIPSInst_SIMM(ir));
1003 u32 val;
1004
b6ee75ed 1005 MIPS_FPU_EMU_INC_STATS(loads);
515b029d 1006 if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
b6ee75ed 1007 MIPS_FPU_EMU_INC_STATS(errors);
515b029d 1008 *fault_addr = va;
1da177e4
LT
1009 return SIGBUS;
1010 }
515b029d
DD
1011 if (__get_user(val, va)) {
1012 MIPS_FPU_EMU_INC_STATS(errors);
1013 *fault_addr = va;
1014 return SIGSEGV;
1015 }
1da177e4
LT
1016 SITOREG(val, MIPSInst_RT(ir));
1017 break;
1018 }
1019
1020 case swc1_op:{
3fccc015 1021 u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1da177e4
LT
1022 MIPSInst_SIMM(ir));
1023 u32 val;
1024
b6ee75ed 1025 MIPS_FPU_EMU_INC_STATS(stores);
1da177e4 1026 SIFROMREG(val, MIPSInst_RT(ir));
515b029d 1027 if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
b6ee75ed 1028 MIPS_FPU_EMU_INC_STATS(errors);
515b029d 1029 *fault_addr = va;
1da177e4
LT
1030 return SIGBUS;
1031 }
515b029d
DD
1032 if (__put_user(val, va)) {
1033 MIPS_FPU_EMU_INC_STATS(errors);
1034 *fault_addr = va;
1035 return SIGSEGV;
1036 }
1da177e4
LT
1037 break;
1038 }
1039
1040 case cop1_op:
1041 switch (MIPSInst_RS(ir)) {
1042
4b724efd 1043#if defined(__mips64)
1da177e4
LT
1044 case dmfc_op:
1045 /* copregister fs -> gpr[rt] */
1046 if (MIPSInst_RT(ir) != 0) {
1047 DIFROMREG(xcp->regs[MIPSInst_RT(ir)],
1048 MIPSInst_RD(ir));
1049 }
1050 break;
1051
1052 case dmtc_op:
1053 /* copregister fs <- rt */
1054 DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1055 break;
1056#endif
1057
1058 case mfc_op:
1059 /* copregister rd -> gpr[rt] */
1da177e4
LT
1060 if (MIPSInst_RT(ir) != 0) {
1061 SIFROMREG(xcp->regs[MIPSInst_RT(ir)],
1062 MIPSInst_RD(ir));
1063 }
1064 break;
1065
1066 case mtc_op:
1067 /* copregister rd <- rt */
1da177e4
LT
1068 SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1069 break;
1070
1071 case cfc_op:{
1072 /* cop control register rd -> gpr[rt] */
1073 u32 value;
1074
1da177e4
LT
1075 if (MIPSInst_RD(ir) == FPCREG_CSR) {
1076 value = ctx->fcr31;
3f135530
SM
1077 value = (value & ~FPU_CSR_RM) |
1078 mips_rm[modeindex(value)];
1da177e4
LT
1079#ifdef CSRTRACE
1080 printk("%p gpr[%d]<-csr=%08x\n",
333d1f67 1081 (void *) (xcp->cp0_epc),
1da177e4
LT
1082 MIPSInst_RT(ir), value);
1083#endif
1084 }
1085 else if (MIPSInst_RD(ir) == FPCREG_RID)
1086 value = 0;
1087 else
1088 value = 0;
1089 if (MIPSInst_RT(ir))
1090 xcp->regs[MIPSInst_RT(ir)] = value;
1091 break;
1092 }
1093
1094 case ctc_op:{
1095 /* copregister rd <- rt */
1096 u32 value;
1097
1098 if (MIPSInst_RT(ir) == 0)
1099 value = 0;
1100 else
1101 value = xcp->regs[MIPSInst_RT(ir)];
1102
1103 /* we only have one writable control reg
1104 */
1105 if (MIPSInst_RD(ir) == FPCREG_CSR) {
1106#ifdef CSRTRACE
1107 printk("%p gpr[%d]->csr=%08x\n",
333d1f67 1108 (void *) (xcp->cp0_epc),
1da177e4
LT
1109 MIPSInst_RT(ir), value);
1110#endif
95e8f634
SM
1111
1112 /*
1113 * Don't write reserved bits,
1114 * and convert to ieee library modes
1115 */
1116 ctx->fcr31 = (value &
1117 ~(FPU_CSR_RSVD | FPU_CSR_RM)) |
1118 ieee_rm[modeindex(value)];
1da177e4
LT
1119 }
1120 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1121 return SIGFPE;
1122 }
1123 break;
1124 }
1125
1126 case bc_op:{
1127 int likely = 0;
1128
1129 if (xcp->cp0_cause & CAUSEF_BD)
1130 return SIGILL;
1131
1132#if __mips >= 4
1133 cond = ctx->fcr31 & fpucondbit[MIPSInst_RT(ir) >> 2];
1134#else
1135 cond = ctx->fcr31 & FPU_CSR_COND;
1136#endif
1137 switch (MIPSInst_RT(ir) & 3) {
1138 case bcfl_op:
1139 likely = 1;
1140 case bcf_op:
1141 cond = !cond;
1142 break;
1143 case bctl_op:
1144 likely = 1;
1145 case bct_op:
1146 break;
1147 default:
1148 /* thats an illegal instruction */
1149 return SIGILL;
1150 }
1151
1152 xcp->cp0_cause |= CAUSEF_BD;
1153 if (cond) {
1154 /* branch taken: emulate dslot
1155 * instruction
1156 */
102cedc3
LY
1157 xcp->cp0_epc += dec_insn.pc_inc;
1158
1159 contpc = MIPSInst_SIMM(ir);
1160 ir = dec_insn.next_insn;
1161 if (dec_insn.micro_mips_mode) {
1162 contpc = (xcp->cp0_epc + (contpc << 1));
1163
1164 /* If 16-bit instruction, not FPU. */
1165 if ((dec_insn.next_pc_inc == 2) ||
1166 (microMIPS32_to_MIPS32((union mips_instruction *)&ir) == SIGILL)) {
1167
1168 /*
1169 * Since this instruction will
1170 * be put on the stack with
1171 * 32-bit words, get around
1172 * this problem by putting a
1173 * NOP16 as the second one.
1174 */
1175 if (dec_insn.next_pc_inc == 2)
1176 ir = (ir & (~0xffff)) | MM_NOP16;
1177
1178 /*
1179 * Single step the non-CP1
1180 * instruction in the dslot.
1181 */
1182 return mips_dsemul(xcp, ir, contpc);
1183 }
1184 } else
1185 contpc = (xcp->cp0_epc + (contpc << 2));
1da177e4
LT
1186
1187 switch (MIPSInst_OPCODE(ir)) {
1188 case lwc1_op:
1189 case swc1_op:
4b724efd 1190#if (__mips >= 2 || defined(__mips64))
1da177e4
LT
1191 case ldc1_op:
1192 case sdc1_op:
1193#endif
1194 case cop1_op:
1195#if __mips >= 4 && __mips != 32
1196 case cop1x_op:
1197#endif
1198 /* its one of ours */
1199 goto emul;
1200#if __mips >= 4
1201 case spec_op:
1202 if (MIPSInst_FUNC(ir) == movc_op)
1203 goto emul;
1204 break;
1205#endif
1206 }
1207
1208 /*
1209 * Single step the non-cp1
1210 * instruction in the dslot
1211 */
e70dfc10 1212 return mips_dsemul(xcp, ir, contpc);
1da177e4
LT
1213 }
1214 else {
1215 /* branch not taken */
1216 if (likely) {
1217 /*
1218 * branch likely nullifies
1219 * dslot if not taken
1220 */
102cedc3
LY
1221 xcp->cp0_epc += dec_insn.pc_inc;
1222 contpc += dec_insn.pc_inc;
1da177e4
LT
1223 /*
1224 * else continue & execute
1225 * dslot as normal insn
1226 */
1227 }
1228 }
1229 break;
1230 }
1231
1232 default:
1233 if (!(MIPSInst_RS(ir) & 0x10))
1234 return SIGILL;
1235 {
1236 int sig;
1237
1238 /* a real fpu computation instruction */
1239 if ((sig = fpu_emu(xcp, ctx, ir)))
1240 return sig;
1241 }
1242 }
1243 break;
1244
1245#if __mips >= 4 && __mips != 32
1246 case cop1x_op:{
515b029d
DD
1247 int sig = fpux_emu(xcp, ctx, ir, fault_addr);
1248 if (sig)
1da177e4
LT
1249 return sig;
1250 break;
1251 }
1252#endif
1253
1254#if __mips >= 4
1255 case spec_op:
1256 if (MIPSInst_FUNC(ir) != movc_op)
1257 return SIGILL;
1258 cond = fpucondbit[MIPSInst_RT(ir) >> 2];
1259 if (((ctx->fcr31 & cond) != 0) == ((MIPSInst_RT(ir) & 1) != 0))
1260 xcp->regs[MIPSInst_RD(ir)] =
1261 xcp->regs[MIPSInst_RS(ir)];
1262 break;
1263#endif
1264
1265 default:
1266 return SIGILL;
1267 }
1268
1269 /* we did it !! */
e70dfc10 1270 xcp->cp0_epc = contpc;
1da177e4 1271 xcp->cp0_cause &= ~CAUSEF_BD;
333d1f67 1272
1da177e4
LT
1273 return 0;
1274}
1275
1276/*
1277 * Conversion table from MIPS compare ops 48-63
1278 * cond = ieee754dp_cmp(x,y,IEEE754_UN,sig);
1279 */
1280static const unsigned char cmptab[8] = {
1281 0, /* cmp_0 (sig) cmp_sf */
1282 IEEE754_CUN, /* cmp_un (sig) cmp_ngle */
1283 IEEE754_CEQ, /* cmp_eq (sig) cmp_seq */
1284 IEEE754_CEQ | IEEE754_CUN, /* cmp_ueq (sig) cmp_ngl */
1285 IEEE754_CLT, /* cmp_olt (sig) cmp_lt */
1286 IEEE754_CLT | IEEE754_CUN, /* cmp_ult (sig) cmp_nge */
1287 IEEE754_CLT | IEEE754_CEQ, /* cmp_ole (sig) cmp_le */
1288 IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */
1289};
1290
1291
1292#if __mips >= 4 && __mips != 32
1293
1294/*
1295 * Additional MIPS4 instructions
1296 */
1297
1298#define DEF3OP(name, p, f1, f2, f3) \
49a89efb 1299static ieee754##p fpemu_##p##_##name(ieee754##p r, ieee754##p s, \
1da177e4
LT
1300 ieee754##p t) \
1301{ \
cd21dfcf 1302 struct _ieee754_csr ieee754_csr_save; \
49a89efb 1303 s = f1(s, t); \
1da177e4 1304 ieee754_csr_save = ieee754_csr; \
49a89efb 1305 s = f2(s, r); \
1da177e4
LT
1306 ieee754_csr_save.cx |= ieee754_csr.cx; \
1307 ieee754_csr_save.sx |= ieee754_csr.sx; \
49a89efb 1308 s = f3(s); \
1da177e4
LT
1309 ieee754_csr.cx |= ieee754_csr_save.cx; \
1310 ieee754_csr.sx |= ieee754_csr_save.sx; \
1311 return s; \
1312}
1313
1314static ieee754dp fpemu_dp_recip(ieee754dp d)
1315{
1316 return ieee754dp_div(ieee754dp_one(0), d);
1317}
1318
1319static ieee754dp fpemu_dp_rsqrt(ieee754dp d)
1320{
1321 return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d));
1322}
1323
1324static ieee754sp fpemu_sp_recip(ieee754sp s)
1325{
1326 return ieee754sp_div(ieee754sp_one(0), s);
1327}
1328
1329static ieee754sp fpemu_sp_rsqrt(ieee754sp s)
1330{
1331 return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
1332}
1333
21a151d8
RB
1334DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add, );
1335DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub, );
1da177e4
LT
1336DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg);
1337DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg);
21a151d8
RB
1338DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add, );
1339DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub, );
1da177e4
LT
1340DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
1341DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
1342
eae89076 1343static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
515b029d 1344 mips_instruction ir, void *__user *fault_addr)
1da177e4
LT
1345{
1346 unsigned rcsr = 0; /* resulting csr */
1347
b6ee75ed 1348 MIPS_FPU_EMU_INC_STATS(cp1xops);
1da177e4
LT
1349
1350 switch (MIPSInst_FMA_FFMT(ir)) {
1351 case s_fmt:{ /* 0 */
1352
1353 ieee754sp(*handler) (ieee754sp, ieee754sp, ieee754sp);
1354 ieee754sp fd, fr, fs, ft;
3fccc015 1355 u32 __user *va;
1da177e4
LT
1356 u32 val;
1357
1358 switch (MIPSInst_FUNC(ir)) {
1359 case lwxc1_op:
3fccc015 1360 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1da177e4
LT
1361 xcp->regs[MIPSInst_FT(ir)]);
1362
b6ee75ed 1363 MIPS_FPU_EMU_INC_STATS(loads);
515b029d 1364 if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
b6ee75ed 1365 MIPS_FPU_EMU_INC_STATS(errors);
515b029d 1366 *fault_addr = va;
1da177e4
LT
1367 return SIGBUS;
1368 }
515b029d
DD
1369 if (__get_user(val, va)) {
1370 MIPS_FPU_EMU_INC_STATS(errors);
1371 *fault_addr = va;
1372 return SIGSEGV;
1373 }
1da177e4
LT
1374 SITOREG(val, MIPSInst_FD(ir));
1375 break;
1376
1377 case swxc1_op:
3fccc015 1378 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1da177e4
LT
1379 xcp->regs[MIPSInst_FT(ir)]);
1380
b6ee75ed 1381 MIPS_FPU_EMU_INC_STATS(stores);
1da177e4
LT
1382
1383 SIFROMREG(val, MIPSInst_FS(ir));
515b029d 1384 if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
b6ee75ed 1385 MIPS_FPU_EMU_INC_STATS(errors);
515b029d 1386 *fault_addr = va;
1da177e4
LT
1387 return SIGBUS;
1388 }
515b029d
DD
1389 if (put_user(val, va)) {
1390 MIPS_FPU_EMU_INC_STATS(errors);
1391 *fault_addr = va;
1392 return SIGSEGV;
1393 }
1da177e4
LT
1394 break;
1395
1396 case madd_s_op:
1397 handler = fpemu_sp_madd;
1398 goto scoptop;
1399 case msub_s_op:
1400 handler = fpemu_sp_msub;
1401 goto scoptop;
1402 case nmadd_s_op:
1403 handler = fpemu_sp_nmadd;
1404 goto scoptop;
1405 case nmsub_s_op:
1406 handler = fpemu_sp_nmsub;
1407 goto scoptop;
1408
1409 scoptop:
1410 SPFROMREG(fr, MIPSInst_FR(ir));
1411 SPFROMREG(fs, MIPSInst_FS(ir));
1412 SPFROMREG(ft, MIPSInst_FT(ir));
1413 fd = (*handler) (fr, fs, ft);
1414 SPTOREG(fd, MIPSInst_FD(ir));
1415
1416 copcsr:
1417 if (ieee754_cxtest(IEEE754_INEXACT))
1418 rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
1419 if (ieee754_cxtest(IEEE754_UNDERFLOW))
1420 rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
1421 if (ieee754_cxtest(IEEE754_OVERFLOW))
1422 rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
1423 if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
1424 rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
1425
1426 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
1da177e4
LT
1427 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1428 /*printk ("SIGFPE: fpu csr = %08x\n",
1429 ctx->fcr31); */
1430 return SIGFPE;
1431 }
1432
1433 break;
1434
1435 default:
1436 return SIGILL;
1437 }
1438 break;
1439 }
1440
1da177e4
LT
1441 case d_fmt:{ /* 1 */
1442 ieee754dp(*handler) (ieee754dp, ieee754dp, ieee754dp);
1443 ieee754dp fd, fr, fs, ft;
3fccc015 1444 u64 __user *va;
1da177e4
LT
1445 u64 val;
1446
1447 switch (MIPSInst_FUNC(ir)) {
1448 case ldxc1_op:
3fccc015 1449 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1da177e4
LT
1450 xcp->regs[MIPSInst_FT(ir)]);
1451
b6ee75ed 1452 MIPS_FPU_EMU_INC_STATS(loads);
515b029d 1453 if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
b6ee75ed 1454 MIPS_FPU_EMU_INC_STATS(errors);
515b029d 1455 *fault_addr = va;
1da177e4
LT
1456 return SIGBUS;
1457 }
515b029d
DD
1458 if (__get_user(val, va)) {
1459 MIPS_FPU_EMU_INC_STATS(errors);
1460 *fault_addr = va;
1461 return SIGSEGV;
1462 }
1da177e4
LT
1463 DITOREG(val, MIPSInst_FD(ir));
1464 break;
1465
1466 case sdxc1_op:
3fccc015 1467 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1da177e4
LT
1468 xcp->regs[MIPSInst_FT(ir)]);
1469
b6ee75ed 1470 MIPS_FPU_EMU_INC_STATS(stores);
1da177e4 1471 DIFROMREG(val, MIPSInst_FS(ir));
515b029d 1472 if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
b6ee75ed 1473 MIPS_FPU_EMU_INC_STATS(errors);
515b029d 1474 *fault_addr = va;
1da177e4
LT
1475 return SIGBUS;
1476 }
515b029d
DD
1477 if (__put_user(val, va)) {
1478 MIPS_FPU_EMU_INC_STATS(errors);
1479 *fault_addr = va;
1480 return SIGSEGV;
1481 }
1da177e4
LT
1482 break;
1483
1484 case madd_d_op:
1485 handler = fpemu_dp_madd;
1486 goto dcoptop;
1487 case msub_d_op:
1488 handler = fpemu_dp_msub;
1489 goto dcoptop;
1490 case nmadd_d_op:
1491 handler = fpemu_dp_nmadd;
1492 goto dcoptop;
1493 case nmsub_d_op:
1494 handler = fpemu_dp_nmsub;
1495 goto dcoptop;
1496
1497 dcoptop:
1498 DPFROMREG(fr, MIPSInst_FR(ir));
1499 DPFROMREG(fs, MIPSInst_FS(ir));
1500 DPFROMREG(ft, MIPSInst_FT(ir));
1501 fd = (*handler) (fr, fs, ft);
1502 DPTOREG(fd, MIPSInst_FD(ir));
1503 goto copcsr;
1504
1505 default:
1506 return SIGILL;
1507 }
1508 break;
1509 }
1da177e4
LT
1510
1511 case 0x7: /* 7 */
1512 if (MIPSInst_FUNC(ir) != pfetch_op) {
1513 return SIGILL;
1514 }
1515 /* ignore prefx operation */
1516 break;
1517
1518 default:
1519 return SIGILL;
1520 }
1521
1522 return 0;
1523}
1524#endif
1525
1526
1527
1528/*
1529 * Emulate a single COP1 arithmetic instruction.
1530 */
eae89076 1531static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1da177e4
LT
1532 mips_instruction ir)
1533{
1534 int rfmt; /* resulting format */
1535 unsigned rcsr = 0; /* resulting csr */
1536 unsigned cond;
1537 union {
1538 ieee754dp d;
1539 ieee754sp s;
1540 int w;
766160c2 1541#ifdef __mips64
1da177e4
LT
1542 s64 l;
1543#endif
1544 } rv; /* resulting value */
1545
b6ee75ed 1546 MIPS_FPU_EMU_INC_STATS(cp1ops);
1da177e4
LT
1547 switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
1548 case s_fmt:{ /* 0 */
1549 union {
1550 ieee754sp(*b) (ieee754sp, ieee754sp);
1551 ieee754sp(*u) (ieee754sp);
1552 } handler;
1553
1554 switch (MIPSInst_FUNC(ir)) {
1555 /* binary ops */
1556 case fadd_op:
1557 handler.b = ieee754sp_add;
1558 goto scopbop;
1559 case fsub_op:
1560 handler.b = ieee754sp_sub;
1561 goto scopbop;
1562 case fmul_op:
1563 handler.b = ieee754sp_mul;
1564 goto scopbop;
1565 case fdiv_op:
1566 handler.b = ieee754sp_div;
1567 goto scopbop;
1568
1569 /* unary ops */
587cb98f 1570#if __mips >= 2 || defined(__mips64)
1da177e4
LT
1571 case fsqrt_op:
1572 handler.u = ieee754sp_sqrt;
1573 goto scopuop;
1574#endif
1575#if __mips >= 4 && __mips != 32
1576 case frsqrt_op:
1577 handler.u = fpemu_sp_rsqrt;
1578 goto scopuop;
1579 case frecip_op:
1580 handler.u = fpemu_sp_recip;
1581 goto scopuop;
1582#endif
1583#if __mips >= 4
1584 case fmovc_op:
1585 cond = fpucondbit[MIPSInst_FT(ir) >> 2];
1586 if (((ctx->fcr31 & cond) != 0) !=
1587 ((MIPSInst_FT(ir) & 1) != 0))
1588 return 0;
1589 SPFROMREG(rv.s, MIPSInst_FS(ir));
1590 break;
1591 case fmovz_op:
1592 if (xcp->regs[MIPSInst_FT(ir)] != 0)
1593 return 0;
1594 SPFROMREG(rv.s, MIPSInst_FS(ir));
1595 break;
1596 case fmovn_op:
1597 if (xcp->regs[MIPSInst_FT(ir)] == 0)
1598 return 0;
1599 SPFROMREG(rv.s, MIPSInst_FS(ir));
1600 break;
1601#endif
1602 case fabs_op:
1603 handler.u = ieee754sp_abs;
1604 goto scopuop;
1605 case fneg_op:
1606 handler.u = ieee754sp_neg;
1607 goto scopuop;
1608 case fmov_op:
1609 /* an easy one */
1610 SPFROMREG(rv.s, MIPSInst_FS(ir));
1611 goto copcsr;
1612
1613 /* binary op on handler */
1614 scopbop:
1615 {
1616 ieee754sp fs, ft;
1617
1618 SPFROMREG(fs, MIPSInst_FS(ir));
1619 SPFROMREG(ft, MIPSInst_FT(ir));
1620
1621 rv.s = (*handler.b) (fs, ft);
1622 goto copcsr;
1623 }
1624 scopuop:
1625 {
1626 ieee754sp fs;
1627
1628 SPFROMREG(fs, MIPSInst_FS(ir));
1629 rv.s = (*handler.u) (fs);
1630 goto copcsr;
1631 }
1632 copcsr:
1633 if (ieee754_cxtest(IEEE754_INEXACT))
1634 rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
1635 if (ieee754_cxtest(IEEE754_UNDERFLOW))
1636 rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
1637 if (ieee754_cxtest(IEEE754_OVERFLOW))
1638 rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
1639 if (ieee754_cxtest(IEEE754_ZERO_DIVIDE))
1640 rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
1641 if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
1642 rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
1643 break;
1644
1645 /* unary conv ops */
1646 case fcvts_op:
1647 return SIGILL; /* not defined */
1648 case fcvtd_op:{
1da177e4
LT
1649 ieee754sp fs;
1650
1651 SPFROMREG(fs, MIPSInst_FS(ir));
1652 rv.d = ieee754dp_fsp(fs);
1653 rfmt = d_fmt;
1654 goto copcsr;
1655 }
1da177e4
LT
1656 case fcvtw_op:{
1657 ieee754sp fs;
1658
1659 SPFROMREG(fs, MIPSInst_FS(ir));
1660 rv.w = ieee754sp_tint(fs);
1661 rfmt = w_fmt;
1662 goto copcsr;
1663 }
1664
587cb98f 1665#if __mips >= 2 || defined(__mips64)
1da177e4
LT
1666 case fround_op:
1667 case ftrunc_op:
1668 case fceil_op:
1669 case ffloor_op:{
1670 unsigned int oldrm = ieee754_csr.rm;
1671 ieee754sp fs;
1672
1673 SPFROMREG(fs, MIPSInst_FS(ir));
3f135530 1674 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
1da177e4
LT
1675 rv.w = ieee754sp_tint(fs);
1676 ieee754_csr.rm = oldrm;
1677 rfmt = w_fmt;
1678 goto copcsr;
1679 }
1680#endif /* __mips >= 2 */
1681
4b724efd 1682#if defined(__mips64)
1da177e4
LT
1683 case fcvtl_op:{
1684 ieee754sp fs;
1685
1686 SPFROMREG(fs, MIPSInst_FS(ir));
1687 rv.l = ieee754sp_tlong(fs);
1688 rfmt = l_fmt;
1689 goto copcsr;
1690 }
1691
1692 case froundl_op:
1693 case ftruncl_op:
1694 case fceill_op:
1695 case ffloorl_op:{
1696 unsigned int oldrm = ieee754_csr.rm;
1697 ieee754sp fs;
1698
1699 SPFROMREG(fs, MIPSInst_FS(ir));
3f135530 1700 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
1da177e4
LT
1701 rv.l = ieee754sp_tlong(fs);
1702 ieee754_csr.rm = oldrm;
1703 rfmt = l_fmt;
1704 goto copcsr;
1705 }
4b724efd 1706#endif /* defined(__mips64) */
1da177e4
LT
1707
1708 default:
1709 if (MIPSInst_FUNC(ir) >= fcmp_op) {
1710 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
1711 ieee754sp fs, ft;
1712
1713 SPFROMREG(fs, MIPSInst_FS(ir));
1714 SPFROMREG(ft, MIPSInst_FT(ir));
1715 rv.w = ieee754sp_cmp(fs, ft,
1716 cmptab[cmpop & 0x7], cmpop & 0x8);
1717 rfmt = -1;
1718 if ((cmpop & 0x8) && ieee754_cxtest
1719 (IEEE754_INVALID_OPERATION))
1720 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
1721 else
1722 goto copcsr;
1723
1724 }
1725 else {
1726 return SIGILL;
1727 }
1728 break;
1729 }
1730 break;
1731 }
1732
1da177e4
LT
1733 case d_fmt:{
1734 union {
1735 ieee754dp(*b) (ieee754dp, ieee754dp);
1736 ieee754dp(*u) (ieee754dp);
1737 } handler;
1738
1739 switch (MIPSInst_FUNC(ir)) {
1740 /* binary ops */
1741 case fadd_op:
1742 handler.b = ieee754dp_add;
1743 goto dcopbop;
1744 case fsub_op:
1745 handler.b = ieee754dp_sub;
1746 goto dcopbop;
1747 case fmul_op:
1748 handler.b = ieee754dp_mul;
1749 goto dcopbop;
1750 case fdiv_op:
1751 handler.b = ieee754dp_div;
1752 goto dcopbop;
1753
1754 /* unary ops */
587cb98f 1755#if __mips >= 2 || defined(__mips64)
1da177e4
LT
1756 case fsqrt_op:
1757 handler.u = ieee754dp_sqrt;
1758 goto dcopuop;
1759#endif
1760#if __mips >= 4 && __mips != 32
1761 case frsqrt_op:
1762 handler.u = fpemu_dp_rsqrt;
1763 goto dcopuop;
1764 case frecip_op:
1765 handler.u = fpemu_dp_recip;
1766 goto dcopuop;
1767#endif
1768#if __mips >= 4
1769 case fmovc_op:
1770 cond = fpucondbit[MIPSInst_FT(ir) >> 2];
1771 if (((ctx->fcr31 & cond) != 0) !=
1772 ((MIPSInst_FT(ir) & 1) != 0))
1773 return 0;
1774 DPFROMREG(rv.d, MIPSInst_FS(ir));
1775 break;
1776 case fmovz_op:
1777 if (xcp->regs[MIPSInst_FT(ir)] != 0)
1778 return 0;
1779 DPFROMREG(rv.d, MIPSInst_FS(ir));
1780 break;
1781 case fmovn_op:
1782 if (xcp->regs[MIPSInst_FT(ir)] == 0)
1783 return 0;
1784 DPFROMREG(rv.d, MIPSInst_FS(ir));
1785 break;
1786#endif
1787 case fabs_op:
1788 handler.u = ieee754dp_abs;
1789 goto dcopuop;
1790
1791 case fneg_op:
1792 handler.u = ieee754dp_neg;
1793 goto dcopuop;
1794
1795 case fmov_op:
1796 /* an easy one */
1797 DPFROMREG(rv.d, MIPSInst_FS(ir));
1798 goto copcsr;
1799
1800 /* binary op on handler */
1801 dcopbop:{
1802 ieee754dp fs, ft;
1803
1804 DPFROMREG(fs, MIPSInst_FS(ir));
1805 DPFROMREG(ft, MIPSInst_FT(ir));
1806
1807 rv.d = (*handler.b) (fs, ft);
1808 goto copcsr;
1809 }
1810 dcopuop:{
1811 ieee754dp fs;
1812
1813 DPFROMREG(fs, MIPSInst_FS(ir));
1814 rv.d = (*handler.u) (fs);
1815 goto copcsr;
1816 }
1817
1818 /* unary conv ops */
1819 case fcvts_op:{
1820 ieee754dp fs;
1821
1822 DPFROMREG(fs, MIPSInst_FS(ir));
1823 rv.s = ieee754sp_fdp(fs);
1824 rfmt = s_fmt;
1825 goto copcsr;
1826 }
1827 case fcvtd_op:
1828 return SIGILL; /* not defined */
1829
1830 case fcvtw_op:{
1831 ieee754dp fs;
1832
1833 DPFROMREG(fs, MIPSInst_FS(ir));
1834 rv.w = ieee754dp_tint(fs); /* wrong */
1835 rfmt = w_fmt;
1836 goto copcsr;
1837 }
1838
587cb98f 1839#if __mips >= 2 || defined(__mips64)
1da177e4
LT
1840 case fround_op:
1841 case ftrunc_op:
1842 case fceil_op:
1843 case ffloor_op:{
1844 unsigned int oldrm = ieee754_csr.rm;
1845 ieee754dp fs;
1846
1847 DPFROMREG(fs, MIPSInst_FS(ir));
3f135530 1848 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
1da177e4
LT
1849 rv.w = ieee754dp_tint(fs);
1850 ieee754_csr.rm = oldrm;
1851 rfmt = w_fmt;
1852 goto copcsr;
1853 }
1854#endif
1855
4b724efd 1856#if defined(__mips64)
1da177e4
LT
1857 case fcvtl_op:{
1858 ieee754dp fs;
1859
1860 DPFROMREG(fs, MIPSInst_FS(ir));
1861 rv.l = ieee754dp_tlong(fs);
1862 rfmt = l_fmt;
1863 goto copcsr;
1864 }
1865
1866 case froundl_op:
1867 case ftruncl_op:
1868 case fceill_op:
1869 case ffloorl_op:{
1870 unsigned int oldrm = ieee754_csr.rm;
1871 ieee754dp fs;
1872
1873 DPFROMREG(fs, MIPSInst_FS(ir));
3f135530 1874 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
1da177e4
LT
1875 rv.l = ieee754dp_tlong(fs);
1876 ieee754_csr.rm = oldrm;
1877 rfmt = l_fmt;
1878 goto copcsr;
1879 }
4b724efd 1880#endif /* __mips >= 3 */
1da177e4
LT
1881
1882 default:
1883 if (MIPSInst_FUNC(ir) >= fcmp_op) {
1884 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
1885 ieee754dp fs, ft;
1886
1887 DPFROMREG(fs, MIPSInst_FS(ir));
1888 DPFROMREG(ft, MIPSInst_FT(ir));
1889 rv.w = ieee754dp_cmp(fs, ft,
1890 cmptab[cmpop & 0x7], cmpop & 0x8);
1891 rfmt = -1;
1892 if ((cmpop & 0x8)
1893 &&
1894 ieee754_cxtest
1895 (IEEE754_INVALID_OPERATION))
1896 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
1897 else
1898 goto copcsr;
1899
1900 }
1901 else {
1902 return SIGILL;
1903 }
1904 break;
1905 }
1906 break;
1907 }
1da177e4
LT
1908
1909 case w_fmt:{
1910 ieee754sp fs;
1911
1912 switch (MIPSInst_FUNC(ir)) {
1913 case fcvts_op:
1914 /* convert word to single precision real */
1915 SPFROMREG(fs, MIPSInst_FS(ir));
1916 rv.s = ieee754sp_fint(fs.bits);
1917 rfmt = s_fmt;
1918 goto copcsr;
1da177e4
LT
1919 case fcvtd_op:
1920 /* convert word to double precision real */
1921 SPFROMREG(fs, MIPSInst_FS(ir));
1922 rv.d = ieee754dp_fint(fs.bits);
1923 rfmt = d_fmt;
1924 goto copcsr;
1da177e4
LT
1925 default:
1926 return SIGILL;
1927 }
1928 break;
1929 }
1930
4b724efd 1931#if defined(__mips64)
1da177e4
LT
1932 case l_fmt:{
1933 switch (MIPSInst_FUNC(ir)) {
1934 case fcvts_op:
1935 /* convert long to single precision real */
1936 rv.s = ieee754sp_flong(ctx->fpr[MIPSInst_FS(ir)]);
1937 rfmt = s_fmt;
1938 goto copcsr;
1939 case fcvtd_op:
1940 /* convert long to double precision real */
1941 rv.d = ieee754dp_flong(ctx->fpr[MIPSInst_FS(ir)]);
1942 rfmt = d_fmt;
1943 goto copcsr;
1944 default:
1945 return SIGILL;
1946 }
1947 break;
1948 }
1949#endif
1950
1951 default:
1952 return SIGILL;
1953 }
1954
1955 /*
1956 * Update the fpu CSR register for this operation.
1957 * If an exception is required, generate a tidy SIGFPE exception,
1958 * without updating the result register.
1959 * Note: cause exception bits do not accumulate, they are rewritten
1960 * for each op; only the flag/sticky bits accumulate.
1961 */
1962 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
1963 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1964 /*printk ("SIGFPE: fpu csr = %08x\n",ctx->fcr31); */
1965 return SIGFPE;
1966 }
1967
1968 /*
1969 * Now we can safely write the result back to the register file.
1970 */
1971 switch (rfmt) {
1972 case -1:{
1973#if __mips >= 4
1974 cond = fpucondbit[MIPSInst_FD(ir) >> 2];
1975#else
1976 cond = FPU_CSR_COND;
1977#endif
1978 if (rv.w)
1979 ctx->fcr31 |= cond;
1980 else
1981 ctx->fcr31 &= ~cond;
1982 break;
1983 }
1da177e4
LT
1984 case d_fmt:
1985 DPTOREG(rv.d, MIPSInst_FD(ir));
1986 break;
1da177e4
LT
1987 case s_fmt:
1988 SPTOREG(rv.s, MIPSInst_FD(ir));
1989 break;
1990 case w_fmt:
1991 SITOREG(rv.w, MIPSInst_FD(ir));
1992 break;
4b724efd 1993#if defined(__mips64)
1da177e4
LT
1994 case l_fmt:
1995 DITOREG(rv.l, MIPSInst_FD(ir));
1996 break;
1997#endif
1998 default:
1999 return SIGILL;
2000 }
2001
2002 return 0;
2003}
2004
4748ac3f
MR
2005/*
2006 * Emulate FPU instructions.
2007 *
2008 * If we use FPU hardware, then we have been typically called to handle
2009 * an unimplemented operation, such as where an operand is a NaN or
2010 * denormalized. In that case exit the emulation loop after a single
2011 * iteration so as to let hardware execute any subsequent instructions.
2012 *
2013 * If we have no FPU hardware or it has been disabled, then continue
2014 * emulating floating-point instructions until one of these conditions
2015 * has occurred:
2016 *
2017 * - a non-FPU instruction has been encountered,
2018 *
2019 * - an attempt to emulate has ended with a signal,
2020 *
2021 * - the ISA mode has been switched.
2022 *
2023 * We need to terminate the emulation loop if we got switched to the
2024 * MIPS16 mode, whether supported or not, so that we do not attempt
2025 * to emulate a MIPS16 instruction as a regular MIPS FPU instruction.
2026 * Similarly if we got switched to the microMIPS mode and only the
2027 * regular MIPS mode is supported, so that we do not attempt to emulate
2028 * a microMIPS instruction as a regular MIPS FPU instruction. Or if
2029 * we got switched to the regular MIPS mode and only the microMIPS mode
2030 * is supported, so that we do not attempt to emulate a regular MIPS
2031 * instruction that should cause an Address Error exception instead.
2032 * For simplicity we always terminate upon an ISA mode switch.
2033 */
e04582b7 2034int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
515b029d 2035 int has_fpu, void *__user *fault_addr)
1da177e4 2036{
333d1f67 2037 unsigned long oldepc, prevepc;
102cedc3
LY
2038 struct mm_decoded_insn dec_insn;
2039 u16 instr[4];
2040 u16 *instr_ptr;
1da177e4
LT
2041 int sig = 0;
2042
2043 oldepc = xcp->cp0_epc;
2044 do {
2045 prevepc = xcp->cp0_epc;
2046
102cedc3
LY
2047 if (get_isa16_mode(prevepc) && cpu_has_mmips) {
2048 /*
2049 * Get next 2 microMIPS instructions and convert them
2050 * into 32-bit instructions.
2051 */
2052 if ((get_user(instr[0], (u16 __user *)msk_isa16_mode(xcp->cp0_epc))) ||
2053 (get_user(instr[1], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 2))) ||
2054 (get_user(instr[2], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 4))) ||
2055 (get_user(instr[3], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 6)))) {
2056 MIPS_FPU_EMU_INC_STATS(errors);
2057 return SIGBUS;
2058 }
2059 instr_ptr = instr;
2060
2061 /* Get first instruction. */
2062 if (mm_insn_16bit(*instr_ptr)) {
2063 /* Duplicate the half-word. */
2064 dec_insn.insn = (*instr_ptr << 16) |
2065 (*instr_ptr);
2066 /* 16-bit instruction. */
2067 dec_insn.pc_inc = 2;
2068 instr_ptr += 1;
2069 } else {
2070 dec_insn.insn = (*instr_ptr << 16) |
2071 *(instr_ptr+1);
2072 /* 32-bit instruction. */
2073 dec_insn.pc_inc = 4;
2074 instr_ptr += 2;
2075 }
2076 /* Get second instruction. */
2077 if (mm_insn_16bit(*instr_ptr)) {
2078 /* Duplicate the half-word. */
2079 dec_insn.next_insn = (*instr_ptr << 16) |
2080 (*instr_ptr);
2081 /* 16-bit instruction. */
2082 dec_insn.next_pc_inc = 2;
2083 } else {
2084 dec_insn.next_insn = (*instr_ptr << 16) |
2085 *(instr_ptr+1);
2086 /* 32-bit instruction. */
2087 dec_insn.next_pc_inc = 4;
2088 }
2089 dec_insn.micro_mips_mode = 1;
2090 } else {
2091 if ((get_user(dec_insn.insn,
2092 (mips_instruction __user *) xcp->cp0_epc)) ||
2093 (get_user(dec_insn.next_insn,
2094 (mips_instruction __user *)(xcp->cp0_epc+4)))) {
2095 MIPS_FPU_EMU_INC_STATS(errors);
2096 return SIGBUS;
2097 }
2098 dec_insn.pc_inc = 4;
2099 dec_insn.next_pc_inc = 4;
2100 dec_insn.micro_mips_mode = 0;
515b029d 2101 }
102cedc3
LY
2102
2103 if ((dec_insn.insn == 0) ||
2104 ((dec_insn.pc_inc == 2) &&
2105 ((dec_insn.insn & 0xffff) == MM_NOP16)))
2106 xcp->cp0_epc += dec_insn.pc_inc; /* Skip NOPs */
1da177e4 2107 else {
cd21dfcf
RB
2108 /*
2109 * The 'ieee754_csr' is an alias of
70342287
RB
2110 * ctx->fcr31. No need to copy ctx->fcr31 to
2111 * ieee754_csr. But ieee754_csr.rm is ieee
cd21dfcf
RB
2112 * library modes. (not mips rounding mode)
2113 */
2114 /* convert to ieee library modes */
2115 ieee754_csr.rm = ieee_rm[ieee754_csr.rm];
102cedc3 2116 sig = cop1Emulate(xcp, ctx, dec_insn, fault_addr);
cd21dfcf
RB
2117 /* revert to mips rounding mode */
2118 ieee754_csr.rm = mips_rm[ieee754_csr.rm];
1da177e4
LT
2119 }
2120
e04582b7 2121 if (has_fpu)
1da177e4
LT
2122 break;
2123 if (sig)
2124 break;
4748ac3f
MR
2125 /*
2126 * We have to check for the ISA bit explicitly here,
2127 * because `get_isa16_mode' may return 0 if support
2128 * for code compression has been globally disabled,
2129 * or otherwise we may produce the wrong signal or
2130 * even proceed successfully where we must not.
2131 */
2132 if ((xcp->cp0_epc ^ prevepc) & 0x1)
2133 break;
1da177e4
LT
2134
2135 cond_resched();
2136 } while (xcp->cp0_epc > prevepc);
2137
2138 /* SIGILL indicates a non-fpu instruction */
2139 if (sig == SIGILL && xcp->cp0_epc != oldepc)
2140 /* but if epc has advanced, then ignore it */
2141 sig = 0;
2142
2143 return sig;
2144}
83fd38ca
AN
2145
2146#ifdef CONFIG_DEBUG_FS
b6ee75ed
DD
2147
2148static int fpuemu_stat_get(void *data, u64 *val)
2149{
2150 int cpu;
2151 unsigned long sum = 0;
2152 for_each_online_cpu(cpu) {
2153 struct mips_fpu_emulator_stats *ps;
2154 local_t *pv;
2155 ps = &per_cpu(fpuemustats, cpu);
2156 pv = (void *)ps + (unsigned long)data;
2157 sum += local_read(pv);
2158 }
2159 *val = sum;
2160 return 0;
2161}
2162DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n");
2163
83fd38ca
AN
2164extern struct dentry *mips_debugfs_dir;
2165static int __init debugfs_fpuemu(void)
2166{
2167 struct dentry *d, *dir;
83fd38ca
AN
2168
2169 if (!mips_debugfs_dir)
2170 return -ENODEV;
2171 dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir);
ecab1f44
Z
2172 if (!dir)
2173 return -ENOMEM;
b6ee75ed
DD
2174
2175#define FPU_STAT_CREATE(M) \
2176 do { \
2177 d = debugfs_create_file(#M , S_IRUGO, dir, \
2178 (void *)offsetof(struct mips_fpu_emulator_stats, M), \
2179 &fops_fpuemu_stat); \
2180 if (!d) \
2181 return -ENOMEM; \
2182 } while (0)
2183
2184 FPU_STAT_CREATE(emulated);
2185 FPU_STAT_CREATE(loads);
2186 FPU_STAT_CREATE(stores);
2187 FPU_STAT_CREATE(cp1ops);
2188 FPU_STAT_CREATE(cp1xops);
2189 FPU_STAT_CREATE(errors);
2190
83fd38ca
AN
2191 return 0;
2192}
2193__initcall(debugfs_fpuemu);
2194#endif