/[qemu]/qemu/op-i386.c
ViewVC logotype

Diff of /qemu/op-i386.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.30 by bellard, Tue May 27 23:27:26 2003 UTC revision 1.31 by bellard, Thu May 29 20:04:27 2003 UTC
# Line 1073  void helper_cpuid(void) Line 1073  void helper_cpuid(void)
1073          EBX = 0x756e6547;          EBX = 0x756e6547;
1074          ECX = 0x6c65746e;          ECX = 0x6c65746e;
1075          EDX = 0x49656e69;          EDX = 0x49656e69;
1076      } else {      } else if (EAX == 1) {
1077          /* EAX = 1 info */          /* EAX = 1 info */
1078          EAX = 0x52b;          EAX = 0x52b;
1079          EBX = 0;          EBX = 0;
# Line 1899  void OPPROTO op_fldt_ST0_A0(void) Line 1899  void OPPROTO op_fldt_ST0_A0(void)
1899      ST0 = *(long double *)A0;      ST0 = *(long double *)A0;
1900  }  }
1901  #else  #else
1902  void helper_fldt_ST0_A0(void)  static inline CPU86_LDouble helper_fldt(uint8_t *ptr)
1903  {  {
1904      CPU86_LDoubleU temp;      CPU86_LDoubleU temp;
1905      int upper, e;      int upper, e;
1906      /* mantissa */      /* mantissa */
1907      upper = lduw((uint8_t *)A0 + 8);      upper = lduw(ptr + 8);
1908      /* XXX: handle overflow ? */      /* XXX: handle overflow ? */
1909      e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */      e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */
1910      e |= (upper >> 4) & 0x800; /* sign */      e |= (upper >> 4) & 0x800; /* sign */
1911      temp.ll = ((ldq((void *)A0) >> 11) & ((1LL << 52) - 1)) | ((uint64_t)e << 52);      temp.ll = ((ldq(ptr) >> 11) & ((1LL << 52) - 1)) | ((uint64_t)e << 52);
1912      ST0 = temp.d;      return temp.d;
1913    }
1914    
1915    void helper_fldt_ST0_A0(void)
1916    {
1917        ST0 = helper_fldt((uint8_t *)A0);
1918  }  }
1919    
1920  void OPPROTO op_fldt_ST0_A0(void)  void OPPROTO op_fldt_ST0_A0(void)
# Line 2008  void OPPROTO op_fstt_ST0_A0(void) Line 2013  void OPPROTO op_fstt_ST0_A0(void)
2013      *(long double *)A0 = ST0;      *(long double *)A0 = ST0;
2014  }  }
2015  #else  #else
2016  void helper_fstt_ST0_A0(void)  
2017    static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr)
2018  {  {
2019      CPU86_LDoubleU temp;      CPU86_LDoubleU temp;
2020      int e;      int e;
2021      temp.d = ST0;      temp.d = f;
2022      /* mantissa */      /* mantissa */
2023      stq((void *)A0, (MANTD(temp) << 11) | (1LL << 63));      stq(ptr, (MANTD(temp) << 11) | (1LL << 63));
2024      /* exponent + sign */      /* exponent + sign */
2025      e = EXPD(temp) - EXPBIAS + 16383;      e = EXPD(temp) - EXPBIAS + 16383;
2026      e |= SIGND(temp) >> 16;      e |= SIGND(temp) >> 16;
2027      stw((uint8_t *)A0 + 8, e);      stw(ptr + 8, e);
2028    }
2029    
2030    void helper_fstt_ST0_A0(void)
2031    {
2032        helper_fstt(ST0, (uint8_t *)A0);
2033  }  }
2034    
2035  void OPPROTO op_fstt_ST0_A0(void)  void OPPROTO op_fstt_ST0_A0(void)
# Line 2254  void OPPROTO op_fucom_ST0_FT0(void) Line 2265  void OPPROTO op_fucom_ST0_FT0(void)
2265      FORCE_RET();      FORCE_RET();
2266  }  }
2267    
2268    /* XXX: handle nans */
2269    void OPPROTO op_fcomi_ST0_FT0(void)
2270    {
2271        int eflags;
2272        eflags = cc_table[CC_OP].compute_all();
2273        eflags &= ~(CC_Z | CC_P | CC_C);
2274        if (ST0 < FT0)
2275            eflags |= CC_C;
2276        else if (ST0 == FT0)
2277            eflags |= CC_Z;
2278        CC_SRC = eflags;
2279        FORCE_RET();
2280    }
2281    
2282    /* XXX: handle nans */
2283    void OPPROTO op_fucomi_ST0_FT0(void)
2284    {
2285        int eflags;
2286        eflags = cc_table[CC_OP].compute_all();
2287        eflags &= ~(CC_Z | CC_P | CC_C);
2288        if (ST0 < FT0)
2289            eflags |= CC_C;
2290        else if (ST0 == FT0)
2291            eflags |= CC_Z;
2292        CC_SRC = eflags;
2293        FORCE_RET();
2294    }
2295    
2296  void OPPROTO op_fadd_ST0_FT0(void)  void OPPROTO op_fadd_ST0_FT0(void)
2297  {  {
2298      ST0 += FT0;      ST0 += FT0;
# Line 2750  void OPPROTO op_fninit(void) Line 2789  void OPPROTO op_fninit(void)
2789      env->fptags[7] = 1;      env->fptags[7] = 1;
2790  }  }
2791    
2792    void helper_fstenv(uint8_t *ptr, int data32)
2793    {
2794        int fpus, fptag, exp, i;
2795        uint64_t mant;
2796        CPU86_LDoubleU tmp;
2797    
2798        fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
2799        fptag = 0;
2800        for (i=7; i>=0; i--) {
2801            fptag <<= 2;
2802            if (env->fptags[i]) {
2803                fptag |= 3;
2804            } else {
2805                tmp.d = env->fpregs[i];
2806                exp = EXPD(tmp);
2807                mant = MANTD(tmp);
2808                if (exp == 0 && mant == 0) {
2809                    /* zero */
2810                    fptag |= 1;
2811                } else if (exp == 0 || exp == MAXEXPD
2812    #ifdef USE_X86LDOUBLE
2813                           || (mant & (1LL << 63)) == 0
2814    #endif
2815                           ) {
2816                    /* NaNs, infinity, denormal */
2817                    fptag |= 2;
2818                }
2819            }
2820        }
2821        if (data32) {
2822            /* 32 bit */
2823            stl(ptr, env->fpuc);
2824            stl(ptr + 4, fpus);
2825            stl(ptr + 8, fptag);
2826            stl(ptr + 12, 0);
2827            stl(ptr + 16, 0);
2828            stl(ptr + 20, 0);
2829            stl(ptr + 24, 0);
2830        } else {
2831            /* 16 bit */
2832            stw(ptr, env->fpuc);
2833            stw(ptr + 2, fpus);
2834            stw(ptr + 4, fptag);
2835            stw(ptr + 6, 0);
2836            stw(ptr + 8, 0);
2837            stw(ptr + 10, 0);
2838            stw(ptr + 12, 0);
2839        }
2840    }
2841    
2842    void helper_fldenv(uint8_t *ptr, int data32)
2843    {
2844        int i, fpus, fptag;
2845    
2846        if (data32) {
2847            env->fpuc = lduw(ptr);
2848            fpus = lduw(ptr + 4);
2849            fptag = lduw(ptr + 8);
2850        }
2851        else {
2852            env->fpuc = lduw(ptr);
2853            fpus = lduw(ptr + 2);
2854            fptag = lduw(ptr + 4);
2855        }
2856        env->fpstt = (fpus >> 11) & 7;
2857        env->fpus = fpus & ~0x3800;
2858        for(i = 0;i < 7; i++) {
2859            env->fptags[i] = ((fptag & 3) == 3);
2860            fptag >>= 2;
2861        }
2862    }
2863    
2864    void helper_fsave(uint8_t *ptr, int data32)
2865    {
2866        CPU86_LDouble tmp;
2867        int i;
2868    
2869        helper_fstenv(ptr, data32);
2870    
2871        ptr += (14 << data32);
2872        for(i = 0;i < 8; i++) {
2873            tmp = ST(i);
2874    #ifdef USE_X86LDOUBLE
2875            *(long double *)ptr = tmp;
2876    #else
2877            helper_fstt(tmp, ptr);
2878    #endif        
2879            ptr += 10;
2880        }
2881    
2882        /* fninit */
2883        env->fpus = 0;
2884        env->fpstt = 0;
2885        env->fpuc = 0x37f;
2886        env->fptags[0] = 1;
2887        env->fptags[1] = 1;
2888        env->fptags[2] = 1;
2889        env->fptags[3] = 1;
2890        env->fptags[4] = 1;
2891        env->fptags[5] = 1;
2892        env->fptags[6] = 1;
2893        env->fptags[7] = 1;
2894    }
2895    
2896    void helper_frstor(uint8_t *ptr, int data32)
2897    {
2898        CPU86_LDouble tmp;
2899        int i;
2900    
2901        helper_fldenv(ptr, data32);
2902        ptr += (14 << data32);
2903    
2904        for(i = 0;i < 8; i++) {
2905    #ifdef USE_X86LDOUBLE
2906            tmp = *(long double *)ptr;
2907    #else
2908            tmp = helper_fldt(ptr);
2909    #endif        
2910            ST(i) = tmp;
2911            ptr += 10;
2912        }
2913    }
2914    
2915    void OPPROTO op_fnstenv_A0(void)
2916    {
2917        helper_fstenv((uint8_t *)A0, PARAM1);
2918    }
2919    
2920    void OPPROTO op_fldenv_A0(void)
2921    {
2922        helper_fldenv((uint8_t *)A0, PARAM1);
2923    }
2924    
2925    void OPPROTO op_fnsave_A0(void)
2926    {
2927        helper_fsave((uint8_t *)A0, PARAM1);
2928    }
2929    
2930    void OPPROTO op_frstor_A0(void)
2931    {
2932        helper_frstor((uint8_t *)A0, PARAM1);
2933    }
2934    
2935  /* threading support */  /* threading support */
2936  void OPPROTO op_lock(void)  void OPPROTO op_lock(void)
2937  {  {

Legend:
Removed from v.1.30  
changed lines
  Added in v.1.31

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26