; Copyright (C) 2009, 2008 Brian Gladman ; ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are ; met: ; 1. Redistributions of source code must retain the above copyright notice, ; this list of conditions and the following disclaimer. ; ; 2. Redistributions in binary form must reproduce the above copyright ; notice, this list of conditions and the following disclaimer in the ; documentation and/or other materials provided with the distribution. ; ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ; PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ; HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; ; Standardised register numbering scheme %define r0 rax %define r1 rdx %define r2 rcx %define r3 rbx %define r4 rsi %define r5 rdi %define r6 rbp %define r7 rsp %define r0d eax %define r1d edx %define r2d ecx %define r3d ebx %define r4d esi %define r5d edi %define r6d ebp %define r7d esp %define r0w ax %define r1w dx %define r2w cx %define r3w bx %define r4w si %define r5w di %define r6w bp %define r7w sp %define r0b al %define r1b dl %define r2b cl %define r3b bl %define r4b sil %define r5b dil %define r6b bpl %define r7b spl ; Standard macro for alignment (used to allow easy subsititution of ; alternative padding schemes) %macro xalign 1 align %1 %endmacro ; YASM macros for handling Windows Prologues and Epilogues ; ; Copyright 2008, 2009 Brian Gladman ; ; Windows x64 prologue macro: ; ; FRAME_PROC name, var_slots, register_save_list ; ; Windows x64 epilogue macro: ; ; EXIT_PROC register_save_list ; ; Windows x64 epilogue and end procedure macro ; ; END_PROC register_save_list ; ; where: ; name: routine name ; var_slots: stack space needed in 8 byte units ; register_save_list: comma separated list of registers to ; save and restore: a list of general ; purpose registers followed, if XMM ; registers are present, by XMM, and ; then a list of the numbers of the ; XMM registers to save and restore ; e.g. rsi, rdi, rbp, XMM, 6, 7, 8 ; On return the macro variable 'stack_use' gives the total number ; of bytes used on the stack. This allows the function parameters ; to be accessed at [rsp + stack_use + 8 * n] where n starts at 1 ; (for n = 1..4 this is shadow space for a register parameter) %macro FRAME_PROC 2-* global __g%1 %ifdef DLL export __g%1 %endif PROC_FRAME __g%1 %rotate 1 %if %1 < 0 %error Negative stack allocation not allowed %else %assign var_slots %1 %endif %rotate 1 %assign reg_slots 0 %assign xmm_seen 0 %if %0 > 2 %rep %0 - 2 %ifnum %1 %if xmm_seen == 0 %error Not an XMM register %else alloc_stack 16 save_xmm128 XMM%1, 0 %assign reg_slots reg_slots + 2 %endif %elifid %1 %ifidni XMM, %1 %if reg_slots & 1 == 0 alloc_stack 8 %assign reg_slots reg_slots + 1 %assign xmm_seen 1 %else %assign xmm_seen 2 %endif %elif xmm_seen == 0 push_reg %1 %assign reg_slots reg_slots + 1 %else %error XMM registers must be last in the save list %endif %else %error Bad parameter list %endif %rotate 1 %endrep %endif %if (reg_slots & 1) == (var_slots & 1) %assign var_slots var_slots + 1 %endif %if var_slots > 0 alloc_stack 8 * var_slots %endif %assign stack_use 8 * (reg_slots + var_slots) END_PROLOGUE %endmacro %macro EXIT_PROC 0-* add rsp, 8 * var_slots %if %0 > 0 %rep %0 %rotate -1 %ifnum %1 movdqa XMM%1, [rsp] add rsp, 16 %elifidni %1, XMM %if xmm_seen == 1 add rsp, 8 %endif %else pop %1 %endif %endrep %endif ret %endmacro %macro END_PROC 0-* %if var_slots add rsp, 8 * var_slots %endif %if %0 > 0 %rep %0 %rotate -1 %ifnum %1 movdqa XMM%1, [rsp] add rsp, 16 %elifidni %1, XMM %if xmm_seen == 1 add rsp, 8 %endif %else pop %1 %endif %endrep %endif ret ENDPROC_FRAME %endmacro %macro LEAF_PROC 1 global __g%1 %ifdef DLL export __g%1 %endif __g%1: %endmacro ; Macros for using assembler code using the GCC Calling ; Conventions in Windows. These macros move the first ; six integer parameters from Microsoft ABI calling ; calling conventions to those used by GCC: ; ; function( MSVC --> GCC ; p1, rcx rdi ; p2, rdx rsi ; p3, r8 rdx ; p4, r9 rcx ; p5, [rsp+40] r8 ; p6, [rsp+48] r9 ; ; WIN64_GCC_PROC name, n_parms, (frame | leaf) ; ; WIN64_GCC_EXIT frame | leaf ; ; WIN64_GCC_END frame | leaf ; ; name subroutine name ; n_parms number of parameters (default 6) ; type frame or leaf function (default frame) ; ; These defines are also used and must be set before the ; macros are used: ; ; reg_save_list list of registers to be saved ; and restored ; var_slots number of 8 byte slots needed ; on the stack (excluding the ; register save/restore space) %macro WIN64_GCC_PROC 1-3 6, frame %ifidn %3, frame %ifndef reg_save_list %define reg_save_list rsi, rdi %endif %ifndef var_slots %define var_slots 0 %endif FRAME_PROC %1, var_slots, reg_save_list %elifidn %3, leaf LEAF_PROC %1 %else %error no (or wrong) function type defined %endif %if %2 > 0 mov rdi, rcx %endif %if %2 > 1 mov rsi, rdx %endif %if %2 > 2 mov rdx, r8 %endif %if %2 > 3 mov rcx, r9 %endif %if %2 > 4 mov r8, [rsp + stack_use + 40] %endif %if %2 > 5 mov r9, [rsp + stack_use + 48] %endif %endmacro %macro WIN64_GCC_EXIT 0-1 frame %ifidn %1, frame EXIT_PROC reg_save_list %elifidn %1, leaf ret %else %error no (or wrong) function type defined %endif %endmacro %macro WIN64_GCC_END 0-1 frame %ifidn %1, frame END_PROC reg_save_list %elifidn %1, leaf ret %else %error no (or wrong) function type defined %endif %endmacro