MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / arch / nios2nommu / lib / string.c
blobb87c195e1cc15e0d4e61b763824888c32f0a5a38
1 /*--------------------------------------------------------------------
3 * arch/nios2nommu/lib/string.c
5 * Derived from various works, Alpha, ix86, M68K, Sparc, ...et al
7 * Copyright (C) 2004 Microtronix Datacom Ltd
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
20 * Jan/20/2004 dgt NiosII
21 * Jun/09/2004 dgt Split out memcpy into separate source file
23 ---------------------------------------------------------------------*/
25 #include <linux/types.h>
26 #include <linux/autoconf.h>
27 #include <asm/nios.h>
28 #include <asm/string.h>
30 #ifdef __HAVE_ARCH_MEMSET
31 void * memset(void * s,int c,size_t count)
34 if (count > 8) {
35 int destptr, charcnt, dwordcnt, fill8reg, wrkrega;
36 __asm__ __volatile__ (
37 // fill8 %3, %5 (c & 0xff)\n\t"
39 " slli %4, %5, 8\n\t"
40 " or %4, %4, %5\n\t"
41 " slli %3, %4, 16\n\t"
42 " or %3, %3, %4\n\t"
44 // Word-align %0 (s) if necessary
46 " andi %4, %0, 0x01\n\t"
47 " beq %4, zero, 1f\n\t"
48 " addi %1, %1, -1\n\t"
49 " stb %3, 0(%0)\n\t"
50 " addi %0, %0, 1\n\t"
51 "1: \n\t"
52 " mov %2, %1\n\t"
54 // Dword-align %0 (s) if necessary
56 " andi %4, %0, 0x02\n\t"
57 " beq %4, zero, 2f\n\t"
58 " addi %1, %1, -2\n\t"
59 " sth %3, 0(%0)\n\t"
60 " addi %0, %0, 2\n\t"
61 " mov %2, %1\n\t"
62 "2: \n\t"
63 // %1 and %2 are how many more bytes to set
65 " srli %2, %2, 2\n\t"
67 // %2 is how many dwords to set
69 "3: ;\n\t"
70 " stw %3, 0(%0)\n\t"
71 " addi %0, %0, 4\n\t"
72 " addi %2, %2, -1\n\t"
73 " bne %2, zero, 3b\n\t"
75 // store residual word and/or byte if necessary
77 " andi %4, %1, 0x02\n\t"
78 " beq %4, zero, 4f\n\t"
79 " sth %3, 0(%0)\n\t"
80 " addi %0, %0, 2\n\t"
81 "4: \n\t"
82 // store residual byte if necessary
84 " andi %4, %1, 0x01\n\t"
85 " beq %4, zero, 5f\n\t"
86 " stb %3, 0(%0)\n\t"
87 "5: \n\t"
89 : "=r" (destptr), /* %0 Output */
90 "=r" (charcnt), /* %1 Output */
91 "=r" (dwordcnt), /* %2 Output */
92 "=r" (fill8reg), /* %3 Output */
93 "=r" (wrkrega) /* %4 Output */
95 : "r" (c & 0xff), /* %5 Input */
96 "0" (s), /* %0 Input/Output */
97 "1" (count) /* %1 Input/Output */
99 : "memory" /* clobbered */
102 else {
103 char* xs=(char*)s;
104 while (count--)
105 *xs++ = c;
107 return s;
109 #endif
111 #ifdef __HAVE_ARCH_MEMMOVE
112 void * memmove(void * d, const void * s, size_t count)
114 unsigned long dst, src;
116 if (d < s) {
117 dst = (unsigned long) d;
118 src = (unsigned long) s;
120 if ((count < 8) || ((dst ^ src) & 3))
121 goto restup;
123 if (dst & 1) {
124 *(char*)dst++=*(char*)src++;
125 count--;
127 if (dst & 2) {
128 *(short*)dst=*(short*)src;
129 src += 2;
130 dst += 2;
131 count -= 2;
133 while (count > 3) {
134 *(long*)dst=*(long*)src;
135 src += 4;
136 dst += 4;
137 count -= 4;
140 restup:
141 while (count--)
142 *(char*)dst++=*(char*)src++;
143 } else {
144 dst = (unsigned long) d + count;
145 src = (unsigned long) s + count;
147 if ((count < 8) || ((dst ^ src) & 3))
148 goto restdown;
150 if (dst & 1) {
151 src--;
152 dst--;
153 count--;
154 *(char*)dst=*(char*)src;
156 if (dst & 2) {
157 src -= 2;
158 dst -= 2;
159 count -= 2;
160 *(short*)dst=*(short*)src;
162 while (count > 3) {
163 src -= 4;
164 dst -= 4;
165 count -= 4;
166 *(long*)dst=*(long*)src;
169 restdown:
170 while (count--) {
171 src--;
172 dst--;
173 *(char*)dst=*(char*)src;
177 return d;
180 #endif