summaryrefslogtreecommitdiff
path: root/libc/string/metag/strcmp.S
diff options
context:
space:
mode:
Diffstat (limited to 'libc/string/metag/strcmp.S')
-rw-r--r--libc/string/metag/strcmp.S65
1 files changed, 65 insertions, 0 deletions
diff --git a/libc/string/metag/strcmp.S b/libc/string/metag/strcmp.S
new file mode 100644
index 000000000..3278ffaa5
--- /dev/null
+++ b/libc/string/metag/strcmp.S
@@ -0,0 +1,65 @@
+! Copyright (C) 2013 Imagination Technologies Ltd.
+
+! Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+
+
+#include <features.h>
+
+ .text
+ .global _strcmp
+ .type _strcmp,function
+!D1Ar1 s1
+!D0Ar2 s2
+_strcmp:
+ TST D1Ar1,#3
+ TSTZ D0Ar2,#3
+ MOVT D1Re0,#0x0101
+ ADD D1Re0,D1Re0,#0x0101
+ BNZ $Lstrcmp_slow
+ GETD D1Ar3,[D1Ar1+#4++] ! Load 32-bits from s1
+ GETD D1Ar5,[D0Ar2+#4++] ! Load 32-bits from s2
+ LSL D0FrT,D1Re0,#7 ! D0FrT = 0x80808080
+$Lstrcmp4_loop:
+ SUB D0Re0,D1Ar3,D1Re0 ! D1Re0 = 0x01010101
+ MOV D0Ar6,D1Ar3
+ SUBS D0Ar4,D1Ar3,D1Ar5 ! Calculate difference
+ XOR D0Ar6,D0Ar6,#-1
+ GETD D1Ar3,[D1Ar1+#4++] ! Load 32-bits from s1
+ AND D0Re0,D0Re0,D0Ar6
+ ANDSZ D0Ar6,D0Re0,D0FrT ! D0FrT = 0x80808080
+ GETD D1Ar5,[D0Ar2+#4++] ! Load 32-bits from s2
+ BZ $Lstrcmp4_loop
+ AND D0Ar6, D0Re0, D0FrT ! D0FrT = 0x80808080
+!
+! Either they are different or they both contain a NULL + junk
+!
+$Lstrcmp4_end:
+ LSLS D0Re0,D0Ar4,#24 ! Was Byte[0] the same?
+ LSLSZ D0Ar2,D0Ar6,#24 ! Yes: AND they where not zero?
+ LSLSZ D0Re0,D0Ar4,#16 ! Yes: Was Byte[1] the same?
+ LSLSZ D0Ar2,D0Ar6,#16 ! Yes: AND they where not zero?
+ LSLSZ D0Re0,D0Ar4,#8 ! Tes: Was Byte[2] the same?
+ LSLSZ D0Ar2,D0Ar6,#8 ! Yes: AND they where not zero?
+ MOVZ D0Re0,D0Ar4 ! Yes: Must by Byte[3] thats the result
+ ASR D0Re0,D0Re0,#24 ! Sign extend result to integer
+ MOV PC,D1RtP
+!
+! Misaligned case, byte at a time
+!
+$Lstrcmp_slow:
+ GETB D1Ar3,[D1Ar1++] ! Load char from s1
+ GETB D1Ar5,[D0Ar2++] ! Load char from s2
+ CMP D1Ar3,#1 ! Null -> C and NZ, rest -> NC (\1->Z)
+ CMPNC D1Ar3,D1Ar5 ! NOT Null: Same -> Z, else -> NZ
+ BZ $Lstrcmp_slow ! NOT Null and Same: Loop
+ SUB D0Re0,D1Ar3,D1Ar5 ! Generate result
+ MOV PC,D1RtP
+
+ .size _strcmp,.-_strcmp
+
+
+libc_hidden_def(strcmp)
+#ifndef __UCLIBC_HAS_LOCALE__
+strong_alias(strcmp,strcoll)
+libc_hidden_def(strcoll)
+#endif