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