Revise for LP64.

Encapsulate previously copied code sections into macros.
This commit is contained in:
ross 2006-07-08 05:09:44 +00:00
parent 032dc727f7
commit a228aa3de2
4 changed files with 696 additions and 0 deletions

View File

@ -0,0 +1,189 @@
/* $NetBSD: _context_u.S,v 1.1 2006/07/08 05:09:44 ross Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Allen Briggs for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <machine/asm.h>
#include "assym.h"
/*
* Define:
* int _getcontext_u(ucontext_t *ctx)
* Store the current context in the provided ctx structure.
* [only store the callee-saved registers]
* int _setcontext_u(const ucontext_t *ctx)
* Restore the current context from the provided ctx structure.
* int _swapcontext_u(ucontext_t *from_ctx, const ucontext_t *to_ctx)
* First, store the current context into from_ctx and then
* restore the current context from the to_ctx.
*/
/*
* According to the SVR4 ABI for PPC, r1, r14-r31, LR, and portions of the
* CR are non-volatile. I.e., they need to be preserved across the function
* call.
*
* If _getcontext_u is called, set the UC_USER_BIT in the UC_FLAGS. If
* _setcontext_u sees that bit, then it will just restore this part of the
* context, otherwise, it will call through to setcontext(2).
*/
/*
* Arrange to not include FP save/restore on a soft-float
* build. Thread switching shouldn't consume 40 system traps.
*/
#ifdef _SOFT_FLOAT
#define FPUFLAG 0
#define GETFP(reg)
#define SETFP
#else
#define FPUFLAG _UC_FPU
#define GETFP(reg) \
mffs %r0 ; \
stfd %r0, (_REG_FPSCR - 4)(reg) ; \
stfd %r14, (_REG_FP0 + 14*8)(reg) ; \
stfd %r15, (_REG_FP0 + 15*8)(reg) ; \
stfd %r16, (_REG_FP0 + 16*8)(reg) ; \
stfd %r17, (_REG_FP0 + 17*8)(reg) ; \
stfd %r18, (_REG_FP0 + 18*8)(reg) ; \
stfd %r19, (_REG_FP0 + 19*8)(reg) ; \
stfd %r20, (_REG_FP0 + 20*8)(reg) ; \
stfd %r21, (_REG_FP0 + 21*8)(reg) ; \
stfd %r22, (_REG_FP0 + 22*8)(reg) ; \
stfd %r23, (_REG_FP0 + 23*8)(reg) ; \
stfd %r24, (_REG_FP0 + 24*8)(reg) ; \
stfd %r25, (_REG_FP0 + 25*8)(reg) ; \
stfd %r26, (_REG_FP0 + 26*8)(reg) ; \
stfd %r27, (_REG_FP0 + 27*8)(reg) ; \
stfd %r28, (_REG_FP0 + 28*8)(reg) ; \
stfd %r29, (_REG_FP0 + 29*8)(reg) ; \
stfd %r30, (_REG_FP0 + 30*8)(reg) ; \
stfd %r31, (_REG_FP0 + 31*8)(reg)
#define SETFP \
andi. %r5, %r3, _UC_FPU ; \
beq 1f ; \
; \
lwz %r5, (_UC_FPVALID)(%r4) ; \
or. %r5, %r5, %r5 ; \
beq 1f ; \
; \
lfd %r14, (_REG_FP0 + 14*8)(%r4) ; \
lfd %r15, (_REG_FP0 + 15*8)(%r4) ; \
lfd %r16, (_REG_FP0 + 16*8)(%r4) ; \
lfd %r17, (_REG_FP0 + 17*8)(%r4) ; \
lfd %r18, (_REG_FP0 + 18*8)(%r4) ; \
lfd %r19, (_REG_FP0 + 19*8)(%r4) ; \
lfd %r20, (_REG_FP0 + 20*8)(%r4) ; \
lfd %r21, (_REG_FP0 + 21*8)(%r4) ; \
lfd %r22, (_REG_FP0 + 22*8)(%r4) ; \
lfd %r23, (_REG_FP0 + 23*8)(%r4) ; \
lfd %r24, (_REG_FP0 + 24*8)(%r4) ; \
lfd %r25, (_REG_FP0 + 25*8)(%r4) ; \
lfd %r26, (_REG_FP0 + 26*8)(%r4) ; \
lfd %r27, (_REG_FP0 + 27*8)(%r4) ; \
lfd %r28, (_REG_FP0 + 28*8)(%r4) ; \
lfd %r29, (_REG_FP0 + 29*8)(%r4) ; \
lfd %r30, (_REG_FP0 + 30*8)(%r4) ; \
lfd %r31, (_REG_FP0 + 31*8)(%r4) ; \
lfd %r0, (_REG_FPSCR - 4)(%r4) ; \
mtfsf 0xff, %r0 ; \
1:
#endif
#define GETC(reg) \
std %r1, (_REG_R0 + 1*8)(reg) ; \
i = 0 ; \
.rept 31-14+1 ; \
std 14+i,[_REG_R0+[[14+i]*8]](reg) ; \
i = i+1 ; \
.endr ; \
mfcr %r0 ; \
std %r0, _REG_CR(reg) ; \
mflr %r0 ; \
std %r0, _REG_LR(reg) ; \
std %r0, _REG_PC(reg) ; \
; \
GETFP(reg) ; \
; \
li %r8, 1 ; \
stw %r8, (_UC_FPVALID)(reg) ; \
slwi %r9, %r8, _UC_USER_BIT ; \
ori %r9, %r9, (_UC_CPU | FPUFLAG) ; \
stw %r9, (UC_FLAGS)(reg)
#define SETC \
li %r9, 1 ; \
slwi %r9, %r9, _UC_USER_BIT ; \
lwz %r3, (UC_FLAGS)(%r4) ; \
and. %r9, %r3, %r9 ; \
beq 2f ; \
; \
lwz %r1, (_REG_R0 + 1*4)(%r4) ; \
/* lmw %r14, (_REG_R0 + 14*4)(%r4) */ ; \
i = 0 ; \
.rept 31-14+1 ; \
ld 14+i,[_REG_R0+[[14+i]*8]](%r4) ;\
i = i+1 ; \
.endr ; \
lwz %r0, _REG_LR(%r4) ; \
mtlr %r0 ; \
lwz %r0, _REG_PC(%r4) ; \
mtctr %r0 ; \
; \
SETFP ; \
; \
lwz %r0, _REG_CR(%r4) ; \
mtcr %r0 ; \
bctr ; \
2: ; \
mr %r3, %r4 ; \
b .setcontext ; \
nop ; \
/* NOTREACHED */
ENTRY(_getcontext_u)
GETC(%r3)
xor %r3,%r3,%r3
blr
ENTRY(_setcontext_u)
mr %r4,%r3
SETC
ENTRY(_swapcontext_u)
GETC(%r3)
SETC

View File

@ -0,0 +1,72 @@
# $NetBSD: genassym.cf,v 1.1 2006/07/08 05:09:44 ross Exp $
# Copyright (c) 2001 Wasabi Systems, Inc.
# All rights reserved.
#
# Written by Allen Briggs for Wasabi Systems, Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed for the NetBSD Project by
# Wasabi Systems, Inc.
# 4. The name of Wasabi Systems, Inc. may not be used to endorse
# or promote products derived from this software without specific prior
# written permission.
#
# THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
include <ucontext.h>
include <sys/queue.h>
include "pthread.h"
include "pthread_int.h"
include "pthread_md.h"
# for _context_u.S
define UC_FLAGS offsetof(ucontext_t, uc_flags)
define _UC_FPVALID offsetof(ucontext_t, uc_mcontext.__fpregs.__fpu_valid)
define _REG_R0 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_R0])
define _REG_CR offsetof(ucontext_t, uc_mcontext.__gregs[_REG_CR])
define _REG_LR offsetof(ucontext_t, uc_mcontext.__gregs[_REG_LR])
define _REG_PC offsetof(ucontext_t, uc_mcontext.__gregs[_REG_PC])
define _REG_MSR offsetof(ucontext_t, uc_mcontext.__gregs[_REG_MSR])
define _REG_CTR offsetof(ucontext_t, uc_mcontext.__gregs[_REG_CTR])
define _REG_XER offsetof(ucontext_t, uc_mcontext.__gregs[_REG_XER])
define _REG_FP0 offsetof(ucontext_t, uc_mcontext.__fpregs.__fpu_regs[0])
define _REG_FPSCR offsetof(ucontext_t, uc_mcontext.__fpregs.__fpu_fpscr)
# uc_flags
define _UC_CPU _UC_CPU
define _UC_FPU _UC_FPU
define _UC_USER_BIT _UC_USER_BIT
#========================================================================
# for pthread_switch.S
define PT_UC offsetof(struct __pthread_st, pt_uc)
define PT_TRAPUC offsetof(struct __pthread_st, pt_trapuc)
define PT_NEXT offsetof(struct __pthread_st, pt_next)
define PT_SPINLOCKS offsetof(struct __pthread_st, pt_spinlocks)
define PT_SWITCHTO offsetof(struct __pthread_st, pt_switchto)
define PT_SWITCHTOUC offsetof(struct __pthread_st, pt_switchtouc)
define PT_HELDLOCK offsetof(struct __pthread_st, pt_heldlock)
define CONTEXTSIZE sizeof(ucontext_t)
define STACKSPACE STACKSPACE

View File

@ -0,0 +1,125 @@
/* $NetBSD: pthread_md.h,v 1.1 2006/07/08 05:09:44 ross Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Allen Briggs for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LIB_PTHREAD_POWERPC_MD_H
#define _LIB_PTHREAD_POWERPC_MD_H
static inline long
pthread__sp(void)
{
long ret;
__asm("mr %0,1" : "=r" (ret));
return ret;
}
#define pthread__uc_sp(ucp) ((ucp)->uc_mcontext.__gregs[1])
#define pthread__uc_pc(ucp) ((ucp)->uc_mcontext.__gregs[34])
/*
* Set initial, sane values for registers whose values aren't just
* "don't care".
* 0xd032 is PSL_USERSET from arch/powerpc/include/psl.h
*/
#define _INITCONTEXT_U_MD(ucp) \
(ucp)->uc_mcontext.__gregs[_REG_MSR] = 0xd032;
/*
* Usable stack space below the ucontext_t.
* For a good time, see comments in pthread_switch.S and
* ../i386/pthread_switch.S about STACK_SWITCH.
*/
#define STACKSPACE 16 /* room for 4 integer values */
/*
* Conversions between struct reg and struct mcontext. Used by
* libpthread_dbg.
*/
#define PTHREAD_UCONTEXT_TO_REG(reg, uc) do { \
memcpy((reg)->fixreg, (uc)->uc_mcontext.__gregs, 32 * 4); \
(reg)->cr = (uc)->uc_mcontext.__gregs[_REG_CR]; \
(reg)->lr = (uc)->uc_mcontext.__gregs[_REG_LR]; \
(reg)->pc = (uc)->uc_mcontext.__gregs[_REG_PC]; \
(reg)->ctr = (uc)->uc_mcontext.__gregs[_REG_CTR]; \
(reg)->xer = (uc)->uc_mcontext.__gregs[_REG_XER]; \
} while (/*CONSTCOND*/0)
#define PTHREAD_REG_TO_UCONTEXT(uc, reg) do { \
memcpy((uc)->uc_mcontext.__gregs, (reg)->fixreg, 32 * 4); \
(uc)->uc_mcontext.__gregs[_REG_CR] = (reg)->cr; \
(uc)->uc_mcontext.__gregs[_REG_LR] = (reg)->lr; \
(uc)->uc_mcontext.__gregs[_REG_PC] = (reg)->pc; \
(uc)->uc_mcontext.__gregs[_REG_CTR] = (reg)->ctr; \
(uc)->uc_mcontext.__gregs[_REG_XER] = (reg)->xer; \
(uc)->uc_flags = ((uc)->uc_flags | _UC_CPU) & ~_UC_USER; \
} while (/*CONSTCOND*/0)
#define PTHREAD_UCONTEXT_TO_FPREG(freg, uc) do { \
memcpy((freg)->fpreg, (uc)->uc_mcontext.__fpregs.__fpu_regs, \
32 * 4); \
(freg)->fpscr = (uc)->uc_mcontext.__fpregs.__fpu_fpscr; \
} while (/*CONSTCOND*/0)
#define PTHREAD_FPREG_TO_UCONTEXT(uc, freg) do { \
memcpy((uc)->uc_mcontext.__fpregs.__fpu_regs, (freg)->fpreg, \
32 * 4); \
(uc)->uc_mcontext.__fpregs.__fpu_fpscr = (freg)->fpscr; \
(uc)->uc_flags = ((uc)->uc_flags | _UC_FPU) & ~_UC_USER; \
} while (/*CONSTCOND*/0)
#define PTHREAD_UCONTEXT_XREG_FLAG _UC_POWERPC_VEC
#define PTHREAD_UCONTEXT_TO_XREG(xreg, uc) do { \
memcpy(((struct vreg *)(xreg))->vreg, \
(uc)->uc_mcontext.__vrf.__vrs, \
16 * _NVR); \
((struct vreg *)(xreg))->vscr = (uc)->uc_mcontext.__vrf.__vscr; \
((struct vreg *)(xreg))->vrsave = (uc)->uc_mcontext.__vrf.__vrsave; \
} while (/*CONSTCOND*/0)
#define PTHREAD_XREG_TO_UCONTEXT(uc, xreg) do { \
memcpy((uc)->uc_mcontext.__vrf.__vrs, \
((struct vreg *)(xreg))->vreg, \
16 * _NVR); \
(uc)->uc_mcontext.__vrf.__vscr = ((struct vreg *)(xreg))->vscr; \
(uc)->uc_mcontext.__vrf.__vrsave = ((struct vreg *)(xreg))->vrsave; \
(uc)->uc_flags = ((uc)->uc_flags | _UC_POWERPC_VEC) & ~_UC_USER; \
} while (/*CONSTCOND*/0)
#endif /* _LIB_PTHREAD_POWERPC_MD_H */

View File

@ -0,0 +1,310 @@
/* $NetBSD: pthread_switch.S,v 1.1 2006/07/08 05:09:44 ross Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Allen Briggs for Wasabi Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <machine/asm.h>
#include "assym.h"
#define NOTREACHED
/*
* PowerPC ABI says stack pointer must be 16-byte aligned.
*/
#define RND_CTXSIZE ((CONTEXTSIZE + 15) & 0xfffffff0)
/*
* Define:
* void pthread__switch(pthread_t self, pthread_t next)
* void pthread__upcall_switch(pthread_t self, pthread_t next)
* void pthread__locked_switch(pthread_t self, pthread_t next,
* pt_spin_t *lock)
*/
/*
* Evil STACK_SWITCH()
* See comments in ../i386/pthread_switch.S.
*/
#define STACK_SWITCH(pt,tmp,z) \
ld tmp, PT_TRAPUC(pt) ; \
or. tmp, tmp, tmp ; \
bne 1f ; \
ld tmp, PT_UC(pt) ; \
1: la %r1, -STACKSPACE(tmp) ; \
li z, 0 ; \
std z, PT_TRAPUC(pt)
/*
* void
* pthread__switch(pthread_t self (%r3), pthread_t next (%r4))
*
* Plain switch that doesn't do any special checking or handle spin-
* preemption. It isn't used much by normal code, actually; its main
* purpose is to be a basic switch engine when the MI code is already
* dealing with spin-preemption or other gunk.
*
* What we do here is allocate the ucontext for the 'self' thread on its
* stack, saving the pointer in self's pthread structure, then swapping
* context to 'next', effectively deallocating next's context on the way
* out.
*
* Stack:
* ------------------------------------------------------------------
* highest addresses
* saved r31 8 (offset is framesize - 8)
* pad 8 pad r31 space up to 16
* pad to round ucontext_t up to a 16 byte boundary
* ucontext_t (offset is SF_SZ )
* other elf stack frame (SF_PARAM_SZ )
* elf stack frame header (SF_HEADER_SZ )
* lowest addresses
* ------------------------------------------------------------------
*/
ENTRY(pthread__switch)
frameSize = SF_SZ + RND_CTXSIZE + 16 # need +8 for r31, & align
saved31 = frameSize - 8
.macro init_frame
stdu %r1, -frameSize(%r1) /* alloc stack space */
mflr %r0
std %r31,saved31(%r1)
std %r3, SF_PARAM+0(%r1) /* self */
std %r4, SF_PARAM+8(%r1) /* next */
std %r5, SF_PARAM+16(%r1) /* lock, for locked_switch */
std %r0, frameSize+SF_LR(%r1) /* Save return address */
la %r31, SF_SZ(%r1) /* %r31 = ucontext */
.endm
init_frame
.macro switch_context
/* Get the current context */
mr %r3, %r31
CALL(_getcontext_u)
ld %r3, SF_PARAM+0(%r1)
ld %r4, SF_PARAM+8(%r1)
ld %r5, SF_PARAM+16(%r1)
/*
* Edit the context to make it continue at switch_return instead of
* here.
*/
ld %r6, pthread__common_return@got(%r2)
std %r6, SF_SZ+_REG_PC(%r1)
std %r31, PT_UC(%r3)
STACK_SWITCH(%r4, %r7, %r6)
.endm
switch_context
.macro set_context
mr %r3, %r7
b ._setcontext_u
.endm
set_context
NOTREACHED
pthread__switch_away:
STACK_SWITCH(%r4, %r6, %r7)
or. %r5, %r5, %r5
beq 1f
lwz %r7, PT_SPINLOCKS(%r3) # w OK
addi %r7, %r7, -1
stw %r7, PT_SPINLOCKS(%r3) # w OK
1: mr %r3, %r6
b ._setcontext_u
NOTREACHED
/*
* void
* pthread__upcall_switch(pthread_t self (%r3), pthread_t next (%r4))
*/
ENTRY(pthread__upcall_switch)
lwz %r6, PT_SPINLOCKS(%r4) # w OK
addi %r6, %r6, 1
stw %r6, PT_SPINLOCKS(%r4) # w OK
STACK_SWITCH(%r4, %r5, %r6)
ld %r7, PT_NEXT(%r3)
or. %r7, %r7, %r7
beq 1f
std %r5, PT_SWITCHTOUC(%r3)
std %r4, PT_SWITCHTO(%r3)
mr %r3, %r4
mr %r4, %r7
li %r5, 1
b pthread__switch_away
NOTREACHED
1: mr %r14, %r3
mr %r15, %r4
mr %r16, %r5
CALL(pthread__sa_recycle)
mr %r3, %r14
mr %r4, %r15
mr %r5, %r16
lwz %r6, PT_SPINLOCKS(%r4) # w OK
addi %r6, %r6, -1
stw %r6, PT_SPINLOCKS(%r4) # w OK
ld %r7, PT_NEXT(%r4)
or. %r7, %r7, %r7
beq 2f
std %r5, PT_SWITCHTOUC(%r4)
std %r4, PT_SWITCHTO(%r4)
mr %r3, %r4
mr %r4, %r7
li %r5, 0
b pthread__switch_away
NOTREACHED
2: mr %r3, %r16
b ._setcontext_u
NOTREACHED
/*
* void
* pthread__locked_switch(pthread_t self (%r3), pthread_t next (%r4),
* pt_spin_t *lock (%r5))
*
* THIS STACK FRAME APPLIES ONLY TO THE ORIGINAL ILP32 CODE
*
* Stack is:
* high addr -- return addr ( 4 bytes)
* %r1@call caller saved %r1 ( 4 bytes)
* any padding to make %r1 a multiple of 16 ... *
* saved %r31 ( 4 bytes) *
* saved %r9 ( 4 bytes) *
* saved %r5 ( 4 bytes) *
* saved %r4 ( 4 bytes) *
* saved %r3 ( 4 bytes) *
* context (RND_CTXSIZE bytes) *
* padding to 16 bytes ( 20 bytes) *
* space for callee ra ( 4 bytes) *
* low addr p__l_s saved %r1 ( 4 bytes) *
*
* STACKSPACE is the space between the bottom of the stack and
* the ucontext on the stack. i.e., 8, but we want to keep the stack
* rounded to a multiple of 16, so it's really 16.
*/
.type locked_return,@function
ENTRY(pthread__locked_switch)
init_frame
/* increment spinlock to make sure that next gets continued */
lwz %r6, PT_SPINLOCKS(%r4) # w OK
addi %r6, %r6, 1
stw %r6, PT_SPINLOCKS(%r4) # w OK
switch_context
/* Check if the switcher was preempted and continued to here. */
ld %r8, PT_NEXT(%r3)
or. %r8, %r8, %r8
beq 1f
/*
* Yes, it was. Stash the thread we were going to switch to,
* the lock the original thread was holding, and switch to the
* next thread in the continuation chain. Mark the fact that
* this was a locked switch, and so the thread does not need to
* be put on a run queue.
* Don't release the lock. It's possible that if we do so,
* PT_SWITCHTO will be stomped by another switch_lock and preemption.
*/
std %r5, PT_HELDLOCK(%r3)
std %r7, PT_SWITCHTOUC(%r3)
std %r4, PT_SWITCHTO(%r3)
lwz %r6, PT_SPINLOCKS(%r3) # w OK
addi %r6, %r6, -1
stw %r6, PT_SPINLOCKS(%r3) # w OK
mr %r3, %r4
mr %r4, %r8
li %r5, 1
b pthread__switch_away
NOTREACHED
/* No locked old-preemption */
1: /*
* We've moved to the new stack, and the old context has been
* saved. The queue lock can be released.
*/
/* Reduce the lock count... */
lwz %r6, PT_SPINLOCKS(%r3) # w OK
addi %r6, %r6, -1
stw %r6, PT_SPINLOCKS(%r3) # w OK
/* ... actually release the lock ... */
sync
xor %r9,%r9,%r9
std %r9, 0(%r5)
/* ... and remove the fake lock */
lwz %r6, PT_SPINLOCKS(%r4) # w OK
addi %r6, %r6, -1
stw %r6, PT_SPINLOCKS(%r4) # w OK
/* Check to see if we were preempted while holding the fake lock */
ld %r8, PT_NEXT(%r4)
or. %r8, %r8, %r8
beq 2f
/* Yes, we were. Go to the next element in the chain. */
std %r7, PT_SWITCHTOUC(%r4)
std %r4, PT_SWITCHTO(%r4)
mr %r3, %r4
mr %r4, %r8
li %r5, 0
b pthread__switch_away
NOTREACHED
2: set_context
NOTREACHED
ENTRY(pthread__common_return)
ld %r31, saved31(%r1)
ld %r0, frameSize+SF_LR(%r1)
la %r1, frameSize(%r1)
mtlr %r0
blr