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

Diff of /qemu/helper-i386.c

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

revision 1.1 by bellard, Thu Jun 5 00:52:34 2003 UTC revision 1.2 by bellard, Mon Jun 9 15:25:54 2003 UTC
# Line 19  Line 19 
19   */   */
20  #include "exec-i386.h"  #include "exec-i386.h"
21    
22    const CPU86_LDouble f15rk[7] =
23    {
24        0.00000000000000000000L,
25        1.00000000000000000000L,
26        3.14159265358979323851L,  /*pi*/
27        0.30102999566398119523L,  /*lg2*/
28        0.69314718055994530943L,  /*ln2*/
29        1.44269504088896340739L,  /*l2e*/
30        3.32192809488736234781L,  /*l2t*/
31    };
32        
33    /* thread support */
34    
35    spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
36    
37    void cpu_lock(void)
38    {
39        spin_lock(&global_cpu_lock);
40    }
41    
42    void cpu_unlock(void)
43    {
44        spin_unlock(&global_cpu_lock);
45    }
46    
47    void cpu_loop_exit(void)
48    {
49        /* NOTE: the register at this point must be saved by hand because
50           longjmp restore them */
51    #ifdef reg_EAX
52        env->regs[R_EAX] = EAX;
53    #endif
54    #ifdef reg_ECX
55        env->regs[R_ECX] = ECX;
56    #endif
57    #ifdef reg_EDX
58        env->regs[R_EDX] = EDX;
59    #endif
60    #ifdef reg_EBX
61        env->regs[R_EBX] = EBX;
62    #endif
63    #ifdef reg_ESP
64        env->regs[R_ESP] = ESP;
65    #endif
66    #ifdef reg_EBP
67        env->regs[R_EBP] = EBP;
68    #endif
69    #ifdef reg_ESI
70        env->regs[R_ESI] = ESI;
71    #endif
72    #ifdef reg_EDI
73        env->regs[R_EDI] = EDI;
74    #endif
75        longjmp(env->jmp_env, 1);
76    }
77    
78  #if 0  #if 0
79  /* full interrupt support (only useful for real CPU emulation, not  /* full interrupt support (only useful for real CPU emulation, not
80     finished) - I won't do it any time soon, finish it if you want ! */     finished) - I won't do it any time soon, finish it if you want ! */
# Line 108  void raise_exception(int exception_index Line 164  void raise_exception(int exception_index
164      raise_interrupt(exception_index, 0, 0, 0);      raise_interrupt(exception_index, 0, 0, 0);
165  }  }
166    
167    #ifdef BUGGY_GCC_DIV64
168    /* gcc 2.95.4 on PowerPC does not seem to like using __udivdi3, so we
169       call it from another function */
170    uint32_t div64(uint32_t *q_ptr, uint64_t num, uint32_t den)
171    {
172        *q_ptr = num / den;
173        return num % den;
174    }
175    
176    int32_t idiv64(int32_t *q_ptr, int64_t num, int32_t den)
177    {
178        *q_ptr = num / den;
179        return num % den;
180    }
181    #endif
182    
183    void helper_divl_EAX_T0(uint32_t eip)
184    {
185        unsigned int den, q, r;
186        uint64_t num;
187        
188        num = EAX | ((uint64_t)EDX << 32);
189        den = T0;
190        if (den == 0) {
191            EIP = eip;
192            raise_exception(EXCP00_DIVZ);
193        }
194    #ifdef BUGGY_GCC_DIV64
195        r = div64(&q, num, den);
196    #else
197        q = (num / den);
198        r = (num % den);
199    #endif
200        EAX = q;
201        EDX = r;
202    }
203    
204    void helper_idivl_EAX_T0(uint32_t eip)
205    {
206        int den, q, r;
207        int64_t num;
208        
209        num = EAX | ((uint64_t)EDX << 32);
210        den = T0;
211        if (den == 0) {
212            EIP = eip;
213            raise_exception(EXCP00_DIVZ);
214        }
215    #ifdef BUGGY_GCC_DIV64
216        r = idiv64(&q, num, den);
217    #else
218        q = (num / den);
219        r = (num % den);
220    #endif
221        EAX = q;
222        EDX = r;
223    }
224    
225    void helper_cmpxchg8b(void)
226    {
227        uint64_t d;
228        int eflags;
229    
230        eflags = cc_table[CC_OP].compute_all();
231        d = ldq((uint8_t *)A0);
232        if (d == (((uint64_t)EDX << 32) | EAX)) {
233            stq((uint8_t *)A0, ((uint64_t)ECX << 32) | EBX);
234            eflags |= CC_Z;
235        } else {
236            EDX = d >> 32;
237            EAX = d;
238            eflags &= ~CC_Z;
239        }
240        CC_SRC = eflags;
241    }
242    
243  /* We simulate a pre-MMX pentium as in valgrind */  /* We simulate a pre-MMX pentium as in valgrind */
244  #define CPUID_FP87 (1 << 0)  #define CPUID_FP87 (1 << 0)
245  #define CPUID_VME  (1 << 1)  #define CPUID_VME  (1 << 1)
# Line 221  void load_seg(int seg_reg, int selector, Line 353  void load_seg(int seg_reg, int selector,
353      env->segs[seg_reg] = selector;      env->segs[seg_reg] = selector;
354  }  }
355    
356    /* rdtsc */
357    #ifndef __i386__
358    uint64_t emu_time;
359    #endif
360    
361    void helper_rdtsc(void)
362    {
363        uint64_t val;
364    #ifdef __i386__
365        asm("rdtsc" : "=A" (val));
366    #else
367        /* better than nothing: the time increases */
368        val = emu_time++;
369    #endif
370        EAX = val;
371        EDX = val >> 32;
372    }
373    
374  void helper_lsl(void)  void helper_lsl(void)
375  {  {
376      unsigned int selector, limit;      unsigned int selector, limit;

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

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