Commit 9c75a31c authored by Michael Neuling's avatar Michael Neuling Committed by Paul Mackerras

powerpc: Add macros to access floating point registers in thread_struct.

We are going to change where the floating point registers are stored
in the thread_struct, so in preparation add some macros to access the
floating point registers.  Update all code to use these new macros.
Signed-off-by: default avatarMichael Neuling <mikey@neuling.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 9e751186
...@@ -366,7 +366,7 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, ...@@ -366,7 +366,7 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,
static int emulate_fp_pair(struct pt_regs *regs, unsigned char __user *addr, static int emulate_fp_pair(struct pt_regs *regs, unsigned char __user *addr,
unsigned int reg, unsigned int flags) unsigned int reg, unsigned int flags)
{ {
char *ptr = (char *) &current->thread.fpr[reg]; char *ptr = (char *) &current->thread.TS_FPR(reg);
int i, ret; int i, ret;
if (!(flags & F)) if (!(flags & F))
...@@ -784,7 +784,7 @@ int fix_alignment(struct pt_regs *regs) ...@@ -784,7 +784,7 @@ int fix_alignment(struct pt_regs *regs)
return -EFAULT; return -EFAULT;
} }
} else if (flags & F) { } else if (flags & F) {
data.dd = current->thread.fpr[reg]; data.dd = current->thread.TS_FPR(reg);
if (flags & S) { if (flags & S) {
/* Single-precision FP store requires conversion... */ /* Single-precision FP store requires conversion... */
#ifdef CONFIG_PPC_FPU #ifdef CONFIG_PPC_FPU
...@@ -862,7 +862,7 @@ int fix_alignment(struct pt_regs *regs) ...@@ -862,7 +862,7 @@ int fix_alignment(struct pt_regs *regs)
if (unlikely(ret)) if (unlikely(ret))
return -EFAULT; return -EFAULT;
} else if (flags & F) } else if (flags & F)
current->thread.fpr[reg] = data.dd; current->thread.TS_FPR(reg) = data.dd;
else else
regs->gpr[reg] = data.ll; regs->gpr[reg] = data.ll;
......
...@@ -110,7 +110,7 @@ int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs) ...@@ -110,7 +110,7 @@ int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
return 0; return 0;
flush_fp_to_thread(current); flush_fp_to_thread(current);
memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs)); memcpy(fpregs, &tsk->thread.TS_FPR(0), sizeof(*fpregs));
return 1; return 1;
} }
......
...@@ -218,7 +218,7 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset, ...@@ -218,7 +218,7 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
flush_fp_to_thread(target); flush_fp_to_thread(target);
BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) != 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, return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
&target->thread.fpr, 0, -1); &target->thread.fpr, 0, -1);
...@@ -231,7 +231,7 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset, ...@@ -231,7 +231,7 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
flush_fp_to_thread(target); flush_fp_to_thread(target);
BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) != 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, return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
&target->thread.fpr, 0, -1); &target->thread.fpr, 0, -1);
...@@ -728,7 +728,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -728,7 +728,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
tmp = ptrace_get_reg(child, (int) index); tmp = ptrace_get_reg(child, (int) index);
} else { } else {
flush_fp_to_thread(child); 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); ret = put_user(tmp,(unsigned long __user *) data);
break; break;
...@@ -755,7 +756,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -755,7 +756,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = ptrace_put_reg(child, index, data); ret = ptrace_put_reg(child, index, data);
} else { } else {
flush_fp_to_thread(child); 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; ret = 0;
} }
break; break;
......
...@@ -64,6 +64,11 @@ static long compat_ptrace_old(struct task_struct *child, long request, ...@@ -64,6 +64,11 @@ static long compat_ptrace_old(struct task_struct *child, long request,
return -EPERM; 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, long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
compat_ulong_t caddr, compat_ulong_t cdata) compat_ulong_t caddr, compat_ulong_t cdata)
{ {
...@@ -122,7 +127,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, ...@@ -122,7 +127,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
* to be an array of unsigned int (32 bits) - the * to be an array of unsigned int (32 bits) - the
* index passed in is based on this assumption. * 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); ret = put_user((unsigned int)tmp, (u32 __user *)data);
break; break;
...@@ -162,7 +168,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, ...@@ -162,7 +168,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
CHECK_FULL_REGS(child->thread.regs); CHECK_FULL_REGS(child->thread.regs);
if (numReg >= PT_FPR0) { if (numReg >= PT_FPR0) {
flush_fp_to_thread(child); 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 */ } else { /* register within PT_REGS struct */
tmp = ptrace_get_reg(child, numReg); tmp = ptrace_get_reg(child, numReg);
} }
...@@ -217,7 +224,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, ...@@ -217,7 +224,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
* to be an array of unsigned int (32 bits) - the * to be an array of unsigned int (32 bits) - the
* index passed in is based on this assumption. * 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; ret = 0;
} }
break; break;
......
...@@ -124,7 +124,7 @@ int Soft_emulate_8xx(struct pt_regs *regs) ...@@ -124,7 +124,7 @@ int Soft_emulate_8xx(struct pt_regs *regs)
disp = instword & 0xffff; disp = instword & 0xffff;
ea = (u32 *)(regs->gpr[idxreg] + disp); ea = (u32 *)(regs->gpr[idxreg] + disp);
ip = (u32 *)&current->thread.fpr[flreg]; ip = (u32 *)&current->thread.TS_FPR(flreg);
switch ( inst ) switch ( inst )
{ {
...@@ -168,7 +168,7 @@ int Soft_emulate_8xx(struct pt_regs *regs) ...@@ -168,7 +168,7 @@ int Soft_emulate_8xx(struct pt_regs *regs)
break; break;
case FMR: case FMR:
/* assume this is a fp move -- Cort */ /* assume this is a fp move -- Cort */
memcpy(ip, &current->thread.fpr[(instword>>11)&0x1f], memcpy(ip, &current->thread.TS_FPR((instword>>11)&0x1f),
sizeof(double)); sizeof(double));
break; break;
default: default:
......
...@@ -230,14 +230,14 @@ do_mathemu(struct pt_regs *regs) ...@@ -230,14 +230,14 @@ do_mathemu(struct pt_regs *regs)
case LFD: case LFD:
idx = (insn >> 16) & 0x1f; idx = (insn >> 16) & 0x1f;
sdisp = (insn & 0xffff); sdisp = (insn & 0xffff);
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp); op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
lfd(op0, op1, op2, op3); lfd(op0, op1, op2, op3);
break; break;
case LFDU: case LFDU:
idx = (insn >> 16) & 0x1f; idx = (insn >> 16) & 0x1f;
sdisp = (insn & 0xffff); sdisp = (insn & 0xffff);
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp); op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
lfd(op0, op1, op2, op3); lfd(op0, op1, op2, op3);
regs->gpr[idx] = (unsigned long)op1; regs->gpr[idx] = (unsigned long)op1;
...@@ -245,21 +245,21 @@ do_mathemu(struct pt_regs *regs) ...@@ -245,21 +245,21 @@ do_mathemu(struct pt_regs *regs)
case STFD: case STFD:
idx = (insn >> 16) & 0x1f; idx = (insn >> 16) & 0x1f;
sdisp = (insn & 0xffff); sdisp = (insn & 0xffff);
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp); op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
stfd(op0, op1, op2, op3); stfd(op0, op1, op2, op3);
break; break;
case STFDU: case STFDU:
idx = (insn >> 16) & 0x1f; idx = (insn >> 16) & 0x1f;
sdisp = (insn & 0xffff); sdisp = (insn & 0xffff);
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp); op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
stfd(op0, op1, op2, op3); stfd(op0, op1, op2, op3);
regs->gpr[idx] = (unsigned long)op1; regs->gpr[idx] = (unsigned long)op1;
break; break;
case OP63: case OP63:
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)&current->thread.fpr[(insn >> 11) & 0x1f]; op1 = (void *)&current->thread.TS_FPR((insn >> 11) & 0x1f);
fmr(op0, op1, op2, op3); fmr(op0, op1, op2, op3);
break; break;
default: default:
...@@ -356,28 +356,28 @@ do_mathemu(struct pt_regs *regs) ...@@ -356,28 +356,28 @@ do_mathemu(struct pt_regs *regs)
switch (type) { switch (type) {
case AB: case AB:
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)&current->thread.fpr[(insn >> 16) & 0x1f]; op1 = (void *)&current->thread.TS_FPR((insn >> 16) & 0x1f);
op2 = (void *)&current->thread.fpr[(insn >> 11) & 0x1f]; op2 = (void *)&current->thread.TS_FPR((insn >> 11) & 0x1f);
break; break;
case AC: case AC:
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)&current->thread.fpr[(insn >> 16) & 0x1f]; op1 = (void *)&current->thread.TS_FPR((insn >> 16) & 0x1f);
op2 = (void *)&current->thread.fpr[(insn >> 6) & 0x1f]; op2 = (void *)&current->thread.TS_FPR((insn >> 6) & 0x1f);
break; break;
case ABC: case ABC:
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)&current->thread.fpr[(insn >> 16) & 0x1f]; op1 = (void *)&current->thread.TS_FPR((insn >> 16) & 0x1f);
op2 = (void *)&current->thread.fpr[(insn >> 11) & 0x1f]; op2 = (void *)&current->thread.TS_FPR((insn >> 11) & 0x1f);
op3 = (void *)&current->thread.fpr[(insn >> 6) & 0x1f]; op3 = (void *)&current->thread.TS_FPR((insn >> 6) & 0x1f);
break; break;
case D: case D:
idx = (insn >> 16) & 0x1f; idx = (insn >> 16) & 0x1f;
sdisp = (insn & 0xffff); sdisp = (insn & 0xffff);
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp); op1 = (void *)((idx ? regs->gpr[idx] : 0) + sdisp);
break; break;
...@@ -387,27 +387,27 @@ do_mathemu(struct pt_regs *regs) ...@@ -387,27 +387,27 @@ do_mathemu(struct pt_regs *regs)
goto illegal; goto illegal;
sdisp = (insn & 0xffff); sdisp = (insn & 0xffff);
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)(regs->gpr[idx] + sdisp); op1 = (void *)(regs->gpr[idx] + sdisp);
break; break;
case X: case X:
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
break; break;
case XA: case XA:
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)&current->thread.fpr[(insn >> 16) & 0x1f]; op1 = (void *)&current->thread.TS_FPR((insn >> 16) & 0x1f);
break; break;
case XB: case XB:
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)&current->thread.fpr[(insn >> 11) & 0x1f]; op1 = (void *)&current->thread.TS_FPR((insn >> 11) & 0x1f);
break; break;
case XE: case XE:
idx = (insn >> 16) & 0x1f; idx = (insn >> 16) & 0x1f;
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
if (!idx) { if (!idx) {
if (((insn >> 1) & 0x3ff) == STFIWX) if (((insn >> 1) & 0x3ff) == STFIWX)
op1 = (void *)(regs->gpr[(insn >> 11) & 0x1f]); op1 = (void *)(regs->gpr[(insn >> 11) & 0x1f]);
...@@ -421,7 +421,7 @@ do_mathemu(struct pt_regs *regs) ...@@ -421,7 +421,7 @@ do_mathemu(struct pt_regs *regs)
case XEU: case XEU:
idx = (insn >> 16) & 0x1f; idx = (insn >> 16) & 0x1f;
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f]; op0 = (void *)&current->thread.TS_FPR((insn >> 21) & 0x1f);
op1 = (void *)((idx ? regs->gpr[idx] : 0) op1 = (void *)((idx ? regs->gpr[idx] : 0)
+ regs->gpr[(insn >> 11) & 0x1f]); + regs->gpr[(insn >> 11) & 0x1f]);
break; break;
...@@ -429,8 +429,8 @@ do_mathemu(struct pt_regs *regs) ...@@ -429,8 +429,8 @@ do_mathemu(struct pt_regs *regs)
case XCR: case XCR:
op0 = (void *)&regs->ccr; op0 = (void *)&regs->ccr;
op1 = (void *)((insn >> 23) & 0x7); op1 = (void *)((insn >> 23) & 0x7);
op2 = (void *)&current->thread.fpr[(insn >> 16) & 0x1f]; op2 = (void *)&current->thread.TS_FPR((insn >> 16) & 0x1f);
op3 = (void *)&current->thread.fpr[(insn >> 11) & 0x1f]; op3 = (void *)&current->thread.TS_FPR((insn >> 11) & 0x1f);
break; break;
case XCRL: case XCRL:
...@@ -450,7 +450,7 @@ do_mathemu(struct pt_regs *regs) ...@@ -450,7 +450,7 @@ do_mathemu(struct pt_regs *regs)
case XFLB: case XFLB:
op0 = (void *)((insn >> 17) & 0xff); op0 = (void *)((insn >> 17) & 0xff);
op1 = (void *)&current->thread.fpr[(insn >> 11) & 0x1f]; op1 = (void *)&current->thread.TS_FPR((insn >> 11) & 0x1f);
break; break;
default: default:
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/stringify.h> #include <linux/stringify.h>
#include <asm/asm-compat.h> #include <asm/asm-compat.h>
#include <asm/processor.h>
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#error __FILE__ should only be used in assembler files #error __FILE__ should only be used in assembler files
...@@ -83,13 +84,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \ ...@@ -83,13 +84,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base) #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 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_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_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_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_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 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_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_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) #define REST_8FPRS(n, base) REST_4FPRS(n, base); REST_4FPRS(n+4, base)
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#include <asm/reg.h> #include <asm/reg.h>
#define TS_FPRWIDTH 1
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/compiler.h> #include <linux/compiler.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
...@@ -140,6 +142,8 @@ typedef struct { ...@@ -140,6 +142,8 @@ typedef struct {
unsigned long seg; unsigned long seg;
} mm_segment_t; } mm_segment_t;
#define TS_FPR(i) fpr[i]
struct thread_struct { struct thread_struct {
unsigned long ksp; /* Kernel stack pointer */ unsigned long ksp; /* Kernel stack pointer */
unsigned long ksp_limit; /* if ksp <= ksp_limit stack overflow */ unsigned long ksp_limit; /* if ksp <= ksp_limit stack overflow */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment