powerpc: Move VMX and VSX asm code to vector.S

Currently, load_up_altivec and give_up_altivec are duplicated
in 32-bit and 64-bit. This creates a common implementation that
is moved away from head_32.S, head_64.S and misc_64.S and into
vector.S, using the same macros we already use for our common
implementation of load_up_fpu.

I also moved the VSX code over to vector.S though in that case
I didn't make it build on 32-bit (yet).

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
Benjamin Herrenschmidt
2009-06-02 21:17:37 +00:00
parent d3f6204a7d
commit e821ea70f3
6 changed files with 213 additions and 306 deletions

View File

@ -743,101 +743,6 @@ PerformanceMonitor:
addi r3,r1,STACK_FRAME_OVERHEAD
EXC_XFER_STD(0xf00, performance_monitor_exception)
#ifdef CONFIG_ALTIVEC
/* Note that the AltiVec support is closely modeled after the FP
* support. Changes to one are likely to be applicable to the
* other! */
load_up_altivec:
/*
* Disable AltiVec for the task which had AltiVec previously,
* and save its AltiVec registers in its thread_struct.
* Enables AltiVec for use in the kernel on return.
* On SMP we know the AltiVec units are free, since we give it up every
* switch. -- Kumar
*/
mfmsr r5
oris r5,r5,MSR_VEC@h
MTMSRD(r5) /* enable use of AltiVec now */
isync
/*
* For SMP, we don't do lazy AltiVec switching because it just gets too
* horrendously complex, especially when a task switches from one CPU
* to another. Instead we call giveup_altivec in switch_to.
*/
#ifndef CONFIG_SMP
tophys(r6,0)
addis r3,r6,last_task_used_altivec@ha
lwz r4,last_task_used_altivec@l(r3)
cmpwi 0,r4,0
beq 1f
add r4,r4,r6
addi r4,r4,THREAD /* want THREAD of last_task_used_altivec */
SAVE_32VRS(0,r10,r4)
mfvscr vr0
li r10,THREAD_VSCR
stvx vr0,r10,r4
lwz r5,PT_REGS(r4)
add r5,r5,r6
lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
lis r10,MSR_VEC@h
andc r4,r4,r10 /* disable altivec for previous task */
stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
#endif /* CONFIG_SMP */
/* enable use of AltiVec after return */
oris r9,r9,MSR_VEC@h
mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
li r4,1
li r10,THREAD_VSCR
stw r4,THREAD_USED_VR(r5)
lvx vr0,r10,r5
mtvscr vr0
REST_32VRS(0,r10,r5)
#ifndef CONFIG_SMP
subi r4,r5,THREAD
sub r4,r4,r6
stw r4,last_task_used_altivec@l(r3)
#endif /* CONFIG_SMP */
/* restore registers and return */
/* we haven't used ctr or xer or lr */
b fast_exception_return
/*
* giveup_altivec(tsk)
* Disable AltiVec for the task given as the argument,
* and save the AltiVec registers in its thread_struct.
* Enables AltiVec for use in the kernel on return.
*/
.globl giveup_altivec
giveup_altivec:
mfmsr r5
oris r5,r5,MSR_VEC@h
SYNC
MTMSRD(r5) /* enable use of AltiVec now */
isync
cmpwi 0,r3,0
beqlr- /* if no previous owner, done */
addi r3,r3,THREAD /* want THREAD of task */
lwz r5,PT_REGS(r3)
cmpwi 0,r5,0
SAVE_32VRS(0, r4, r3)
mfvscr vr0
li r4,THREAD_VSCR
stvx vr0,r4,r3
beq 1f
lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
lis r3,MSR_VEC@h
andc r4,r4,r3 /* disable AltiVec for previous task */
stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
#ifndef CONFIG_SMP
li r5,0
lis r4,last_task_used_altivec@ha
stw r5,last_task_used_altivec@l(r4)
#endif /* CONFIG_SMP */
blr
#endif /* CONFIG_ALTIVEC */
/*
* This code is jumped to from the startup code to copy