将内联ASM转换为x64 igraph的内在函数

时间:2012-10-30 20:19:34

标签: c++ c assembly visual-studio-2012 intrinsics

我正在从源代码编译python扩展IGRAPH for x64而不是x86,它在发行版中可用。我已经把它全部整理到了VS 2012中,当我在src / math.c中注释如下时编译它

#ifndef HAVE_LOGBL
long double igraph_logbl(long double x) {
long double res;
/**#if defined(_MSC_VER)
  __asm { fld [x] }
  __asm { fxtract }
  __asm { fstp st }
  __asm { fistp [res] }
 #else
 __asm__ ("fxtract\n\t"
 "fstp  %%st" : "=t" (res) : "0" (x));
 #endif*/
    return res;
 }
#endif

问题是我不太清楚并且我不太了解它是否存在从x86到x64的问题。这是一个包含4个程序集内容的简短片段,必须从我看到的内容转换为x64内部函数。

任何指针?内在正确的方式?或者它应该是子程序还是纯C?

编辑:如果有人想要查看http://igraph.sourceforge.net/download.html

,请为igraph扩展程序添加链接

1 个答案:

答案 0 :(得分:2)

在x64中,浮点通常使用SSE2指令执行,因为它们通常要快得多。这里唯一的问题是SSE中没有与fxtract op相同的(这通常意味着FPU版本将被实现为复合指令,因此非常慢)。因此,在x64上实现C函数可能同样快。

我发现函数有点难以阅读,但是我可以告诉它调用fxtract然后将整数值存储到long double指向的地址。这意味着long double将在其中具有“部分”未定义的值。最好我可以告诉上面的代码程序集不应该工作......但是自从我编写任何x87代码以来,它已经很长时间了,所以我可能只是生锈了。

无论如何,该函数似乎是logb的一个实现,您将无法在MSVC中实现该实现。但是,它可以使用frexp函数实现如下:

long double igraph_logbl(long double x) 
{
    int exp = 0;
    frexpl( x, &exp );
    return (long double)exp;
 }