1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (c) 1994, 1995, 1996, 1997, 1998, 2001 Ralf Baechle
7 * Copyright (c) 2001 MIPS Technologies, Inc.
8 */
9#ifndef __ASM_STRING_H
10#define __ASM_STRING_H
11
12#include <linux/config.h>
13
14#define __HAVE_ARCH_STRCPY
15extern __inline__ char *strcpy(char *__dest, __const__ char *__src)
16{
17  char *__xdest = __dest;
18
19  __asm__ __volatile__(
20	".set\tnoreorder\n\t"
21	".set\tnoat\n"
22	"1:\tlbu\t$1,(%1)\n\t"
23	"addiu\t%1,1\n\t"
24	"sb\t$1,(%0)\n\t"
25	"bnez\t$1,1b\n\t"
26	"addiu\t%0,1\n\t"
27	".set\tat\n\t"
28	".set\treorder"
29	: "=r" (__dest), "=r" (__src)
30        : "0" (__dest), "1" (__src)
31	: "memory");
32
33  return __xdest;
34}
35
36#define __HAVE_ARCH_STRNCPY
37extern __inline__ char *strncpy(char *__dest, __const__ char *__src, size_t __n)
38{
39  char *__xdest = __dest;
40
41  if (__n == 0)
42    return __xdest;
43
44  __asm__ __volatile__(
45	".set\tnoreorder\n\t"
46	".set\tnoat\n"
47	"1:\tlbu\t$1,(%1)\n\t"
48	"subu\t%2,1\n\t"
49	"sb\t$1,(%0)\n\t"
50	"beqz\t$1,2f\n\t"
51	"addiu\t%0,1\n\t"
52	"bnez\t%2,1b\n\t"
53	"addiu\t%1,1\n"
54	"2:\n\t"
55	".set\tat\n\t"
56	".set\treorder"
57        : "=r" (__dest), "=r" (__src), "=r" (__n)
58        : "0" (__dest), "1" (__src), "2" (__n)
59        : "memory");
60
61  return __xdest;
62}
63
64#define __HAVE_ARCH_STRCMP
65extern __inline__ int strcmp(__const__ char *__cs, __const__ char *__ct)
66{
67  int __res;
68
69  __asm__ __volatile__(
70	".set\tnoreorder\n\t"
71	".set\tnoat\n\t"
72	"lbu\t%2,(%0)\n"
73	"1:\tlbu\t$1,(%1)\n\t"
74	"addiu\t%0,1\n\t"
75	"bne\t$1,%2,2f\n\t"
76	"addiu\t%1,1\n\t"
77	"bnez\t%2,1b\n\t"
78	"lbu\t%2,(%0)\n\t"
79#if defined(CONFIG_CPU_R3000)
80	"nop\n\t"
81#endif
82	"move\t%2,$1\n"
83	"2:\tsubu\t%2,$1\n"
84	"3:\t.set\tat\n\t"
85	".set\treorder"
86	: "=r" (__cs), "=r" (__ct), "=r" (__res)
87	: "0" (__cs), "1" (__ct));
88
89  return __res;
90}
91
92#define __HAVE_ARCH_STRNCMP
93extern __inline__ int
94strncmp(__const__ char *__cs, __const__ char *__ct, size_t __count)
95{
96	int __res;
97
98	__asm__ __volatile__(
99	".set\tnoreorder\n\t"
100	".set\tnoat\n"
101	"1:\tlbu\t%3,(%0)\n\t"
102	"beqz\t%2,2f\n\t"
103	"lbu\t$1,(%1)\n\t"
104	"subu\t%2,1\n\t"
105	"bne\t$1,%3,3f\n\t"
106	"addiu\t%0,1\n\t"
107	"bnez\t%3,1b\n\t"
108	"addiu\t%1,1\n"
109	"2:\n\t"
110#if defined(CONFIG_CPU_R3000)
111	"nop\n\t"
112#endif
113	"move\t%3,$1\n"
114	"3:\tsubu\t%3,$1\n\t"
115	".set\tat\n\t"
116	".set\treorder"
117	: "=r" (__cs), "=r" (__ct), "=r" (__count), "=r" (__res)
118	: "0" (__cs), "1" (__ct), "2" (__count));
119
120	return __res;
121}
122
123#define __HAVE_ARCH_MEMSET
124extern void *memset(void *__s, int __c, size_t __count);
125
126#define __HAVE_ARCH_MEMCPY
127extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
128
129#define __HAVE_ARCH_MEMMOVE
130extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
131
132/* Don't build bcopy at all ...  */
133#define __HAVE_ARCH_BCOPY
134
135#define __HAVE_ARCH_MEMSCAN
136extern __inline__ void *memscan(void *__addr, int __c, size_t __size)
137{
138	char *__end = (char *)__addr + __size;
139	unsigned char __uc = (unsigned char) __c;
140
141	__asm__(".set\tpush\n\t"
142		".set\tnoat\n\t"
143		".set\treorder\n\t"
144		"1:\tbeq\t%0,%1,2f\n\t"
145		"addiu\t%0,1\n\t"
146		"lbu\t$1,-1(%0)\n\t"
147		"bne\t$1,%z4,1b\n"
148		"2:\t.set\tpop"
149		: "=r" (__addr), "=r" (__end)
150		: "0" (__addr), "1" (__end), "Jr" (__uc));
151
152	return __addr;
153}
154
155#endif /* __ASM_STRING_H */
156