summaryrefslogtreecommitdiffhomepage
path: root/src/string/ntapi_tt_aligned_memcpy_utf16.c
blob: 474c8e4b83934a78b1fd7f4fbde9ebac8da22b97 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/********************************************************/
/*  ntapi: Native API core library                      */
/*  Copyright (C) 2013--2017  Z. Gilboa                 */
/*  Released under GPLv2 and GPLv3; see COPYING.NTAPI.  */
/********************************************************/

#include <psxtypes/psxtypes.h>

wchar16_t * __cdecl __ntapi_tt_aligned_memcpy_utf16(
	__in	uintptr_t *	dst,
	__in	uintptr_t *	src,
	__in	size_t		bytes)
{
	size_t 		aligned_block;
	size_t		copied;

	wchar16_t *	wch_src;
	wchar16_t *	wch_dst;

	#if defined (__X86_64_MODEL)
	uint32_t *	uint32_src;
	uint32_t *	uint32_dst;
	#endif

	aligned_block = bytes;
	aligned_block /= sizeof(uintptr_t);
	aligned_block *= sizeof(uintptr_t);

	copied = 0;

	while (copied < aligned_block) {
		*dst = *src;
		src++;
		dst++;
		copied += sizeof(uintptr_t);
	}

	#if defined (__X86_64_MODEL)
		switch (bytes % sizeof(uintptr_t)) {
			case 6:
				uint32_src = (uint32_t *)src;
				uint32_dst = (uint32_t *)dst;
				*uint32_dst = *uint32_src;

				uint32_src++;
				uint32_dst++;

				/* make the compiler happy */
				wch_src = (wchar16_t *)uint32_src;
				wch_dst = (wchar16_t *)uint32_dst;
				*wch_dst = *wch_src;
				break;

			case 4:
				uint32_src = (uint32_t *)src;
				uint32_dst = (uint32_t *)dst;
				*uint32_dst = *uint32_src;
				break;
		}
	#endif

	if (bytes % sizeof(uintptr_t)) {
		/* the remainder must be 2 */
		wch_src = (wchar16_t *)src;
		wch_dst = (wchar16_t *)dst;
		*wch_dst = *wch_src;
	}

	return (wchar16_t *)dst;
}