From d0d304b3422938044ff15cd3659c9b64b18735a4 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 12 Oct 2011 21:11:02 +0000 Subject: [PATCH] [RTL] On x86 builds use the asm versions of the byte swap functions. This is neccessary for RtlUlonglongByteswap, because the function breaks the calling convention on Windows, not cleaning up the stack. Make the asm compatible to ML and improve it a bit. Investigated by Thomas Faber. svn path=/trunk/; revision=54097 --- reactos/lib/rtl/CMakeLists.txt | 5 ++++- reactos/lib/rtl/byteswap.c | 11 +++++++--- reactos/lib/rtl/i386/rtlswap.S | 39 +++++++++++++++++++--------------- reactos/lib/rtl/rtl.rbuild | 4 +++- 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/reactos/lib/rtl/CMakeLists.txt b/reactos/lib/rtl/CMakeLists.txt index 83e38da00c3..7dd2fe8c14e 100644 --- a/reactos/lib/rtl/CMakeLists.txt +++ b/reactos/lib/rtl/CMakeLists.txt @@ -14,7 +14,6 @@ list(APPEND SOURCE avltable.c bitmap.c bootdata.c - byteswap.c compress.c condvar.c crc32.c @@ -71,10 +70,12 @@ if(ARCH MATCHES i386) i386/except.c i386/interlck.S i386/rtlmem.s + i386/rtlswap.s i386/res_asm.s i386/thread.c) elseif(ARCH MATCHES amd64) list(APPEND SOURCE + byteswap.c amd64/debug_asm.S amd64/except_asm.S amd64/slist.S @@ -83,10 +84,12 @@ elseif(ARCH MATCHES amd64) mem.c) elseif(ARCH MATCHES arm) list(APPEND SOURCE + byteswap.c arm/debug_asm.S mem.c) elseif(ARCH MATCHES powerpc) list(APPEND SOURCE + byteswap.c powerpc/debug.c powerpc/except.c powerpc/interlocked.c diff --git a/reactos/lib/rtl/byteswap.c b/reactos/lib/rtl/byteswap.c index b11715ec86f..b58f6cf05f6 100644 --- a/reactos/lib/rtl/byteswap.c +++ b/reactos/lib/rtl/byteswap.c @@ -12,6 +12,11 @@ #define NDEBUG #include +#if defined(_M_IX86) +/* RtlUlonglongByteSwap is broken and cannot be done in C on x86 */ +#error "Use rtlswap.S!" +#endif + #undef RtlUlonglongByteSwap #undef RtlUlongByteSwap #undef RtlUshortByteSwap @@ -31,7 +36,7 @@ FASTCALL RtlUshortByteSwap( IN USHORT Source) { -#if defined(_M_IX86) || defined(_M_AMD64) +#if defined(_M_AMD64) return _byteswap_ushort(Source); #else return (Source >> 8) | (Source << 8); @@ -55,7 +60,7 @@ FASTCALL RtlUlongByteSwap( IN ULONG Source) { -#if defined(_M_IX86) || defined(_M_AMD64) +#if defined(_M_AMD64) return _byteswap_ulong(Source); #else return ((ULONG)RtlUshortByteSwap((USHORT)Source) << 16) | RtlUshortByteSwap((USHORT)(Source >> 16)); @@ -80,7 +85,7 @@ ULONGLONG FASTCALL RtlUlonglongByteSwap( IN ULONGLONG Source) { -#if defined(_M_IX86) || defined(_M_AMD64) +#if defined(_M_AMD64) return _byteswap_uint64(Source); #else return ((ULONGLONG) RtlUlongByteSwap (Source) << 32) | RtlUlongByteSwap (Source>>32); diff --git a/reactos/lib/rtl/i386/rtlswap.S b/reactos/lib/rtl/i386/rtlswap.S index 6ded910eb85..cd37de3a249 100644 --- a/reactos/lib/rtl/i386/rtlswap.S +++ b/reactos/lib/rtl/i386/rtlswap.S @@ -4,50 +4,55 @@ * PURPOSE: Byte swap functions * FILE: lib/rtl/i386/rtlswap.S * PROGRAMER: Alex Ionescu (alex.ionescu@reactos.org) + * Timo Kreuzer (timo.kreuzer@reactos.org) */ -.intel_syntax noprefix +#include -.globl @RtlUshortByteSwap@4 -.globl @RtlUlongByteSwap@4 -.globl @RtlUlonglongByteSwap@8 +PUBLIC @RtlUshortByteSwap@4 +PUBLIC @RtlUlongByteSwap@4 +PUBLIC @RtlUlonglongByteSwap@8 /* FUNCTIONS ***************************************************************/ +.code -.func @RtlUshortByteSwap@4, @RtlUshortByteSwap@4 @RtlUshortByteSwap@4: +FUNC RtlUshortByteSwap + FPO 0, 0, 0, 0, 0, FRAME_FPO /* Swap high and low bits */ mov ah, cl mov al, ch ret -.endfunc +ENDFUNC RtlUshortByteSwap -.func @RtlUlongByteSwap@4, @RtlUlongByteSwap@4 @RtlUlongByteSwap@4: +FUNC RtlUlongByteSwap + FPO 0, 0, 0, 0, 0, FRAME_FPO /* Swap high and low bits */ mov eax, ecx bswap eax ret -.endfunc +ENDFUNC RtlUlongByteSwap -.func @RtlUlonglongByteSwap@8, @RtlUlonglongByteSwap@8 @RtlUlonglongByteSwap@8: +FUNC RtlUlonglongByteSwap + FPO 0, 2, 0, 0, 0, FRAME_FPO /* Get 64-bit integer */ - mov edx, [esp+8] - mov eax, [esp+4] + mov eax, [esp+8] + mov edx, [esp+4] /* Swap it */ bswap edx bswap eax - /* Return it */ - mov ecx, eax - mov eax, edx - mov edx, ecx + /* Return it (NOTE: this might look wrong, since fastcall functions + should clean up the stack, even if the first parameter is an ULONGLONG, + and therefore put on tthe stack instead of in ecx and edx, + but thats exactly how the function behaves on Windows! */ ret -.endfunc - +ENDFUNC RtlUlonglongByteSwap +END diff --git a/reactos/lib/rtl/rtl.rbuild b/reactos/lib/rtl/rtl.rbuild index 348a7a31350..75758ab5353 100644 --- a/reactos/lib/rtl/rtl.rbuild +++ b/reactos/lib/rtl/rtl.rbuild @@ -20,6 +20,7 @@ + byteswap.c debug.c except.c @@ -30,12 +31,14 @@ + byteswap.c debug_asm.S mem.c + byteswap.c debug_asm.S except_asm.S @@ -51,7 +54,6 @@ assert.c atom.c avltable.c - byteswap.c bitmap.c bootdata.c compress.c