qemu/linux-user/sparc/target_cpu.h
<<
>>
Prefs
   1/*
   2 * SPARC specific CPU ABI and functions for linux-user
   3 *
   4 * Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
   5 * Copyright (C) 2003-2005 Fabrice Bellard
   6 *
   7 * This library is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU Lesser General Public
   9 * License as published by the Free Software Foundation; either
  10 * version 2.1 of the License, or (at your option) any later version.
  11 *
  12 * This library is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15 * Lesser General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU Lesser General Public
  18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  19 */
  20#ifndef SPARC_TARGET_CPU_H
  21#define SPARC_TARGET_CPU_H
  22
  23#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
  24# define TARGET_STACK_BIAS 2047
  25#else
  26# define TARGET_STACK_BIAS 0
  27#endif
  28
  29static inline void cpu_clone_regs_child(CPUSPARCState *env, target_ulong newsp,
  30                                        unsigned flags)
  31{
  32    /*
  33     * After cpu_copy, env->regwptr is pointing into the old env.
  34     * Update the new cpu to use its own register window.
  35     */
  36    env->regwptr = env->regbase + (env->cwp * 16);
  37
  38    if (newsp) {
  39        /* When changing stacks, do it with clean register windows.  */
  40#ifdef TARGET_SPARC64
  41        env->cansave = env->nwindows - 2;
  42        env->cleanwin = env->nwindows - 2;
  43        env->canrestore = 0;
  44#else
  45        env->wim = 1 << env->cwp;
  46#endif
  47        /* ??? The kernel appears to copy one stack frame to the new stack. */
  48        /* ??? The kernel force aligns the new stack. */
  49        /* Userspace provides a biased stack pointer value. */
  50        env->regwptr[WREG_SP] = newsp;
  51    }
  52
  53    if (flags & CLONE_VM) {
  54        /*
  55         * Syscall return for clone child: %o0 = 0 and clear CF since this
  56         * counts as a success return value.  Advance the PC past the syscall.
  57         * For fork child, all of this happens in cpu_loop, and we must not
  58         * do the pc advance twice.
  59         */
  60        env->regwptr[WREG_O0] = 0;
  61#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
  62        env->xcc &= ~PSR_CARRY;
  63#else
  64        env->psr &= ~PSR_CARRY;
  65#endif
  66        env->pc = env->npc;
  67        env->npc = env->npc + 4;
  68    }
  69
  70    /* Set the second return value for the child: %o1 = 1.  */
  71    env->regwptr[WREG_O1] = 1;
  72}
  73
  74static inline void cpu_clone_regs_parent(CPUSPARCState *env, unsigned flags)
  75{
  76    /* Set the second return value for the parent: %o1 = 0.  */
  77    env->regwptr[WREG_O1] = 0;
  78}
  79
  80static inline void cpu_set_tls(CPUSPARCState *env, target_ulong newtls)
  81{
  82    env->gregs[7] = newtls;
  83}
  84
  85static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
  86{
  87    return state->regwptr[WREG_SP] + TARGET_STACK_BIAS;
  88}
  89
  90#endif
  91