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 106291ad77SPeter Maydell * version 2 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 23608999d1SRichard Henderson static inline void cpu_clone_regs_child(CPUSPARCState *env, target_ulong newsp, 24608999d1SRichard Henderson unsigned flags) 256291ad77SPeter Maydell { 26*2ad983e0SRichard Henderson /* 27*2ad983e0SRichard Henderson * After cpu_copy, env->regwptr is pointing into the old env. 28*2ad983e0SRichard Henderson * Update the new cpu to use its own register window. 29f5147c93SPeter Maydell */ 30*2ad983e0SRichard Henderson env->regwptr = env->regbase + (env->cwp * 16); 31*2ad983e0SRichard Henderson 32*2ad983e0SRichard Henderson if (newsp) { 33*2ad983e0SRichard Henderson /* When changing stacks, do it with clean register windows. */ 34*2ad983e0SRichard Henderson #ifdef TARGET_SPARC64 35*2ad983e0SRichard Henderson env->cansave = env->nwindows - 2; 36*2ad983e0SRichard Henderson env->cleanwin = env->nwindows - 2; 37*2ad983e0SRichard Henderson env->canrestore = 0; 38*2ad983e0SRichard Henderson #else 39*2ad983e0SRichard Henderson env->wim = 1 << env->cwp; 40*2ad983e0SRichard Henderson #endif 41*2ad983e0SRichard Henderson /* ??? The kernel appears to copy one stack frame to the new stack. */ 42*2ad983e0SRichard Henderson /* ??? The kernel force aligns the new stack. */ 43*2ad983e0SRichard Henderson env->regwptr[WREG_SP] = newsp; 44*2ad983e0SRichard Henderson } 45*2ad983e0SRichard Henderson 46*2ad983e0SRichard Henderson if (flags & CLONE_VM) { 47*2ad983e0SRichard Henderson /* 48*2ad983e0SRichard Henderson * Syscall return for clone child: %o0 = 0 and clear CF since this 49*2ad983e0SRichard Henderson * counts as a success return value. Advance the PC past the syscall. 50*2ad983e0SRichard Henderson * For fork child, all of this happens in cpu_loop, and we must not 51*2ad983e0SRichard Henderson * do the pc advance twice. 52*2ad983e0SRichard Henderson */ 53*2ad983e0SRichard Henderson env->regwptr[WREG_O0] = 0; 54f5147c93SPeter Maydell #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) 55f5147c93SPeter Maydell env->xcc &= ~PSR_CARRY; 56f5147c93SPeter Maydell #else 57f5147c93SPeter Maydell env->psr &= ~PSR_CARRY; 58f5147c93SPeter Maydell #endif 59*2ad983e0SRichard Henderson env->pc = env->npc; 60*2ad983e0SRichard Henderson env->npc = env->npc + 4; 61*2ad983e0SRichard Henderson } 62*2ad983e0SRichard Henderson 63*2ad983e0SRichard Henderson /* Set the second return value for the child: %o1 = 1. */ 64*2ad983e0SRichard Henderson env->regwptr[WREG_O1] = 1; 656291ad77SPeter Maydell } 666291ad77SPeter Maydell 6707a6ecf4SRichard Henderson static inline void cpu_clone_regs_parent(CPUSPARCState *env, unsigned flags) 6807a6ecf4SRichard Henderson { 69*2ad983e0SRichard Henderson /* Set the second return value for the parent: %o1 = 0. */ 70*2ad983e0SRichard Henderson env->regwptr[WREG_O1] = 0; 7107a6ecf4SRichard Henderson } 7207a6ecf4SRichard Henderson 73f5147c93SPeter Maydell static inline void cpu_set_tls(CPUSPARCState *env, target_ulong newtls) 74f5147c93SPeter Maydell { 75f5147c93SPeter Maydell env->gregs[7] = newtls; 76f5147c93SPeter Maydell } 776291ad77SPeter Maydell 789850f9f6SLaurent Vivier static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state) 799850f9f6SLaurent Vivier { 80083244d3SRichard Henderson return state->regwptr[WREG_SP]; 819850f9f6SLaurent Vivier } 82083244d3SRichard Henderson 836291ad77SPeter Maydell #endif 84