Commit 2d0e9143e2d6fc705cba6c27c221c5c9a7c81a29

Authored by bellard
1 parent 87f4827e

more code moved to helpers - sipmplified x86 float constants definitions


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@217 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 150 additions and 0 deletions
helper-i386.c
... ... @@ -19,6 +19,62 @@
19 19 */
20 20 #include "exec-i386.h"
21 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 +
22 78 #if 0
23 79 /* full interrupt support (only useful for real CPU emulation, not
24 80 finished) - I won't do it any time soon, finish it if you want ! */
... ... @@ -108,6 +164,82 @@ void raise_exception(int exception_index)
108 164 raise_interrupt(exception_index, 0, 0, 0);
109 165 }
110 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 +
111 243 /* We simulate a pre-MMX pentium as in valgrind */
112 244 #define CPUID_FP87 (1 << 0)
113 245 #define CPUID_VME (1 << 1)
... ... @@ -221,6 +353,24 @@ void load_seg(int seg_reg, int selector, unsigned cur_eip)
221 353 env->segs[seg_reg] = selector;
222 354 }
223 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 +
224 374 void helper_lsl(void)
225 375 {
226 376 unsigned int selector, limit;
... ...