From 5ef54116ea1c576995f0074b71400bf7bda08cf1 Mon Sep 17 00:00:00 2001 From: bellard Date: Tue, 18 Jul 2006 21:14:09 +0000 Subject: [PATCH] Sparc64 user emulator fixes (Blue Swirl) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2063 c046a42c-6fe2-441c-8c8c-71466251a162 --- linux-user/elfload.c | 8 +++++--- linux-user/main.c | 22 ++++++++++++++++++++++ target-sparc/translate.c | 4 ++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 687ff77b4d..57b5ed27d8 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -135,11 +135,13 @@ enum #define ELF_START_MMAP 0x80000000 -#define elf_check_arch(x) ( (x) == EM_SPARC ) +#define elf_check_arch(x) ( (x) == EM_SPARCV9 ) #define ELF_CLASS ELFCLASS64 #define ELF_DATA ELFDATA2MSB -#define ELF_ARCH EM_SPARC +#define ELF_ARCH EM_SPARCV9 + +#define STACK_BIAS 2047 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) { @@ -147,7 +149,7 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i regs->pc = infop->entry; regs->npc = regs->pc + 4; regs->y = 0; - regs->u_regs[14] = infop->start_stack - 16 * 4; + regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS; } #else diff --git a/linux-user/main.c b/linux-user/main.c index 6c3d5db7ee..d1693110fa 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -473,11 +473,17 @@ static inline void save_window_offset(CPUSPARCState *env, int cwp1) static void save_window(CPUSPARCState *env) { +#ifndef TARGET_SPARC64 unsigned int new_wim; new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) & ((1LL << NWINDOWS) - 1); save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1)); env->wim = new_wim; +#else + save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1)); + env->cansave++; + env->canrestore--; +#endif } static void restore_window(CPUSPARCState *env) @@ -500,6 +506,12 @@ static void restore_window(CPUSPARCState *env) sp_ptr += sizeof(target_ulong); } env->wim = new_wim; +#ifdef TARGET_SPARC64 + env->canrestore++; + if (env->cleanwin < NWINDOWS - 1) + env->cleanwin++; + env->cansave--; +#endif } static void flush_windows(CPUSPARCState *env) @@ -532,8 +544,12 @@ void cpu_loop (CPUSPARCState *env) trapnr = cpu_sparc_exec (env); switch (trapnr) { +#ifndef TARGET_SPARC64 case 0x88: case 0x90: +#else + case 0x16d: +#endif ret = do_syscall (env, env->gregs[1], env->regwptr[0], env->regwptr[1], env->regwptr[2], env->regwptr[3], @@ -574,6 +590,12 @@ void cpu_loop (CPUSPARCState *env) } break; #else + case TT_SPILL: /* window overflow */ + save_window(env); + break; + case TT_FILL: /* window underflow */ + restore_window(env); + break; // XXX #endif case EXCP_INTERRUPT: diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 4a8ad7061b..a522d778be 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -2731,6 +2731,10 @@ void cpu_reset(CPUSPARCState *env) env->regwptr = env->regbase + (env->cwp * 16); #if defined(CONFIG_USER_ONLY) env->user_mode_only = 1; +#ifdef TARGET_SPARC64 + env->cleanwin = NWINDOWS - 1; + env->cansave = NWINDOWS - 1; +#endif #else env->psrs = 1; env->psrps = 1;