16291ad77SPeter Maydell /* 26291ad77SPeter Maydell * SPARC specific CPU ABI and functions for linux-user 36291ad77SPeter Maydell * 46291ad77SPeter Maydell * Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at> 56291ad77SPeter Maydell * Copyright (C) 2003-2005 Fabrice Bellard 66291ad77SPeter Maydell * 76291ad77SPeter Maydell * This library is free software; you can redistribute it and/or 86291ad77SPeter Maydell * modify it under the terms of the GNU Lesser General Public 96291ad77SPeter Maydell * License as published by the Free Software Foundation; either 101c79145fSChetan Pant * version 2.1 of the License, or (at your option) any later version. 116291ad77SPeter Maydell * 126291ad77SPeter Maydell * This library is distributed in the hope that it will be useful, 136291ad77SPeter Maydell * but WITHOUT ANY WARRANTY; without even the implied warranty of 146291ad77SPeter Maydell * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 156291ad77SPeter Maydell * Lesser General Public License for more details. 166291ad77SPeter Maydell * 176291ad77SPeter Maydell * You should have received a copy of the GNU Lesser General Public 186291ad77SPeter Maydell * License along with this library; if not, see <http://www.gnu.org/licenses/>. 196291ad77SPeter Maydell */ 2055c5063cSMarkus Armbruster #ifndef SPARC_TARGET_CPU_H 2155c5063cSMarkus Armbruster #define SPARC_TARGET_CPU_H 226291ad77SPeter Maydell 23*eb215f40SRichard Henderson #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) 24*eb215f40SRichard Henderson # define TARGET_STACK_BIAS 2047 25*eb215f40SRichard Henderson #else 26*eb215f40SRichard Henderson # define TARGET_STACK_BIAS 0 27*eb215f40SRichard Henderson #endif 28*eb215f40SRichard Henderson 29608999d1SRichard Henderson static inline void cpu_clone_regs_child(CPUSPARCState *env, target_ulong newsp, 30608999d1SRichard Henderson unsigned flags) 316291ad77SPeter Maydell { 322ad983e0SRichard Henderson /* 332ad983e0SRichard Henderson * After cpu_copy, env->regwptr is pointing into the old env. 342ad983e0SRichard Henderson * Update the new cpu to use its own register window. 35f5147c93SPeter Maydell */ 362ad983e0SRichard Henderson env->regwptr = env->regbase + (env->cwp * 16); 372ad983e0SRichard Henderson 382ad983e0SRichard Henderson if (newsp) { 392ad983e0SRichard Henderson /* When changing stacks, do it with clean register windows. */ 402ad983e0SRichard Henderson #ifdef TARGET_SPARC64 412ad983e0SRichard Henderson env->cansave = env->nwindows - 2; 422ad983e0SRichard Henderson env->cleanwin = env->nwindows - 2; 432ad983e0SRichard Henderson env->canrestore = 0; 442ad983e0SRichard Henderson #else 452ad983e0SRichard Henderson env->wim = 1 << env->cwp; 462ad983e0SRichard Henderson #endif 472ad983e0SRichard Henderson /* ??? The kernel appears to copy one stack frame to the new stack. */ 482ad983e0SRichard Henderson /* ??? The kernel force aligns the new stack. */ 49*eb215f40SRichard Henderson /* Userspace provides a biased stack pointer value. */ 502ad983e0SRichard Henderson env->regwptr[WREG_SP] = newsp; 512ad983e0SRichard Henderson } 522ad983e0SRichard Henderson 532ad983e0SRichard Henderson if (flags & CLONE_VM) { 542ad983e0SRichard Henderson /* 552ad983e0SRichard Henderson * Syscall return for clone child: %o0 = 0 and clear CF since this 562ad983e0SRichard Henderson * counts as a success return value. Advance the PC past the syscall. 572ad983e0SRichard Henderson * For fork child, all of this happens in cpu_loop, and we must not 582ad983e0SRichard Henderson * do the pc advance twice. 592ad983e0SRichard Henderson */ 602ad983e0SRichard Henderson env->regwptr[WREG_O0] = 0; 61f5147c93SPeter Maydell #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) 62f5147c93SPeter Maydell env->xcc &= ~PSR_CARRY; 63f5147c93SPeter Maydell #else 64f5147c93SPeter Maydell env->psr &= ~PSR_CARRY; 65f5147c93SPeter Maydell #endif 662ad983e0SRichard Henderson env->pc = env->npc; 672ad983e0SRichard Henderson env->npc = env->npc + 4; 682ad983e0SRichard Henderson } 692ad983e0SRichard Henderson 702ad983e0SRichard Henderson /* Set the second return value for the child: %o1 = 1. */ 712ad983e0SRichard Henderson env->regwptr[WREG_O1] = 1; 726291ad77SPeter Maydell } 736291ad77SPeter Maydell 7407a6ecf4SRichard Henderson static inline void cpu_clone_regs_parent(CPUSPARCState *env, unsigned flags) 7507a6ecf4SRichard Henderson { 762ad983e0SRichard Henderson /* Set the second return value for the parent: %o1 = 0. */ 772ad983e0SRichard Henderson env->regwptr[WREG_O1] = 0; 7807a6ecf4SRichard Henderson } 7907a6ecf4SRichard Henderson 80f5147c93SPeter Maydell static inline void cpu_set_tls(CPUSPARCState *env, target_ulong newtls) 81f5147c93SPeter Maydell { 82f5147c93SPeter Maydell env->gregs[7] = newtls; 83f5147c93SPeter Maydell } 846291ad77SPeter Maydell 859850f9f6SLaurent Vivier static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state) 869850f9f6SLaurent Vivier { 87*eb215f40SRichard Henderson return state->regwptr[WREG_SP] + TARGET_STACK_BIAS; 889850f9f6SLaurent Vivier } 89083244d3SRichard Henderson 906291ad77SPeter Maydell #endif 91