cxx*_*xxl 10 integer-division intrinsics visual-c++ 128-bit
我想知道在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位整数的支持会解决我的问题.
编辑:答案是否定的,Visual Studio 2010或2012中没有_udiv128内在函数.
Ale*_*nze 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;
}
Run Code Online (Sandbox Code Playgroud)
小智 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
Run Code Online (Sandbox Code Playgroud)
我不是专家,但我发现了这一点:
http://research.swtch.com/2008/01/division-via-multiplication.html
有趣的东西。希望能帮助到你。
编辑:这也很有洞察力:http ://www.gamedev.net/topic/508197-x64-div-intrinsic/
| 归档时间: |
|
| 查看次数: |
5352 次 |
| 最近记录: |