How can I perform 64-bit division with a 32-bit divide instruction?

前端 未结 2 844
鱼传尺愫
鱼传尺愫 2020-12-17 20:00

This is (AFAIK) a specific question within this general topic.

Here\'s the situation:

I have an embedded system (a video game console) based on a 32-bit RISC

相关标签:
2条回答
  • 2020-12-17 20:25

    If your dividend is unsigned 64 bits, your divisor is unsigned 32 bits, the architecture is i386 (x86), the div assembly instruction can help you with some preparation:

    #include <stdint.h>
    /* Returns *a % b, and sets *a = *a_old / b; */
    uint32_t UInt64DivAndGetMod(uint64_t *a, uint32_t b) {
    #ifdef __i386__  /* u64 / u32 division with little i386 machine code. */
      uint32_t upper = ((uint32_t*)a)[1], r;
      ((uint32_t*)a)[1] = 0;
      if (upper >= b) {   
        ((uint32_t*)a)[1] = upper / b;
        upper %= b;
      }
      __asm__("divl %2" : "=a" (((uint32_t*)a)[0]), "=d" (r) :
          "rm" (b), "0" (((uint32_t*)a)[0]), "1" (upper));
      return r;
    #else
      const uint64_t q = *a / b;  /* Calls __udivdi3 in libgcc. */
      const uint32_t r = *a - b * q;  /* `r = *a % b' would use __umoddi3. */
      *a = q;
      return r;
    #endif
    }
    

    If the line above with __udivdi3 doesn't compile for you, use the __div64_32 function from the Linux kernel: https://github.com/torvalds/linux/blob/master/lib/div64.c

    0 讨论(0)
  • 2020-12-17 20:30

    GCC has such a routine for many processors, named _divdi3 (usually implemented using a common divmod call). Here's one. Some Unix kernels have an implementation too, e.g. FreeBSD.

    0 讨论(0)
提交回复
热议问题