| // Macros for entering C code |
| // |
| // Copyright (C) 2008,2009 Kevin O'Connor <kevin@koconnor.net> |
| // |
| // This file may be distributed under the terms of the GNU LGPLv3 license. |
| |
| |
| /**************************************************************** |
| * Entry macros |
| ****************************************************************/ |
| |
| // Call a C function - this does the minimal work necessary to |
| // call into C. It sets up %ds, backs up %es, and backs up |
| // those registers that are call clobbered by the C compiler. |
| .macro ENTRY cfunc |
| cli // In case something far-calls instead of using "int" |
| cld |
| pushl %eax // Save registers clobbered by C code |
| pushl %ecx |
| pushl %edx |
| pushw %es |
| pushw %ds |
| movw %ss, %ax // Move %ss to %ds |
| movw %ax, %ds |
| pushl %esp // Backup %esp, then clear high bits |
| movzwl %sp, %esp |
| calll \cfunc |
| popl %esp // Restore %esp (including high bits) |
| popw %ds // Restore registers saved above |
| popw %es |
| popl %edx |
| popl %ecx |
| popl %eax |
| .endm |
| |
| // As above, but get calling function from stack. |
| .macro ENTRY_ST |
| cli |
| cld |
| pushl %ecx |
| pushl %edx |
| pushw %es |
| pushw %ds |
| movw %ss, %cx // Move %ss to %ds |
| movw %cx, %ds |
| pushl %esp // Backup %esp, then clear high bits |
| movzwl %sp, %esp |
| movl 16(%esp), %ecx // Get calling function |
| movl %eax, 16(%esp) // Save %eax |
| calll *%ecx |
| popl %esp // Restore %esp (including high bits) |
| popw %ds // Restore registers saved above |
| popw %es |
| popl %edx |
| popl %ecx |
| popl %eax |
| .endm |
| |
| // Call a C function with current register list as an |
| // argument. This backs up the registers and sets %eax |
| // to point to the backup. On return, the registers are |
| // restored from the structure. |
| .macro ENTRY_ARG cfunc |
| cli |
| cld |
| pushl %eax // Save registers (matches struct bregs) |
| pushl %ecx |
| pushl %edx |
| pushl %ebx |
| pushl %ebp |
| pushl %esi |
| pushl %edi |
| pushw %es |
| pushw %ds |
| movw %ss, %ax // Move %ss to %ds |
| movw %ax, %ds |
| movl %esp, %ebx // Backup %esp, then zero high bits |
| movzwl %sp, %esp |
| movl %esp, %eax // First arg is pointer to struct bregs |
| calll \cfunc |
| movl %ebx, %esp // Restore %esp (including high bits) |
| popw %ds // Restore registers (from struct bregs) |
| popw %es |
| popl %edi |
| popl %esi |
| popl %ebp |
| popl %ebx |
| popl %edx |
| popl %ecx |
| popl %eax |
| .endm |
| |
| // As above, but get calling function from stack. |
| .macro ENTRY_ARG_ST |
| cli |
| cld |
| pushl %ecx |
| pushl %edx |
| pushl %ebx |
| pushl %ebp |
| pushl %esi |
| pushl %edi |
| pushw %es |
| pushw %ds |
| movw %ss, %cx // Move %ss to %ds |
| movw %cx, %ds |
| movl %esp, %ebx // Backup %esp, then zero high bits |
| movzwl %sp, %esp |
| movl 28(%esp), %ecx // Get calling function |
| movl %eax, 28(%esp) // Save %eax |
| movl %esp, %eax // First arg is pointer to struct bregs |
| calll *%ecx |
| movl %ebx, %esp // Restore %esp (including high bits) |
| popw %ds // Restore registers (from struct bregs) |
| popw %es |
| popl %edi |
| popl %esi |
| popl %ebp |
| popl %ebx |
| popl %edx |
| popl %ecx |
| popl %eax |
| .endm |
| |
| // Same as ENTRY_ARG, but don't mangle %esp |
| .macro ENTRY_ARG_ESP cfunc |
| cli |
| cld |
| pushl %eax // Save registers (matches struct bregs) |
| pushl %ecx |
| pushl %edx |
| pushl %ebx |
| pushl %ebp |
| pushl %esi |
| pushl %edi |
| pushw %es |
| pushw %ds |
| movw %ss, %ax // Move %ss to %ds |
| movw %ax, %ds |
| movl %esp, %eax // First arg is pointer to struct bregs |
| calll \cfunc |
| popw %ds // Restore registers (from struct bregs) |
| popw %es |
| popl %edi |
| popl %esi |
| popl %ebp |
| popl %ebx |
| popl %edx |
| popl %ecx |
| popl %eax |
| .endm |
| |
| // Reset stack, transition to 32bit mode, and call a C function. |
| // Clobbers %ax |
| .macro ENTRY_INTO32 cfunc |
| xorw %ax, %ax |
| movw %ax, %ss |
| movl $ BUILD_STACK_ADDR , %esp |
| pushl $ \cfunc |
| jmp transition32 |
| .endm |
| |
| // Declare a function |
| .macro DECLFUNC func |
| .section .text.asm.\func |
| .global \func |
| .endm |
| |
| // Declare an exported function |
| .macro EXPORTFUNC func |
| .section .text.asm.export.\func |
| .global \func |
| .endm |