11

これは(AFAIK)この一般的なトピック内の特定の質問です。

状況は次のとおりです。

32ビットRISCマイクロコントローラー(NECのV810のバリアント)に基づく組み込みシステム(ビデオゲームコンソール)があります。固定小数点数学ライブラリを書きたいです。この記事を読みましたが、付属のソースコードは386アセンブリで記述されているため、直接使用することも、簡単に変更することもできません。

V810には整数の乗算/除算が組み込まれていますが、上記の記事で説明した18.14形式を使用したいと思います。これには、64ビット整数を32ビット整数で除算する必要があり、V810は(符号付きまたは符号なし)32ビット/ 32ビット除算のみを実行します(32ビット整数と32ビット余りを生成します)。

だから、私の質問は、64ビット/32ビットの除算を32ビット/32ビットの除算でシミュレートするにはどうすればよいですか(配当の事前シフトを可能にするため)?または、別の方法で問題を調べるために、標準の32ビット算術/論理演算を使用して18.14固定小数点を別の固定小数点で除算するための最良の方法は何ですか?(「最良」とは、最速、最小、またはその両方を意味します)。

代数、(V810)アセンブリ、および擬似コードはすべて問題ありません。Cからコードを呼び出します。

前もって感謝します!

編集:どういうわけか私はこの質問を逃しました...しかし、それでも超効率的にするためにいくつかの変更が必要です(それはすでにあるかもしれませんが、v810によって提供される浮動小数点divよりも高速でなければなりません...)、ですから、評判ポイントと引き換えに私のために自由に仕事をしてください;)(そしてもちろん私の図書館のドキュメントのクレジット)。

4

2 に答える 2

6

GCC には、_divdi3 という名前の多くのプロセッサ用のルーチンがあります (通常、一般的な divmod 呼び出しを使用して実装されます)。これが 1 つです。FreeBSDなど、一部の Unix カーネルにも実装があります。

于 2010-08-26T07:52:46.647 に答える
2

被除数が符号なし 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がコンパイルされない場合は__div64_32、Linux カーネルの関数を使用してください: https://github.com/torvalds/linux/blob/master/lib/div64.c

于 2017-02-01T14:34:21.400 に答える