理解为gcc编写的asm块

时间:2017-08-20 01:43:58

标签: c gcc assembly mips64

以下程序集在简单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上运行此方法的方法,并且当我找到一种方法时会更新(在解决了我确定已经犯下的所有错误之后)。< / p>

我对x86程序集的经验很少,说,我模糊地认识到这是一个循环,但我无法找到gsLQC1指令的含义。或者循环的目的是什么。

如果您对我有任何疑问,我将很乐意回答。如果您有任何见解,我很乐意听到他们的意见。谢谢你的时间。

修改

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

我正在用我自己的一些评论更新下面的内容,大会的原作者没有写这些,但我80%确信它们是正确的,因为我对GCC的asm块表示法的研究。

    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程序集。

感谢你对这个问题感兴趣。我很感激你的时间。再说一遍,如果还有其他问题,我会很乐意尽力回答。

P.S。可以找到原始代码here,我询问的程序集从第189行开始

1 个答案:

答案 0 :(得分:0)

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

一般来说,我在想:

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所做的事情的详细信息(如果不知道我们正在谈论什么硬件,这很难说),那就像我能得到的那样接近。

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