簡體   English   中英

如何使用32位除法指令執行64位除法?

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

這是(AFAIK) 這個一般主題中的一個具體問題。

情況如下:

我有一個基於32位RISC微控制器(NEC V810的變體)的嵌入式系統(視頻游戲控制台)。 我想寫一個定點數學庫。 我讀過這篇文章 ,但隨附的源代碼是用386匯編編寫的,所以它既不能直接使用也不能輕易修改。

V810有內置的整數乘法/除法,但我想使用上面文章中提到的18.14格式。 這需要將64位int除以32位int,而V810僅執行(有符號或無符號)32位/ 32位除法(產生32位商和32位余數)。

所以,我的問題是:如何使用32位/ 32位模擬64位/ 32位除法(以允許紅移的預移位)? 或者,從另一種方式來看問題,使用標准的32位算術/邏輯運算將18.14定點除以另一種定義的最佳方法是什么? (“最好”意味着最快,最小或兩者兼而有之)。

代數,(V810)匯編和偽代碼都很好。 我將從C調用代碼。

提前致謝!

編輯:不知怎的,我錯過了這個問題 ...但是,它仍然需要一些修改才能超級高效(它必須比v810提供的浮點div快,盡管它可能已經......),因此,我可以隨意為我工作,以換取聲望點;)(當然,我的圖書館文檔中也有用)。

GCC對許多處理器都有這樣的例程,名為_divdi3(通常使用公共的divmod調用實現)。 這是一個 一些Unix內核也有一個實現,例如FreeBSD

如果你的被除數是無符號的64位,你的除數是無符號32位,架構是i386(x86), div匯編指令可以幫助你做一些准備:

#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
}

如果上面的__udivdi3行沒有為您編譯,請使用Linux內核中的__div64_32函數: https//github.com/torvalds/linux/blob/master/lib/div64.c

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM