syscall.c (5f022626c8807e5848af223908d533973a4b2922) | syscall.c (21ba856499f9c0ccdc05ed04432df059ae76b337) |
---|---|
1/* 2 * Linux syscalls 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 10209 unchanged lines hidden (view full) --- 10218#endif 10219#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA) 10220 /* Alpha specific */ 10221 case TARGET_NR_osf_getsysinfo: 10222 ret = -TARGET_EOPNOTSUPP; 10223 switch (arg1) { 10224 case TARGET_GSI_IEEE_FP_CONTROL: 10225 { | 1/* 2 * Linux syscalls 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 10209 unchanged lines hidden (view full) --- 10218#endif 10219#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA) 10220 /* Alpha specific */ 10221 case TARGET_NR_osf_getsysinfo: 10222 ret = -TARGET_EOPNOTSUPP; 10223 switch (arg1) { 10224 case TARGET_GSI_IEEE_FP_CONTROL: 10225 { |
10226 uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env); | 10226 uint64_t fpcr = cpu_alpha_load_fpcr(cpu_env); 10227 uint64_t swcr = ((CPUAlphaState *)cpu_env)->swcr; |
10227 | 10228 |
10228 /* Copied from linux ieee_fpcr_to_swcr. */ 10229 swcr = (fpcr >> 35) & SWCR_STATUS_MASK; 10230 swcr |= (fpcr >> 36) & SWCR_MAP_DMZ; 10231 swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV 10232 | SWCR_TRAP_ENABLE_DZE 10233 | SWCR_TRAP_ENABLE_OVF); 10234 swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF 10235 | SWCR_TRAP_ENABLE_INE); 10236 swcr |= (fpcr >> 47) & SWCR_MAP_UMZ; 10237 swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO; | 10229 swcr &= ~SWCR_STATUS_MASK; 10230 swcr |= (fpcr >> 35) & SWCR_STATUS_MASK; |
10238 10239 if (put_user_u64 (swcr, arg2)) 10240 return -TARGET_EFAULT; 10241 ret = 0; 10242 } 10243 break; 10244 10245 /* case GSI_IEEE_STATE_AT_SIGNAL: --- 10 unchanged lines hidden (view full) --- 10256#endif 10257#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA) 10258 /* Alpha specific */ 10259 case TARGET_NR_osf_setsysinfo: 10260 ret = -TARGET_EOPNOTSUPP; 10261 switch (arg1) { 10262 case TARGET_SSI_IEEE_FP_CONTROL: 10263 { | 10231 10232 if (put_user_u64 (swcr, arg2)) 10233 return -TARGET_EFAULT; 10234 ret = 0; 10235 } 10236 break; 10237 10238 /* case GSI_IEEE_STATE_AT_SIGNAL: --- 10 unchanged lines hidden (view full) --- 10249#endif 10250#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA) 10251 /* Alpha specific */ 10252 case TARGET_NR_osf_setsysinfo: 10253 ret = -TARGET_EOPNOTSUPP; 10254 switch (arg1) { 10255 case TARGET_SSI_IEEE_FP_CONTROL: 10256 { |
10264 uint64_t swcr, fpcr, orig_fpcr; | 10257 uint64_t swcr, fpcr; |
10265 10266 if (get_user_u64 (swcr, arg2)) { 10267 return -TARGET_EFAULT; 10268 } | 10258 10259 if (get_user_u64 (swcr, arg2)) { 10260 return -TARGET_EFAULT; 10261 } |
10269 orig_fpcr = cpu_alpha_load_fpcr(cpu_env); 10270 fpcr = orig_fpcr & FPCR_DYN_MASK; | |
10271 | 10262 |
10272 /* Copied from linux ieee_swcr_to_fpcr. */ 10273 fpcr |= (swcr & SWCR_STATUS_MASK) << 35; 10274 fpcr |= (swcr & SWCR_MAP_DMZ) << 36; 10275 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV 10276 | SWCR_TRAP_ENABLE_DZE 10277 | SWCR_TRAP_ENABLE_OVF)) << 48; 10278 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF 10279 | SWCR_TRAP_ENABLE_INE)) << 57; 10280 fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0); 10281 fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41; | 10263 /* 10264 * The kernel calls swcr_update_status to update the 10265 * status bits from the fpcr at every point that it 10266 * could be queried. Therefore, we store the status 10267 * bits only in FPCR. 10268 */ 10269 ((CPUAlphaState *)cpu_env)->swcr 10270 = swcr & (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK); |
10282 | 10271 |
10272 fpcr = cpu_alpha_load_fpcr(cpu_env); 10273 fpcr &= ((uint64_t)FPCR_DYN_MASK << 32); 10274 fpcr |= alpha_ieee_swcr_to_fpcr(swcr); |
|
10283 cpu_alpha_store_fpcr(cpu_env, fpcr); 10284 ret = 0; 10285 } 10286 break; 10287 10288 case TARGET_SSI_IEEE_RAISE_EXCEPTION: 10289 { | 10275 cpu_alpha_store_fpcr(cpu_env, fpcr); 10276 ret = 0; 10277 } 10278 break; 10279 10280 case TARGET_SSI_IEEE_RAISE_EXCEPTION: 10281 { |
10290 uint64_t exc, fpcr, orig_fpcr; 10291 int si_code; | 10282 uint64_t exc, fpcr, fex; |
10292 10293 if (get_user_u64(exc, arg2)) { 10294 return -TARGET_EFAULT; 10295 } | 10283 10284 if (get_user_u64(exc, arg2)) { 10285 return -TARGET_EFAULT; 10286 } |
10287 exc &= SWCR_STATUS_MASK; 10288 fpcr = cpu_alpha_load_fpcr(cpu_env); |
|
10296 | 10289 |
10297 orig_fpcr = cpu_alpha_load_fpcr(cpu_env); | 10290 /* Old exceptions are not signaled. */ 10291 fex = alpha_ieee_fpcr_to_swcr(fpcr); 10292 fex = exc & ~fex; 10293 fex >>= SWCR_STATUS_TO_EXCSUM_SHIFT; 10294 fex &= ((CPUArchState *)cpu_env)->swcr; |
10298 | 10295 |
10299 /* We only add to the exception status here. */ 10300 fpcr = orig_fpcr | ((exc & SWCR_STATUS_MASK) << 35); 10301 | 10296 /* Update the hardware fpcr. */ 10297 fpcr |= alpha_ieee_swcr_to_fpcr(exc); |
10302 cpu_alpha_store_fpcr(cpu_env, fpcr); | 10298 cpu_alpha_store_fpcr(cpu_env, fpcr); |
10303 ret = 0; | |
10304 | 10299 |
10305 /* Old exceptions are not signaled. */ 10306 fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK); 10307 10308 /* If any exceptions set by this call, 10309 and are unmasked, send a signal. */ 10310 si_code = 0; 10311 if ((fpcr & (FPCR_INE | FPCR_INED)) == FPCR_INE) { 10312 si_code = TARGET_FPE_FLTRES; 10313 } 10314 if ((fpcr & (FPCR_UNF | FPCR_UNFD)) == FPCR_UNF) { 10315 si_code = TARGET_FPE_FLTUND; 10316 } 10317 if ((fpcr & (FPCR_OVF | FPCR_OVFD)) == FPCR_OVF) { 10318 si_code = TARGET_FPE_FLTOVF; 10319 } 10320 if ((fpcr & (FPCR_DZE | FPCR_DZED)) == FPCR_DZE) { 10321 si_code = TARGET_FPE_FLTDIV; 10322 } 10323 if ((fpcr & (FPCR_INV | FPCR_INVD)) == FPCR_INV) { 10324 si_code = TARGET_FPE_FLTINV; 10325 } 10326 if (si_code != 0) { | 10300 if (fex) { 10301 int si_code = TARGET_FPE_FLTUNK; |
10327 target_siginfo_t info; | 10302 target_siginfo_t info; |
10303 10304 if (fex & SWCR_TRAP_ENABLE_DNO) { 10305 si_code = TARGET_FPE_FLTUND; 10306 } 10307 if (fex & SWCR_TRAP_ENABLE_INE) { 10308 si_code = TARGET_FPE_FLTRES; 10309 } 10310 if (fex & SWCR_TRAP_ENABLE_UNF) { 10311 si_code = TARGET_FPE_FLTUND; 10312 } 10313 if (fex & SWCR_TRAP_ENABLE_OVF) { 10314 si_code = TARGET_FPE_FLTOVF; 10315 } 10316 if (fex & SWCR_TRAP_ENABLE_DZE) { 10317 si_code = TARGET_FPE_FLTDIV; 10318 } 10319 if (fex & SWCR_TRAP_ENABLE_INV) { 10320 si_code = TARGET_FPE_FLTINV; 10321 } 10322 |
|
10328 info.si_signo = SIGFPE; 10329 info.si_errno = 0; 10330 info.si_code = si_code; 10331 info._sifields._sigfault._addr 10332 = ((CPUArchState *)cpu_env)->pc; 10333 queue_signal((CPUArchState *)cpu_env, info.si_signo, 10334 QEMU_SI_FAULT, &info); 10335 } | 10323 info.si_signo = SIGFPE; 10324 info.si_errno = 0; 10325 info.si_code = si_code; 10326 info._sifields._sigfault._addr 10327 = ((CPUArchState *)cpu_env)->pc; 10328 queue_signal((CPUArchState *)cpu_env, info.si_signo, 10329 QEMU_SI_FAULT, &info); 10330 } |
10331 ret = 0; |
|
10336 } 10337 break; 10338 10339 /* case SSI_NVPAIRS: 10340 -- Used with SSIN_UACPROC to enable unaligned accesses. 10341 case SSI_IEEE_STATE_AT_SIGNAL: 10342 case SSI_IEEE_IGNORE_STATE_AT_SIGNAL: 10343 -- Not implemented in linux kernel --- 1325 unchanged lines hidden --- | 10332 } 10333 break; 10334 10335 /* case SSI_NVPAIRS: 10336 -- Used with SSIN_UACPROC to enable unaligned accesses. 10337 case SSI_IEEE_STATE_AT_SIGNAL: 10338 case SSI_IEEE_IGNORE_STATE_AT_SIGNAL: 10339 -- Not implemented in linux kernel --- 1325 unchanged lines hidden --- |