summaryrefslogtreecommitdiff
path: root/libc/string/x86_64/strcat.S
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-04-15 08:27:24 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-04-15 08:27:24 +0000
commitdf7958a9606a342e3c3ac5a40fc41f3a79669d62 (patch)
treef22657788d4ca4bd427f7ff7247dfa353590ac9c /libc/string/x86_64/strcat.S
parent534dfb536f19737f2642ee56dd67a97c5db6a74e (diff)
amd64 string ops: use alignment more carefully, and comment it.
By capping max padding to not be bigger than three next insns, we avoid having ridiculously big NOPs like this one: 53:66 66 66 66 2e 0f 1f nopw %cs:0x0(%rax,%rax,1) 5a:84 00 00 00 00 00 which was bigger than next three insns combined! Size changes: text data bss dec hex filename 102 0 0 102 66 x86_64/memcpy.o 102 0 0 102 66 x86_64.old/memcpy.o 90 0 0 90 5a x86_64/mempcpy.o 102 0 0 102 66 x86_64.old/mempcpy.o 210 0 0 210 d2 x86_64/memset.o 242 0 0 242 f2 x86_64.old/memset.o 213 0 0 213 d5 x86_64/stpcpy.o 220 0 0 220 dc x86_64.old/stpcpy.o 428 0 0 428 1ac x86_64/strcat.o 444 0 0 444 1bc x86_64.old/strcat.o 417 0 0 417 1a1 x86_64/strchr.o 418 0 0 418 1a2 x86_64.old/strchr.o 33 0 0 33 21 x86_64/strcmp.o 33 0 0 33 21 x86_64.old/strcmp.o 213 0 0 213 d5 x86_64/strcpy.o 220 0 0 220 dc x86_64.old/strcpy.o 135 0 0 135 87 x86_64/strcspn.o 151 0 0 151 97 x86_64.old/strcspn.o 225 0 0 225 e1 x86_64/strlen.o 233 0 0 233 e9 x86_64.old/strlen.o 140 0 0 140 8c x86_64/strpbrk.o 156 0 0 156 9c x86_64.old/strpbrk.o 135 0 0 135 87 x86_64/strspn.o 151 0 0 151 97 x86_64.old/strspn.o Also, a few files got their .text alignment relaxed from 16 to 8 bytes, which reduces padding at link time.
Diffstat (limited to 'libc/string/x86_64/strcat.S')
-rw-r--r--libc/string/x86_64/strcat.S19
1 files changed, 14 insertions, 5 deletions
diff --git a/libc/string/x86_64/strcat.S b/libc/string/x86_64/strcat.S
index 9e2da50f2..23d068fea 100644
--- a/libc/string/x86_64/strcat.S
+++ b/libc/string/x86_64/strcat.S
@@ -45,7 +45,9 @@ ENTRY (BP_SYM (strcat))
/* Now the source is aligned. Scan for NUL byte. */
- .p2align 4
+
+ /* Next 3 insns are 10 bytes total, make sure we decode them in one go */
+ .p2align 4,,10
4:
/* First unroll. */
movq (%rax), %rcx /* get double word (= 8 bytes) in question */
@@ -103,8 +105,11 @@ ENTRY (BP_SYM (strcat))
the addition will not result in 0. */
jz 4b /* no NUL found => continue loop */
- .p2align 4 /* Align, it is a jump target. */
-3: subq $8,%rax /* correct pointer increment. */
+ /* Align, it is a jump target. */
+ /* Next 3 insns are 8 bytes total, make sure we decode them in one go */
+ .p2align 3,,8
+3:
+ subq $8,%rax /* correct pointer increment. */
testb %cl, %cl /* is first byte NUL? */
jz 2f /* yes => return */
@@ -160,7 +165,9 @@ ENTRY (BP_SYM (strcat))
/* Now the sources is aligned. Unfortunatly we cannot force
to have both source and destination aligned, so ignore the
alignment of the destination. */
- .p2align 4
+
+ /* Next 3 insns are 10 bytes total, make sure we decode them in one go */
+ .p2align 4,,10
22:
/* 1st unroll. */
movq (%rsi), %rax /* Read double word (8 bytes). */
@@ -237,7 +244,9 @@ ENTRY (BP_SYM (strcat))
/* Do the last few bytes. %rax contains the value to write.
The loop is unrolled twice. */
- .p2align 4
+
+ /* Next 3 insns are 6 bytes total, make sure we decode them in one go */
+ .p2align 3,,6
23:
movb %al, (%rdx) /* 1st byte. */
testb %al, %al /* Is it NUL. */