Sim target on Cygwin64: Modern Cygwin X86_64 machines follow the Microsoft ABI for parameter passing. The older,inux System 5 ABI will not work on X86_64-based Cygwin machines. With this change, the simulator agains works with the newer Cygwin64 platform

This commit is contained in:
Gregory Nutt 2015-09-24 14:41:57 -06:00
parent 569a29a327
commit 50b64f6991
2 changed files with 89 additions and 16 deletions

View File

@ -41,6 +41,45 @@ config SIM_CYGWIN_DECORATED
underscore to the beginning of the symbol name. Newer versions of
Cygwin do not seem to do this.
choice
prompt "X64_64 ABI"
default SIM_X8664_SYSTEMV if HOST_LINUX
default SIM_X8664_MICROSOFT if HOST_WINDOWS
depends on HOST_X86_64 && !SIM_32
config SIM_X8664_SYSTEMV
bool "System V AMD64 ABI"
---help---
The calling convention of the System V AMD64 ABI is followed on Solaris,
Linux, FreeBSD, Mac OS X, and other UNIX-like or POSIX-compliant operating
systems. The first six integer or pointer arguments are passed in registers
RDI, RSI, RDX, RCX, R8, and R9, while XMM0, XMM1, XMM2, XMM3, XMM4, XMM5,
XMM6 and XMM7 are used for floating point arguments. For system calls, R10
is used instead of RCX. As in the Microsoft x64 calling convention,
additional arguments are passed on the stack and the return value is stored
in RAX.
Registers RBP, RBX, and R12-R15 are callee-save registers; all others must
be saved by the caller if they wish to preserve their values.
Unlike the Microsoft calling convention, a shadow space is not provided; on
function entry, the return address is adjacent to the seventh integer argument
on the stack.
config SIM_X8664_MICROSOFT
bool "Microsoft x64 calling convention"
---help---
The Microsoft x64 calling convention is followed on Microsoft Windows and
pre-boot UEFI (for long mode on x86-64). It uses registers RCX, RDX, R8,
R9 for the first four integer or pointer arguments (in that order), and
XMM0, XMM1, XMM2, XMM3 are used for floating point arguments. Additional
arguments are pushed onto the stack (right to left). Integer return
values (similar to x86) are returned in RAX if 64 bits or less. Floating
point return values are returned in XMM0. Parameters less than 64 bits
long are not zero extended; the high bits are not zeroed.
endchoice
config SIM_WALLTIME
bool "Execution simulation in near real-time"
default n

View File

@ -43,6 +43,40 @@
* Pre-processor Definitions
**************************************************************************/
/* The Microsoft x64 calling convention is followed on Microsoft Windows and
* pre-boot UEFI (for long mode on x86-64). It uses registers RCX, RDX, R8,
* R9 for the first four integer or pointer arguments (in that order), and
* XMM0, XMM1, XMM2, XMM3 are used for floating point arguments. Additional
* arguments are pushed onto the stack (right to left). Integer return
* values (similar to x86) are returned in RAX if 64 bits or less. Floating
* point return values are returned in XMM0. Parameters less than 64 bits
* long are not zero extended; the high bits are not zeroed.
*/
#ifdef CONFIG_SIM_X8664_MICROSOFT
# define REGS %rcx
/* The calling convention of the System V AMD64 ABI is followed on Solaris,
* Linux, FreeBSD, Mac OS X, and other UNIX-like or POSIX-compliant operating
* systems. The first six integer or pointer arguments are passed in registers
* RDI, RSI, RDX, RCX, R8, and R9, while XMM0, XMM1, XMM2, XMM3, XMM4, XMM5,
* XMM6 and XMM7 are used for floating point arguments. For system calls, R10
* is used instead of RCX. As in the Microsoft x64 calling convention,
* additional arguments are passed on the stack and the return value is stored
* in RAX.
*
* Registers RBP, RBX, and R12-R15 are callee-save registers; all others must
* be saved by the caller if they wish to preserve their values.
*
* Unlike the Microsoft calling convention, a shadow space is not provided; on
* function entry, the return address is adjacent to the seventh integer
* argument on the stack.
*/
#else /* if defined(CONFIG_SIM_X8664_SYSTEMV) */
# define REGS %rdi
#endif
#ifdef __CYGWIN__
//# define SYMBOL(s) _##s
# define SYMBOL(s) s
@ -92,11 +126,11 @@ SYMBOL(up_setjmp):
/* Save 1: rbx */
movq %rbx, JB_RBX(%rdi)
movq %rbx, JB_RBX(REGS)
/* Save 2: Value of the rsp *after* returning */
movq %rsp, JB_RSP(%rdi)
movq %rsp, JB_RSP(REGS)
/* Fix up the return stack */
@ -105,12 +139,12 @@ SYMBOL(up_setjmp):
/* Save registers */
/* Storage order: %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, %rip */
movq %rbp, JB_RBP(%rdi) /* Save 3: rbp */
movq %r12, JB_R12(%rdi) /* Save 4: r12 */
movq %r13, JB_R13(%rdi) /* Save 5: r13 */
movq %r14, JB_R14(%rdi) /* Save 6: r14 */
movq %r15, JB_R15(%rdi) /* Save 7: r15 */
movq %rsi, JB_RSI(%rdi) /* Save 8: Return address */
movq %rbp, JB_RBP(REGS) /* Save 3: rbp */
movq %r12, JB_R12(REGS) /* Save 4: r12 */
movq %r13, JB_R13(REGS) /* Save 5: r13 */
movq %r14, JB_R14(REGS) /* Save 6: r14 */
movq %r15, JB_R15(REGS) /* Save 7: r15 */
movq %rsi, JB_RSI(REGS) /* Save 8: Return address */
ret
@ -131,17 +165,17 @@ SYMBOL(up_longjmp):
/* Restore registers */
movq JB_RBX(%rdi),%rbx /* Save 1: rbx */
movq JB_RSP(%rdi),%rsp /* Save 2: rsp */
movq JB_RBP(%rdi),%rbp /* Save 3: rdi */
movq JB_R12(%rdi),%r12 /* Save 4: r12 */
movq JB_R13(%rdi),%r13 /* Save 5: r13 */
movq JB_R14(%rdi),%r14 /* Save 6: r14 */
movq JB_R15(%rdi),%r15 /* Save 7: rbp */
movq JB_RBX(REGS),%rbx /* Save 1: rbx */
movq JB_RSP(REGS),%rsp /* Save 2: rsp */
movq JB_RBP(REGS),%rbp /* Save 3: rdi */
movq JB_R12(REGS),%r12 /* Save 4: r12 */
movq JB_R13(REGS),%r13 /* Save 5: r13 */
movq JB_R14(REGS),%r14 /* Save 6: r14 */
movq JB_R15(REGS),%r15 /* Save 7: rbp */
/* And return */
jmp *JB_RSI(%rdi) /* Save 8: rsi */
jmp *JB_RSI(REGS) /* Save 8: rsi */
#ifndef __CYGWIN__
.size SYMBOL(up_longjmp), . - SYMBOL(up_longjmp)