Pergunta

Estou tentando fazer um programa compilado com o GCC e usando o QT e o SSE Intrinsics. Parece que quando uma das minhas funções é chamada pelo QT, o alinhamento da pilha não é preservado. Aqui está um pequeno exemplo para ilustrar o que quero dizer:

#include <cstdio>
#include <emmintrin.h>
#include <QtGui/QApplication.h>
#include <QtGui/QWidget.h>


class Widget: public QWidget {
public:
    void paintEvent(QPaintEvent *) {
        __m128 a;
        printf("a: 0x%08x\n", ((void *) &a));
    }
};


int main(int argc, char** argv)
{
    QApplication application(argc, argv);
    Widget w;
    w.paintEvent(NULL); // Called from here, my function behaves correctly
    w.show();
    w.update();
    // Qt will call Widget::paintEvent and my __m128 will not be
    // aligned on 16 bytes as it should
    application.processEvents();

    return 0;
}

Aqui está a saída:

a: 0x0023ff40 // OK, that's aligned on 16 bytes
a: 0x0023d14c // Not aligned!

Configuração:

  • Intel Core2
  • Winxp, SP3
  • GCC 4.4 (Mingw incluído no QT SDK 2010.01)

Tentei compilar o programa de exemplo com as mesmas opções que as que vi no QT Makefile:

-O2 -Wall -frtti -fexceptions -mthreads

, opções de link:

-enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-s -mthreads

Agora não sei em que instruções procurar. Quaisquer dicas seriam bem vindas. Obrigado!

Fabien

Foi útil?

Solução

Você pode usar a opção -mstackrealign Para fazer isso sem adicionar atributos ao seu código -fonte:

-mstackrealignRealine a pilha na entrada. Na Intel X86, a opção -mstackrealign gerará um prólogo e um epílogo alternativo que realinha a pilha de tempo de execução, se necessário. Isso suporta códigos herdados de mistura que mantêm uma pilha alinhada de 4 bytes com códigos modernos que mantêm uma pilha de 16 bytes para a compatibilidade do SSE. Veja também o atributo force_align_arg_pointer, aplicável a funções individuais.

(a partir de os documentos do GCC)

Outras dicas

__attribute__((force_align_arg_pointer)) void paintEvent(QPaintEvent *);

fez funcionar! Alguém tem uma solução melhor?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top