From 11f10c6f057adac6163320d6665c12beb69648f5 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 10 Apr 2010 11:47:55 +0200 Subject: [PATCH] msvcrt: Implemented setjmp for x86_64. --- dlls/msvcrt/except.c | 42 ++++++++++++++++++++++++++++++++++- dlls/msvcrt/msvcrt.spec | 6 +++-- include/msvcrt/setjmp.h | 49 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 90 insertions(+), 7 deletions(-) diff --git a/dlls/msvcrt/except.c b/dlls/msvcrt/except.c index 9f7c22d0af3..b502db18db7 100644 --- a/dlls/msvcrt/except.c +++ b/dlls/msvcrt/except.c @@ -410,7 +410,47 @@ void __stdcall _seh_longjmp_unwind(struct MSVCRT___JUMP_BUFFER *jmp) { msvcrt_local_unwind2( (MSVCRT_EXCEPTION_FRAME *)jmp->Registration, jmp->TryLevel, (void *)jmp->Ebp ); } -#endif /* i386 */ + +#elif defined(__x86_64__) + +/******************************************************************* + * _setjmp (MSVCRT.@) + */ +__ASM_GLOBAL_FUNC( MSVCRT__setjmp, + "xorq %rdx,%rdx\n\t" /* frame */ + "jmp " __ASM_NAME("MSVCRT__setjmpex") ); + +/******************************************************************* + * _setjmpex (MSVCRT.@) + */ +__ASM_GLOBAL_FUNC( MSVCRT__setjmpex, + "movq %rdx,(%rcx)\n\t" /* jmp_buf->Frame */ + "movq %rbx,0x8(%rcx)\n\t" /* jmp_buf->Rbx */ + "leaq 0x8(%rsp),%rax\n\t" + "movq %rax,0x10(%rcx)\n\t" /* jmp_buf->Rsp */ + "movq %rbp,0x18(%rcx)\n\t" /* jmp_buf->Rbp */ + "movq %rsi,0x20(%rcx)\n\t" /* jmp_buf->Rsi */ + "movq %rdi,0x28(%rcx)\n\t" /* jmp_buf->Rdi */ + "movq %r12,0x30(%rcx)\n\t" /* jmp_buf->R12 */ + "movq %r13,0x38(%rcx)\n\t" /* jmp_buf->R13 */ + "movq %r14,0x40(%rcx)\n\t" /* jmp_buf->R14 */ + "movq %r15,0x48(%rcx)\n\t" /* jmp_buf->R15 */ + "movq (%rsp),%rax\n\t" + "movq %rax,0x50(%rcx)\n\t" /* jmp_buf->Rip */ + "movdqa %xmm6,0x60(%rcx)\n\t" /* jmp_buf->Xmm6 */ + "movdqa %xmm7,0x70(%rcx)\n\t" /* jmp_buf->Xmm7 */ + "movdqa %xmm8,0x80(%rcx)\n\t" /* jmp_buf->Xmm8 */ + "movdqa %xmm9,0x90(%rcx)\n\t" /* jmp_buf->Xmm9 */ + "movdqa %xmm10,0xa0(%rcx)\n\t" /* jmp_buf->Xmm10 */ + "movdqa %xmm11,0xb0(%rcx)\n\t" /* jmp_buf->Xmm11 */ + "movdqa %xmm12,0xc0(%rcx)\n\t" /* jmp_buf->Xmm12 */ + "movdqa %xmm13,0xd0(%rcx)\n\t" /* jmp_buf->Xmm13 */ + "movdqa %xmm14,0xe0(%rcx)\n\t" /* jmp_buf->Xmm14 */ + "movdqa %xmm15,0xf0(%rcx)\n\t" /* jmp_buf->Xmm15 */ + "xorq %rax,%rax\n\t" + "retq" ); + +#endif /* __x86_64__ */ static MSVCRT___sighandler_t sighandlers[MSVCRT_NSIG] = { MSVCRT_SIG_DFL }; diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 95f610ea6cd..eac8f466415 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -815,8 +815,9 @@ # stub _set_output_format @ cdecl _set_sbh_threshold(long) @ cdecl _seterrormode(long) -@ cdecl -i386 -norelay _setjmp(ptr) MSVCRT__setjmp -@ cdecl -i386 -norelay _setjmp3(ptr long) MSVCRT__setjmp3 +@ cdecl -arch=i386,x86_64 -norelay _setjmp(ptr) MSVCRT__setjmp +@ cdecl -arch=i386 -norelay _setjmp3(ptr long) MSVCRT__setjmp3 +@ cdecl -arch=x86_64 -norelay _setjmpex(ptr ptr) MSVCRT__setjmpex @ cdecl _setmaxstdio(long) @ cdecl _setmbcp(long) @ cdecl _setmode(long long) @@ -1299,6 +1300,7 @@ @ varargs scanf(str) MSVCRT_scanf # stub scanf_s @ cdecl setbuf(ptr ptr) MSVCRT_setbuf +@ cdecl -arch=x86_64 -norelay -private setjmp(ptr) MSVCRT__setjmp @ cdecl setlocale(long str) MSVCRT_setlocale @ cdecl setvbuf(ptr str long long) MSVCRT_setvbuf @ cdecl signal(long long) MSVCRT_signal diff --git a/include/msvcrt/setjmp.h b/include/msvcrt/setjmp.h index 82d7be65bfc..ded4c9a7300 100644 --- a/include/msvcrt/setjmp.h +++ b/include/msvcrt/setjmp.h @@ -42,12 +42,53 @@ typedef struct __JUMP_BUFFER unsigned long UnwindData[6]; } _JUMP_BUFFER; -#endif /* __i386__ */ +#define _JBLEN 16 +#define _JBTYPE int -#define _JBLEN 16 -#define _JBTYPE int -typedef _JBTYPE jmp_buf[_JBLEN]; +#elif defined(__x86_64__) +typedef struct _SETJMP_FLOAT128 +{ + unsigned __int64 DECLSPEC_ALIGN(16) Part[2]; +} SETJMP_FLOAT128; + +typedef struct _JUMP_BUFFER +{ + unsigned __int64 Frame; + unsigned __int64 Rbx; + unsigned __int64 Rsp; + unsigned __int64 Rbp; + unsigned __int64 Rsi; + unsigned __int64 Rdi; + unsigned __int64 R12; + unsigned __int64 R13; + unsigned __int64 R14; + unsigned __int64 R15; + unsigned __int64 Rip; + unsigned __int64 Spare; + SETJMP_FLOAT128 Xmm6; + SETJMP_FLOAT128 Xmm7; + SETJMP_FLOAT128 Xmm8; + SETJMP_FLOAT128 Xmm9; + SETJMP_FLOAT128 Xmm10; + SETJMP_FLOAT128 Xmm11; + SETJMP_FLOAT128 Xmm12; + SETJMP_FLOAT128 Xmm13; + SETJMP_FLOAT128 Xmm14; + SETJMP_FLOAT128 Xmm15; +} _JUMP_BUFFER; + +#define _JBLEN 16 +typedef SETJMP_FLOAT128 _JBTYPE; + +#else + +#define _JBLEN 1 +#define _JBTYPE int + +#endif + +typedef _JBTYPE jmp_buf[_JBLEN]; #ifdef __cplusplus extern "C" {