[英]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快,盡管它可能已經......),因此,我可以隨意為我工作,以換取聲望點;)(當然,我的圖書館文檔中也有用)。
如果你的被除數是無符號的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.