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

Diff of /qemu/target-i386/helper.c

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

revision 1.50 by bellard, Sat Jul 23 17:41:26 2005 UTC revision 1.51 by bellard, Sat Jul 23 20:21:38 2005 UTC
# Line 1209  void raise_exception(int exception_index Line 1209  void raise_exception(int exception_index
1209  #ifdef BUGGY_GCC_DIV64  #ifdef BUGGY_GCC_DIV64
1210  /* gcc 2.95.4 on PowerPC does not seem to like using __udivdi3, so we  /* gcc 2.95.4 on PowerPC does not seem to like using __udivdi3, so we
1211     call it from another function */     call it from another function */
1212  uint32_t div32(uint32_t *q_ptr, uint64_t num, uint32_t den)  uint32_t div32(uint64_t *q_ptr, uint64_t num, uint32_t den)
1213  {  {
1214      *q_ptr = num / den;      *q_ptr = num / den;
1215      return num % den;      return num % den;
1216  }  }
1217    
1218  int32_t idiv32(int32_t *q_ptr, int64_t num, int32_t den)  int32_t idiv32(int64_t *q_ptr, int64_t num, int32_t den)
1219  {  {
1220      *q_ptr = num / den;      *q_ptr = num / den;
1221      return num % den;      return num % den;
# Line 1224  int32_t idiv32(int32_t *q_ptr, int64_t n Line 1224  int32_t idiv32(int32_t *q_ptr, int64_t n
1224    
1225  void helper_divl_EAX_T0(void)  void helper_divl_EAX_T0(void)
1226  {  {
1227      unsigned int den, q, r;      unsigned int den, r;
1228      uint64_t num;      uint64_t num, q;
1229            
1230      num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);      num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
1231      den = T0;      den = T0;
# Line 1238  void helper_divl_EAX_T0(void) Line 1238  void helper_divl_EAX_T0(void)
1238      q = (num / den);      q = (num / den);
1239      r = (num % den);      r = (num % den);
1240  #endif  #endif
1241        if (q > 0xffffffff)
1242            raise_exception(EXCP00_DIVZ);
1243      EAX = (uint32_t)q;      EAX = (uint32_t)q;
1244      EDX = (uint32_t)r;      EDX = (uint32_t)r;
1245  }  }
1246    
1247  void helper_idivl_EAX_T0(void)  void helper_idivl_EAX_T0(void)
1248  {  {
1249      int den, q, r;      int den, r;
1250      int64_t num;      int64_t num, q;
1251            
1252      num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);      num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
1253      den = T0;      den = T0;
# Line 1258  void helper_idivl_EAX_T0(void) Line 1260  void helper_idivl_EAX_T0(void)
1260      q = (num / den);      q = (num / den);
1261      r = (num % den);      r = (num % den);
1262  #endif  #endif
1263        if (q != (int32_t)q)
1264            raise_exception(EXCP00_DIVZ);
1265      EAX = (uint32_t)q;      EAX = (uint32_t)q;
1266      EDX = (uint32_t)r;      EDX = (uint32_t)r;
1267  }  }
# Line 3254  static void imul64(uint64_t *plow, uint6 Line 3258  static void imul64(uint64_t *plow, uint6
3258      }      }
3259  }  }
3260    
3261  /* XXX: overflow support */  /* return TRUE if overflow */
3262  static void div64(uint64_t *plow, uint64_t *phigh, uint64_t b)  static int div64(uint64_t *plow, uint64_t *phigh, uint64_t b)
3263  {  {
3264      uint64_t q, r, a1, a0;      uint64_t q, r, a1, a0;
3265      int i, qb;      int i, qb;
# Line 3268  static void div64(uint64_t *plow, uint64 Line 3272  static void div64(uint64_t *plow, uint64
3272          *plow = q;          *plow = q;
3273          *phigh = r;          *phigh = r;
3274      } else {      } else {
3275            if (a1 >= b)
3276                return 1;
3277          /* XXX: use a better algorithm */          /* XXX: use a better algorithm */
3278          for(i = 0; i < 64; i++) {          for(i = 0; i < 64; i++) {
3279              a1 = (a1 << 1) | (a0 >> 63);              a1 = (a1 << 1) | (a0 >> 63);
# Line 3286  static void div64(uint64_t *plow, uint64 Line 3292  static void div64(uint64_t *plow, uint64
3292          *plow = a0;          *plow = a0;
3293          *phigh = a1;          *phigh = a1;
3294      }      }
3295        return 0;
3296  }  }
3297    
3298  static void idiv64(uint64_t *plow, uint64_t *phigh, int64_t b)  /* return TRUE if overflow */
3299    static int idiv64(uint64_t *plow, uint64_t *phigh, int64_t b)
3300  {  {
3301      int sa, sb;      int sa, sb;
3302      sa = ((int64_t)*phigh < 0);      sa = ((int64_t)*phigh < 0);
# Line 3297  static void idiv64(uint64_t *plow, uint6 Line 3305  static void idiv64(uint64_t *plow, uint6
3305      sb = (b < 0);      sb = (b < 0);
3306      if (sb)      if (sb)
3307          b = -b;          b = -b;
3308      div64(plow, phigh, b);      if (div64(plow, phigh, b) != 0)
3309      if (sa ^ sb)          return 1;
3310        if (sa ^ sb) {
3311            if (*plow > (1ULL << 63))
3312                return 1;
3313          *plow = - *plow;          *plow = - *plow;
3314        } else {
3315            if (*plow >= (1ULL << 63))
3316                return 1;
3317        }
3318      if (sa)      if (sa)
3319          *phigh = - *phigh;          *phigh = - *phigh;
3320        return 0;
3321  }  }
3322    
3323  void helper_mulq_EAX_T0(void)  void helper_mulq_EAX_T0(void)
# Line 3344  void helper_divq_EAX_T0(void) Line 3360  void helper_divq_EAX_T0(void)
3360      }      }
3361      r0 = EAX;      r0 = EAX;
3362      r1 = EDX;      r1 = EDX;
3363      div64(&r0, &r1, T0);      if (div64(&r0, &r1, T0))
3364            raise_exception(EXCP00_DIVZ);
3365      EAX = r0;      EAX = r0;
3366      EDX = r1;      EDX = r1;
3367  }  }
# Line 3357  void helper_idivq_EAX_T0(void) Line 3374  void helper_idivq_EAX_T0(void)
3374      }      }
3375      r0 = EAX;      r0 = EAX;
3376      r1 = EDX;      r1 = EDX;
3377      idiv64(&r0, &r1, T0);      if (idiv64(&r0, &r1, T0))
3378            raise_exception(EXCP00_DIVZ);
3379      EAX = r0;      EAX = r0;
3380      EDX = r1;      EDX = r1;
3381  }  }

Legend:
Removed from v.1.50  
changed lines
  Added in v.1.51

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