diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2017-10-19 14:39:30 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2017-10-19 14:39:30 +0100 |
| commit | f2a48d696c12aaac12993364371daae9f6233c37 (patch) | |
| tree | 57a2098280251432d049b2f7f963894f2eae3def /linux-user/signal.c | |
| parent | ba6f0fc25e3c14fbb36f4b5a616a89cd3f1de6d0 (diff) | |
| parent | f443e3960d9d3340dd286e5fc0b661bb165a8b22 (diff) | |
| download | focaccia-qemu-f2a48d696c12aaac12993364371daae9f6233c37.tar.gz focaccia-qemu-f2a48d696c12aaac12993364371daae9f6233c37.zip | |
Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20171018' into staging
Linux-user updates for Qemu 2.11 # gpg: Signature made Wed 18 Oct 2017 13:20:14 BST # gpg: using RSA key 0xB44890DEDE3C9BC0 # gpg: Good signature from "Riku Voipio <riku.voipio@iki.fi>" # gpg: aka "Riku Voipio <riku.voipio@linaro.org>" # Primary key fingerprint: FF82 03C8 C391 98AE 0581 41EF B448 90DE DE3C 9BC0 * remotes/riku/tags/pull-linux-user-20171018: linux-user: Fix TARGET_MTIOCTOP/MTIOCGET/MTIOCPOS values linux-user/main: support dfilter linux-user: Fix target FS_IOC_GETFLAGS and FS_IOC_SETFLAGS numbers linux-user/sh4: Reduce TARGET_VIRT_ADDR_SPACE_BITS to 31 linux-user: Tidy and enforce reserved_va initialization tcg: Fix off-by-one in assert in page_set_flags linux-user: Allow -R values up to 0xffff0000 for 32-bit ARM guests linux-user: remove duplicate break in syscall target/m68k,linux-user: manage FP registers in ucontext linux-user: fix O_TMPFILE handling Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'linux-user/signal.c')
| -rw-r--r-- | linux-user/signal.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/linux-user/signal.c b/linux-user/signal.c index cc0c3fcee9..7a238aaea1 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -5704,6 +5704,24 @@ give_sigsegv: force_sigsegv(sig); } +static inline void target_rt_save_fpu_state(struct target_ucontext *uc, + CPUM68KState *env) +{ + int i; + target_fpregset_t *fpregs = &uc->tuc_mcontext.fpregs; + + __put_user(env->fpcr, &fpregs->f_fpcntl[0]); + __put_user(env->fpsr, &fpregs->f_fpcntl[1]); + /* fpiar is not emulated */ + + for (i = 0; i < 8; i++) { + uint32_t high = env->fregs[i].d.high << 16; + __put_user(high, &fpregs->f_fpregs[i * 3]); + __put_user(env->fregs[i].d.low, + (uint64_t *)&fpregs->f_fpregs[i * 3 + 1]); + } +} + static inline int target_rt_setup_ucontext(struct target_ucontext *uc, CPUM68KState *env) { @@ -5730,9 +5748,32 @@ static inline int target_rt_setup_ucontext(struct target_ucontext *uc, __put_user(env->pc, &gregs[16]); __put_user(sr, &gregs[17]); + target_rt_save_fpu_state(uc, env); + return 0; } +static inline void target_rt_restore_fpu_state(CPUM68KState *env, + struct target_ucontext *uc) +{ + int i; + target_fpregset_t *fpregs = &uc->tuc_mcontext.fpregs; + uint32_t fpcr; + + __get_user(fpcr, &fpregs->f_fpcntl[0]); + cpu_m68k_set_fpcr(env, fpcr); + __get_user(env->fpsr, &fpregs->f_fpcntl[1]); + /* fpiar is not emulated */ + + for (i = 0; i < 8; i++) { + uint32_t high; + __get_user(high, &fpregs->f_fpregs[i * 3]); + env->fregs[i].d.high = high >> 16; + __get_user(env->fregs[i].d.low, + (uint64_t *)&fpregs->f_fpregs[i * 3 + 1]); + } +} + static inline int target_rt_restore_ucontext(CPUM68KState *env, struct target_ucontext *uc) { @@ -5764,6 +5805,8 @@ static inline int target_rt_restore_ucontext(CPUM68KState *env, __get_user(temp, &gregs[17]); cpu_m68k_set_ccr(env, temp); + target_rt_restore_fpu_state(env, uc); + return 0; badframe: |