Procházet zdrojové kódy

[libc] Reduce overall code size by externalising memmove()

Typical saving is 15-20 bytes in each file using memmove().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown před 12 roky
rodič
revize
fc30b13b25
2 změnil soubory, kde provedl 74 přidání a 24 odebrání
  1. 49
    1
      src/arch/x86/core/x86_string.c
  2. 25
    23
      src/arch/x86/include/bits/string.h

+ 49
- 1
src/arch/x86/core/x86_string.c Zobrazit soubor

@@ -35,7 +35,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
35 35
  * @v len		Length
36 36
  * @ret dest		Destination address
37 37
  */
38
-void * __memcpy ( void *dest, const void *src, size_t len ) {
38
+void * __attribute__ (( noinline )) __memcpy ( void *dest, const void *src,
39
+					       size_t len ) {
39 40
 	void *edi = dest;
40 41
 	const void *esi = src;
41 42
 	int discard_ecx;
@@ -56,3 +57,50 @@ void * __memcpy ( void *dest, const void *src, size_t len ) {
56 57
 			       : "memory" );
57 58
 	return dest;
58 59
 }
60
+
61
+/**
62
+ * Copy memory area backwards
63
+ *
64
+ * @v dest		Destination address
65
+ * @v src		Source address
66
+ * @v len		Length
67
+ * @ret dest		Destination address
68
+ */
69
+void * __attribute__ (( noinline )) __memcpy_reverse ( void *dest,
70
+						       const void *src,
71
+						       size_t len ) {
72
+	void *edi = ( dest + len - 1 );
73
+	const void *esi = ( src + len - 1 );
74
+	int discard_ecx;
75
+
76
+	/* Assume memmove() is not performance-critical, and perform a
77
+	 * bytewise copy for simplicity.
78
+	 */
79
+	__asm__ __volatile__ ( "std\n\t"
80
+			       "rep movsb\n\t"
81
+			       "cld\n\t"
82
+			       : "=&D" ( edi ), "=&S" ( esi ),
83
+				 "=&c" ( discard_ecx )
84
+			       : "0" ( edi ), "1" ( esi ),
85
+				 "2" ( len )
86
+			       : "memory" );
87
+	return dest;
88
+}
89
+
90
+
91
+/**
92
+ * Copy (possibly overlapping) memory area
93
+ *
94
+ * @v dest		Destination address
95
+ * @v src		Source address
96
+ * @v len		Length
97
+ * @ret dest		Destination address
98
+ */
99
+void * __memmove ( void *dest, const void *src, size_t len ) {
100
+
101
+	if ( dest <= src ) {
102
+		return __memcpy ( dest, src, len );
103
+	} else {
104
+		return __memcpy_reverse ( dest, src, len );
105
+	}
106
+}

+ 25
- 23
src/arch/x86/include/bits/string.h Zobrazit soubor

@@ -26,6 +26,7 @@ FILE_LICENCE ( PUBLIC_DOMAIN );
26 26
 #define __HAVE_ARCH_MEMCPY
27 27
 
28 28
 extern void * __memcpy ( void *dest, const void *src, size_t len );
29
+extern void * __memcpy_reverse ( void *dest, const void *src, size_t len );
29 30
 
30 31
 static inline __attribute__ (( always_inline )) void *
31 32
 __constant_memcpy ( void *dest, const void *src, size_t len ) {
@@ -144,29 +145,30 @@ __constant_memcpy ( void *dest, const void *src, size_t len ) {
144 145
 	  __memcpy ( (dest), (src), (len) ) )
145 146
 
146 147
 #define __HAVE_ARCH_MEMMOVE
147
-static inline void * memmove(void * dest,const void * src, size_t n)
148
-{
149
-int d0, d1, d2;
150
-if (dest<src)
151
-__asm__ __volatile__(
152
-	"cld\n\t"
153
-	"rep\n\t"
154
-	"movsb"
155
-	: "=&c" (d0), "=&S" (d1), "=&D" (d2)
156
-	:"0" (n),"1" (src),"2" (dest)
157
-	: "memory");
158
-else
159
-__asm__ __volatile__(
160
-	"std\n\t"
161
-	"rep\n\t"
162
-	"movsb\n\t"
163
-	"cld"
164
-	: "=&c" (d0), "=&S" (d1), "=&D" (d2)
165
-	:"0" (n),
166
-	 "1" (n-1+(const char *)src),
167
-	 "2" (n-1+(char *)dest)
168
-	:"memory");
169
-return dest;
148
+
149
+extern void * __memmove ( void *dest, const void *src, size_t len );
150
+
151
+/**
152
+ * Copy (possibly overlapping) memory area
153
+ *
154
+ * @v dest		Destination address
155
+ * @v src		Source address
156
+ * @v len		Length
157
+ * @ret dest		Destination address
158
+ */
159
+static inline __attribute__ (( always_inline )) void *
160
+memmove ( void *dest, const void *src, size_t len ) {
161
+	ssize_t offset = ( dest - src );
162
+
163
+	if ( __builtin_constant_p ( offset ) ) {
164
+		if ( offset <= 0 ) {
165
+			return memcpy ( dest, src, len );
166
+		} else {
167
+			return __memcpy_reverse ( dest, src, len );
168
+		}
169
+	} else {
170
+		return __memmove ( dest, src, len );
171
+	}
170 172
 }
171 173
 
172 174
 #define __HAVE_ARCH_MEMSET

Načítá se…
Zrušit
Uložit