/[qemu]/qemu/vl.c
ViewVC logotype

Diff of /qemu/vl.c

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

revision 1.113 by bellard, Thu Jan 6 20:43:38 2005 UTC revision 1.114 by bellard, Sat Jan 8 18:55:47 2005 UTC
# Line 2082  static void cpu_get_seg(QEMUFile *f, Seg Line 2082  static void cpu_get_seg(QEMUFile *f, Seg
2082  void cpu_save(QEMUFile *f, void *opaque)  void cpu_save(QEMUFile *f, void *opaque)
2083  {  {
2084      CPUState *env = opaque;      CPUState *env = opaque;
2085      uint16_t fptag, fpus, fpuc;      uint16_t fptag, fpus, fpuc, fpregs_format;
2086      uint32_t hflags;      uint32_t hflags;
2087      int i;      int i;
2088        
2089      for(i = 0; i < CPU_NB_REGS; i++)      for(i = 0; i < CPU_NB_REGS; i++)
2090          qemu_put_betls(f, &env->regs[i]);          qemu_put_betls(f, &env->regs[i]);
2091      qemu_put_betls(f, &env->eip);      qemu_put_betls(f, &env->eip);
2092      qemu_put_betls(f, &env->eflags);      qemu_put_betls(f, &env->eflags);
     qemu_put_betl(f, 0); /* XXX: suppress that */  
2093      hflags = env->hflags; /* XXX: suppress most of the redundant hflags */      hflags = env->hflags; /* XXX: suppress most of the redundant hflags */
2094      qemu_put_be32s(f, &hflags);      qemu_put_be32s(f, &hflags);
2095            
# Line 2098  void cpu_save(QEMUFile *f, void *opaque) Line 2097  void cpu_save(QEMUFile *f, void *opaque)
2097      fpuc = env->fpuc;      fpuc = env->fpuc;
2098      fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;      fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
2099      fptag = 0;      fptag = 0;
2100      for (i=7; i>=0; i--) {      for(i = 0; i < 8; i++) {
2101          fptag <<= 2;          fptag |= ((!env->fptags[i]) << i);
         if (env->fptags[i]) {  
             fptag |= 3;  
         }  
2102      }      }
2103            
2104      qemu_put_be16s(f, &fpuc);      qemu_put_be16s(f, &fpuc);
2105      qemu_put_be16s(f, &fpus);      qemu_put_be16s(f, &fpus);
2106      qemu_put_be16s(f, &fptag);      qemu_put_be16s(f, &fptag);
2107    
2108    #ifdef USE_X86LDOUBLE
2109        fpregs_format = 0;
2110    #else
2111        fpregs_format = 1;
2112    #endif
2113        qemu_put_be16s(f, &fpregs_format);
2114        
2115      for(i = 0; i < 8; i++) {      for(i = 0; i < 8; i++) {
2116          uint64_t mant;          uint64_t mant;
2117          uint16_t exp;          uint16_t exp;
2118          cpu_get_fp80(&mant, &exp, env->fpregs[i]);  #ifdef USE_X86LDOUBLE
2119            /* we save the real CPU data (in case of MMX usage only 'mant'
2120               contains the MMX register */
2121            cpu_get_fp80(&mant, &exp, env->fpregs[i].d);
2122          qemu_put_be64(f, mant);          qemu_put_be64(f, mant);
2123          qemu_put_be16(f, exp);          qemu_put_be16(f, exp);
2124    #else
2125            /* if we use doubles for float emulation, we save the doubles to
2126               avoid losing information in case of MMX usage. It can give
2127               problems if the image is restored on a CPU where long
2128               doubles are used instead. */
2129            qemu_put_be64(f, env->fpregs[i].xmm.MMX_Q(0));
2130    #endif
2131      }      }
2132    
2133      for(i = 0; i < 6; i++)      for(i = 0; i < 6; i++)
# Line 2139  void cpu_save(QEMUFile *f, void *opaque) Line 2152  void cpu_save(QEMUFile *f, void *opaque)
2152      /* MMU */      /* MMU */
2153      qemu_put_be32s(f, &env->a20_mask);      qemu_put_be32s(f, &env->a20_mask);
2154    
2155  #ifdef TARGET_X86_64      /* XMM */
2156        qemu_put_be32s(f, &env->mxcsr);
2157      for(i = 0; i < CPU_NB_REGS; i++) {      for(i = 0; i < CPU_NB_REGS; i++) {
2158          qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0));          qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0));
2159          qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1));          qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1));
2160      }      }
2161    
2162    #ifdef TARGET_X86_64
2163      qemu_put_be64s(f, &env->efer);      qemu_put_be64s(f, &env->efer);
2164      qemu_put_be64s(f, &env->star);      qemu_put_be64s(f, &env->star);
2165      qemu_put_be64s(f, &env->lstar);      qemu_put_be64s(f, &env->lstar);
# Line 2154  void cpu_save(QEMUFile *f, void *opaque) Line 2169  void cpu_save(QEMUFile *f, void *opaque)
2169  #endif  #endif
2170  }  }
2171    
2172    /* XXX: add that in a FPU generic layer */
2173    union x86_longdouble {
2174        uint64_t mant;
2175        uint16_t exp;
2176    };
2177    
2178    #define MANTD1(fp)      (fp & ((1LL << 52) - 1))
2179    #define EXPBIAS1 1023
2180    #define EXPD1(fp)       ((fp >> 52) & 0x7FF)
2181    #define SIGND1(fp)      ((fp >> 32) & 0x80000000)
2182    
2183    static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
2184    {
2185        int e;
2186        /* mantissa */
2187        p->mant = (MANTD1(temp) << 11) | (1LL << 63);
2188        /* exponent + sign */
2189        e = EXPD1(temp) - EXPBIAS1 + 16383;
2190        e |= SIGND1(temp) >> 16;
2191        p->exp = e;
2192    }
2193    
2194  int cpu_load(QEMUFile *f, void *opaque, int version_id)  int cpu_load(QEMUFile *f, void *opaque, int version_id)
2195  {  {
2196      CPUState *env = opaque;      CPUState *env = opaque;
2197      int i;      int i, guess_mmx;
2198      uint32_t hflags;      uint32_t hflags;
2199      uint16_t fpus, fpuc, fptag;      uint16_t fpus, fpuc, fptag, fpregs_format;
2200    
2201      if (version_id != 2)      if (version_id != 3)
2202          return -EINVAL;          return -EINVAL;
2203      for(i = 0; i < CPU_NB_REGS; i++)      for(i = 0; i < CPU_NB_REGS; i++)
2204          qemu_get_betls(f, &env->regs[i]);          qemu_get_betls(f, &env->regs[i]);
2205      qemu_get_betls(f, &env->eip);      qemu_get_betls(f, &env->eip);
2206      qemu_get_betls(f, &env->eflags);      qemu_get_betls(f, &env->eflags);
     qemu_get_betl(f); /* XXX: suppress that */  
2207      qemu_get_be32s(f, &hflags);      qemu_get_be32s(f, &hflags);
2208    
2209      qemu_get_be16s(f, &fpuc);      qemu_get_be16s(f, &fpuc);
2210      qemu_get_be16s(f, &fpus);      qemu_get_be16s(f, &fpus);
2211      qemu_get_be16s(f, &fptag);      qemu_get_be16s(f, &fptag);
2212        qemu_get_be16s(f, &fpregs_format);
2213        
2214        /* NOTE: we cannot always restore the FPU state if the image come
2215           from a host with a different 'USE_X86LDOUBLE' define. We guess
2216           if we are in an MMX state to restore correctly in that case. */
2217        guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0);
2218      for(i = 0; i < 8; i++) {      for(i = 0; i < 8; i++) {
2219          uint64_t mant;          uint64_t mant;
2220          uint16_t exp;          uint16_t exp;
2221          mant = qemu_get_be64(f);          union x86_longdouble *p;
2222          exp = qemu_get_be16(f);          
2223          env->fpregs[i] = cpu_set_fp80(mant, exp);          switch(fpregs_format) {
2224            case 0:
2225                mant = qemu_get_be64(f);
2226                exp = qemu_get_be16(f);
2227    #ifdef USE_X86LDOUBLE
2228                env->fpregs[i].d = cpu_set_fp80(mant, exp);
2229    #else
2230                /* difficult case */
2231                if (guess_mmx)
2232                    env->fpregs[i].xmm.MMX_Q(0) = mant;
2233                else
2234                    env->fpregs[i].d = cpu_set_fp80(mant, exp);
2235    #endif
2236                break;
2237            case 1:
2238                mant = qemu_get_be64(f);
2239    #ifdef USE_X86LDOUBLE
2240                /* difficult case */
2241                p = (void *)&env->fpregs[i];
2242                if (guess_mmx) {
2243                    p->mant = mant;
2244                    p->exp = 0xffff;
2245                } else {
2246                    fp64_to_fp80(p, mant);
2247                }
2248    #else
2249                env->fpregs[i].xmm.MMX_Q(0) = mant;
2250    #endif            
2251                break;
2252            default:
2253                return -EINVAL;
2254            }
2255      }      }
2256    
2257      env->fpuc = fpuc;      env->fpuc = fpuc;
2258      env->fpstt = (fpus >> 11) & 7;      env->fpstt = (fpus >> 11) & 7;
2259      env->fpus = fpus & ~0x3800;      env->fpus = fpus & ~0x3800;
2260        fptag ^= 0xff;
2261      for(i = 0; i < 8; i++) {      for(i = 0; i < 8; i++) {
2262          env->fptags[i] = ((fptag & 3) == 3);          env->fptags[i] = (fptag >> i) & 1;
         fptag >>= 2;  
2263      }      }
2264            
2265      for(i = 0; i < 6; i++)      for(i = 0; i < 6; i++)
# Line 2212  int cpu_load(QEMUFile *f, void *opaque, Line 2284  int cpu_load(QEMUFile *f, void *opaque,
2284      /* MMU */      /* MMU */
2285      qemu_get_be32s(f, &env->a20_mask);      qemu_get_be32s(f, &env->a20_mask);
2286    
2287  #ifdef TARGET_X86_64      qemu_get_be32s(f, &env->mxcsr);
2288      for(i = 0; i < CPU_NB_REGS; i++) {      for(i = 0; i < CPU_NB_REGS; i++) {
2289          qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));          qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
2290          qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));          qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
2291      }      }
2292    
2293    #ifdef TARGET_X86_64
2294      qemu_get_be64s(f, &env->efer);      qemu_get_be64s(f, &env->efer);
2295      qemu_get_be64s(f, &env->star);      qemu_get_be64s(f, &env->star);
2296      qemu_get_be64s(f, &env->lstar);      qemu_get_be64s(f, &env->lstar);
# Line 3433  int main(int argc, char **argv) Line 3506  int main(int argc, char **argv)
3506      cpu_single_env = env;      cpu_single_env = env;
3507    
3508      register_savevm("timer", 0, 1, timer_save, timer_load, env);      register_savevm("timer", 0, 1, timer_save, timer_load, env);
3509      register_savevm("cpu", 0, 2, cpu_save, cpu_load, env);      register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
3510      register_savevm("ram", 0, 1, ram_save, ram_load, NULL);      register_savevm("ram", 0, 1, ram_save, ram_load, NULL);
3511      qemu_register_reset(main_cpu_reset, global_env);      qemu_register_reset(main_cpu_reset, global_env);
3512    

Legend:
Removed from v.1.113  
changed lines
  Added in v.1.114

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