static int emulate_fp_pair(struct pt_regs *regs, unsigned char __user *addr,
unsigned int reg, unsigned int flags)
{
- char *ptr = (char *) ¤t->thread.fpr[reg];
+ char *ptr = (char *) ¤t->thread.TS_FPR(reg);
int i, ret;
if (!(flags & F))
return -EFAULT;
}
} else if (flags & F) {
- data.dd = current->thread.fpr[reg];
+ data.dd = current->thread.TS_FPR(reg);
if (flags & S) {
/* Single-precision FP store requires conversion... */
#ifdef CONFIG_PPC_FPU
if (unlikely(ret))
return -EFAULT;
} else if (flags & F)
- current->thread.fpr[reg] = data.dd;
+ current->thread.TS_FPR(reg) = data.dd;
else
regs->gpr[reg] = data.ll;
return 0;
flush_fp_to_thread(current);
- memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
+ memcpy(fpregs, &tsk->thread.TS_FPR(0), sizeof(*fpregs));
return 1;
}
flush_fp_to_thread(target);
BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
- offsetof(struct thread_struct, fpr[32]));
+ offsetof(struct thread_struct, TS_FPR(32)));
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
&target->thread.fpr, 0, -1);
flush_fp_to_thread(target);
BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
- offsetof(struct thread_struct, fpr[32]));
+ offsetof(struct thread_struct, TS_FPR(32)));
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
&target->thread.fpr, 0, -1);
tmp = ptrace_get_reg(child, (int) index);
} else {
flush_fp_to_thread(child);
- tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
+ tmp = ((unsigned long *)child->thread.fpr)
+ [TS_FPRWIDTH * (index - PT_FPR0)];
}
ret = put_user(tmp,(unsigned long __user *) data);
break;
ret = ptrace_put_reg(child, index, data);
} else {
flush_fp_to_thread(child);
- ((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
+ ((unsigned long *)child->thread.fpr)
+ [TS_FPRWIDTH * (index - PT_FPR0)] = data;
ret = 0;
}
break;
return -EPERM;
}
+/* Macros to workout the correct index for the FPR in the thread struct */
+#define FPRNUMBER(i) (((i) - PT_FPR0) >> 1)
+#define FPRHALF(i) (((i) - PT_FPR0) & 1)
+#define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) + FPRHALF(i)
+
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
compat_ulong_t caddr, compat_ulong_t cdata)
{
* to be an array of unsigned int (32 bits) - the
* index passed in is based on this assumption.
*/
- tmp = ((unsigned int *)child->thread.fpr)[index - PT_FPR0];
+ tmp = ((unsigned int *)child->thread.fpr)
+ [FPRINDEX(index)];
}
ret = put_user((unsigned int)tmp, (u32 __user *)data);
break;
CHECK_FULL_REGS(child->thread.regs);
if (numReg >= PT_FPR0) {
flush_fp_to_thread(child);
- tmp = ((unsigned long int *)child->thread.fpr)[numReg - PT_FPR0];
+ tmp = ((unsigned long int *)child->thread.fpr)
+ [FPRINDEX(numReg)];
} else { /* register within PT_REGS struct */
tmp = ptrace_get_reg(child, numReg);
}
* to be an array of unsigned int (32 bits) - the
* index passed in is based on this assumption.
*/
- ((unsigned int *)child->thread.fpr)[index - PT_FPR0] = data;
+ ((unsigned int *)child->thread.fpr)
+ [FPRINDEX(index)] = data;
ret = 0;
}
break;
disp = instword & 0xffff;
ea = (u32 *)(regs->gpr[idxreg] + disp);
- ip = (u32 *)¤t->thread.fpr[flreg];
+ ip = (u32 *)¤t->thread.TS_FPR(flreg);
switch ( inst )
{
break;
case FMR:
/* assume this is a fp move -- Cort */
- memcpy(ip, ¤t->thread.fpr[(instword>>11)&0x1f],
+ memcpy(ip, ¤t->thread.TS_FPR((instword>>11)&0x1f),
sizeof(double));
break;
default:
case LFD:
idx = (insn >> 16) & 0x1f;
sdisp = (insn & 0xffff);
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
lfd(op0, op1, op2, op3);
break;
case LFDU:
idx = (insn >> 16) & 0x1f;
sdisp = (insn & 0xffff);
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
lfd(op0, op1, op2, op3);
regs->gpr[idx] = (unsigned long)op1;
case STFD:
idx = (insn >> 16) & 0x1f;
sdisp = (insn & 0xffff);
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
stfd(op0, op1, op2, op3);
break;
case STFDU:
idx = (insn >> 16) & 0x1f;
sdisp = (insn & 0xffff);
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
stfd(op0, op1, op2, op3);
regs->gpr[idx] = (unsigned long)op1;
break;
case OP63:
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
- op1 = (void *)¤t->thread.fpr[(insn >> 11) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
+ op1 = (void *)¤t->thread.TS_FPR((insn >> 11) & 0x1f);
fmr(op0, op1, op2, op3);
break;
default:
switch (type) {
case AB:
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
- op1 = (void *)¤t->thread.fpr[(insn >> 16) & 0x1f];
- op2 = (void *)¤t->thread.fpr[(insn >> 11) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
+ op1 = (void *)¤t->thread.TS_FPR((insn >> 16) & 0x1f);
+ op2 = (void *)¤t->thread.TS_FPR((insn >> 11) & 0x1f);
break;
case AC:
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
- op1 = (void *)¤t->thread.fpr[(insn >> 16) & 0x1f];
- op2 = (void *)¤t->thread.fpr[(insn >> 6) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
+ op1 = (void *)¤t->thread.TS_FPR((insn >> 16) & 0x1f);
+ op2 = (void *)¤t->thread.TS_FPR((insn >> 6) & 0x1f);
break;
case ABC:
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
- op1 = (void *)¤t->thread.fpr[(insn >> 16) & 0x1f];
- op2 = (void *)¤t->thread.fpr[(insn >> 11) & 0x1f];
- op3 = (void *)¤t->thread.fpr[(insn >> 6) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
+ op1 = (void *)¤t->thread.TS_FPR((insn >> 16) & 0x1f);
+ op2 = (void *)¤t->thread.TS_FPR((insn >> 11) & 0x1f);
+ op3 = (void *)¤t->thread.TS_FPR((insn >> 6) & 0x1f);
break;
case D:
idx = (insn >> 16) & 0x1f;
sdisp = (insn & 0xffff);
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
break;
goto illegal;
sdisp = (insn & 0xffff);
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)(regs->gpr[idx] + sdisp);
break;
case X:
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
break;
case XA:
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
- op1 = (void *)¤t->thread.fpr[(insn >> 16) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
+ op1 = (void *)¤t->thread.TS_FPR((insn >> 16) & 0x1f);
break;
case XB:
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
- op1 = (void *)¤t->thread.fpr[(insn >> 11) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
+ op1 = (void *)¤t->thread.TS_FPR((insn >> 11) & 0x1f);
break;
case XE:
idx = (insn >> 16) & 0x1f;
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
if (!idx) {
if (((insn >> 1) & 0x3ff) == STFIWX)
op1 = (void *)(regs->gpr[(insn >> 11) & 0x1f]);
case XEU:
idx = (insn >> 16) & 0x1f;
- op0 = (void *)¤t->thread.fpr[(insn >> 21) & 0x1f];
+ op0 = (void *)¤t->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)((idx ? regs->gpr[idx] : 0)
+ regs->gpr[(insn >> 11) & 0x1f]);
break;
case XCR:
op0 = (void *)®s->ccr;
op1 = (void *)((insn >> 23) & 0x7);
- op2 = (void *)¤t->thread.fpr[(insn >> 16) & 0x1f];
- op3 = (void *)¤t->thread.fpr[(insn >> 11) & 0x1f];
+ op2 = (void *)¤t->thread.TS_FPR((insn >> 16) & 0x1f);
+ op3 = (void *)¤t->thread.TS_FPR((insn >> 11) & 0x1f);
break;
case XCRL:
case XFLB:
op0 = (void *)((insn >> 17) & 0xff);
- op1 = (void *)¤t->thread.fpr[(insn >> 11) & 0x1f];
+ op1 = (void *)¤t->thread.TS_FPR((insn >> 11) & 0x1f);
break;
default:
#include <linux/stringify.h>
#include <asm/asm-compat.h>
+#include <asm/processor.h>
#ifndef __ASSEMBLY__
#error __FILE__ should only be used in assembler files
#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base)
#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base)
-#define SAVE_FPR(n, base) stfd n,THREAD_FPR0+8*(n)(base)
+#define SAVE_FPR(n, base) stfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
#define SAVE_2FPRS(n, base) SAVE_FPR(n, base); SAVE_FPR(n+1, base)
#define SAVE_4FPRS(n, base) SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
#define SAVE_8FPRS(n, base) SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base)
#define SAVE_16FPRS(n, base) SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base)
#define SAVE_32FPRS(n, base) SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base)
-#define REST_FPR(n, base) lfd n,THREAD_FPR0+8*(n)(base)
+#define REST_FPR(n, base) lfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
#define REST_2FPRS(n, base) REST_FPR(n, base); REST_FPR(n+1, base)
#define REST_4FPRS(n, base) REST_2FPRS(n, base); REST_2FPRS(n+2, base)
#define REST_8FPRS(n, base) REST_4FPRS(n, base); REST_4FPRS(n+4, base)
#include <asm/reg.h>
+#define TS_FPRWIDTH 1
+
#ifndef __ASSEMBLY__
#include <linux/compiler.h>
#include <asm/ptrace.h>
unsigned long seg;
} mm_segment_t;
+#define TS_FPR(i) fpr[i]
+
struct thread_struct {
unsigned long ksp; /* Kernel stack pointer */
unsigned long ksp_limit; /* if ksp <= ksp_limit stack overflow */