我想知道在Visual C ++中是否真的没有128位除法内部函数?
有一个名为_umul128()
的64x64 = 128位乘法内部函数,它很好地匹配MUL
x64汇编程序指令。
当然,我假设会有一个128/64 = 64位内部分区(对DIV
指令进行建模),但令我惊讶的是,Visual C ++和英特尔C ++似乎都没有它,至少它是未在intrin.h中列出。
有人可以证实吗?我尝试grep'ing编译器可执行文件中的函数名称,但首先找不到_umul128
,所以我想我看错了。
更新:至少我现在在Visual C ++ 2010的c1.dll中找到了模式umul128
(没有前导下划线)。所有其他内在函数都列在它周围,但遗憾的是没有“udiv128”或者喜欢:(所以看起来他们真的已经“忘记”去实现它了。
澄清一下:我不只是在寻找128位数据类型,而是在C ++中将128位标量int除以64位int的方法。 内部函数或本机 128位整数支持可以解决我的问题。
编辑:答案是否定的,截至2017年,Visual Studio 2010中没有_udiv128
内在函数,但它在Visual Studio 2019 RTM中可用
答案 0 :(得分:10)
如果你不介意小黑客,这可能会有所帮助(仅限64位模式,未经测试):
#include <windows.h>
#include <stdio.h>
unsigned char udiv128Data[] =
{
0x48, 0x89, 0xD0, // mov rax,rdx
0x48, 0x89, 0xCA, // mov rdx,rcx
0x49, 0xF7, 0xF0, // div r8
0x49, 0x89, 0x11, // mov [r9],rdx
0xC3 // ret
};
unsigned char sdiv128Data[] =
{
0x48, 0x89, 0xD0, // mov rax,rdx
0x48, 0x89, 0xCA, // mov rdx,rcx
0x49, 0xF7, 0xF8, // idiv r8
0x49, 0x89, 0x11, // mov [r9],rdx
0xC3 // ret
};
unsigned __int64 (__fastcall *udiv128)(unsigned __int64 numhi,
unsigned __int64 numlo,
unsigned __int64 den,
unsigned __int64* rem) =
(unsigned __int64 (__fastcall *)(unsigned __int64,
unsigned __int64,
unsigned __int64,
unsigned __int64*))udiv128Data;
__int64 (__fastcall *sdiv128)(__int64 numhi,
__int64 numlo,
__int64 den,
__int64* rem) =
(__int64 (__fastcall *)(__int64,
__int64,
__int64,
__int64*))sdiv128Data;
int main(void)
{
DWORD dummy;
unsigned __int64 ur;
__int64 sr;
VirtualProtect(udiv128Data, sizeof(udiv128Data), PAGE_EXECUTE_READWRITE, &dummy);
VirtualProtect(sdiv128Data, sizeof(sdiv128Data), PAGE_EXECUTE_READWRITE, &dummy);
printf("0x00000123456789ABCDEF000000000000 / 0x0001000000000000 = 0x%llX\n",
udiv128(0x00000123456789AB, 0xCDEF000000000000, 0x0001000000000000, &ur));
printf("-6 / -2 = %lld\n",
sdiv128(-1, -6, -2, &sr));
return 0;
}
答案 1 :(得分:6)
一项小改进 - 少一条指令
extern "C" digit64 udiv128(digit64 low, digit64 hi, digit64 divisor, digit64 *remainder);
; Arguments
; RCX Low Digit
; RDX High Digit
; R8 Divisor
; R9 *Remainder
; RAX Quotient upon return
.code
udiv128 proc
mov rax, rcx ; Put the low digit in place (hi is already there)
div r8 ; 128 bit divide rdx-rax/r8 = rdx remainder, rax quotient
mov [r9], rdx ; Save the reminder
ret ; Return the quotient
udiv128 endp
end
答案 2 :(得分:2)
String pathName = new java.io.File(Application.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getName();
内部函数将128位整数除以64位整数。返回值保存商,内部函数通过指针参数返回余数。_div128
是Microsoft专用的。
据说去年from "Dev16"可用,但我不确定是哪个版本。我猜它是VS 16.0 A.K.A VS2019,但是MSDN上的文档显示它可以更进一步地进入VS2015
答案 3 :(得分:1)
我不是专家,但我挖了这个:
http://research.swtch.com/2008/01/division-via-multiplication.html
有趣的东西。希望它有所帮助。
编辑:这也很有见地:http://www.gamedev.net/topic/508197-x64-div-intrinsic/