使用MinGW时带有浮点值的错误调用约定

问题描述 投票:1回答:1

[我试图将我的汇编函数与C代码一起使用,发现MinGw不遵循浮点值的调用约定,这与mingw的版本不同。

具有单个功能test.c的测试文件

#include <xmmintrin.h>

float vector_dot(__m128 v1, __m128 v2)
{
     __m128 resp = _mm_mul_ps(v1, v2);
     float res;
     _mm_store_ss(&res, resp);
     return res;
};

编译为汇编

gcc -O -S test.c -msse4.1
    .file   "test.c"
    .text
    .globl  _vector_dot
    .def    _vector_dot;    .scl    2;  .type   32; .endef
_vector_dot:
LFB503:
    .cfi_startproc
    pushl   %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    andl    $-16, %esp
    subl    $16, %esp
    mulps   %xmm1, %xmm0
    movss   %xmm0, 12(%esp)
    flds    12(%esp)
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
LFE503:
    .ident  "GCC: (MinGW.org GCC-6.3.0-1) 6.3.0"

浮点结果存储到ST0寄存器,而不是xmm0,就像在Linux上一样

但是在MinGW的不同版本中:

    .file   "test.c"
    .text
    .globl  vector_dot
    .def    vector_dot; .scl    2;  .type   32; .endef
    .seh_proc   vector_dot
vector_dot:
    .seh_endprologue
    movaps  (%rdx), %xmm0
    mulps   (%rcx), %xmm0
    ret
    .seh_endproc
    .ident  "GCC: (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 7.3.0"

仅2条指令,xmm0,xmm1中为args,并且按预期结果为xmm0。

但是,在这种情况下,从C代码进行的函数调用在rax和rdx寄存器中具有错误的args

我的集合

vector_dot: /* vector xmm0, vector xmm1 -> float xmm0 */
  mulps  %xmm1,%xmm0 

vector_horizontal_sum: /* vector xmm0 -> float xmm0 (0 + 1 + 2 + 3) */
   movshdup  %xmm0, %xmm1
   addps        %xmm1, %xmm0
   movhlps     %xmm0, %xmm1
   addss        %xmm1, %xmm0
   ret

C中的函数头

extern float vector_dot(__m128 vector_1, __m128 vector_2) asm("vector_dot");

调用我的函数

    float values1[] __attribute__((aligned(16))) = { 1.3f, 5.4f, -4.f, 5. } ;
    __m128 vec1 = _mm_load_ps(values1);

    float values2[] __attribute__((aligned(16))) = {0.5f, -43.5f, 0, 0 };
    __m128 vec2 = _mm_load_ps(values2);

    float dot = vector_dot(vec1, vec2);

函数调用程序集,编译器未将xmm寄存器用于args,导致我的程序崩溃

0x401614  <+  180>        0f 28 45 e0                 movaps -0x20(%rbp),%xmm0
0x401618  <+  184>        0f 29 85 40 ff ff ff        movaps %xmm0,-0xc0(%rbp)
0x40161f  <+  191>        0f 28 45 d0                 movaps -0x30(%rbp),%xmm0
0x401623  <+  195>        0f 29 85 30 ff ff ff        movaps %xmm0,-0xd0(%rbp)
0x40162a  <+  202>        48 8d 95 30 ff ff ff        lea    -0xd0(%rbp),%rdx
0x401631  <+  209>        48 8d 85 40 ff ff ff        lea    -0xc0(%rbp),%rax
0x401638  <+  216>        48 89 c1                    mov    %rax,%rcx
0x40163b  <+  219>        e8 d4 29 00 00              callq  0x404014 <vector_dot>
0x401640  <+  224>        66 0f 7e c0                 movd   %xmm0,%eax
0x401644  <+  228>        89 45 cc                    mov    %eax,-0x34(%rbp)

我的代码出什么问题了,这是MinGW编译器错误吗?

c gcc assembly mingw gas
1个回答
0
投票

比较mingw 32位和mingw 64位二进制文​​件是错误的,所以当使用最新的mingw-w64进行编译时,所有调用约定都按预期方式进行。

© www.soinside.com 2019 - 2024. All rights reserved.