Piotr Caban : msvcrt: Use unaligned data types in memset.
Alexandre Julliard
julliard at winehq.org
Thu Sep 16 15:34:31 CDT 2021
Module: wine
Branch: master
Commit: 2c01333d03153a2d3cc2622fa18a9ad323dd9edb
URL: https://source.winehq.org/git/wine.git/?a=commit;h=2c01333d03153a2d3cc2622fa18a9ad323dd9edb
Author: Piotr Caban <piotr at codeweavers.com>
Date: Thu Sep 16 13:51:58 2021 +0200
msvcrt: Use unaligned data types in memset.
This fixes a regression in memset on ARM described by Martin:
ARM can do 64 bit writes with the STRD instruction, but that
instruction requires a 32 bit aligned address - while these stores
are unaligned.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Martin Storsjö <martin at martin.st>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/msvcrt/string.c | 32 ++++++++++++++++++--------------
1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/dlls/msvcrt/string.c b/dlls/msvcrt/string.c
index f2b1b4a5b11..5655fbfe68a 100644
--- a/dlls/msvcrt/string.c
+++ b/dlls/msvcrt/string.c
@@ -2872,21 +2872,25 @@ static inline void memset_aligned_32(unsigned char *d, uint64_t v, size_t n)
*/
void *__cdecl memset(void *dst, int c, size_t n)
{
+ typedef uint64_t DECLSPEC_ALIGN(1) unaligned_ui64;
+ typedef uint32_t DECLSPEC_ALIGN(1) unaligned_ui32;
+ typedef uint16_t DECLSPEC_ALIGN(1) unaligned_ui16;
+
uint64_t v = 0x101010101010101ull * (unsigned char)c;
unsigned char *d = (unsigned char *)dst;
size_t a = 0x20 - ((uintptr_t)d & 0x1f);
if (n >= 16)
{
- *(uint64_t *)(d + 0) = v;
- *(uint64_t *)(d + 8) = v;
- *(uint64_t *)(d + n - 16) = v;
- *(uint64_t *)(d + n - 8) = v;
+ *(unaligned_ui64 *)(d + 0) = v;
+ *(unaligned_ui64 *)(d + 8) = v;
+ *(unaligned_ui64 *)(d + n - 16) = v;
+ *(unaligned_ui64 *)(d + n - 8) = v;
if (n <= 32) return dst;
- *(uint64_t *)(d + 16) = v;
- *(uint64_t *)(d + 24) = v;
- *(uint64_t *)(d + n - 32) = v;
- *(uint64_t *)(d + n - 24) = v;
+ *(unaligned_ui64 *)(d + 16) = v;
+ *(unaligned_ui64 *)(d + 24) = v;
+ *(unaligned_ui64 *)(d + n - 32) = v;
+ *(unaligned_ui64 *)(d + n - 24) = v;
if (n <= 64) return dst;
n = (n - a) & ~0x1f;
@@ -2895,20 +2899,20 @@ void *__cdecl memset(void *dst, int c, size_t n)
}
if (n >= 8)
{
- *(uint64_t *)d = v;
- *(uint64_t *)(d + n - 8) = v;
+ *(unaligned_ui64 *)d = v;
+ *(unaligned_ui64 *)(d + n - 8) = v;
return dst;
}
if (n >= 4)
{
- *(uint32_t *)d = v;
- *(uint32_t *)(d + n - 4) = v;
+ *(unaligned_ui32 *)d = v;
+ *(unaligned_ui32 *)(d + n - 4) = v;
return dst;
}
if (n >= 2)
{
- *(uint16_t *)d = v;
- *(uint16_t *)(d + n - 2) = v;
+ *(unaligned_ui16 *)d = v;
+ *(unaligned_ui16 *)(d + n - 2) = v;
return dst;
}
if (n >= 1)
More information about the wine-cvs
mailing list