drm/panthor: Don't add write fences to the shared BOs
[drm/drm-misc.git] / arch / riscv / lib / strcmp.S
blob57a5c00662315d753dbb9daf6102200025f389cd
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <linux/linkage.h>
4 #include <asm/asm.h>
5 #include <asm/alternative-macros.h>
6 #include <asm/hwcap.h>
8 /* int strcmp(const char *cs, const char *ct) */
9 SYM_FUNC_START(strcmp)
11         ALTERNATIVE("nop", "j strcmp_zbb", 0, RISCV_ISA_EXT_ZBB, CONFIG_RISCV_ISA_ZBB)
13         /*
14          * Returns
15          *   a0 - comparison result, value like strcmp
16          *
17          * Parameters
18          *   a0 - string1
19          *   a1 - string2
20          *
21          * Clobbers
22          *   t0, t1
23          */
25         lbu     t0, 0(a0)
26         lbu     t1, 0(a1)
27         addi    a0, a0, 1
28         addi    a1, a1, 1
29         bne     t0, t1, 2f
30         bnez    t0, 1b
31         li      a0, 0
32         ret
34         /*
35          * strcmp only needs to return (< 0, 0, > 0) values
36          * not necessarily -1, 0, +1
37          */
38         sub     a0, t0, t1
39         ret
42  * Variant of strcmp using the ZBB extension if available.
43  * The code was published as part of the bitmanip manual
44  * in Appendix A.
45  */
46 #ifdef CONFIG_RISCV_ISA_ZBB
47 strcmp_zbb:
49 .option push
50 .option arch,+zbb
52         /*
53          * Returns
54          *   a0 - comparison result, value like strcmp
55          *
56          * Parameters
57          *   a0 - string1
58          *   a1 - string2
59          *
60          * Clobbers
61          *   t0, t1, t2, t3, t4
62          */
64         or      t2, a0, a1
65         li      t4, -1
66         and     t2, t2, SZREG-1
67         bnez    t2, 3f
69         /* Main loop for aligned string.  */
70         .p2align 3
72         REG_L   t0, 0(a0)
73         REG_L   t1, 0(a1)
74         orc.b   t3, t0
75         bne     t3, t4, 2f
76         addi    a0, a0, SZREG
77         addi    a1, a1, SZREG
78         beq     t0, t1, 1b
80         /*
81          * Words don't match, and no null byte in the first
82          * word. Get bytes in big-endian order and compare.
83          */
84 #ifndef CONFIG_CPU_BIG_ENDIAN
85         rev8    t0, t0
86         rev8    t1, t1
87 #endif
89         /* Synthesize (t0 >= t1) ? 1 : -1 in a branchless sequence. */
90         sltu    a0, t0, t1
91         neg     a0, a0
92         ori     a0, a0, 1
93         ret
96         /*
97          * Found a null byte.
98          * If words don't match, fall back to simple loop.
99          */
100         bne     t0, t1, 3f
102         /* Otherwise, strings are equal. */
103         li      a0, 0
104         ret
106         /* Simple loop for misaligned strings. */
107         .p2align 3
109         lbu     t0, 0(a0)
110         lbu     t1, 0(a1)
111         addi    a0, a0, 1
112         addi    a1, a1, 1
113         bne     t0, t1, 4f
114         bnez    t0, 3b
117         sub     a0, t0, t1
118         ret
120 .option pop
121 #endif
122 SYM_FUNC_END(strcmp)
123 SYM_FUNC_ALIAS(__pi_strcmp, strcmp)
124 EXPORT_SYMBOL(strcmp)