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 23eb215f40SRichard Henderson #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) 24eb215f40SRichard Henderson # define TARGET_STACK_BIAS 2047 25eb215f40SRichard Henderson #else 26eb215f40SRichard Henderson # define TARGET_STACK_BIAS 0 27eb215f40SRichard Henderson #endif 28eb215f40SRichard Henderson 29*2a1905c7SRichard Henderson static void set_syscall_C(CPUSPARCState *env, bool val) 30*2a1905c7SRichard Henderson { 31*2a1905c7SRichard Henderson #ifndef TARGET_SPARC64 32*2a1905c7SRichard Henderson env->icc_C = val; 33*2a1905c7SRichard Henderson #elif defined(TARGET_ABI32) 34*2a1905c7SRichard Henderson env->icc_C = (uint64_t)val << 32; 35*2a1905c7SRichard Henderson #else 36*2a1905c7SRichard Henderson env->xcc_C = val; 37*2a1905c7SRichard Henderson #endif 38*2a1905c7SRichard Henderson } 39*2a1905c7SRichard Henderson 40608999d1SRichard Henderson static inline void cpu_clone_regs_child(CPUSPARCState *env, target_ulong newsp, 41608999d1SRichard Henderson unsigned flags) 426291ad77SPeter Maydell { 432ad983e0SRichard Henderson /* 442ad983e0SRichard Henderson * After cpu_copy, env->regwptr is pointing into the old env. 452ad983e0SRichard Henderson * Update the new cpu to use its own register window. 46f5147c93SPeter Maydell */ 472ad983e0SRichard Henderson env->regwptr = env->regbase + (env->cwp * 16); 482ad983e0SRichard Henderson 492ad983e0SRichard Henderson if (newsp) { 502ad983e0SRichard Henderson /* When changing stacks, do it with clean register windows. */ 512ad983e0SRichard Henderson #ifdef TARGET_SPARC64 522ad983e0SRichard Henderson env->cansave = env->nwindows - 2; 532ad983e0SRichard Henderson env->cleanwin = env->nwindows - 2; 542ad983e0SRichard Henderson env->canrestore = 0; 552ad983e0SRichard Henderson #else 562ad983e0SRichard Henderson env->wim = 1 << env->cwp; 572ad983e0SRichard Henderson #endif 582ad983e0SRichard Henderson /* ??? The kernel appears to copy one stack frame to the new stack. */ 592ad983e0SRichard Henderson /* ??? The kernel force aligns the new stack. */ 60eb215f40SRichard Henderson /* Userspace provides a biased stack pointer value. */ 612ad983e0SRichard Henderson env->regwptr[WREG_SP] = newsp; 622ad983e0SRichard Henderson } 632ad983e0SRichard Henderson 642ad983e0SRichard Henderson if (flags & CLONE_VM) { 652ad983e0SRichard Henderson /* 662ad983e0SRichard Henderson * Syscall return for clone child: %o0 = 0 and clear CF since this 672ad983e0SRichard Henderson * counts as a success return value. Advance the PC past the syscall. 682ad983e0SRichard Henderson * For fork child, all of this happens in cpu_loop, and we must not 692ad983e0SRichard Henderson * do the pc advance twice. 702ad983e0SRichard Henderson */ 712ad983e0SRichard Henderson env->regwptr[WREG_O0] = 0; 72*2a1905c7SRichard Henderson set_syscall_C(env, 0); 732ad983e0SRichard Henderson env->pc = env->npc; 742ad983e0SRichard Henderson env->npc = env->npc + 4; 752ad983e0SRichard Henderson } 762ad983e0SRichard Henderson 772ad983e0SRichard Henderson /* Set the second return value for the child: %o1 = 1. */ 782ad983e0SRichard Henderson env->regwptr[WREG_O1] = 1; 796291ad77SPeter Maydell } 806291ad77SPeter Maydell 8107a6ecf4SRichard Henderson static inline void cpu_clone_regs_parent(CPUSPARCState *env, unsigned flags) 8207a6ecf4SRichard Henderson { 832ad983e0SRichard Henderson /* Set the second return value for the parent: %o1 = 0. */ 842ad983e0SRichard Henderson env->regwptr[WREG_O1] = 0; 8507a6ecf4SRichard Henderson } 8607a6ecf4SRichard Henderson 87f5147c93SPeter Maydell static inline void cpu_set_tls(CPUSPARCState *env, target_ulong newtls) 88f5147c93SPeter Maydell { 89f5147c93SPeter Maydell env->gregs[7] = newtls; 90f5147c93SPeter Maydell } 916291ad77SPeter Maydell 929850f9f6SLaurent Vivier static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state) 939850f9f6SLaurent Vivier { 94eb215f40SRichard Henderson return state->regwptr[WREG_SP] + TARGET_STACK_BIAS; 959850f9f6SLaurent Vivier } 96083244d3SRichard Henderson 976291ad77SPeter Maydell #endif 98