Revision 6e06d515

b/linux-user/syscall.c
7699 7699
        ret = -TARGET_EOPNOTSUPP;
7700 7700
        switch (arg1) {
7701 7701
          case TARGET_SSI_IEEE_FP_CONTROL:
7702
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
7703 7702
            {
7704 7703
                uint64_t swcr, fpcr, orig_fpcr;
7705 7704

  
7706
                if (get_user_u64 (swcr, arg2))
7705
                if (get_user_u64 (swcr, arg2)) {
7707 7706
                    goto efault;
7708
                orig_fpcr = cpu_alpha_load_fpcr (cpu_env);
7707
                }
7708
                orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
7709 7709
                fpcr = orig_fpcr & FPCR_DYN_MASK;
7710 7710

  
7711 7711
                /* Copied from linux ieee_swcr_to_fpcr.  */
......
7719 7719
                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
7720 7720
                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
7721 7721

  
7722
                cpu_alpha_store_fpcr (cpu_env, fpcr);
7722
                cpu_alpha_store_fpcr(cpu_env, fpcr);
7723 7723
                ret = 0;
7724
            }
7725
            break;
7726

  
7727
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
7728
            {
7729
                uint64_t exc, fpcr, orig_fpcr;
7730
                int si_code;
7731

  
7732
                if (get_user_u64(exc, arg2)) {
7733
                    goto efault;
7734
                }
7724 7735

  
7725
                if (arg1 == TARGET_SSI_IEEE_RAISE_EXCEPTION) {
7726
                    /* Old exceptions are not signaled.  */
7727
                    fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
7736
                orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
7728 7737

  
7729
                    /* If any exceptions set by this call, and are unmasked,
7730
                       send a signal.  */
7731
                    /* ??? FIXME */
7738
                /* We only add to the exception status here.  */
7739
                fpcr = orig_fpcr | ((exc & SWCR_STATUS_MASK) << 35);
7740

  
7741
                cpu_alpha_store_fpcr(cpu_env, fpcr);
7742
                ret = 0;
7743

  
7744
                /* Old exceptions are not signaled.  */
7745
                fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
7746

  
7747
                /* If any exceptions set by this call,
7748
                   and are unmasked, send a signal.  */
7749
                si_code = 0;
7750
                if ((fpcr & (FPCR_INE | FPCR_INED)) == FPCR_INE) {
7751
                    si_code = TARGET_FPE_FLTRES;
7752
                }
7753
                if ((fpcr & (FPCR_UNF | FPCR_UNFD)) == FPCR_UNF) {
7754
                    si_code = TARGET_FPE_FLTUND;
7755
                }
7756
                if ((fpcr & (FPCR_OVF | FPCR_OVFD)) == FPCR_OVF) {
7757
                    si_code = TARGET_FPE_FLTOVF;
7758
                }
7759
                if ((fpcr & (FPCR_DZE | FPCR_DZED)) == FPCR_DZE) {
7760
                    si_code = TARGET_FPE_FLTDIV;
7761
                }
7762
                if ((fpcr & (FPCR_INV | FPCR_INVD)) == FPCR_INV) {
7763
                    si_code = TARGET_FPE_FLTINV;
7764
                }
7765
                if (si_code != 0) {
7766
                    target_siginfo_t info;
7767
                    info.si_signo = SIGFPE;
7768
                    info.si_errno = 0;
7769
                    info.si_code = si_code;
7770
                    info._sifields._sigfault._addr
7771
                        = ((CPUArchState *)cpu_env)->pc;
7772
                    queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
7732 7773
                }
7733 7774
            }
7734 7775
            break;

Also available in: Unified diff