11 #include <linux/types.h>
12 #include <linux/sched.h>
13 #include <linux/errno.h>
14 #include <linux/perf_event.h>
17 #include <asm/ptrace.h>
18 #include <asm/uaccess.h>
19 #include <asm/cacheflush.h>
85 #define FSR_TEM_SHIFT 23UL
86 #define FSR_TEM_MASK (0x1fUL << FSR_TEM_SHIFT)
87 #define FSR_AEXC_SHIFT 5UL
88 #define FSR_AEXC_MASK (0x1fUL << FSR_AEXC_SHIFT)
89 #define FSR_CEXC_SHIFT 0UL
90 #define FSR_CEXC_MASK (0x1fUL << FSR_CEXC_SHIFT)
100 static inline int record_exception(
struct pt_regs *
regs,
int eflag)
109 if(would_trap != 0) {
111 if((eflag & (eflag - 1)) != 0) {
152 if(would_trap == 0) {
153 regs->tpc = regs->tnpc;
157 return (would_trap ? 0 : 1);
168 unsigned long pc = regs->tpc;
169 unsigned long tstate = regs->tstate;
175 #define TYPE(ftt, r, ru, b, bu, a, au) type = (au << 2) | (a << 0) | (bu << 5) | (b << 3) | (ru << 8) | (r << 6) | (ftt << 9)
187 die_if_kernel(
"unfinished/unimplemented FPop from kernel", regs);
189 if (test_thread_flag(TIF_32BIT))
192 if ((insn & 0xc1f80000) == 0x81a00000) {
193 switch ((insn >> 5) & 0x1ff) {
260 else if ((insn & 0xc1f80000) == 0x81a80000) {
262 switch ((insn >> 5) & 0x1ff) {
271 if (!((insn >> 11) & 3))
277 switch ((insn >> 14) & 0x7) {
279 case 1:
if (XR) IR = 1;
break;
280 case 2:
if (XR == 1 || XR == 2) IR = 1;
break;
281 case 3:
if (XR & 1) IR = 1;
break;
282 case 4:
if (XR == 1) IR = 1;
break;
283 case 5:
if (XR & 2) IR = 1;
break;
284 case 6:
if (XR == 2) IR = 1;
break;
285 case 7:
if (XR == 3) IR = 1;
break;
287 if ((insn >> 14) & 8)
293 XR = regs->tstate >> 32;
294 if ((insn >> 5) & 0x80)
298 freg = ((XR >> 2) ^ XR) & 2;
299 switch ((insn >> 14) & 0x7) {
301 case 1:
if (XR & 4) IR = 1;
break;
302 case 2:
if ((XR & 4) || freg) IR = 1;
break;
303 case 3:
if (freg) IR = 1;
break;
304 case 4:
if (XR & 5) IR = 1;
break;
305 case 5:
if (XR & 1) IR = 1;
break;
306 case 6:
if (XR & 8) IR = 1;
break;
307 case 7:
if (XR & 2) IR = 1;
break;
309 if ((insn >> 14) & 8)
318 freg = (insn >> 14) & 0x1f;
329 struct reg_window __user *
win;
332 get_user(XR, &win->locals[freg - 16]);
335 switch ((insn >> 10) & 3) {
336 case 1:
if (!XR) IR = 1;
break;
337 case 2:
if (XR <= 0) IR = 1;
break;
338 case 3:
if (XR < 0) IR = 1;
break;
340 if ((insn >> 10) & 4)
347 regs->tpc = regs->tnpc;
350 }
else if (IR == 1) {
352 insn = (insn & 0x3e00001f) | 0x81a00060;
366 if (!illegal_insn_trap) {
368 if (ftt != (type >> 9))
372 freg = ((insn >> 14) & 0x1f);
373 switch (type & 0x3) {
374 case 3:
if (freg & 2) {
378 case 2: freg = ((freg & 1) << 5) | (freg & 0x1e);
385 switch (type & 0x7) {
390 freg = (insn & 0x1f);
391 switch ((type >> 3) & 0x3) {
392 case 3:
if (freg & 2) {
396 case 2: freg = ((freg & 1) << 5) | (freg & 0x1e);
403 switch ((type >> 3) & 0x7) {
408 freg = ((insn >> 25) & 0x1f);
409 switch ((type >> 6) & 0x3) {
410 case 3:
if (freg & 2) {
414 case 2: freg = ((freg & 1) << 5) | (freg & 0x1e);
430 switch ((insn >> 5) & 0x1ff) {
456 case FMOVQ: rd->q[0] = rs2->q[0]; rd->q[1] = rs2->q[1];
break;
457 case FABSQ: rd->q[0] = rs2->q[0] & 0x7fffffffffffffff
UL; rd->q[1] = rs2->q[1];
break;
458 case FNEGQ: rd->q[0] = rs2->q[0] ^ 0x8000000000000000
UL; rd->q[1] = rs2->q[1];
break;
488 (((insn >> 5) & 0x1ff) ==
FCMPEQ ||
494 switch ((type >> 6) & 0x7) {
496 if (XR == -1) XR = 2;
499 case 0: xfsr &= ~0xc00; xfsr |= (XR << 10);
break;
500 case 1: xfsr &= ~0x300000000
UL; xfsr |= (XR << 32);
break;
501 case 2: xfsr &= ~0xc00000000
UL; xfsr |= (XR << 34);
break;
502 case 3: xfsr &= ~0x3000000000
UL; xfsr |= (XR << 36);
break;
506 case 1: rd->s =
IR;
break;
507 case 2: rd->d = XR;
break;
515 return record_exception(regs, _fex);
519 regs->tpc = regs->tnpc;