inline assembler

固定小数点演算の掛け算割り算で桁落ちを避ける為に__int64を使うと、__allmulや__alldivがcallされて遅いので、inline assemblerを使って関数を作ってみた。int 3h以外で初めて書いてみたけど短いのは案外簡単だなぁ。スタック弄りは未だやり方が不明…。

// 掛け算を行って右シフトする。固定小数点演算等に利用。
template <typename T, size_t shifts>
T mulShift(T lhs, T rhs)
{
	// enum hack.. http://d.hatena.ne.jp/paserry/20050304
	enum
	{
		s1 = shifts,
		s2 = sizeof(T)*8 - shifts,
	};
	__asm {
		mov eax, lhs
		mov edx, rhs
		imul edx
		shr eax, s1
		shl edx, s2
		or eax, edx
	}
}

// 左シフトして割り算する。固定小数点演算等に利用。
template <typename T, size_t shifts>
T divShift(T lhs, T rhs)
{
	enum
	{
		s1 = shifts,
		s2 = sizeof(T)*8 - shifts,
	};
	__asm {
		mov edx, lhs
		mov eax, lhs
		sar edx, s2
		sal eax, s1
		idiv rhs
	}
}

http://pc8.2ch.net/test/read.cgi/tech/1136527588/
http://www.sandpile.org/