NetBSD-5.0.2/lib/libpthread/arch/hppa/_context_u.S
/* $NetBSD: _context_u.S,v 1.4 2008/08/11 21:45:24 skrll Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Wayne Knowles
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 THE FOUNDATION OR CONTRIBUTORS
* 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 <machine/mcontext.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.
*/
/* Macro to Save the callee-save register set */
#define GETC(reg) ! \
stw %r3, (UC_REGS + 3 * SZREG)(reg) ! \
stw %r4, (UC_REGS + 4 * SZREG)(reg) ! \
stw %r5, (UC_REGS + 5 * SZREG)(reg) ! \
stw %r6, (UC_REGS + 6 * SZREG)(reg) ! \
stw %r7, (UC_REGS + 7 * SZREG)(reg) ! \
stw %r8, (UC_REGS + 8 * SZREG)(reg) ! \
stw %r9, (UC_REGS + 9 * SZREG)(reg) ! \
stw %r10, (UC_REGS + 10 * SZREG)(reg) ! \
stw %r11, (UC_REGS + 11 * SZREG)(reg) ! \
stw %r12, (UC_REGS + 12 * SZREG)(reg) ! \
stw %r13, (UC_REGS + 13 * SZREG)(reg) ! \
stw %r14, (UC_REGS + 14 * SZREG)(reg) ! \
stw %r15, (UC_REGS + 15 * SZREG)(reg) ! \
stw %r16, (UC_REGS + 16 * SZREG)(reg) ! \
stw %r17, (UC_REGS + 17 * SZREG)(reg) ! \
stw %r18, (UC_REGS + 18 * SZREG)(reg) ! \
stw %dp, (UC_REGS + 27 * SZREG)(reg) ! \
stw %sp, (UC_REGS + 30 * SZREG)(reg) ! \
stw %rp, (UC_REGS + 2 * SZREG)(reg) ! \
stw %rp, (UC_REGS + 35 * SZREG)(reg) ! \
ldil L%_UC_USER, %r1 ! \
ldo _UC_CPU(%r1), %r1 ! \
stw %r1, (UC_FLAGS)(reg)
#ifdef PIC
#define LDADDR ! \
addil LT%_C_LABEL(setcontext), %r19 ! \
ldo RT%_C_LABEL(setcontext)(%r1), %r1 ! \
bb,<,n %r1, 30, 99f ! \
depi 0, 31, 2, %r1 ! \
ldw 0(%r1), %rp ! \
ldw 4(%r1), %r19 ! \
99:
#else
#define LDADDR ! \
ldil L%_C_LABEL(setcontext), %rp ! \
ldo R%_C_LABEL(setcontext)(%rp), %rp
#endif
#define SETC(reg) ! \
ldw (UC_FLAGS)(reg), %r1 ! \
bb,>=,n %r1, (31 - _UC_USER_BIT), 1f ! \
ldw (UC_REGS + 3 * SZREG)(reg), %r3 ! \
ldw (UC_REGS + 4 * SZREG)(reg), %r4 ! \
ldw (UC_REGS + 5 * SZREG)(reg), %r5 ! \
ldw (UC_REGS + 6 * SZREG)(reg), %r6 ! \
ldw (UC_REGS + 7 * SZREG)(reg), %r7 ! \
ldw (UC_REGS + 8 * SZREG)(reg), %r8 ! \
ldw (UC_REGS + 9 * SZREG)(reg), %r9 ! \
ldw (UC_REGS + 10 * SZREG)(reg), %r10 ! \
ldw (UC_REGS + 11 * SZREG)(reg), %r11 ! \
ldw (UC_REGS + 12 * SZREG)(reg), %r12 ! \
ldw (UC_REGS + 13 * SZREG)(reg), %r13 ! \
ldw (UC_REGS + 14 * SZREG)(reg), %r14 ! \
ldw (UC_REGS + 15 * SZREG)(reg), %r15 ! \
ldw (UC_REGS + 16 * SZREG)(reg), %r16 ! \
ldw (UC_REGS + 17 * SZREG)(reg), %r17 ! \
ldw (UC_REGS + 18 * SZREG)(reg), %r18 ! \
ldw (UC_REGS + 27 * SZREG)(reg), %dp ! \
ldw (UC_REGS + 30 * SZREG)(reg), %sp ! \
ldw (UC_REGS + 2 * SZREG)(reg), %rp ! \
/* part procedure call, part RET */ ! \
ldw (UC_REGS + _REG_PCOQH * SZREG)(reg), %r1! \
bv,n %r0(%r1) ! \
/* NOTREACHED */ ! \
! \
1: ! \
LDADDR ! \
bv,n %r0(%rp) ! \
/* NOTREACHED */
ENTRY(_getcontext_u, 0)
GETC(%arg0)
bv %r0(%rp)
copy %r0, %ret0
EXIT(_getcontext_u)
ENTRY(_setcontext_u, 0)
SETC(%arg0)
EXIT(_setcontext_u)
ENTRY(_swapcontext_u, 0)
GETC(%arg0)
SETC(%arg1)
EXIT(_swapcontext_u)
LEAF_ENTRY(pthread__ras_simple_lock_init)
ldi 1,%ret0 /* 1 == unlocked */
stw %ret0,0(%arg0)
stw %ret0,4(%arg0)
stw %ret0,8(%arg0)
stw %ret0,12(%arg0)
bv,n %r0(%rp)
EXIT(pthread__ras_simple_lock_init)
.global pthread__lock_ras_start
.global pthread__lock_ras_end
LEAF_ENTRY(pthread__ras_simple_lock_try)
ldo 15(%arg0),%arg0
depi 0,31,4,%arg0
pthread__lock_ras_start:
ldw 0(%arg0),%ret0
stw %r0,0(%arg0) /* 0 == locked */
pthread__lock_ras_end:
comiclr,= 0,%ret0,%ret0 /* if locked return 0 */
ldi 1,%ret0 /* else return 1 */
bv,n %r0(%rp)
EXIT(pthread__ras_simple_lock_try)
LEAF_ENTRY(pthread__ras_simple_unlock)
ldo 15(%arg0),%arg0
depi 0,31,4,%arg0
ldi 1,%ret0 /* 1 == unlocked */
bv %r0(%rp)
stw %ret0,0(%arg0)
EXIT(pthread__ras_simple_unlock)