1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 .file "asm_subr.s" 28 29#include <SYS.h> 30#include <sys/regset.h> 31#include <../assym.h> 32 33 /* 34 * This is where execution resumes when a thread created with 35 * thr_create() or pthread_create() returns (see setup_context()). 36 * We pass the (void *) return value to _thrp_terminate(). 37 */ 38 ENTRY(_lwp_start) 39 movq %rax, %rdi 40 call _thrp_terminate 41 RET /* actually, never returns */ 42 SET_SIZE(_lwp_start) 43 44 /* All we need to do now is (carefully) call lwp_exit(). */ 45 ENTRY(_lwp_terminate) 46 SYSTRAP_RVAL1(lwp_exit) 47 RET /* if we return, it is very bad */ 48 SET_SIZE(_lwp_terminate) 49 50 ENTRY(set_curthread) 51 movq %rdi, %fs:0 52 ret 53 SET_SIZE(set_curthread) 54 55 ENTRY(__lwp_park) 56 movq %rsi, %rdx 57 movq %rdi, %rsi 58 movq $0, %rdi 59 SYSTRAP_RVAL1(lwp_park) 60 SYSLWPERR 61 RET 62 SET_SIZE(__lwp_park) 63 64 ENTRY(__lwp_unpark) 65 movq %rdi, %rsi 66 movq $1, %rdi 67 SYSTRAP_RVAL1(lwp_park) 68 SYSLWPERR 69 RET 70 SET_SIZE(__lwp_unpark) 71 72 ENTRY(__lwp_unpark_all) 73 movq %rsi, %rdx 74 movq %rdi, %rsi 75 movq $2, %rdi 76 SYSTRAP_RVAL1(lwp_park) 77 SYSLWPERR 78 RET 79 SET_SIZE(__lwp_unpark_all) 80 81/* 82 * __sighndlr(int sig, siginfo_t *si, ucontext_t *uc, void (*hndlr)()) 83 * 84 * This is called from sigacthandler() for the entire purpose of 85 * communicating the ucontext to java's stack tracing functions. 86 */ 87 ENTRY(__sighndlr) 88 .globl __sighndlrend 89 pushq %rbp 90 movq %rsp, %rbp 91 call *%rcx 92 leave 93 ret 94__sighndlrend: 95 SET_SIZE(__sighndlr) 96 97/* 98 * int _sigsetjmp(sigjmp_buf env, int savemask) 99 * 100 * This version is faster than the old non-threaded version because we 101 * don't normally have to call __getcontext() to get the signal mask. 102 * (We have a copy of it in the ulwp_t structure.) 103 */ 104 105#undef sigsetjmp 106 107#if SIZEOF_SIGJMP_BUF < SIZEOF_UCONTEXT_T 108 109#error "sigjmp_buf is too small to contain a ucontext_t" 110 111#else 112 113#if defined(__GNUC_AS__) 114#define REGOFF(reg) ( reg * CLONGSIZE ) 115#else 116#define REGOFF(reg) [ reg \* CLONGSIZE ] 117#endif 118 119 ENTRY2(sigsetjmp,_sigsetjmp) 120 pushq %rbp 121 movq %rsp, %rbp 122 123 /* construct a complete gregset_t for __csigsetjmp */ 124 subq $REGOFF(_NGREG), %rsp 125 movq %r15, REGOFF(REG_R15) (%rsp) 126 movq %r14, REGOFF(REG_R14) (%rsp) 127 movq %r13, REGOFF(REG_R13) (%rsp) 128 movq %r12, REGOFF(REG_R12) (%rsp) 129 movq %r11, REGOFF(REG_R11) (%rsp) 130 movq %r10, REGOFF(REG_R10) (%rsp) 131 movq %r9, REGOFF(REG_R9) (%rsp) 132 movq %r8, REGOFF(REG_R8) (%rsp) 133 movq %rdi, REGOFF(REG_RDI) (%rsp) 134 movq %rsi, REGOFF(REG_RSI) (%rsp) 135 movq %rbx, REGOFF(REG_RBX) (%rsp) 136 movq %rdx, REGOFF(REG_RDX) (%rsp) 137 movq %rcx, REGOFF(REG_RCX) (%rsp) 138 movq $0, REGOFF(REG_RAX) (%rsp) 139 movq $0, REGOFF(REG_TRAPNO) (%rsp) 140 movq $0, REGOFF(REG_ERR) (%rsp) 141 xorq %rax, %rax 142 movw %cs, %ax 143 movq %rax, REGOFF(REG_CS) (%rsp) 144 movq $0, REGOFF(REG_RFL) (%rsp) 145 movw %ss, %ax 146 movq %rax, REGOFF(REG_SS) (%rsp) 147 movw %fs, %ax 148 movq %rax, REGOFF(REG_FS) (%rsp) 149 movw %gs, %ax 150 movq %rax, REGOFF(REG_GS) (%rsp) 151 movw %es, %ax 152 movq %rax, REGOFF(REG_ES) (%rsp) 153 movw %ds, %ax 154 movq %rax, REGOFF(REG_DS) (%rsp) 155 movq %fs:0, %rax 156 movq %rax, REGOFF(REG_FSBASE) (%rsp) 157 movq $0, REGOFF(REG_GSBASE) (%rsp) 158 159 movq (%rbp), %rax /* previous %rbp */ 160 movq %rax, REGOFF(REG_RBP) (%rsp) 161 movq 8(%rbp), %rax /* previous %rip */ 162 movq %rax, REGOFF(REG_RIP) (%rsp) 163 leaq 16(%rbp), %rax /* previous %rsp */ 164 movq %rax, REGOFF(REG_RSP) (%rsp) 165 166 movq %rsp, %rdx /* pointer to gregset_t */ 167 call __csigsetjmp 168 xorq %rax, %rax 169 leave 170 ret 171 SET_SIZE(sigsetjmp) 172 SET_SIZE(_sigsetjmp) 173 174#endif /* SIZEOF_SIGJMP_BUF < SIZEOF_UCONTEXT_T */ 175