From 50b64f699110ff3f011239db7d6310f94872b994 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 24 Sep 2015 14:41:57 -0600 Subject: [PATCH] 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 --- arch/sim/Kconfig | 39 ++++++++++++++++++++++ arch/sim/src/up_setjmp64.S | 66 +++++++++++++++++++++++++++++--------- 2 files changed, 89 insertions(+), 16 deletions(-) diff --git a/arch/sim/Kconfig b/arch/sim/Kconfig index 7587cab19e..5238083187 100644 --- a/arch/sim/Kconfig +++ b/arch/sim/Kconfig @@ -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 diff --git a/arch/sim/src/up_setjmp64.S b/arch/sim/src/up_setjmp64.S index 75c01dc03f..28ec8f14a8 100644 --- a/arch/sim/src/up_setjmp64.S +++ b/arch/sim/src/up_setjmp64.S @@ -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)