Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/math-emu/cp1emu.c
26439 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* cp1emu.c: a MIPS coprocessor 1 (FPU) instruction emulator
4
*
5
* MIPS floating point support
6
* Copyright (C) 1994-2000 Algorithmics Ltd.
7
*
8
* Kevin D. Kissell, [email protected] and Carsten Langgaard, [email protected]
9
* Copyright (C) 2000 MIPS Technologies, Inc.
10
*
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
16
* the hardware FPU at the boundaries of the IEEE-754 representation
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
*
21
* Note if you know that you won't have an FPU, then you'll get much
22
* better performance by compiling with -msoft-float!
23
*/
24
#include <linux/sched.h>
25
#include <linux/debugfs.h>
26
#include <linux/percpu-defs.h>
27
#include <linux/perf_event.h>
28
29
#include <asm/branch.h>
30
#include <asm/inst.h>
31
#include <asm/ptrace.h>
32
#include <asm/signal.h>
33
#include <linux/uaccess.h>
34
35
#include <asm/cpu-info.h>
36
#include <asm/processor.h>
37
#include <asm/fpu_emulator.h>
38
#include <asm/fpu.h>
39
#include <asm/mips-r2-to-r6-emul.h>
40
41
#include "ieee754.h"
42
43
/* Function which emulates a floating point instruction. */
44
45
static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
46
mips_instruction);
47
48
static int fpux_emu(struct pt_regs *,
49
struct mips_fpu_struct *, mips_instruction, void __user **);
50
51
/* Control registers */
52
53
#define FPCREG_RID 0 /* $0 = revision id */
54
#define FPCREG_FCCR 25 /* $25 = fccr */
55
#define FPCREG_FEXR 26 /* $26 = fexr */
56
#define FPCREG_FENR 28 /* $28 = fenr */
57
#define FPCREG_CSR 31 /* $31 = csr */
58
59
/* convert condition code register number to csr bit */
60
const unsigned int fpucondbit[8] = {
61
FPU_CSR_COND,
62
FPU_CSR_COND1,
63
FPU_CSR_COND2,
64
FPU_CSR_COND3,
65
FPU_CSR_COND4,
66
FPU_CSR_COND5,
67
FPU_CSR_COND6,
68
FPU_CSR_COND7
69
};
70
71
/* (microMIPS) Convert certain microMIPS instructions to MIPS32 format. */
72
static const int sd_format[] = {16, 17, 0, 0, 0, 0, 0, 0};
73
static const int sdps_format[] = {16, 17, 22, 0, 0, 0, 0, 0};
74
static const int dwl_format[] = {17, 20, 21, 0, 0, 0, 0, 0};
75
static 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
*/
82
static 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:
369
case mm_mfhc1_op:
370
case mm_mthc1_op:
371
if (insn.mm_fp1_format.op == mm_mfc1_op)
372
op = mfc_op;
373
else if (insn.mm_fp1_format.op == mm_mtc1_op)
374
op = mtc_op;
375
else if (insn.mm_fp1_format.op == mm_cfc1_op)
376
op = cfc_op;
377
else if (insn.mm_fp1_format.op == mm_ctc1_op)
378
op = ctc_op;
379
else if (insn.mm_fp1_format.op == mm_mfhc1_op)
380
op = mfhc_op;
381
else
382
op = mthc_op;
383
mips32_insn.fp1_format.opcode = cop1_op;
384
mips32_insn.fp1_format.op = op;
385
mips32_insn.fp1_format.rt =
386
insn.mm_fp1_format.rt;
387
mips32_insn.fp1_format.fs =
388
insn.mm_fp1_format.fs;
389
mips32_insn.fp1_format.fd = 0;
390
mips32_insn.fp1_format.func = 0;
391
break;
392
default:
393
return SIGILL;
394
}
395
break;
396
case mm_32f_74_op: /* 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;
408
}
409
break;
410
default:
411
return SIGILL;
412
}
413
414
*insn_ptr = mips32_insn;
415
return 0;
416
}
417
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
*/
424
int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
425
unsigned long *contpc)
426
{
427
union mips_instruction insn = (union mips_instruction)dec_insn.insn;
428
unsigned int fcr31;
429
unsigned int bit = 0;
430
unsigned int bit0;
431
union fpureg *fpr;
432
433
switch (insn.i_format.opcode) {
434
case spec_op:
435
switch (insn.r_format.func) {
436
case jalr_op:
437
if (insn.r_format.rd != 0) {
438
regs->regs[insn.r_format.rd] =
439
regs->cp0_epc + dec_insn.pc_inc +
440
dec_insn.next_pc_inc;
441
}
442
fallthrough;
443
case jr_op:
444
/* For R6, JR already emulated in jalr_op */
445
if (NO_R6EMU && insn.r_format.func == jr_op)
446
break;
447
*contpc = regs->regs[insn.r_format.rs];
448
return 1;
449
}
450
break;
451
case bcond_op:
452
switch (insn.i_format.rt) {
453
case bltzal_op:
454
case bltzall_op:
455
if (NO_R6EMU && (insn.i_format.rs ||
456
insn.i_format.rt == bltzall_op))
457
break;
458
459
regs->regs[31] = regs->cp0_epc +
460
dec_insn.pc_inc +
461
dec_insn.next_pc_inc;
462
fallthrough;
463
case bltzl_op:
464
if (NO_R6EMU)
465
break;
466
fallthrough;
467
case bltz_op:
468
if ((long)regs->regs[insn.i_format.rs] < 0)
469
*contpc = regs->cp0_epc +
470
dec_insn.pc_inc +
471
(insn.i_format.simmediate << 2);
472
else
473
*contpc = regs->cp0_epc +
474
dec_insn.pc_inc +
475
dec_insn.next_pc_inc;
476
return 1;
477
case bgezal_op:
478
case bgezall_op:
479
if (NO_R6EMU && (insn.i_format.rs ||
480
insn.i_format.rt == bgezall_op))
481
break;
482
483
regs->regs[31] = regs->cp0_epc +
484
dec_insn.pc_inc +
485
dec_insn.next_pc_inc;
486
fallthrough;
487
case bgezl_op:
488
if (NO_R6EMU)
489
break;
490
fallthrough;
491
case bgez_op:
492
if ((long)regs->regs[insn.i_format.rs] >= 0)
493
*contpc = regs->cp0_epc +
494
dec_insn.pc_inc +
495
(insn.i_format.simmediate << 2);
496
else
497
*contpc = regs->cp0_epc +
498
dec_insn.pc_inc +
499
dec_insn.next_pc_inc;
500
return 1;
501
}
502
break;
503
case jalx_op:
504
set_isa16_mode(bit);
505
fallthrough;
506
case jal_op:
507
regs->regs[31] = regs->cp0_epc +
508
dec_insn.pc_inc +
509
dec_insn.next_pc_inc;
510
fallthrough;
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;
519
case beql_op:
520
if (NO_R6EMU)
521
break;
522
fallthrough;
523
case beq_op:
524
if (regs->regs[insn.i_format.rs] ==
525
regs->regs[insn.i_format.rt])
526
*contpc = regs->cp0_epc +
527
dec_insn.pc_inc +
528
(insn.i_format.simmediate << 2);
529
else
530
*contpc = regs->cp0_epc +
531
dec_insn.pc_inc +
532
dec_insn.next_pc_inc;
533
return 1;
534
case bnel_op:
535
if (NO_R6EMU)
536
break;
537
fallthrough;
538
case bne_op:
539
if (regs->regs[insn.i_format.rs] !=
540
regs->regs[insn.i_format.rt])
541
*contpc = regs->cp0_epc +
542
dec_insn.pc_inc +
543
(insn.i_format.simmediate << 2);
544
else
545
*contpc = regs->cp0_epc +
546
dec_insn.pc_inc +
547
dec_insn.next_pc_inc;
548
return 1;
549
case blezl_op:
550
if (!insn.i_format.rt && NO_R6EMU)
551
break;
552
fallthrough;
553
case blez_op:
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
}
578
if ((long)regs->regs[insn.i_format.rs] <= 0)
579
*contpc = regs->cp0_epc +
580
dec_insn.pc_inc +
581
(insn.i_format.simmediate << 2);
582
else
583
*contpc = regs->cp0_epc +
584
dec_insn.pc_inc +
585
dec_insn.next_pc_inc;
586
return 1;
587
case bgtzl_op:
588
if (!insn.i_format.rt && NO_R6EMU)
589
break;
590
fallthrough;
591
case bgtz_op:
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
617
if ((long)regs->regs[insn.i_format.rs] > 0)
618
*contpc = regs->cp0_epc +
619
dec_insn.pc_inc +
620
(insn.i_format.simmediate << 2);
621
else
622
*contpc = regs->cp0_epc +
623
dec_insn.pc_inc +
624
dec_insn.next_pc_inc;
625
return 1;
626
case pop10_op:
627
case pop30_op:
628
if (!cpu_has_mips_r6)
629
break;
630
if (insn.i_format.rt && !insn.i_format.rs)
631
regs->regs[31] = regs->cp0_epc + 4;
632
*contpc = regs->cp0_epc + dec_insn.pc_inc +
633
dec_insn.next_pc_inc;
634
635
return 1;
636
#ifdef CONFIG_CPU_CAVIUM_OCTEON
637
case lwc2_op: /* 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;
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
673
return 1;
674
case balc6_op:
675
if (!cpu_has_mips_r6)
676
break;
677
regs->regs[31] = regs->cp0_epc + 4;
678
*contpc = regs->cp0_epc + dec_insn.pc_inc +
679
dec_insn.next_pc_inc;
680
681
return 1;
682
case pop66_op:
683
if (!cpu_has_mips_r6)
684
break;
685
*contpc = regs->cp0_epc + dec_insn.pc_inc +
686
dec_insn.next_pc_inc;
687
688
return 1;
689
case pop76_op:
690
if (!cpu_has_mips_r6)
691
break;
692
if (!insn.i_format.rs)
693
regs->regs[31] = regs->cp0_epc + 4;
694
*contpc = regs->cp0_epc + dec_insn.pc_inc +
695
dec_insn.next_pc_inc;
696
697
return 1;
698
#endif
699
case cop0_op:
700
case cop1_op:
701
/* 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;
706
fpr = &current->thread.fpu.fpr[insn.i_format.rt];
707
bit0 = get_fpr32(fpr, 0) & 0x1;
708
switch (insn.i_format.rs) {
709
case bc1eqz_op:
710
bit = bit0 == 0;
711
break;
712
case bc1nez_op:
713
bit = bit0 != 0;
714
break;
715
}
716
if (bit)
717
*contpc = regs->cp0_epc +
718
dec_insn.pc_inc +
719
(insn.i_format.simmediate << 2);
720
else
721
*contpc = regs->cp0_epc +
722
dec_insn.pc_inc +
723
dec_insn.next_pc_inc;
724
725
return 1;
726
}
727
/* R2/R6 compatible cop1 instruction */
728
fallthrough;
729
case cop2_op:
730
case cop1x_op:
731
if (insn.i_format.rs == bc_op) {
732
preempt_disable();
733
if (is_fpu_owner())
734
fcr31 = read_32bit_cp1_register(CP1_STATUS);
735
else
736
fcr31 = current->thread.fpu.fcr31;
737
preempt_enable();
738
739
bit = (insn.i_format.rt >> 2);
740
bit += (bit != 0);
741
bit += 23;
742
switch (insn.i_format.rt & 3) {
743
case 0: /* 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;
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;
765
}
766
}
767
break;
768
}
769
return 0;
770
}
771
772
/*
773
* In the Linux kernel, we support selection of FPR format on the
774
* basis of the Status.FR bit. If an FPU is not present, the FR bit
775
* is hardwired to zero, which would imply a 32-bit FPU even for
776
* 64-bit CPUs so we rather look at TIF_32BIT_FPREGS.
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
780
* compatibility enabled and on 32-bit without 64-bit FPU support.
781
*/
782
static inline int cop1_64bit(struct pt_regs *xcp)
783
{
784
if (IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_MIPS32_O32))
785
return 1;
786
else if (IS_ENABLED(CONFIG_32BIT) &&
787
!IS_ENABLED(CONFIG_MIPS_O32_FP64_SUPPORT))
788
return 0;
789
790
return !test_thread_flag(TIF_32BIT_FPREGS);
791
}
792
793
static inline bool hybrid_fprs(void)
794
{
795
return test_thread_flag(TIF_HYBRID_FPREGS);
796
}
797
798
#define SIFROMREG(si, x) \
799
do { \
800
if (cop1_64bit(xcp) && !hybrid_fprs()) \
801
(si) = (int)get_fpr32(&ctx->fpr[x], 0); \
802
else \
803
(si) = (int)get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \
804
} while (0)
805
806
#define SITOREG(si, x) \
807
do { \
808
if (cop1_64bit(xcp) && !hybrid_fprs()) { \
809
unsigned int i; \
810
set_fpr32(&ctx->fpr[x], 0, si); \
811
for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \
812
set_fpr32(&ctx->fpr[x], i, 0); \
813
} else { \
814
set_fpr32(&ctx->fpr[(x) & ~1], (x) & 1, si); \
815
} \
816
} while (0)
817
818
#define SIFROMHREG(si, x) ((si) = (int)get_fpr32(&ctx->fpr[x], 1))
819
820
#define SITOHREG(si, x) \
821
do { \
822
unsigned int i; \
823
set_fpr32(&ctx->fpr[x], 1, si); \
824
for (i = 2; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \
825
set_fpr32(&ctx->fpr[x], i, 0); \
826
} while (0)
827
828
#define DIFROMREG(di, x) \
829
((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) ^ 1)], 0))
830
831
#define DITOREG(di, x) \
832
do { \
833
unsigned int fpr, i; \
834
fpr = (x) & ~(cop1_64bit(xcp) ^ 1); \
835
set_fpr64(&ctx->fpr[fpr], 0, di); \
836
for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val64); i++) \
837
set_fpr64(&ctx->fpr[fpr], i, 0); \
838
} while (0)
839
840
#define SPFROMREG(sp, x) SIFROMREG((sp).bits, x)
841
#define SPTOREG(sp, x) SITOREG((sp).bits, x)
842
#define DPFROMREG(dp, x) DIFROMREG((dp).bits, x)
843
#define DPTOREG(dp, x) DITOREG((dp).bits, x)
844
845
/*
846
* Emulate a CFC1 instruction.
847
*/
848
static inline void cop1_cfc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
849
mips_instruction ir)
850
{
851
u32 fcr31 = ctx->fcr31;
852
u32 value = 0;
853
854
switch (MIPSInst_RD(ir)) {
855
case FPCREG_CSR:
856
value = fcr31;
857
pr_debug("%p gpr[%d]<-csr=%08x\n",
858
(void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
859
break;
860
861
case FPCREG_FENR:
862
if (!cpu_has_mips_r)
863
break;
864
value = (fcr31 >> (FPU_CSR_FS_S - MIPS_FENR_FS_S)) &
865
MIPS_FENR_FS;
866
value |= fcr31 & (FPU_CSR_ALL_E | FPU_CSR_RM);
867
pr_debug("%p gpr[%d]<-enr=%08x\n",
868
(void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
869
break;
870
871
case FPCREG_FEXR:
872
if (!cpu_has_mips_r)
873
break;
874
value = fcr31 & (FPU_CSR_ALL_X | FPU_CSR_ALL_S);
875
pr_debug("%p gpr[%d]<-exr=%08x\n",
876
(void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
877
break;
878
879
case FPCREG_FCCR:
880
if (!cpu_has_mips_r)
881
break;
882
value = (fcr31 >> (FPU_CSR_COND_S - MIPS_FCCR_COND0_S)) &
883
MIPS_FCCR_COND0;
884
value |= (fcr31 >> (FPU_CSR_COND1_S - MIPS_FCCR_COND1_S)) &
885
(MIPS_FCCR_CONDX & ~MIPS_FCCR_COND0);
886
pr_debug("%p gpr[%d]<-ccr=%08x\n",
887
(void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
888
break;
889
890
case FPCREG_RID:
891
value = boot_cpu_data.fpu_id;
892
break;
893
894
default:
895
break;
896
}
897
898
if (MIPSInst_RT(ir))
899
xcp->regs[MIPSInst_RT(ir)] = value;
900
}
901
902
/*
903
* Emulate a CTC1 instruction.
904
*/
905
static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
906
mips_instruction ir)
907
{
908
u32 fcr31 = ctx->fcr31;
909
u32 value;
910
u32 mask;
911
912
if (MIPSInst_RT(ir) == 0)
913
value = 0;
914
else
915
value = xcp->regs[MIPSInst_RT(ir)];
916
917
switch (MIPSInst_RD(ir)) {
918
case FPCREG_CSR:
919
pr_debug("%p gpr[%d]->csr=%08x\n",
920
(void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
921
922
/* Preserve read-only bits. */
923
mask = boot_cpu_data.fpu_msk31;
924
fcr31 = (value & ~mask) | (fcr31 & mask);
925
break;
926
927
case FPCREG_FENR:
928
if (!cpu_has_mips_r)
929
break;
930
pr_debug("%p gpr[%d]->enr=%08x\n",
931
(void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
932
fcr31 &= ~(FPU_CSR_FS | FPU_CSR_ALL_E | FPU_CSR_RM);
933
fcr31 |= (value << (FPU_CSR_FS_S - MIPS_FENR_FS_S)) &
934
FPU_CSR_FS;
935
fcr31 |= value & (FPU_CSR_ALL_E | FPU_CSR_RM);
936
break;
937
938
case FPCREG_FEXR:
939
if (!cpu_has_mips_r)
940
break;
941
pr_debug("%p gpr[%d]->exr=%08x\n",
942
(void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
943
fcr31 &= ~(FPU_CSR_ALL_X | FPU_CSR_ALL_S);
944
fcr31 |= value & (FPU_CSR_ALL_X | FPU_CSR_ALL_S);
945
break;
946
947
case FPCREG_FCCR:
948
if (!cpu_has_mips_r)
949
break;
950
pr_debug("%p gpr[%d]->ccr=%08x\n",
951
(void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
952
fcr31 &= ~(FPU_CSR_CONDX | FPU_CSR_COND);
953
fcr31 |= (value << (FPU_CSR_COND_S - MIPS_FCCR_COND0_S)) &
954
FPU_CSR_COND;
955
fcr31 |= (value << (FPU_CSR_COND1_S - MIPS_FCCR_COND1_S)) &
956
FPU_CSR_CONDX;
957
break;
958
959
default:
960
break;
961
}
962
963
ctx->fcr31 = fcr31;
964
}
965
966
/*
967
* Emulate the single floating point instruction pointed at by EPC.
968
* Two instructions if the instruction is in a branch delay slot.
969
*/
970
971
static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
972
struct mm_decoded_insn dec_insn, void __user **fault_addr)
973
{
974
unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc;
975
unsigned int cond, cbit, bit0;
976
mips_instruction ir;
977
int likely, pc_inc;
978
union fpureg *fpr;
979
u32 __user *wva;
980
u64 __user *dva;
981
u32 wval;
982
u64 dval;
983
int sig;
984
985
/*
986
* 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
992
/* XXX NEC Vr54xx bug workaround */
993
if (delay_slot(xcp)) {
994
if (dec_insn.micro_mips_mode) {
995
if (!mm_isBranchInstr(xcp, dec_insn, &contpc))
996
clear_delay_slot(xcp);
997
} else {
998
if (!isBranchInstr(xcp, dec_insn, &contpc))
999
clear_delay_slot(xcp);
1000
}
1001
}
1002
1003
if (delay_slot(xcp)) {
1004
/*
1005
* The instruction to be emulated is in a branch delay slot
1006
* which means that we have to emulate the branch instruction
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
*/
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
}
1022
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
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))
1042
return SIGILL;
1043
}
1044
1045
emul:
1046
perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, xcp, 0);
1047
MIPS_FPU_EMU_INC_STATS(emulated);
1048
switch (MIPSInst_OPCODE(ir)) {
1049
case ldc1_op:
1050
dva = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1051
MIPSInst_SIMM(ir));
1052
MIPS_FPU_EMU_INC_STATS(loads);
1053
1054
if (!access_ok(dva, sizeof(u64))) {
1055
MIPS_FPU_EMU_INC_STATS(errors);
1056
*fault_addr = dva;
1057
return SIGBUS;
1058
}
1059
if (__get_user(dval, dva)) {
1060
MIPS_FPU_EMU_INC_STATS(errors);
1061
*fault_addr = dva;
1062
return SIGSEGV;
1063
}
1064
DITOREG(dval, MIPSInst_RT(ir));
1065
break;
1066
1067
case sdc1_op:
1068
dva = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1069
MIPSInst_SIMM(ir));
1070
MIPS_FPU_EMU_INC_STATS(stores);
1071
DIFROMREG(dval, MIPSInst_RT(ir));
1072
if (!access_ok(dva, sizeof(u64))) {
1073
MIPS_FPU_EMU_INC_STATS(errors);
1074
*fault_addr = dva;
1075
return SIGBUS;
1076
}
1077
if (__put_user(dval, dva)) {
1078
MIPS_FPU_EMU_INC_STATS(errors);
1079
*fault_addr = dva;
1080
return SIGSEGV;
1081
}
1082
break;
1083
1084
case lwc1_op:
1085
wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1086
MIPSInst_SIMM(ir));
1087
MIPS_FPU_EMU_INC_STATS(loads);
1088
if (!access_ok(wva, sizeof(u32))) {
1089
MIPS_FPU_EMU_INC_STATS(errors);
1090
*fault_addr = wva;
1091
return SIGBUS;
1092
}
1093
if (__get_user(wval, wva)) {
1094
MIPS_FPU_EMU_INC_STATS(errors);
1095
*fault_addr = wva;
1096
return SIGSEGV;
1097
}
1098
SITOREG(wval, MIPSInst_RT(ir));
1099
break;
1100
1101
case swc1_op:
1102
wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1103
MIPSInst_SIMM(ir));
1104
MIPS_FPU_EMU_INC_STATS(stores);
1105
SIFROMREG(wval, MIPSInst_RT(ir));
1106
if (!access_ok(wva, sizeof(u32))) {
1107
MIPS_FPU_EMU_INC_STATS(errors);
1108
*fault_addr = wva;
1109
return SIGBUS;
1110
}
1111
if (__put_user(wval, wva)) {
1112
MIPS_FPU_EMU_INC_STATS(errors);
1113
*fault_addr = wva;
1114
return SIGSEGV;
1115
}
1116
break;
1117
1118
case cop1_op:
1119
switch (MIPSInst_RS(ir)) {
1120
case dmfc_op:
1121
if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1122
return SIGILL;
1123
1124
/* 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:
1132
if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1133
return SIGILL;
1134
1135
/* copregister fs <- rt */
1136
DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1137
break;
1138
1139
case mfhc_op:
1140
if (!cpu_has_mips_r2_r6)
1141
return SIGILL;
1142
1143
/* 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:
1151
if (!cpu_has_mips_r2_r6)
1152
return SIGILL;
1153
1154
/* copregister rd <- gpr[rt] */
1155
SITOHREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1156
break;
1157
1158
case mfc_op:
1159
/* copregister rd -> gpr[rt] */
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 */
1168
SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1169
break;
1170
1171
case cfc_op:
1172
/* cop control register rd -> gpr[rt] */
1173
cop1_cfc(xcp, ctx, ir);
1174
break;
1175
1176
case ctc_op:
1177
/* copregister rd <- rt */
1178
cop1_ctc(xcp, ctx, ir);
1179
if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1180
return SIGFPE;
1181
}
1182
break;
1183
1184
case bc1eqz_op:
1185
case bc1nez_op:
1186
if (!cpu_has_mips_r6 || delay_slot(xcp))
1187
return SIGILL;
1188
1189
likely = 0;
1190
cond = 0;
1191
fpr = &current->thread.fpu.fpr[MIPSInst_RT(ir)];
1192
bit0 = get_fpr32(fpr, 0) & 0x1;
1193
switch (MIPSInst_RS(ir)) {
1194
case bc1eqz_op:
1195
MIPS_FPU_EMU_INC_STATS(bc1eqz);
1196
cond = bit0 == 0;
1197
break;
1198
case bc1nez_op:
1199
MIPS_FPU_EMU_INC_STATS(bc1nez);
1200
cond = bit0 != 0;
1201
break;
1202
}
1203
goto branch_common;
1204
1205
case bc_op:
1206
if (delay_slot(xcp))
1207
return SIGILL;
1208
1209
if (cpu_has_mips_4_5_r)
1210
cbit = fpucondbit[MIPSInst_RT(ir) >> 2];
1211
else
1212
cbit = FPU_CSR_COND;
1213
cond = ctx->fcr31 & cbit;
1214
1215
likely = 0;
1216
switch (MIPSInst_RT(ir) & 3) {
1217
case bcfl_op:
1218
if (cpu_has_mips_2_3_4_5_r)
1219
likely = 1;
1220
fallthrough;
1221
case bcf_op:
1222
cond = !cond;
1223
break;
1224
case bctl_op:
1225
if (cpu_has_mips_2_3_4_5_r)
1226
likely = 1;
1227
fallthrough;
1228
case bct_op:
1229
break;
1230
}
1231
branch_common:
1232
MIPS_FPU_EMU_INC_STATS(branches);
1233
set_delay_slot(xcp);
1234
if (cond) {
1235
/*
1236
* Branch taken: emulate dslot instruction
1237
*/
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;
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
*/
1271
sig = mips_dsemul(xcp, ir,
1272
bcpc, contpc);
1273
if (sig < 0)
1274
break;
1275
if (sig)
1276
xcp->cp0_epc = bcpc;
1277
/*
1278
* SIGILL forces out of
1279
* the emulation loop.
1280
*/
1281
return sig ? sig : SIGILL;
1282
}
1283
} else
1284
contpc = (xcp->cp0_epc + (contpc << 2));
1285
1286
switch (MIPSInst_OPCODE(ir)) {
1287
case lwc1_op:
1288
case swc1_op:
1289
goto emul;
1290
1291
case ldc1_op:
1292
case sdc1_op:
1293
if (cpu_has_mips_2_3_4_5_r)
1294
goto emul;
1295
1296
goto bc_sigill;
1297
1298
case cop1_op:
1299
goto emul;
1300
1301
case cop1x_op:
1302
if (cpu_has_mips_4_5_64_r2_r6)
1303
/* its one of ours */
1304
goto emul;
1305
1306
goto bc_sigill;
1307
1308
case spec_op:
1309
switch (MIPSInst_FUNC(ir)) {
1310
case movc_op:
1311
if (cpu_has_mips_4_5_r)
1312
goto emul;
1313
1314
goto bc_sigill;
1315
}
1316
break;
1317
1318
bc_sigill:
1319
xcp->cp0_epc = bcpc;
1320
return SIGILL;
1321
}
1322
1323
/*
1324
* Single step the non-cp1
1325
* instruction in the dslot
1326
*/
1327
sig = mips_dsemul(xcp, ir, bcpc, contpc);
1328
if (sig < 0)
1329
break;
1330
if (sig)
1331
xcp->cp0_epc = bcpc;
1332
/* SIGILL forces out of the emulation loop. */
1333
return sig ? sig : SIGILL;
1334
} else if (likely) { /* branch not taken */
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
}
1346
break;
1347
1348
default:
1349
if (!(MIPSInst_RS(ir) & 0x10))
1350
return SIGILL;
1351
1352
/* a real fpu computation instruction */
1353
sig = fpu_emu(xcp, ctx, ir);
1354
if (sig)
1355
return sig;
1356
}
1357
break;
1358
1359
case cop1x_op:
1360
if (!cpu_has_mips_4_5_64_r2_r6)
1361
return SIGILL;
1362
1363
sig = fpux_emu(xcp, ctx, ir, fault_addr);
1364
if (sig)
1365
return sig;
1366
break;
1367
1368
case spec_op:
1369
if (!cpu_has_mips_4_5_r)
1370
return SIGILL;
1371
1372
if (MIPSInst_FUNC(ir) != movc_op)
1373
return SIGILL;
1374
cond = fpucondbit[MIPSInst_RT(ir) >> 2];
1375
if (((ctx->fcr31 & cond) != 0) == ((MIPSInst_RT(ir) & 1) != 0))
1376
xcp->regs[MIPSInst_RD(ir)] =
1377
xcp->regs[MIPSInst_RS(ir)];
1378
break;
1379
default:
1380
return SIGILL;
1381
}
1382
1383
/* we did it !! */
1384
xcp->cp0_epc = contpc;
1385
clear_delay_slot(xcp);
1386
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
*/
1394
static 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
1405
static 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
1413
1414
/*
1415
* Additional MIPS4 instructions
1416
*/
1417
1418
#define DEF3OP(name, p, f1, f2, f3) \
1419
static union ieee754##p fpemu_##p##_##name(union ieee754##p r, \
1420
union ieee754##p s, union ieee754##p t) \
1421
{ \
1422
struct _ieee754_csr ieee754_csr_save; \
1423
s = f1(s, t); \
1424
ieee754_csr_save = ieee754_csr; \
1425
s = f2(s, r); \
1426
ieee754_csr_save.cx |= ieee754_csr.cx; \
1427
ieee754_csr_save.sx |= ieee754_csr.sx; \
1428
s = f3(s); \
1429
ieee754_csr.cx |= ieee754_csr_save.cx; \
1430
ieee754_csr.sx |= ieee754_csr_save.sx; \
1431
return s; \
1432
}
1433
1434
static union ieee754dp fpemu_dp_recip(union ieee754dp d)
1435
{
1436
return ieee754dp_div(ieee754dp_one(0), d);
1437
}
1438
1439
static union ieee754dp fpemu_dp_rsqrt(union ieee754dp d)
1440
{
1441
return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d));
1442
}
1443
1444
static union ieee754sp fpemu_sp_recip(union ieee754sp s)
1445
{
1446
return ieee754sp_div(ieee754sp_one(0), s);
1447
}
1448
1449
static union ieee754sp fpemu_sp_rsqrt(union ieee754sp s)
1450
{
1451
return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
1452
}
1453
1454
DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add, );
1455
DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub, );
1456
DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg);
1457
DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg);
1458
DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add, );
1459
DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub, );
1460
DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
1461
DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
1462
1463
static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1464
mips_instruction ir, void __user **fault_addr)
1465
{
1466
unsigned int rcsr = 0; /* resulting csr */
1467
1468
MIPS_FPU_EMU_INC_STATS(cp1xops);
1469
1470
switch (MIPSInst_FMA_FFMT(ir)) {
1471
case s_fmt:{ /* 0 */
1472
1473
union ieee754sp(*handler) (union ieee754sp, union ieee754sp, union ieee754sp);
1474
union ieee754sp fd, fr, fs, ft;
1475
u32 __user *va;
1476
u32 val;
1477
1478
switch (MIPSInst_FUNC(ir)) {
1479
case lwxc1_op:
1480
va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1481
xcp->regs[MIPSInst_FT(ir)]);
1482
1483
MIPS_FPU_EMU_INC_STATS(loads);
1484
if (!access_ok(va, sizeof(u32))) {
1485
MIPS_FPU_EMU_INC_STATS(errors);
1486
*fault_addr = va;
1487
return SIGBUS;
1488
}
1489
if (__get_user(val, va)) {
1490
MIPS_FPU_EMU_INC_STATS(errors);
1491
*fault_addr = va;
1492
return SIGSEGV;
1493
}
1494
SITOREG(val, MIPSInst_FD(ir));
1495
break;
1496
1497
case swxc1_op:
1498
va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1499
xcp->regs[MIPSInst_FT(ir)]);
1500
1501
MIPS_FPU_EMU_INC_STATS(stores);
1502
1503
SIFROMREG(val, MIPSInst_FS(ir));
1504
if (!access_ok(va, sizeof(u32))) {
1505
MIPS_FPU_EMU_INC_STATS(errors);
1506
*fault_addr = va;
1507
return SIGBUS;
1508
}
1509
if (put_user(val, va)) {
1510
MIPS_FPU_EMU_INC_STATS(errors);
1511
*fault_addr = va;
1512
return SIGSEGV;
1513
}
1514
break;
1515
1516
case madd_s_op:
1517
if (cpu_has_mac2008_only)
1518
handler = ieee754sp_madd;
1519
else
1520
handler = fpemu_sp_madd;
1521
goto scoptop;
1522
case msub_s_op:
1523
if (cpu_has_mac2008_only)
1524
handler = ieee754sp_msub;
1525
else
1526
handler = fpemu_sp_msub;
1527
goto scoptop;
1528
case nmadd_s_op:
1529
if (cpu_has_mac2008_only)
1530
handler = ieee754sp_nmadd;
1531
else
1532
handler = fpemu_sp_nmadd;
1533
goto scoptop;
1534
case nmsub_s_op:
1535
if (cpu_has_mac2008_only)
1536
handler = ieee754sp_nmsub;
1537
else
1538
handler = fpemu_sp_nmsub;
1539
goto scoptop;
1540
1541
scoptop:
1542
SPFROMREG(fr, MIPSInst_FR(ir));
1543
SPFROMREG(fs, MIPSInst_FS(ir));
1544
SPFROMREG(ft, MIPSInst_FT(ir));
1545
fd = (*handler) (fr, fs, ft);
1546
SPTOREG(fd, MIPSInst_FD(ir));
1547
1548
copcsr:
1549
if (ieee754_cxtest(IEEE754_INEXACT)) {
1550
MIPS_FPU_EMU_INC_STATS(ieee754_inexact);
1551
rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
1552
}
1553
if (ieee754_cxtest(IEEE754_UNDERFLOW)) {
1554
MIPS_FPU_EMU_INC_STATS(ieee754_underflow);
1555
rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
1556
}
1557
if (ieee754_cxtest(IEEE754_OVERFLOW)) {
1558
MIPS_FPU_EMU_INC_STATS(ieee754_overflow);
1559
rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
1560
}
1561
if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) {
1562
MIPS_FPU_EMU_INC_STATS(ieee754_invalidop);
1563
rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
1564
}
1565
1566
ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
1567
if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1568
/*printk ("SIGFPE: FPU csr = %08x\n",
1569
ctx->fcr31); */
1570
return SIGFPE;
1571
}
1572
1573
break;
1574
1575
default:
1576
return SIGILL;
1577
}
1578
break;
1579
}
1580
1581
case d_fmt:{ /* 1 */
1582
union ieee754dp(*handler) (union ieee754dp, union ieee754dp, union ieee754dp);
1583
union ieee754dp fd, fr, fs, ft;
1584
u64 __user *va;
1585
u64 val;
1586
1587
switch (MIPSInst_FUNC(ir)) {
1588
case ldxc1_op:
1589
va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1590
xcp->regs[MIPSInst_FT(ir)]);
1591
1592
MIPS_FPU_EMU_INC_STATS(loads);
1593
if (!access_ok(va, sizeof(u64))) {
1594
MIPS_FPU_EMU_INC_STATS(errors);
1595
*fault_addr = va;
1596
return SIGBUS;
1597
}
1598
if (__get_user(val, va)) {
1599
MIPS_FPU_EMU_INC_STATS(errors);
1600
*fault_addr = va;
1601
return SIGSEGV;
1602
}
1603
DITOREG(val, MIPSInst_FD(ir));
1604
break;
1605
1606
case sdxc1_op:
1607
va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1608
xcp->regs[MIPSInst_FT(ir)]);
1609
1610
MIPS_FPU_EMU_INC_STATS(stores);
1611
DIFROMREG(val, MIPSInst_FS(ir));
1612
if (!access_ok(va, sizeof(u64))) {
1613
MIPS_FPU_EMU_INC_STATS(errors);
1614
*fault_addr = va;
1615
return SIGBUS;
1616
}
1617
if (__put_user(val, va)) {
1618
MIPS_FPU_EMU_INC_STATS(errors);
1619
*fault_addr = va;
1620
return SIGSEGV;
1621
}
1622
break;
1623
1624
case madd_d_op:
1625
if (cpu_has_mac2008_only)
1626
handler = ieee754dp_madd;
1627
else
1628
handler = fpemu_dp_madd;
1629
goto dcoptop;
1630
case msub_d_op:
1631
if (cpu_has_mac2008_only)
1632
handler = ieee754dp_msub;
1633
else
1634
handler = fpemu_dp_msub;
1635
goto dcoptop;
1636
case nmadd_d_op:
1637
if (cpu_has_mac2008_only)
1638
handler = ieee754dp_nmadd;
1639
else
1640
handler = fpemu_dp_nmadd;
1641
goto dcoptop;
1642
case nmsub_d_op:
1643
if (cpu_has_mac2008_only)
1644
handler = ieee754dp_nmsub;
1645
else
1646
handler = fpemu_dp_nmsub;
1647
goto dcoptop;
1648
1649
dcoptop:
1650
DPFROMREG(fr, MIPSInst_FR(ir));
1651
DPFROMREG(fs, MIPSInst_FS(ir));
1652
DPFROMREG(ft, MIPSInst_FT(ir));
1653
fd = (*handler) (fr, fs, ft);
1654
DPTOREG(fd, MIPSInst_FD(ir));
1655
goto copcsr;
1656
1657
default:
1658
return SIGILL;
1659
}
1660
break;
1661
}
1662
1663
case 0x7:
1664
if (MIPSInst_FUNC(ir) != pfetch_op)
1665
return SIGILL;
1666
1667
/* ignore prefx operation */
1668
break;
1669
1670
default:
1671
return SIGILL;
1672
}
1673
1674
return 0;
1675
}
1676
1677
1678
1679
/*
1680
* Emulate a single COP1 arithmetic instruction.
1681
*/
1682
static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1683
mips_instruction ir)
1684
{
1685
int rfmt; /* resulting format */
1686
unsigned int rcsr = 0; /* resulting csr */
1687
unsigned int oldrm;
1688
unsigned int cbit;
1689
unsigned int cond;
1690
union {
1691
union ieee754dp d;
1692
union ieee754sp s;
1693
int w;
1694
s64 l;
1695
} rv; /* resulting value */
1696
u64 bits;
1697
1698
MIPS_FPU_EMU_INC_STATS(cp1ops);
1699
switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
1700
case s_fmt: { /* 0 */
1701
union {
1702
union ieee754sp(*b) (union ieee754sp, union ieee754sp);
1703
union ieee754sp(*u) (union ieee754sp);
1704
} handler;
1705
union ieee754sp fd, fs, ft;
1706
1707
switch (MIPSInst_FUNC(ir)) {
1708
/* binary ops */
1709
case fadd_op:
1710
MIPS_FPU_EMU_INC_STATS(add_s);
1711
handler.b = ieee754sp_add;
1712
goto scopbop;
1713
case fsub_op:
1714
MIPS_FPU_EMU_INC_STATS(sub_s);
1715
handler.b = ieee754sp_sub;
1716
goto scopbop;
1717
case fmul_op:
1718
MIPS_FPU_EMU_INC_STATS(mul_s);
1719
handler.b = ieee754sp_mul;
1720
goto scopbop;
1721
case fdiv_op:
1722
MIPS_FPU_EMU_INC_STATS(div_s);
1723
handler.b = ieee754sp_div;
1724
goto scopbop;
1725
1726
/* unary ops */
1727
case fsqrt_op:
1728
if (!cpu_has_mips_2_3_4_5_r)
1729
return SIGILL;
1730
1731
MIPS_FPU_EMU_INC_STATS(sqrt_s);
1732
handler.u = ieee754sp_sqrt;
1733
goto scopuop;
1734
1735
/*
1736
* Note that on some MIPS IV implementations such as the
1737
* R5000 and R8000 the FSQRT and FRECIP instructions do not
1738
* achieve full IEEE-754 accuracy - however this emulator does.
1739
*/
1740
case frsqrt_op:
1741
if (!cpu_has_mips_4_5_64_r2_r6)
1742
return SIGILL;
1743
1744
MIPS_FPU_EMU_INC_STATS(rsqrt_s);
1745
handler.u = fpemu_sp_rsqrt;
1746
goto scopuop;
1747
1748
case frecip_op:
1749
if (!cpu_has_mips_4_5_64_r2_r6)
1750
return SIGILL;
1751
1752
MIPS_FPU_EMU_INC_STATS(recip_s);
1753
handler.u = fpemu_sp_recip;
1754
goto scopuop;
1755
1756
case fmovc_op:
1757
if (!cpu_has_mips_4_5_r)
1758
return SIGILL;
1759
1760
cond = fpucondbit[MIPSInst_FT(ir) >> 2];
1761
if (((ctx->fcr31 & cond) != 0) !=
1762
((MIPSInst_FT(ir) & 1) != 0))
1763
return 0;
1764
SPFROMREG(rv.s, MIPSInst_FS(ir));
1765
break;
1766
1767
case fmovz_op:
1768
if (!cpu_has_mips_4_5_r)
1769
return SIGILL;
1770
1771
if (xcp->regs[MIPSInst_FT(ir)] != 0)
1772
return 0;
1773
SPFROMREG(rv.s, MIPSInst_FS(ir));
1774
break;
1775
1776
case fmovn_op:
1777
if (!cpu_has_mips_4_5_r)
1778
return SIGILL;
1779
1780
if (xcp->regs[MIPSInst_FT(ir)] == 0)
1781
return 0;
1782
SPFROMREG(rv.s, MIPSInst_FS(ir));
1783
break;
1784
1785
case fseleqz_op:
1786
if (!cpu_has_mips_r6)
1787
return SIGILL;
1788
1789
MIPS_FPU_EMU_INC_STATS(seleqz_s);
1790
SPFROMREG(rv.s, MIPSInst_FT(ir));
1791
if (rv.w & 0x1)
1792
rv.w = 0;
1793
else
1794
SPFROMREG(rv.s, MIPSInst_FS(ir));
1795
break;
1796
1797
case fselnez_op:
1798
if (!cpu_has_mips_r6)
1799
return SIGILL;
1800
1801
MIPS_FPU_EMU_INC_STATS(selnez_s);
1802
SPFROMREG(rv.s, MIPSInst_FT(ir));
1803
if (rv.w & 0x1)
1804
SPFROMREG(rv.s, MIPSInst_FS(ir));
1805
else
1806
rv.w = 0;
1807
break;
1808
1809
case fmaddf_op: {
1810
union ieee754sp ft, fs, fd;
1811
1812
if (!cpu_has_mips_r6)
1813
return SIGILL;
1814
1815
MIPS_FPU_EMU_INC_STATS(maddf_s);
1816
SPFROMREG(ft, MIPSInst_FT(ir));
1817
SPFROMREG(fs, MIPSInst_FS(ir));
1818
SPFROMREG(fd, MIPSInst_FD(ir));
1819
rv.s = ieee754sp_maddf(fd, fs, ft);
1820
goto copcsr;
1821
}
1822
1823
case fmsubf_op: {
1824
union ieee754sp ft, fs, fd;
1825
1826
if (!cpu_has_mips_r6)
1827
return SIGILL;
1828
1829
MIPS_FPU_EMU_INC_STATS(msubf_s);
1830
SPFROMREG(ft, MIPSInst_FT(ir));
1831
SPFROMREG(fs, MIPSInst_FS(ir));
1832
SPFROMREG(fd, MIPSInst_FD(ir));
1833
rv.s = ieee754sp_msubf(fd, fs, ft);
1834
goto copcsr;
1835
}
1836
1837
case frint_op: {
1838
union ieee754sp fs;
1839
1840
if (!cpu_has_mips_r6)
1841
return SIGILL;
1842
1843
MIPS_FPU_EMU_INC_STATS(rint_s);
1844
SPFROMREG(fs, MIPSInst_FS(ir));
1845
rv.s = ieee754sp_rint(fs);
1846
goto copcsr;
1847
}
1848
1849
case fclass_op: {
1850
union ieee754sp fs;
1851
1852
if (!cpu_has_mips_r6)
1853
return SIGILL;
1854
1855
MIPS_FPU_EMU_INC_STATS(class_s);
1856
SPFROMREG(fs, MIPSInst_FS(ir));
1857
rv.w = ieee754sp_2008class(fs);
1858
rfmt = w_fmt;
1859
goto copcsr;
1860
}
1861
1862
case fmin_op: {
1863
union ieee754sp fs, ft;
1864
1865
if (!cpu_has_mips_r6)
1866
return SIGILL;
1867
1868
MIPS_FPU_EMU_INC_STATS(min_s);
1869
SPFROMREG(ft, MIPSInst_FT(ir));
1870
SPFROMREG(fs, MIPSInst_FS(ir));
1871
rv.s = ieee754sp_fmin(fs, ft);
1872
goto copcsr;
1873
}
1874
1875
case fmina_op: {
1876
union ieee754sp fs, ft;
1877
1878
if (!cpu_has_mips_r6)
1879
return SIGILL;
1880
1881
MIPS_FPU_EMU_INC_STATS(mina_s);
1882
SPFROMREG(ft, MIPSInst_FT(ir));
1883
SPFROMREG(fs, MIPSInst_FS(ir));
1884
rv.s = ieee754sp_fmina(fs, ft);
1885
goto copcsr;
1886
}
1887
1888
case fmax_op: {
1889
union ieee754sp fs, ft;
1890
1891
if (!cpu_has_mips_r6)
1892
return SIGILL;
1893
1894
MIPS_FPU_EMU_INC_STATS(max_s);
1895
SPFROMREG(ft, MIPSInst_FT(ir));
1896
SPFROMREG(fs, MIPSInst_FS(ir));
1897
rv.s = ieee754sp_fmax(fs, ft);
1898
goto copcsr;
1899
}
1900
1901
case fmaxa_op: {
1902
union ieee754sp fs, ft;
1903
1904
if (!cpu_has_mips_r6)
1905
return SIGILL;
1906
1907
MIPS_FPU_EMU_INC_STATS(maxa_s);
1908
SPFROMREG(ft, MIPSInst_FT(ir));
1909
SPFROMREG(fs, MIPSInst_FS(ir));
1910
rv.s = ieee754sp_fmaxa(fs, ft);
1911
goto copcsr;
1912
}
1913
1914
case fabs_op:
1915
MIPS_FPU_EMU_INC_STATS(abs_s);
1916
handler.u = ieee754sp_abs;
1917
goto scopuop;
1918
1919
case fneg_op:
1920
MIPS_FPU_EMU_INC_STATS(neg_s);
1921
handler.u = ieee754sp_neg;
1922
goto scopuop;
1923
1924
case fmov_op:
1925
/* an easy one */
1926
MIPS_FPU_EMU_INC_STATS(mov_s);
1927
SPFROMREG(rv.s, MIPSInst_FS(ir));
1928
goto copcsr;
1929
1930
/* binary op on handler */
1931
scopbop:
1932
SPFROMREG(fs, MIPSInst_FS(ir));
1933
SPFROMREG(ft, MIPSInst_FT(ir));
1934
1935
rv.s = (*handler.b) (fs, ft);
1936
goto copcsr;
1937
scopuop:
1938
SPFROMREG(fs, MIPSInst_FS(ir));
1939
rv.s = (*handler.u) (fs);
1940
goto copcsr;
1941
copcsr:
1942
if (ieee754_cxtest(IEEE754_INEXACT)) {
1943
MIPS_FPU_EMU_INC_STATS(ieee754_inexact);
1944
rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
1945
}
1946
if (ieee754_cxtest(IEEE754_UNDERFLOW)) {
1947
MIPS_FPU_EMU_INC_STATS(ieee754_underflow);
1948
rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
1949
}
1950
if (ieee754_cxtest(IEEE754_OVERFLOW)) {
1951
MIPS_FPU_EMU_INC_STATS(ieee754_overflow);
1952
rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
1953
}
1954
if (ieee754_cxtest(IEEE754_ZERO_DIVIDE)) {
1955
MIPS_FPU_EMU_INC_STATS(ieee754_zerodiv);
1956
rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
1957
}
1958
if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) {
1959
MIPS_FPU_EMU_INC_STATS(ieee754_invalidop);
1960
rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
1961
}
1962
break;
1963
1964
/* unary conv ops */
1965
case fcvts_op:
1966
return SIGILL; /* not defined */
1967
1968
case fcvtd_op:
1969
MIPS_FPU_EMU_INC_STATS(cvt_d_s);
1970
SPFROMREG(fs, MIPSInst_FS(ir));
1971
rv.d = ieee754dp_fsp(fs);
1972
rfmt = d_fmt;
1973
goto copcsr;
1974
1975
case fcvtw_op:
1976
MIPS_FPU_EMU_INC_STATS(cvt_w_s);
1977
SPFROMREG(fs, MIPSInst_FS(ir));
1978
rv.w = ieee754sp_tint(fs);
1979
rfmt = w_fmt;
1980
goto copcsr;
1981
1982
case fround_op:
1983
case ftrunc_op:
1984
case fceil_op:
1985
case ffloor_op:
1986
if (!cpu_has_mips_2_3_4_5_r)
1987
return SIGILL;
1988
1989
if (MIPSInst_FUNC(ir) == fceil_op)
1990
MIPS_FPU_EMU_INC_STATS(ceil_w_s);
1991
if (MIPSInst_FUNC(ir) == ffloor_op)
1992
MIPS_FPU_EMU_INC_STATS(floor_w_s);
1993
if (MIPSInst_FUNC(ir) == fround_op)
1994
MIPS_FPU_EMU_INC_STATS(round_w_s);
1995
if (MIPSInst_FUNC(ir) == ftrunc_op)
1996
MIPS_FPU_EMU_INC_STATS(trunc_w_s);
1997
1998
oldrm = ieee754_csr.rm;
1999
SPFROMREG(fs, MIPSInst_FS(ir));
2000
ieee754_csr.rm = MIPSInst_FUNC(ir);
2001
rv.w = ieee754sp_tint(fs);
2002
ieee754_csr.rm = oldrm;
2003
rfmt = w_fmt;
2004
goto copcsr;
2005
2006
case fsel_op:
2007
if (!cpu_has_mips_r6)
2008
return SIGILL;
2009
2010
MIPS_FPU_EMU_INC_STATS(sel_s);
2011
SPFROMREG(fd, MIPSInst_FD(ir));
2012
if (fd.bits & 0x1)
2013
SPFROMREG(rv.s, MIPSInst_FT(ir));
2014
else
2015
SPFROMREG(rv.s, MIPSInst_FS(ir));
2016
break;
2017
2018
case fcvtl_op:
2019
if (!cpu_has_mips_3_4_5_64_r2_r6)
2020
return SIGILL;
2021
2022
MIPS_FPU_EMU_INC_STATS(cvt_l_s);
2023
SPFROMREG(fs, MIPSInst_FS(ir));
2024
rv.l = ieee754sp_tlong(fs);
2025
rfmt = l_fmt;
2026
goto copcsr;
2027
2028
case froundl_op:
2029
case ftruncl_op:
2030
case fceill_op:
2031
case ffloorl_op:
2032
if (!cpu_has_mips_3_4_5_64_r2_r6)
2033
return SIGILL;
2034
2035
if (MIPSInst_FUNC(ir) == fceill_op)
2036
MIPS_FPU_EMU_INC_STATS(ceil_l_s);
2037
if (MIPSInst_FUNC(ir) == ffloorl_op)
2038
MIPS_FPU_EMU_INC_STATS(floor_l_s);
2039
if (MIPSInst_FUNC(ir) == froundl_op)
2040
MIPS_FPU_EMU_INC_STATS(round_l_s);
2041
if (MIPSInst_FUNC(ir) == ftruncl_op)
2042
MIPS_FPU_EMU_INC_STATS(trunc_l_s);
2043
2044
oldrm = ieee754_csr.rm;
2045
SPFROMREG(fs, MIPSInst_FS(ir));
2046
ieee754_csr.rm = MIPSInst_FUNC(ir);
2047
rv.l = ieee754sp_tlong(fs);
2048
ieee754_csr.rm = oldrm;
2049
rfmt = l_fmt;
2050
goto copcsr;
2051
2052
default:
2053
if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) {
2054
unsigned int cmpop;
2055
union ieee754sp fs, ft;
2056
2057
cmpop = MIPSInst_FUNC(ir) - fcmp_op;
2058
SPFROMREG(fs, MIPSInst_FS(ir));
2059
SPFROMREG(ft, MIPSInst_FT(ir));
2060
rv.w = ieee754sp_cmp(fs, ft,
2061
cmptab[cmpop & 0x7], cmpop & 0x8);
2062
rfmt = -1;
2063
if ((cmpop & 0x8) && ieee754_cxtest
2064
(IEEE754_INVALID_OPERATION))
2065
rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2066
else
2067
goto copcsr;
2068
2069
} else
2070
return SIGILL;
2071
break;
2072
}
2073
break;
2074
}
2075
2076
case d_fmt: {
2077
union ieee754dp fd, fs, ft;
2078
union {
2079
union ieee754dp(*b) (union ieee754dp, union ieee754dp);
2080
union ieee754dp(*u) (union ieee754dp);
2081
} handler;
2082
2083
switch (MIPSInst_FUNC(ir)) {
2084
/* binary ops */
2085
case fadd_op:
2086
MIPS_FPU_EMU_INC_STATS(add_d);
2087
handler.b = ieee754dp_add;
2088
goto dcopbop;
2089
case fsub_op:
2090
MIPS_FPU_EMU_INC_STATS(sub_d);
2091
handler.b = ieee754dp_sub;
2092
goto dcopbop;
2093
case fmul_op:
2094
MIPS_FPU_EMU_INC_STATS(mul_d);
2095
handler.b = ieee754dp_mul;
2096
goto dcopbop;
2097
case fdiv_op:
2098
MIPS_FPU_EMU_INC_STATS(div_d);
2099
handler.b = ieee754dp_div;
2100
goto dcopbop;
2101
2102
/* unary ops */
2103
case fsqrt_op:
2104
if (!cpu_has_mips_2_3_4_5_r)
2105
return SIGILL;
2106
2107
MIPS_FPU_EMU_INC_STATS(sqrt_d);
2108
handler.u = ieee754dp_sqrt;
2109
goto dcopuop;
2110
/*
2111
* Note that on some MIPS IV implementations such as the
2112
* R5000 and R8000 the FSQRT and FRECIP instructions do not
2113
* achieve full IEEE-754 accuracy - however this emulator does.
2114
*/
2115
case frsqrt_op:
2116
if (!cpu_has_mips_4_5_64_r2_r6)
2117
return SIGILL;
2118
2119
MIPS_FPU_EMU_INC_STATS(rsqrt_d);
2120
handler.u = fpemu_dp_rsqrt;
2121
goto dcopuop;
2122
case frecip_op:
2123
if (!cpu_has_mips_4_5_64_r2_r6)
2124
return SIGILL;
2125
2126
MIPS_FPU_EMU_INC_STATS(recip_d);
2127
handler.u = fpemu_dp_recip;
2128
goto dcopuop;
2129
case fmovc_op:
2130
if (!cpu_has_mips_4_5_r)
2131
return SIGILL;
2132
2133
cond = fpucondbit[MIPSInst_FT(ir) >> 2];
2134
if (((ctx->fcr31 & cond) != 0) !=
2135
((MIPSInst_FT(ir) & 1) != 0))
2136
return 0;
2137
DPFROMREG(rv.d, MIPSInst_FS(ir));
2138
break;
2139
case fmovz_op:
2140
if (!cpu_has_mips_4_5_r)
2141
return SIGILL;
2142
2143
if (xcp->regs[MIPSInst_FT(ir)] != 0)
2144
return 0;
2145
DPFROMREG(rv.d, MIPSInst_FS(ir));
2146
break;
2147
case fmovn_op:
2148
if (!cpu_has_mips_4_5_r)
2149
return SIGILL;
2150
2151
if (xcp->regs[MIPSInst_FT(ir)] == 0)
2152
return 0;
2153
DPFROMREG(rv.d, MIPSInst_FS(ir));
2154
break;
2155
2156
case fseleqz_op:
2157
if (!cpu_has_mips_r6)
2158
return SIGILL;
2159
2160
MIPS_FPU_EMU_INC_STATS(seleqz_d);
2161
DPFROMREG(rv.d, MIPSInst_FT(ir));
2162
if (rv.l & 0x1)
2163
rv.l = 0;
2164
else
2165
DPFROMREG(rv.d, MIPSInst_FS(ir));
2166
break;
2167
2168
case fselnez_op:
2169
if (!cpu_has_mips_r6)
2170
return SIGILL;
2171
2172
MIPS_FPU_EMU_INC_STATS(selnez_d);
2173
DPFROMREG(rv.d, MIPSInst_FT(ir));
2174
if (rv.l & 0x1)
2175
DPFROMREG(rv.d, MIPSInst_FS(ir));
2176
else
2177
rv.l = 0;
2178
break;
2179
2180
case fmaddf_op: {
2181
union ieee754dp ft, fs, fd;
2182
2183
if (!cpu_has_mips_r6)
2184
return SIGILL;
2185
2186
MIPS_FPU_EMU_INC_STATS(maddf_d);
2187
DPFROMREG(ft, MIPSInst_FT(ir));
2188
DPFROMREG(fs, MIPSInst_FS(ir));
2189
DPFROMREG(fd, MIPSInst_FD(ir));
2190
rv.d = ieee754dp_maddf(fd, fs, ft);
2191
goto copcsr;
2192
}
2193
2194
case fmsubf_op: {
2195
union ieee754dp ft, fs, fd;
2196
2197
if (!cpu_has_mips_r6)
2198
return SIGILL;
2199
2200
MIPS_FPU_EMU_INC_STATS(msubf_d);
2201
DPFROMREG(ft, MIPSInst_FT(ir));
2202
DPFROMREG(fs, MIPSInst_FS(ir));
2203
DPFROMREG(fd, MIPSInst_FD(ir));
2204
rv.d = ieee754dp_msubf(fd, fs, ft);
2205
goto copcsr;
2206
}
2207
2208
case frint_op: {
2209
union ieee754dp fs;
2210
2211
if (!cpu_has_mips_r6)
2212
return SIGILL;
2213
2214
MIPS_FPU_EMU_INC_STATS(rint_d);
2215
DPFROMREG(fs, MIPSInst_FS(ir));
2216
rv.d = ieee754dp_rint(fs);
2217
goto copcsr;
2218
}
2219
2220
case fclass_op: {
2221
union ieee754dp fs;
2222
2223
if (!cpu_has_mips_r6)
2224
return SIGILL;
2225
2226
MIPS_FPU_EMU_INC_STATS(class_d);
2227
DPFROMREG(fs, MIPSInst_FS(ir));
2228
rv.l = ieee754dp_2008class(fs);
2229
rfmt = l_fmt;
2230
goto copcsr;
2231
}
2232
2233
case fmin_op: {
2234
union ieee754dp fs, ft;
2235
2236
if (!cpu_has_mips_r6)
2237
return SIGILL;
2238
2239
MIPS_FPU_EMU_INC_STATS(min_d);
2240
DPFROMREG(ft, MIPSInst_FT(ir));
2241
DPFROMREG(fs, MIPSInst_FS(ir));
2242
rv.d = ieee754dp_fmin(fs, ft);
2243
goto copcsr;
2244
}
2245
2246
case fmina_op: {
2247
union ieee754dp fs, ft;
2248
2249
if (!cpu_has_mips_r6)
2250
return SIGILL;
2251
2252
MIPS_FPU_EMU_INC_STATS(mina_d);
2253
DPFROMREG(ft, MIPSInst_FT(ir));
2254
DPFROMREG(fs, MIPSInst_FS(ir));
2255
rv.d = ieee754dp_fmina(fs, ft);
2256
goto copcsr;
2257
}
2258
2259
case fmax_op: {
2260
union ieee754dp fs, ft;
2261
2262
if (!cpu_has_mips_r6)
2263
return SIGILL;
2264
2265
MIPS_FPU_EMU_INC_STATS(max_d);
2266
DPFROMREG(ft, MIPSInst_FT(ir));
2267
DPFROMREG(fs, MIPSInst_FS(ir));
2268
rv.d = ieee754dp_fmax(fs, ft);
2269
goto copcsr;
2270
}
2271
2272
case fmaxa_op: {
2273
union ieee754dp fs, ft;
2274
2275
if (!cpu_has_mips_r6)
2276
return SIGILL;
2277
2278
MIPS_FPU_EMU_INC_STATS(maxa_d);
2279
DPFROMREG(ft, MIPSInst_FT(ir));
2280
DPFROMREG(fs, MIPSInst_FS(ir));
2281
rv.d = ieee754dp_fmaxa(fs, ft);
2282
goto copcsr;
2283
}
2284
2285
case fabs_op:
2286
MIPS_FPU_EMU_INC_STATS(abs_d);
2287
handler.u = ieee754dp_abs;
2288
goto dcopuop;
2289
2290
case fneg_op:
2291
MIPS_FPU_EMU_INC_STATS(neg_d);
2292
handler.u = ieee754dp_neg;
2293
goto dcopuop;
2294
2295
case fmov_op:
2296
/* an easy one */
2297
MIPS_FPU_EMU_INC_STATS(mov_d);
2298
DPFROMREG(rv.d, MIPSInst_FS(ir));
2299
goto copcsr;
2300
2301
/* binary op on handler */
2302
dcopbop:
2303
DPFROMREG(fs, MIPSInst_FS(ir));
2304
DPFROMREG(ft, MIPSInst_FT(ir));
2305
2306
rv.d = (*handler.b) (fs, ft);
2307
goto copcsr;
2308
dcopuop:
2309
DPFROMREG(fs, MIPSInst_FS(ir));
2310
rv.d = (*handler.u) (fs);
2311
goto copcsr;
2312
2313
/*
2314
* unary conv ops
2315
*/
2316
case fcvts_op:
2317
MIPS_FPU_EMU_INC_STATS(cvt_s_d);
2318
DPFROMREG(fs, MIPSInst_FS(ir));
2319
rv.s = ieee754sp_fdp(fs);
2320
rfmt = s_fmt;
2321
goto copcsr;
2322
2323
case fcvtd_op:
2324
return SIGILL; /* not defined */
2325
2326
case fcvtw_op:
2327
MIPS_FPU_EMU_INC_STATS(cvt_w_d);
2328
DPFROMREG(fs, MIPSInst_FS(ir));
2329
rv.w = ieee754dp_tint(fs); /* wrong */
2330
rfmt = w_fmt;
2331
goto copcsr;
2332
2333
case fround_op:
2334
case ftrunc_op:
2335
case fceil_op:
2336
case ffloor_op:
2337
if (!cpu_has_mips_2_3_4_5_r)
2338
return SIGILL;
2339
2340
if (MIPSInst_FUNC(ir) == fceil_op)
2341
MIPS_FPU_EMU_INC_STATS(ceil_w_d);
2342
if (MIPSInst_FUNC(ir) == ffloor_op)
2343
MIPS_FPU_EMU_INC_STATS(floor_w_d);
2344
if (MIPSInst_FUNC(ir) == fround_op)
2345
MIPS_FPU_EMU_INC_STATS(round_w_d);
2346
if (MIPSInst_FUNC(ir) == ftrunc_op)
2347
MIPS_FPU_EMU_INC_STATS(trunc_w_d);
2348
2349
oldrm = ieee754_csr.rm;
2350
DPFROMREG(fs, MIPSInst_FS(ir));
2351
ieee754_csr.rm = MIPSInst_FUNC(ir);
2352
rv.w = ieee754dp_tint(fs);
2353
ieee754_csr.rm = oldrm;
2354
rfmt = w_fmt;
2355
goto copcsr;
2356
2357
case fsel_op:
2358
if (!cpu_has_mips_r6)
2359
return SIGILL;
2360
2361
MIPS_FPU_EMU_INC_STATS(sel_d);
2362
DPFROMREG(fd, MIPSInst_FD(ir));
2363
if (fd.bits & 0x1)
2364
DPFROMREG(rv.d, MIPSInst_FT(ir));
2365
else
2366
DPFROMREG(rv.d, MIPSInst_FS(ir));
2367
break;
2368
2369
case fcvtl_op:
2370
if (!cpu_has_mips_3_4_5_64_r2_r6)
2371
return SIGILL;
2372
2373
MIPS_FPU_EMU_INC_STATS(cvt_l_d);
2374
DPFROMREG(fs, MIPSInst_FS(ir));
2375
rv.l = ieee754dp_tlong(fs);
2376
rfmt = l_fmt;
2377
goto copcsr;
2378
2379
case froundl_op:
2380
case ftruncl_op:
2381
case fceill_op:
2382
case ffloorl_op:
2383
if (!cpu_has_mips_3_4_5_64_r2_r6)
2384
return SIGILL;
2385
2386
if (MIPSInst_FUNC(ir) == fceill_op)
2387
MIPS_FPU_EMU_INC_STATS(ceil_l_d);
2388
if (MIPSInst_FUNC(ir) == ffloorl_op)
2389
MIPS_FPU_EMU_INC_STATS(floor_l_d);
2390
if (MIPSInst_FUNC(ir) == froundl_op)
2391
MIPS_FPU_EMU_INC_STATS(round_l_d);
2392
if (MIPSInst_FUNC(ir) == ftruncl_op)
2393
MIPS_FPU_EMU_INC_STATS(trunc_l_d);
2394
2395
oldrm = ieee754_csr.rm;
2396
DPFROMREG(fs, MIPSInst_FS(ir));
2397
ieee754_csr.rm = MIPSInst_FUNC(ir);
2398
rv.l = ieee754dp_tlong(fs);
2399
ieee754_csr.rm = oldrm;
2400
rfmt = l_fmt;
2401
goto copcsr;
2402
2403
default:
2404
if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) {
2405
unsigned int cmpop;
2406
union ieee754dp fs, ft;
2407
2408
cmpop = MIPSInst_FUNC(ir) - fcmp_op;
2409
DPFROMREG(fs, MIPSInst_FS(ir));
2410
DPFROMREG(ft, MIPSInst_FT(ir));
2411
rv.w = ieee754dp_cmp(fs, ft,
2412
cmptab[cmpop & 0x7], cmpop & 0x8);
2413
rfmt = -1;
2414
if ((cmpop & 0x8)
2415
&&
2416
ieee754_cxtest
2417
(IEEE754_INVALID_OPERATION))
2418
rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2419
else
2420
goto copcsr;
2421
2422
}
2423
else {
2424
return SIGILL;
2425
}
2426
break;
2427
}
2428
break;
2429
}
2430
2431
case w_fmt: {
2432
union ieee754dp fs;
2433
2434
switch (MIPSInst_FUNC(ir)) {
2435
case fcvts_op:
2436
/* convert word to single precision real */
2437
MIPS_FPU_EMU_INC_STATS(cvt_s_w);
2438
SPFROMREG(fs, MIPSInst_FS(ir));
2439
rv.s = ieee754sp_fint(fs.bits);
2440
rfmt = s_fmt;
2441
goto copcsr;
2442
case fcvtd_op:
2443
/* convert word to double precision real */
2444
MIPS_FPU_EMU_INC_STATS(cvt_d_w);
2445
SPFROMREG(fs, MIPSInst_FS(ir));
2446
rv.d = ieee754dp_fint(fs.bits);
2447
rfmt = d_fmt;
2448
goto copcsr;
2449
default: {
2450
/* Emulating the new CMP.condn.fmt R6 instruction */
2451
#define CMPOP_MASK 0x7
2452
#define SIGN_BIT (0x1 << 3)
2453
#define PREDICATE_BIT (0x1 << 4)
2454
2455
int cmpop = MIPSInst_FUNC(ir) & CMPOP_MASK;
2456
int sig = MIPSInst_FUNC(ir) & SIGN_BIT;
2457
union ieee754sp fs, ft;
2458
2459
/* This is an R6 only instruction */
2460
if (!cpu_has_mips_r6 ||
2461
(MIPSInst_FUNC(ir) & 0x20))
2462
return SIGILL;
2463
2464
if (!sig) {
2465
if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2466
switch (cmpop) {
2467
case 0:
2468
MIPS_FPU_EMU_INC_STATS(cmp_af_s);
2469
break;
2470
case 1:
2471
MIPS_FPU_EMU_INC_STATS(cmp_un_s);
2472
break;
2473
case 2:
2474
MIPS_FPU_EMU_INC_STATS(cmp_eq_s);
2475
break;
2476
case 3:
2477
MIPS_FPU_EMU_INC_STATS(cmp_ueq_s);
2478
break;
2479
case 4:
2480
MIPS_FPU_EMU_INC_STATS(cmp_lt_s);
2481
break;
2482
case 5:
2483
MIPS_FPU_EMU_INC_STATS(cmp_ult_s);
2484
break;
2485
case 6:
2486
MIPS_FPU_EMU_INC_STATS(cmp_le_s);
2487
break;
2488
case 7:
2489
MIPS_FPU_EMU_INC_STATS(cmp_ule_s);
2490
break;
2491
}
2492
} else {
2493
switch (cmpop) {
2494
case 1:
2495
MIPS_FPU_EMU_INC_STATS(cmp_or_s);
2496
break;
2497
case 2:
2498
MIPS_FPU_EMU_INC_STATS(cmp_une_s);
2499
break;
2500
case 3:
2501
MIPS_FPU_EMU_INC_STATS(cmp_ne_s);
2502
break;
2503
}
2504
}
2505
} else {
2506
if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2507
switch (cmpop) {
2508
case 0:
2509
MIPS_FPU_EMU_INC_STATS(cmp_saf_s);
2510
break;
2511
case 1:
2512
MIPS_FPU_EMU_INC_STATS(cmp_sun_s);
2513
break;
2514
case 2:
2515
MIPS_FPU_EMU_INC_STATS(cmp_seq_s);
2516
break;
2517
case 3:
2518
MIPS_FPU_EMU_INC_STATS(cmp_sueq_s);
2519
break;
2520
case 4:
2521
MIPS_FPU_EMU_INC_STATS(cmp_slt_s);
2522
break;
2523
case 5:
2524
MIPS_FPU_EMU_INC_STATS(cmp_sult_s);
2525
break;
2526
case 6:
2527
MIPS_FPU_EMU_INC_STATS(cmp_sle_s);
2528
break;
2529
case 7:
2530
MIPS_FPU_EMU_INC_STATS(cmp_sule_s);
2531
break;
2532
}
2533
} else {
2534
switch (cmpop) {
2535
case 1:
2536
MIPS_FPU_EMU_INC_STATS(cmp_sor_s);
2537
break;
2538
case 2:
2539
MIPS_FPU_EMU_INC_STATS(cmp_sune_s);
2540
break;
2541
case 3:
2542
MIPS_FPU_EMU_INC_STATS(cmp_sne_s);
2543
break;
2544
}
2545
}
2546
}
2547
2548
/* fmt is w_fmt for single precision so fix it */
2549
rfmt = s_fmt;
2550
/* default to false */
2551
rv.w = 0;
2552
2553
/* CMP.condn.S */
2554
SPFROMREG(fs, MIPSInst_FS(ir));
2555
SPFROMREG(ft, MIPSInst_FT(ir));
2556
2557
/* positive predicates */
2558
if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2559
if (ieee754sp_cmp(fs, ft, cmptab[cmpop],
2560
sig))
2561
rv.w = -1; /* true, all 1s */
2562
if ((sig) &&
2563
ieee754_cxtest(IEEE754_INVALID_OPERATION))
2564
rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2565
else
2566
goto copcsr;
2567
} else {
2568
/* negative predicates */
2569
switch (cmpop) {
2570
case 1:
2571
case 2:
2572
case 3:
2573
if (ieee754sp_cmp(fs, ft,
2574
negative_cmptab[cmpop],
2575
sig))
2576
rv.w = -1; /* true, all 1s */
2577
if (sig &&
2578
ieee754_cxtest(IEEE754_INVALID_OPERATION))
2579
rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2580
else
2581
goto copcsr;
2582
break;
2583
default:
2584
/* Reserved R6 ops */
2585
return SIGILL;
2586
}
2587
}
2588
break;
2589
}
2590
}
2591
break;
2592
}
2593
2594
case l_fmt:
2595
2596
if (!cpu_has_mips_3_4_5_64_r2_r6)
2597
return SIGILL;
2598
2599
DIFROMREG(bits, MIPSInst_FS(ir));
2600
2601
switch (MIPSInst_FUNC(ir)) {
2602
case fcvts_op:
2603
/* convert long to single precision real */
2604
MIPS_FPU_EMU_INC_STATS(cvt_s_l);
2605
rv.s = ieee754sp_flong(bits);
2606
rfmt = s_fmt;
2607
goto copcsr;
2608
case fcvtd_op:
2609
/* convert long to double precision real */
2610
MIPS_FPU_EMU_INC_STATS(cvt_d_l);
2611
rv.d = ieee754dp_flong(bits);
2612
rfmt = d_fmt;
2613
goto copcsr;
2614
default: {
2615
/* Emulating the new CMP.condn.fmt R6 instruction */
2616
int cmpop = MIPSInst_FUNC(ir) & CMPOP_MASK;
2617
int sig = MIPSInst_FUNC(ir) & SIGN_BIT;
2618
union ieee754dp fs, ft;
2619
2620
if (!cpu_has_mips_r6 ||
2621
(MIPSInst_FUNC(ir) & 0x20))
2622
return SIGILL;
2623
2624
if (!sig) {
2625
if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2626
switch (cmpop) {
2627
case 0:
2628
MIPS_FPU_EMU_INC_STATS(cmp_af_d);
2629
break;
2630
case 1:
2631
MIPS_FPU_EMU_INC_STATS(cmp_un_d);
2632
break;
2633
case 2:
2634
MIPS_FPU_EMU_INC_STATS(cmp_eq_d);
2635
break;
2636
case 3:
2637
MIPS_FPU_EMU_INC_STATS(cmp_ueq_d);
2638
break;
2639
case 4:
2640
MIPS_FPU_EMU_INC_STATS(cmp_lt_d);
2641
break;
2642
case 5:
2643
MIPS_FPU_EMU_INC_STATS(cmp_ult_d);
2644
break;
2645
case 6:
2646
MIPS_FPU_EMU_INC_STATS(cmp_le_d);
2647
break;
2648
case 7:
2649
MIPS_FPU_EMU_INC_STATS(cmp_ule_d);
2650
break;
2651
}
2652
} else {
2653
switch (cmpop) {
2654
case 1:
2655
MIPS_FPU_EMU_INC_STATS(cmp_or_d);
2656
break;
2657
case 2:
2658
MIPS_FPU_EMU_INC_STATS(cmp_une_d);
2659
break;
2660
case 3:
2661
MIPS_FPU_EMU_INC_STATS(cmp_ne_d);
2662
break;
2663
}
2664
}
2665
} else {
2666
if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2667
switch (cmpop) {
2668
case 0:
2669
MIPS_FPU_EMU_INC_STATS(cmp_saf_d);
2670
break;
2671
case 1:
2672
MIPS_FPU_EMU_INC_STATS(cmp_sun_d);
2673
break;
2674
case 2:
2675
MIPS_FPU_EMU_INC_STATS(cmp_seq_d);
2676
break;
2677
case 3:
2678
MIPS_FPU_EMU_INC_STATS(cmp_sueq_d);
2679
break;
2680
case 4:
2681
MIPS_FPU_EMU_INC_STATS(cmp_slt_d);
2682
break;
2683
case 5:
2684
MIPS_FPU_EMU_INC_STATS(cmp_sult_d);
2685
break;
2686
case 6:
2687
MIPS_FPU_EMU_INC_STATS(cmp_sle_d);
2688
break;
2689
case 7:
2690
MIPS_FPU_EMU_INC_STATS(cmp_sule_d);
2691
break;
2692
}
2693
} else {
2694
switch (cmpop) {
2695
case 1:
2696
MIPS_FPU_EMU_INC_STATS(cmp_sor_d);
2697
break;
2698
case 2:
2699
MIPS_FPU_EMU_INC_STATS(cmp_sune_d);
2700
break;
2701
case 3:
2702
MIPS_FPU_EMU_INC_STATS(cmp_sne_d);
2703
break;
2704
}
2705
}
2706
}
2707
2708
/* fmt is l_fmt for double precision so fix it */
2709
rfmt = d_fmt;
2710
/* default to false */
2711
rv.l = 0;
2712
2713
/* CMP.condn.D */
2714
DPFROMREG(fs, MIPSInst_FS(ir));
2715
DPFROMREG(ft, MIPSInst_FT(ir));
2716
2717
/* positive predicates */
2718
if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2719
if (ieee754dp_cmp(fs, ft,
2720
cmptab[cmpop], sig))
2721
rv.l = -1LL; /* true, all 1s */
2722
if (sig &&
2723
ieee754_cxtest(IEEE754_INVALID_OPERATION))
2724
rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2725
else
2726
goto copcsr;
2727
} else {
2728
/* negative predicates */
2729
switch (cmpop) {
2730
case 1:
2731
case 2:
2732
case 3:
2733
if (ieee754dp_cmp(fs, ft,
2734
negative_cmptab[cmpop],
2735
sig))
2736
rv.l = -1LL; /* true, all 1s */
2737
if (sig &&
2738
ieee754_cxtest(IEEE754_INVALID_OPERATION))
2739
rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2740
else
2741
goto copcsr;
2742
break;
2743
default:
2744
/* Reserved R6 ops */
2745
return SIGILL;
2746
}
2747
}
2748
break;
2749
}
2750
}
2751
break;
2752
2753
default:
2754
return SIGILL;
2755
}
2756
2757
/*
2758
* Update the fpu CSR register for this operation.
2759
* If an exception is required, generate a tidy SIGFPE exception,
2760
* without updating the result register.
2761
* Note: cause exception bits do not accumulate, they are rewritten
2762
* for each op; only the flag/sticky bits accumulate.
2763
*/
2764
ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
2765
if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
2766
/*printk ("SIGFPE: FPU csr = %08x\n",ctx->fcr31); */
2767
return SIGFPE;
2768
}
2769
2770
/*
2771
* Now we can safely write the result back to the register file.
2772
*/
2773
switch (rfmt) {
2774
case -1:
2775
2776
if (cpu_has_mips_4_5_r)
2777
cbit = fpucondbit[MIPSInst_FD(ir) >> 2];
2778
else
2779
cbit = FPU_CSR_COND;
2780
if (rv.w)
2781
ctx->fcr31 |= cbit;
2782
else
2783
ctx->fcr31 &= ~cbit;
2784
break;
2785
2786
case d_fmt:
2787
DPTOREG(rv.d, MIPSInst_FD(ir));
2788
break;
2789
case s_fmt:
2790
SPTOREG(rv.s, MIPSInst_FD(ir));
2791
break;
2792
case w_fmt:
2793
SITOREG(rv.w, MIPSInst_FD(ir));
2794
break;
2795
case l_fmt:
2796
if (!cpu_has_mips_3_4_5_64_r2_r6)
2797
return SIGILL;
2798
2799
DITOREG(rv.l, MIPSInst_FD(ir));
2800
break;
2801
default:
2802
return SIGILL;
2803
}
2804
2805
return 0;
2806
}
2807
2808
/*
2809
* Emulate FPU instructions.
2810
*
2811
* If we use FPU hardware, then we have been typically called to handle
2812
* an unimplemented operation, such as where an operand is a NaN or
2813
* denormalized. In that case exit the emulation loop after a single
2814
* iteration so as to let hardware execute any subsequent instructions.
2815
*
2816
* If we have no FPU hardware or it has been disabled, then continue
2817
* emulating floating-point instructions until one of these conditions
2818
* has occurred:
2819
*
2820
* - a non-FPU instruction has been encountered,
2821
*
2822
* - an attempt to emulate has ended with a signal,
2823
*
2824
* - the ISA mode has been switched.
2825
*
2826
* We need to terminate the emulation loop if we got switched to the
2827
* MIPS16 mode, whether supported or not, so that we do not attempt
2828
* to emulate a MIPS16 instruction as a regular MIPS FPU instruction.
2829
* Similarly if we got switched to the microMIPS mode and only the
2830
* regular MIPS mode is supported, so that we do not attempt to emulate
2831
* a microMIPS instruction as a regular MIPS FPU instruction. Or if
2832
* we got switched to the regular MIPS mode and only the microMIPS mode
2833
* is supported, so that we do not attempt to emulate a regular MIPS
2834
* instruction that should cause an Address Error exception instead.
2835
* For simplicity we always terminate upon an ISA mode switch.
2836
*/
2837
int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
2838
int has_fpu, void __user **fault_addr)
2839
{
2840
unsigned long oldepc, prevepc;
2841
struct mm_decoded_insn dec_insn;
2842
u16 instr[4];
2843
u16 *instr_ptr;
2844
int sig = 0;
2845
2846
/*
2847
* Initialize context if it hasn't been used already, otherwise ensure
2848
* it has been saved to struct thread_struct.
2849
*/
2850
if (!init_fp_ctx(current))
2851
lose_fpu(1);
2852
2853
oldepc = xcp->cp0_epc;
2854
do {
2855
prevepc = xcp->cp0_epc;
2856
2857
if (get_isa16_mode(prevepc) && cpu_has_mmips) {
2858
/*
2859
* Get next 2 microMIPS instructions and convert them
2860
* into 32-bit instructions.
2861
*/
2862
if ((get_user(instr[0], (u16 __user *)msk_isa16_mode(xcp->cp0_epc))) ||
2863
(get_user(instr[1], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 2))) ||
2864
(get_user(instr[2], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 4))) ||
2865
(get_user(instr[3], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 6)))) {
2866
MIPS_FPU_EMU_INC_STATS(errors);
2867
return SIGBUS;
2868
}
2869
instr_ptr = instr;
2870
2871
/* Get first instruction. */
2872
if (mm_insn_16bit(*instr_ptr)) {
2873
/* Duplicate the half-word. */
2874
dec_insn.insn = (*instr_ptr << 16) |
2875
(*instr_ptr);
2876
/* 16-bit instruction. */
2877
dec_insn.pc_inc = 2;
2878
instr_ptr += 1;
2879
} else {
2880
dec_insn.insn = (*instr_ptr << 16) |
2881
*(instr_ptr+1);
2882
/* 32-bit instruction. */
2883
dec_insn.pc_inc = 4;
2884
instr_ptr += 2;
2885
}
2886
/* Get second instruction. */
2887
if (mm_insn_16bit(*instr_ptr)) {
2888
/* Duplicate the half-word. */
2889
dec_insn.next_insn = (*instr_ptr << 16) |
2890
(*instr_ptr);
2891
/* 16-bit instruction. */
2892
dec_insn.next_pc_inc = 2;
2893
} else {
2894
dec_insn.next_insn = (*instr_ptr << 16) |
2895
*(instr_ptr+1);
2896
/* 32-bit instruction. */
2897
dec_insn.next_pc_inc = 4;
2898
}
2899
dec_insn.micro_mips_mode = 1;
2900
} else {
2901
if ((get_user(dec_insn.insn,
2902
(mips_instruction __user *) xcp->cp0_epc)) ||
2903
(get_user(dec_insn.next_insn,
2904
(mips_instruction __user *)(xcp->cp0_epc+4)))) {
2905
MIPS_FPU_EMU_INC_STATS(errors);
2906
return SIGBUS;
2907
}
2908
dec_insn.pc_inc = 4;
2909
dec_insn.next_pc_inc = 4;
2910
dec_insn.micro_mips_mode = 0;
2911
}
2912
2913
if ((dec_insn.insn == 0) ||
2914
((dec_insn.pc_inc == 2) &&
2915
((dec_insn.insn & 0xffff) == MM_NOP16)))
2916
xcp->cp0_epc += dec_insn.pc_inc; /* Skip NOPs */
2917
else {
2918
/*
2919
* The 'ieee754_csr' is an alias of ctx->fcr31.
2920
* No need to copy ctx->fcr31 to ieee754_csr.
2921
*/
2922
sig = cop1Emulate(xcp, ctx, dec_insn, fault_addr);
2923
}
2924
2925
if (has_fpu)
2926
break;
2927
if (sig)
2928
break;
2929
/*
2930
* We have to check for the ISA bit explicitly here,
2931
* because `get_isa16_mode' may return 0 if support
2932
* for code compression has been globally disabled,
2933
* or otherwise we may produce the wrong signal or
2934
* even proceed successfully where we must not.
2935
*/
2936
if ((xcp->cp0_epc ^ prevepc) & 0x1)
2937
break;
2938
2939
cond_resched();
2940
} while (xcp->cp0_epc > prevepc);
2941
2942
/* SIGILL indicates a non-fpu instruction */
2943
if (sig == SIGILL && xcp->cp0_epc != oldepc)
2944
/* but if EPC has advanced, then ignore it */
2945
sig = 0;
2946
2947
return sig;
2948
}
2949
2950