8

這是(AFAIK)this general topic中的一個特定問題。如何使用32位除法指令執行64位除法?

這裏的情況:

我有一個基於32位RISC微控制器的嵌入式系統(視頻遊戲控制檯)(NEC的V810的變體)。我想寫一個定點數學庫。我讀this article,但隨附的源代碼是用386彙編編寫的,所以它既不可直接使用也不易修改。

V810內置了整數乘法/除法,但我想使用上述文章中提到的18.14格式。這要求將一個64位整數除以一個32位整數,並且V810只做(有符號或無符號)32位/ 32位除法(產生一個32位商和一個32位餘數)。

所以,我的問題是:如何模擬一個32位/ 32位的64位/ 32位除法(以允許預先移動除數)?或者,從另一個角度來看待問題,使用標準32位算術/邏輯運算來劃分另一個18.14定點的最佳方法是什麼? (「最好」意思是最快,最小或兩者)。

代數,(V810)程序集和僞代碼都很好。我會打電話給代碼C.

在此先感謝!

編輯:不知何故我錯過了this question ...但是,它仍然需要一些修改才能超級高效(它必須比v810提供的浮點格更快,儘管它可能已經是.. ),所以請隨時爲我做我的工作以換取名譽點;)(當然,在我的圖書館文檔中還有信用)。

+0

[32/16位除法處理器上的64/32位除法](https://stackoverflow.com/q/ 4771823/995714) – 2017-05-23 08:59:15

回答

5

GCC對許多處理器都有這樣的例程,名爲_divdi3(通常使用普通的divmod調用來實現)。 Here's one。一些Unix內核也有一個實現,例如, FreeBSD

+0

這似乎正是我所需要的。感謝您鏈接到相關的代碼!順便說一句,我使用GCC,但我使用的是newlib,它不包含這些東西。 – RunnerPack 2010-08-31 08:39:28

0

如果被除數是無符號的64位,您的除數是無符號的32位,該體系結構是I386(86),所述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