1/*
2 * Copyright (C) 2017 Hangzhou C-SKY Microsystems co.,ltd.
3 *
4 * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB
5 * in this tarball.
6 */
7
8#include <endian.h>
9#include "macro.S"
10
11#ifdef WANT_WIDE
12# define Wstrcmp wcscmp
13# define Wstrcoll wcscoll
14#else
15# define Wstrcmp strcmp
16# define Wstrcoll strcoll
17#endif
18
19/* FIXME attention!!! it may be a bug when WANT_WIDE define */
20/*libc_hidden_proto(Wstrcmp)*/
21	.align 2
22	.global Wstrcmp
23	.type   Wstrcmp, @function
24Wstrcmp:
25    mov        a3, a0
26
27    or         a0, a1
28    andi       a0, 0x3
29    M_BNEZ     a0, 4f
30    1:                   // if aligned, load word each time.
31
32    ldw        a0, (a3, 0)
33    ldw        t0, (a1, 0)
34    M_BNE      a0, t0, 1f // if d[i] != s[i], goto 1f
35    tstnbz     a0       // if d[i] == s[i], check if d or s is at the end.
36    bf         3f       // if at the end, goto 3f (finish comparing)
37    ldw        a0, (a3, 4)
38    ldw        t0, (a1, 4)
39    M_BNE      a0, t0, 1f
40    tstnbz     a0
41    bf         3f
42
43    ldw        a0, (a3, 8)
44    ldw        t0, (a1, 8)
45    M_BNE      a0, t0, 1f
46    tstnbz     a0
47    bf         3f
48
49    ldw        a0, (a3, 12)
50    ldw        t0, (a1, 12)
51    M_BNE      a0, t0, 1f
52    tstnbz     a0
53    bf         3f
54
55    ldw        a0, (a3, 16)
56    ldw        t0, (a1, 16)
57    M_BNE      a0, t0, 1f
58    tstnbz     a0
59    bf         3f
60
61    ldw        a0, (a3, 20)
62    ldw        t0, (a1, 20)
63    M_BNE      a0, t0, 1f
64    tstnbz     a0
65    bf         3f
66
67    ldw        a0, (a3, 24)
68    ldw        t0, (a1, 24)
69    M_BNE      a0, t0, 1f
70    tstnbz     a0
71    bf         3f
72
73    ldw        a0, (a3, 28)
74    ldw        t0, (a1, 28)
75    M_BNE      a0, t0, 1f
76    tstnbz     a0
77    bf         3f
78
79    addi       a3, 32
80    addi       a1, 32
81    br         1b
82
83#ifdef __CSKYBE__
84    /* d[i] != s[i] in word, so we check byte 0 ? */
85    1:
86    xtrb0      t1, a0
87    mov        a2, t1
88    xtrb0      t1, t0
89    M_BNE      a2, t1, 2f
90    cmpnei     a2, 0
91    bf         2f
92
93    /* d[i] != s[i] in word, so we check byte 1 ? */
94    xtrb1      t1, a0
95    mov        a2, t1
96    xtrb1      t1, t0
97    M_BNE      a2, t1, 2f
98    cmpnei     a2, 0
99    bf         2f
100
101    /* d[i] != s[i] in word, so we check byte 1 ? */
102    xtrb2      t1, a0
103    mov        a2, t1
104    xtrb2      t1, t0
105    M_BNE      a2, t1, 2f
106    cmpnei     a2, 0
107    bf         2f
108
109    /* d[i] != s[i] in word, so we check byte 1 ? */
110    xtrb3      t1, a0
111    mov        a2, t1
112    xtrb3      t1, t0
113
114#else /* little endian */
115    /* d[i] != s[i] in word, so we check byte 0 ? */
116    1:
117    xtrb3      t1, a0
118    mov        a2, t1
119    xtrb3      t1, t0
120    M_BNE      a2, t1, 2f
121    cmpnei     a2, 0
122    bf         2f
123
124    /* d[i] != s[i] in word, so we check byte 1 ? */
125    xtrb2      t1, a0
126    mov        a2, t1
127    xtrb2      t1, t0
128    M_BNE      a2, t1, 2f
129    cmpnei     a2, 0
130    bf         2f
131
132    /* d[i] != s[i] in word, so we check byte 1 ? */
133    xtrb1      t1, a0
134    mov        a2, t1
135    xtrb1      t1, t0
136    M_BNE      a2, t1, 2f
137    cmpnei     a2, 0
138    bf         2f
139
140    /* d[i] != s[i] in word, so we check byte 1 ? */
141    xtrb0      t1, a0
142    mov        a2, t1
143    xtrb0      t1, t0
144
145#endif
146    /* get the result when d[i] != s[i] */
147    2:
148    subu       a2, t1
149    mov        a0, a2
150    jmp        r15
151
152    /* return when d[i] == s[i] */
153    3:
154    subu       a0, t0
155    jmp        r15
156
157     /* cmp when d or s is not aligned */
158    4:
159    ldb       a0, (a3,0)
160    ldb       t0, (a1, 0)
161    M_BNE     a0, t0, 3b
162    addi      a1, 1
163    addi      a3, 1
164    M_BNEZ    a0, 4b
165    jmp        r15
166
167    .size   Wstrcmp, .-Wstrcmp
168
169libc_hidden_def(Wstrcmp)
170.weak Wstrcmp
171#ifndef __UCLIBC_HAS_LOCALE__
172/* libc_hidden_proto(Wstrcoll) */
173strong_alias(Wstrcmp,Wstrcoll)
174libc_hidden_def(Wstrcoll)
175#endif
176