diff options
Diffstat (limited to 'linux-user')
| -rw-r--r-- | linux-user/nios2/target_cpu.h | 4 | ||||
| -rw-r--r-- | linux-user/nios2/target_signal.h | 6 | ||||
| -rw-r--r-- | linux-user/nios2/target_structs.h | 4 | ||||
| -rw-r--r-- | linux-user/nios2/target_syscall.h | 6 | ||||
| -rw-r--r-- | linux-user/riscv/target_cpu.h | 4 | ||||
| -rw-r--r-- | linux-user/riscv/target_signal.h | 6 | ||||
| -rw-r--r-- | linux-user/riscv/target_structs.h | 4 | ||||
| -rw-r--r-- | linux-user/syscall.c | 106 | ||||
| -rw-r--r-- | linux-user/syscall_defs.h | 3 | ||||
| -rw-r--r-- | linux-user/xtensa/syscall_nr.h | 6 | ||||
| -rw-r--r-- | linux-user/xtensa/target_structs.h | 4 | ||||
| -rw-r--r-- | linux-user/xtensa/termbits.h | 6 |
12 files changed, 78 insertions, 81 deletions
diff --git a/linux-user/nios2/target_cpu.h b/linux-user/nios2/target_cpu.h index 14f63338fa..5596c05c9c 100644 --- a/linux-user/nios2/target_cpu.h +++ b/linux-user/nios2/target_cpu.h @@ -17,8 +17,8 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ -#ifndef TARGET_CPU_H -#define TARGET_CPU_H +#ifndef NIOS2_TARGET_CPU_H +#define NIOS2_TARGET_CPU_H static inline void cpu_clone_regs(CPUNios2State *env, target_ulong newsp) { diff --git a/linux-user/nios2/target_signal.h b/linux-user/nios2/target_signal.h index 7776bcdbfd..fe48721b3d 100644 --- a/linux-user/nios2/target_signal.h +++ b/linux-user/nios2/target_signal.h @@ -1,5 +1,5 @@ -#ifndef TARGET_SIGNAL_H -#define TARGET_SIGNAL_H +#ifndef NIOS2_TARGET_SIGNAL_H +#define NIOS2_TARGET_SIGNAL_H /* this struct defines a stack used during syscall handling */ @@ -18,4 +18,4 @@ typedef struct target_sigaltstack { #include "../generic/signal.h" -#endif /* TARGET_SIGNAL_H */ +#endif /* NIOS2_TARGET_SIGNAL_H */ diff --git a/linux-user/nios2/target_structs.h b/linux-user/nios2/target_structs.h index 8713772089..7145251706 100644 --- a/linux-user/nios2/target_structs.h +++ b/linux-user/nios2/target_structs.h @@ -16,8 +16,8 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ -#ifndef TARGET_STRUCTS_H -#define TARGET_STRUCTS_H +#ifndef NIOS2_TARGET_STRUCTS_H +#define NIOS2_TARGET_STRUCTS_H struct target_ipc_perm { abi_int __key; /* Key. */ diff --git a/linux-user/nios2/target_syscall.h b/linux-user/nios2/target_syscall.h index ca6b7e69f6..f3b2a500f4 100644 --- a/linux-user/nios2/target_syscall.h +++ b/linux-user/nios2/target_syscall.h @@ -1,5 +1,5 @@ -#ifndef TARGET_SYSCALL_H -#define TARGET_SYSCALL_H +#ifndef NIOS2_TARGET_SYSCALL_H +#define NIOS2_TARGET_SYSCALL_H #define UNAME_MACHINE "nios2" #define UNAME_MINIMUM_RELEASE "3.19.0" @@ -34,4 +34,4 @@ struct target_pt_regs { #define TARGET_MLOCKALL_MCL_CURRENT 1 #define TARGET_MLOCKALL_MCL_FUTURE 2 -#endif /* TARGET_SYSCALL_H */ +#endif /* NIOS2_TARGET_SYSCALL_H */ diff --git a/linux-user/riscv/target_cpu.h b/linux-user/riscv/target_cpu.h index 7e090f376a..90f9a4171e 100644 --- a/linux-user/riscv/target_cpu.h +++ b/linux-user/riscv/target_cpu.h @@ -1,5 +1,5 @@ -#ifndef TARGET_CPU_H -#define TARGET_CPU_H +#ifndef RISCV_TARGET_CPU_H +#define RISCV_TARGET_CPU_H static inline void cpu_clone_regs(CPURISCVState *env, target_ulong newsp) { diff --git a/linux-user/riscv/target_signal.h b/linux-user/riscv/target_signal.h index c8b1455800..f113ba9a55 100644 --- a/linux-user/riscv/target_signal.h +++ b/linux-user/riscv/target_signal.h @@ -1,5 +1,5 @@ -#ifndef TARGET_SIGNAL_H -#define TARGET_SIGNAL_H +#ifndef RISCV_TARGET_SIGNAL_H +#define RISCV_TARGET_SIGNAL_H typedef struct target_sigaltstack { abi_ulong ss_sp; @@ -15,4 +15,4 @@ typedef struct target_sigaltstack { #include "../generic/signal.h" -#endif /* TARGET_SIGNAL_H */ +#endif /* RISCV_TARGET_SIGNAL_H */ diff --git a/linux-user/riscv/target_structs.h b/linux-user/riscv/target_structs.h index 4f0462c497..ea3e5ed17e 100644 --- a/linux-user/riscv/target_structs.h +++ b/linux-user/riscv/target_structs.h @@ -4,8 +4,8 @@ * This is a copy of ../aarch64/target_structs.h atm. * */ -#ifndef TARGET_STRUCTS_H -#define TARGET_STRUCTS_H +#ifndef RISCV_TARGET_STRUCTS_H +#define RISCV_TARGET_STRUCTS_H struct target_ipc_perm { abi_int __key; /* Key. */ diff --git a/linux-user/syscall.c b/linux-user/syscall.c index f5ff6f5dc8..efa3ec2837 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -10223,18 +10223,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, switch (arg1) { case TARGET_GSI_IEEE_FP_CONTROL: { - uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env); - - /* Copied from linux ieee_fpcr_to_swcr. */ - swcr = (fpcr >> 35) & SWCR_STATUS_MASK; - swcr |= (fpcr >> 36) & SWCR_MAP_DMZ; - swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV - | SWCR_TRAP_ENABLE_DZE - | SWCR_TRAP_ENABLE_OVF); - swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF - | SWCR_TRAP_ENABLE_INE); - swcr |= (fpcr >> 47) & SWCR_MAP_UMZ; - swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO; + uint64_t fpcr = cpu_alpha_load_fpcr(cpu_env); + uint64_t swcr = ((CPUAlphaState *)cpu_env)->swcr; + + swcr &= ~SWCR_STATUS_MASK; + swcr |= (fpcr >> 35) & SWCR_STATUS_MASK; if (put_user_u64 (swcr, arg2)) return -TARGET_EFAULT; @@ -10261,25 +10254,24 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, switch (arg1) { case TARGET_SSI_IEEE_FP_CONTROL: { - uint64_t swcr, fpcr, orig_fpcr; + uint64_t swcr, fpcr; if (get_user_u64 (swcr, arg2)) { return -TARGET_EFAULT; } - orig_fpcr = cpu_alpha_load_fpcr(cpu_env); - fpcr = orig_fpcr & FPCR_DYN_MASK; - - /* Copied from linux ieee_swcr_to_fpcr. */ - fpcr |= (swcr & SWCR_STATUS_MASK) << 35; - fpcr |= (swcr & SWCR_MAP_DMZ) << 36; - fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV - | SWCR_TRAP_ENABLE_DZE - | SWCR_TRAP_ENABLE_OVF)) << 48; - fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF - | SWCR_TRAP_ENABLE_INE)) << 57; - fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0); - fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41; + /* + * The kernel calls swcr_update_status to update the + * status bits from the fpcr at every point that it + * could be queried. Therefore, we store the status + * bits only in FPCR. + */ + ((CPUAlphaState *)cpu_env)->swcr + = swcr & (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK); + + fpcr = cpu_alpha_load_fpcr(cpu_env); + fpcr &= ((uint64_t)FPCR_DYN_MASK << 32); + fpcr |= alpha_ieee_swcr_to_fpcr(swcr); cpu_alpha_store_fpcr(cpu_env, fpcr); ret = 0; } @@ -10287,44 +10279,47 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, case TARGET_SSI_IEEE_RAISE_EXCEPTION: { - uint64_t exc, fpcr, orig_fpcr; - int si_code; + uint64_t exc, fpcr, fex; if (get_user_u64(exc, arg2)) { return -TARGET_EFAULT; } + exc &= SWCR_STATUS_MASK; + fpcr = cpu_alpha_load_fpcr(cpu_env); - orig_fpcr = cpu_alpha_load_fpcr(cpu_env); - - /* We only add to the exception status here. */ - fpcr = orig_fpcr | ((exc & SWCR_STATUS_MASK) << 35); + /* Old exceptions are not signaled. */ + fex = alpha_ieee_fpcr_to_swcr(fpcr); + fex = exc & ~fex; + fex >>= SWCR_STATUS_TO_EXCSUM_SHIFT; + fex &= ((CPUArchState *)cpu_env)->swcr; + /* Update the hardware fpcr. */ + fpcr |= alpha_ieee_swcr_to_fpcr(exc); cpu_alpha_store_fpcr(cpu_env, fpcr); - ret = 0; - /* Old exceptions are not signaled. */ - fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK); - - /* If any exceptions set by this call, - and are unmasked, send a signal. */ - si_code = 0; - if ((fpcr & (FPCR_INE | FPCR_INED)) == FPCR_INE) { - si_code = TARGET_FPE_FLTRES; - } - if ((fpcr & (FPCR_UNF | FPCR_UNFD)) == FPCR_UNF) { - si_code = TARGET_FPE_FLTUND; - } - if ((fpcr & (FPCR_OVF | FPCR_OVFD)) == FPCR_OVF) { - si_code = TARGET_FPE_FLTOVF; - } - if ((fpcr & (FPCR_DZE | FPCR_DZED)) == FPCR_DZE) { - si_code = TARGET_FPE_FLTDIV; - } - if ((fpcr & (FPCR_INV | FPCR_INVD)) == FPCR_INV) { - si_code = TARGET_FPE_FLTINV; - } - if (si_code != 0) { + if (fex) { + int si_code = TARGET_FPE_FLTUNK; target_siginfo_t info; + + if (fex & SWCR_TRAP_ENABLE_DNO) { + si_code = TARGET_FPE_FLTUND; + } + if (fex & SWCR_TRAP_ENABLE_INE) { + si_code = TARGET_FPE_FLTRES; + } + if (fex & SWCR_TRAP_ENABLE_UNF) { + si_code = TARGET_FPE_FLTUND; + } + if (fex & SWCR_TRAP_ENABLE_OVF) { + si_code = TARGET_FPE_FLTOVF; + } + if (fex & SWCR_TRAP_ENABLE_DZE) { + si_code = TARGET_FPE_FLTDIV; + } + if (fex & SWCR_TRAP_ENABLE_INV) { + si_code = TARGET_FPE_FLTINV; + } + info.si_signo = SIGFPE; info.si_errno = 0; info.si_code = si_code; @@ -10333,6 +10328,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, queue_signal((CPUArchState *)cpu_env, info.si_signo, QEMU_SI_FAULT, &info); } + ret = 0; } break; diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 12c8407144..1f5b2d18db 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -635,7 +635,8 @@ typedef struct target_siginfo { #define TARGET_FPE_FLTRES (6) /* floating point inexact result */ #define TARGET_FPE_FLTINV (7) /* floating point invalid operation */ #define TARGET_FPE_FLTSUB (8) /* subscript out of range */ -#define TARGET_NSIGFPE 8 +#define TARGET_FPE_FLTUNK (14) /* undiagnosed fp exception */ +#define TARGET_NSIGFPE 15 /* * SIGSEGV si_codes diff --git a/linux-user/xtensa/syscall_nr.h b/linux-user/xtensa/syscall_nr.h index cd5ef45f84..27645bea47 100644 --- a/linux-user/xtensa/syscall_nr.h +++ b/linux-user/xtensa/syscall_nr.h @@ -8,8 +8,8 @@ * Copyright (C) 2001 - 2009 Tensilica Inc. */ -#ifndef _XTENSA_UNISTD_H -#define _XTENSA_UNISTD_H +#ifndef XTENSA_SYSCALL_NR_H +#define XTENSA_SYSCALL_NR_H #define TARGET_NR_spill 0 #define TARGET_NR_xtensa 1 @@ -434,4 +434,4 @@ #define TARGET_NR_syscall_count 352 -#endif /* _XTENSA_UNISTD_H */ +#endif /* XTENSA_SYSCALL_NR_H */ diff --git a/linux-user/xtensa/target_structs.h b/linux-user/xtensa/target_structs.h index 1b3d9ca314..9cde6844b8 100644 --- a/linux-user/xtensa/target_structs.h +++ b/linux-user/xtensa/target_structs.h @@ -1,5 +1,5 @@ -#ifndef XTENSA_TARGET_STRUCTS_T -#define XTENSA_TARGET_STRUCTS_T +#ifndef XTENSA_TARGET_STRUCTS_H +#define XTENSA_TARGET_STRUCTS_H struct target_ipc_perm { abi_int __key; /* Key. */ diff --git a/linux-user/xtensa/termbits.h b/linux-user/xtensa/termbits.h index eed8286de7..d1e09e61a6 100644 --- a/linux-user/xtensa/termbits.h +++ b/linux-user/xtensa/termbits.h @@ -10,8 +10,8 @@ * Copyright (C) 2001 - 2005 Tensilica Inc. */ -#ifndef _XTENSA_TERMBITS_H -#define _XTENSA_TERMBITS_H +#ifndef XTENSA_TERMBITS_H +#define XTENSA_TERMBITS_H #include <linux/posix_types.h> @@ -325,4 +325,4 @@ struct target_ktermios { #define TARGET_TIOCMIWAIT _IO('T', 92) /* wait for a change on serial input line(s) */ #define TARGET_TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ -#endif /* _XTENSA_TERMBITS_H */ +#endif /* XTENSA_TERMBITS_H */ |