According to the Microsoft 64-bit ABI specification, registers RDI, RSI and XMM6-15 are non-volatile and the stack alignment is 16 bytes. In practice, the Windows implementation appears to not be so picky about the 16-byte alignment requirement, probably because it never to save SSE registers and instead just never uses them. This led to a large list (https://bugs.winehq.org/show_bug.cgi?id=27680) of Win64 programs violating the ABI with impunity, but crashing in Wine until force_align_arg_pointer was added to gcc and used in Wine.

Stack re-alignment was originally done prior to int register saves, but was moved to after SSE saves in 2010 to better facilitate parallelization, and for simplicity's sake, the stack pointer was considered invalid after stack re-alignment and SSE movs were emitted unaligned relative to the frame pointer. But now that forced stack re-alignment is the new normal for Wine64, it means that it always gets the unaligned movs in Wine. This patch set fixes the problem while preserving the improved parallelization of int register saves of Richard Henderson's patch in 2010.

This patchset is a prerequisite to another I'm still refining that out-of-lines these pro/epilogues. I'm still pretty new to this project, so I hope I haven't missed anything. (No additional failures in tests.)

Daniel Santos
2016-12-21  Daniel Santos  <daniel.san...@pobox.com>

        * config/i386/i386.h (struct machine_frame_state): New fields
        sp_realigned and sp_realigned_offset.

        * config/i386/i386.c
        (struct ix86_frame): New fields stack_realign_allocate_offset and
        stack_realign_offset.
        (ix86_compute_frame_layout): Modify re-alignment calculations.
        (sp_valid_at, fp_valid_at): New inline functions.
        (choose_basereg): New function.
        (choose_baseaddr): Add align parameter, use choose_basereg and modify
        all callers.
        (ix86_emit_save_reg_using_mov, ix86_emit_restore_sse_regs_using_mov):
        Use align parameter of choose_baseaddr to generated aligned SSE movs
        when possible.
        (pro_epilogue_adjust_stack): Modify to track
        machine_frame_state::sp_realigned.
        (ix86_expand_prologue): Modify stack re-alignment code.
        (ix86_emit_leave): Clear machine_frame_state::sp_realigned.
        (ix86_expand_epilogue): Modify validity checks of frame and stack
        pointers.


Reply via email to