• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 *  linux/arch/m32r/strlen.S --  strlen code.
4 *
5 *  Copyright (C) 2001  Hirokazu Takata
6 *
7 *  size_t strlen(const char *s);
8 *
9 */
10
11#include <linux/linkage.h>
12#include <asm/assembler.h>
13
14#ifdef CONFIG_ISA_DUAL_ISSUE
15
16	.text
17ENTRY(strlen)
18	mv	r6, r0		    ||	ldi	r2, #0
19	and3	r0, r0, #3
20	bnez	r0, strlen_byte
21;
22strlen_word:
23	ld	r0, @r6+
24;
25	seth	r5, #high(0x01010101)
26	or3	r5, r5, #low(0x01010101)
27	sll3	r7, r5, #7
28strlen_word_loop:
29	ld	r1, @r6+	    ||	not	r4, r0
30	sub	r0, r5		    ||	and	r4, r7
31	and	r4, r0
32	bnez	r4, strlen_last_bytes
33	ld	r0, @r6+	    ||	not	r4, r1
34	sub	r1, r5		    ||	and	r4, r7
35	and	r4, r1		    ||	addi	r2, #4
36	bnez	r4, strlen_last_bytes
37	addi	r2, #4		    ||	bra.s	strlen_word_loop
38
39	; NOTE: If a null char. exists, return 0.
40	; if ((x - 0x01010101) & ~x & 0x80808080)
41	;     return 0;
42;
43strlen_byte:
44	ldb	r1, @r6		    ||	addi	r6, #1
45	beqz	r1, strlen_exit
46	addi	r2, #1		    ||	bra.s	strlen_byte
47;
48strlen_last_bytes:
49	ldi	r0, #4		    ||	addi	r6, #-8
50;
51strlen_byte_loop:
52	ldb	r1, @r6		    ||	addi	r6, #1
53	addi	r0, #-1		    ||  cmpz	r1
54	bc.s	strlen_exit	    ||  cmpz	r0
55	addi	r2, #1		    ||	bnc.s	strlen_byte_loop
56;
57strlen_exit:
58	mv	r0, r2		    ||	jmp	r14
59
60#else /* not CONFIG_ISA_DUAL_ISSUE */
61
62	.text
63ENTRY(strlen)
64	mv	r6, r0
65	ldi	r2, #0
66	and3	r0, r0, #3
67	bnez	r0, strlen_byte
68;
69strlen_word:
70	ld	r0, @r6+
71;
72	seth	r5, #high(0x01010101)
73	or3	r5, r5, #low(0x01010101)
74	sll3	r7, r5, #7
75strlen_word_loop:
76	ld	r1, @r6+
77	not	r4, r0		; NOTE: If a null char. exists, return 0.
78	sub	r0, r5		; if ((x - 0x01010101) & ~x & 0x80808080)
79	and	r4, r7		;     return 0;
80	and	r4, r0
81	bnez	r4, strlen_last_bytes
82	addi	r2, #4
83;
84	ld	r0, @r6+
85	not	r4, r1		; NOTE: If a null char. exists, return 0.
86	sub	r1, r5		; if ((x - 0x01010101) & ~x & 0x80808080)
87	and	r4, r7		;     return 0;
88	and	r4, r1
89	bnez	r4, strlen_last_bytes
90	addi	r2, #4
91	bra	strlen_word_loop
92;
93strlen_byte:
94	ldb	r1, @r6
95	addi	r6, #1
96	beqz	r1, strlen_exit
97	addi	r2, #1
98	bra	strlen_byte
99;
100strlen_last_bytes:
101	ldi	r0, #4
102	addi	r6, #-8
103;
104strlen_byte_loop:
105	ldb	r1, @r6
106	addi	r6, #1
107	addi	r0, #-1
108	beqz	r1, strlen_exit
109	addi	r2, #1
110	bnez	r0, strlen_byte_loop
111;
112strlen_exit:
113	mv	r0, r2
114	jmp	r14
115
116#endif /* not CONFIG_ISA_DUAL_ISSUE */
117
118	.end
119