@ -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 ;