summaryrefslogtreecommitdiff
path: root/newlib/libc/machine/i386/strchr.S
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/machine/i386/strchr.S')
-rw-r--r--newlib/libc/machine/i386/strchr.S84
1 files changed, 84 insertions, 0 deletions
diff --git a/newlib/libc/machine/i386/strchr.S b/newlib/libc/machine/i386/strchr.S
new file mode 100644
index 00000000000..f224f380ce4
--- /dev/null
+++ b/newlib/libc/machine/i386/strchr.S
@@ -0,0 +1,84 @@
+/*
+ * ====================================================
+ * Copyright (C) 1998 by Cygnus Solutions. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+ #include "i386mach.h"
+
+ .global SYM (strchr)
+
+SYM (strchr):
+
+ pushl ebp
+ movl esp,ebp
+ pushl edi
+ pushl ebx
+ xorl ebx,ebx
+ movl 8(ebp),edi
+ movb 12(ebp),bl
+
+#ifndef __OPTIMIZE_SIZE__
+/* check if string is aligned, if not do check one byte at a time */
+ test $3,edi
+ jne L9
+
+/* create 4 byte mask which is just the desired byte repeated 4 times */
+ movl ebx,ecx
+ sall $8,ebx
+ subl $4,edi
+ orl ecx,ebx
+ movl ebx,edx
+ sall $16,ebx
+ orl edx,ebx
+
+/* loop performing 4 byte mask checking for 0 byte or desired byte */
+ .p2align 4,,7
+L10:
+ addl $4,edi
+ movl (edi),ecx
+ leal -16843009(ecx),edx
+ movl ecx,eax
+ notl eax
+ andl eax,edx
+ testl $-2139062144,edx
+ jne L9
+
+ movl ebx,eax
+ xorl ecx,eax
+ leal -16843009(eax),edx
+ notl eax
+ andl eax,edx
+ testl $-2139062144,edx
+ je L10
+#endif /* not __OPTIMIZE_SIZE__ */
+
+/* loop while (*s && *s++ != c) */
+L9:
+ leal -1(edi),eax
+ .p2align 4,,7
+L15:
+ incl eax
+ movb (eax),dl
+ testb dl,dl
+ je L14
+ cmpb bl,dl
+ jne L15
+
+L14:
+/* if (*s == c) return address otherwise return NULL */
+ cmpb bl,(eax)
+ je L19
+ xorl eax,eax
+
+L19:
+ leal -8(ebp),esp
+ popl ebx
+ popl edi
+ leave
+ ret
+