0

以下程序集在简单 C 中的含义是什么(这是用 gcc 编译的):

asm volatile
    (
    "mov.d %0,%4\n\t"
    "L1: bge %2,%3,L2\n\t"
    "gsLQC1 $f2,$f0,0(%1)\n\t"
    "gsLQC1 $f6,$f4,0(%5)\n\t"
    "madd.d %0,%0,$f6,$f2\n\t"
    "madd.d %0,%0,$f4,$f0\n\t"
    "add %1,%1,16\n\t"
    "add %2,%2,2\n\t"
    "add %5,%5,16\n\t"
    "j L1\n\t"
    "L2: nop\n\t" 
    :"=f"(sham)
    :"r"(foo),"r"(bar),"r"(ro),"f"(sham),"r"(bo)
    :"$f0","$f2","$f4","$f6"
    );

经过几个小时的搜索和阅读,我得到了以下 AT&T 语法的汇编代码:

mov.d %xmm0,%xmm1
L1: bge %ebx,%ecx,L2
gsLQC1 $f2,$f0,0(%eax)
gsLQC1 $f6,$f4,0(%esi)
madd.d %xmm0,%xmm0,$f6,$f2
madd.d %xmm0,%xmm0,$f4,$f0
add %eax,%eax,16
add %ebx,%ebx,2
add %esi,%esi,16
jmp L1
L2: nop

我正在寻找一种在 Windows 上运行它的方法,并且当我找到一种方法时会更新(在修复了我确定我犯的所有错误之后)。

我对 x86 汇编的经验很少,也就是说,我隐约认识到这是一个循环,但我一直无法找到指令 gsLQC1 的含义。或者循环的目的是什么。

如果您有任何问题要问我,我很乐意为您解答。如果您有任何见解,我很想听听他们的意见。感谢您的时间。

编辑:

该函数本身正在处理执行主要与矩阵有关的奇异值分解 (SVD)。

我正在用我自己的一些评论更新下面的内容,程序集的原始作者没有写这些,但鉴于我对 GCC 的 asm 块表示法的研究,我有 80% 的信心它们是正确的。

    asm volatile
       (
       "mov.d %0,%4\n\t"
       "L1: bge %2,%3,L2\n\t"
       "gsLQC1 $f2,$f0,0(%1)\n\t"
       "gsLQC1 $f6,$f4,0(%5)\n\t"
       "madd.d %0,%0,$f6,$f2\n\t"
       "madd.d %0,%0,$f4,$f0\n\t"
       "add %1,%1,16\n\t"
       "add %2,%2,2\n\t"
       "add %5,%5,16\n\t"
       "j L1\n\t"
       "L2: nop\n\t" 
       :"=f"(sham) /*Corresponds to %0 in the above code*/
       :"r"(foo) /*Corresponds to %1*/,"r"(bar) /*%2*/,"r"(ro) /*%3*/,"f"(sham) /*%4*/,"r"(bo) /*%5*/
       :"$f0","$f2","$f4","$f6"
       );

我认为这是在 x86 中,但很可能是错误的。我相信以上是为龙芯家族的处理器编写的 MIPS64 程序集。

感谢您对这个问题的兴趣。我很感激你的时间。同样,如果有任何其他问题,我很乐意尽力回答。

PS原始代码可以在这里找到,我要问的程序集从第189行开始

4

1 回答 1

1

这不是真正的答案,但也不适合评论。鉴于您省略了几条关键信息(源指令用于什么处理器、参数的数据类型、代码在做什么的一般意义等),很难找到一个好的答案。

在一般意义上,我会想:

float messy(const float *foo, int bar, int ro, const float *bo)
{
    float sham = 0;

    while (bar < ro)
    {
       __m256 a = _mm256_load_ps(foo);
       __m256 b = _mm256_load_ps(bar);

       __m256 c = _mm256_add_ps(a, a);
       __m256 d = _mm256_add_ps(b, b);

       foo += 2;
       bar += 2;
       bo += 2;
    }

    return sham;
}

这并不完全正确,因为(除其他外)sham还没有设置好。但这是一个开始的地方。如果没有详细信息madd.d(如果不知道我们在谈论什么硬件,很难说),那是我能得到的最接近的结果。

只是为了强调我在评论中所说的话,原始代码似乎写得不好(修改只读参数、双跳、NO COMMENTS 等)。

于 2017-08-20T04:00:17.010 回答