Commit | Line | Data |
---|---|---|
1da177e4 LT |
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) 1998, 1999, 2000 by Ralf Baechle | |
7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | |
26c5e07d SH |
8 | * Copyright (C) 2007 by Maciej W. Rozycki |
9 | * Copyright (C) 2011, 2012 MIPS Technologies, Inc. | |
1da177e4 LT |
10 | */ |
11 | #include <asm/asm.h> | |
048eb582 | 12 | #include <asm/asm-offsets.h> |
1da177e4 LT |
13 | #include <asm/regdef.h> |
14 | ||
a583158c AN |
15 | #if LONGSIZE == 4 |
16 | #define LONG_S_L swl | |
17 | #define LONG_S_R swr | |
18 | #else | |
19 | #define LONG_S_L sdl | |
20 | #define LONG_S_R sdr | |
21 | #endif | |
22 | ||
26c5e07d SH |
23 | #ifdef CONFIG_CPU_MICROMIPS |
24 | #define STORSIZE (LONGSIZE * 2) | |
25 | #define STORMASK (STORSIZE - 1) | |
26 | #define FILL64RG t8 | |
27 | #define FILLPTRG t7 | |
28 | #undef LONG_S | |
29 | #define LONG_S LONG_SP | |
30 | #else | |
31 | #define STORSIZE LONGSIZE | |
32 | #define STORMASK LONGMASK | |
33 | #define FILL64RG a1 | |
34 | #define FILLPTRG t0 | |
35 | #endif | |
36 | ||
1da177e4 LT |
37 | #define EX(insn,reg,addr,handler) \ |
38 | 9: insn reg, addr; \ | |
70342287 RB |
39 | .section __ex_table,"a"; \ |
40 | PTR 9b, handler; \ | |
1da177e4 LT |
41 | .previous |
42 | ||
43 | .macro f_fill64 dst, offset, val, fixup | |
26c5e07d SH |
44 | EX(LONG_S, \val, (\offset + 0 * STORSIZE)(\dst), \fixup) |
45 | EX(LONG_S, \val, (\offset + 1 * STORSIZE)(\dst), \fixup) | |
46 | EX(LONG_S, \val, (\offset + 2 * STORSIZE)(\dst), \fixup) | |
47 | EX(LONG_S, \val, (\offset + 3 * STORSIZE)(\dst), \fixup) | |
48 | #if ((defined(CONFIG_CPU_MICROMIPS) && (LONGSIZE == 4)) || !defined(CONFIG_CPU_MICROMIPS)) | |
49 | EX(LONG_S, \val, (\offset + 4 * STORSIZE)(\dst), \fixup) | |
50 | EX(LONG_S, \val, (\offset + 5 * STORSIZE)(\dst), \fixup) | |
51 | EX(LONG_S, \val, (\offset + 6 * STORSIZE)(\dst), \fixup) | |
52 | EX(LONG_S, \val, (\offset + 7 * STORSIZE)(\dst), \fixup) | |
53 | #endif | |
54 | #if (!defined(CONFIG_CPU_MICROMIPS) && (LONGSIZE == 4)) | |
55 | EX(LONG_S, \val, (\offset + 8 * STORSIZE)(\dst), \fixup) | |
56 | EX(LONG_S, \val, (\offset + 9 * STORSIZE)(\dst), \fixup) | |
57 | EX(LONG_S, \val, (\offset + 10 * STORSIZE)(\dst), \fixup) | |
58 | EX(LONG_S, \val, (\offset + 11 * STORSIZE)(\dst), \fixup) | |
59 | EX(LONG_S, \val, (\offset + 12 * STORSIZE)(\dst), \fixup) | |
60 | EX(LONG_S, \val, (\offset + 13 * STORSIZE)(\dst), \fixup) | |
61 | EX(LONG_S, \val, (\offset + 14 * STORSIZE)(\dst), \fixup) | |
62 | EX(LONG_S, \val, (\offset + 15 * STORSIZE)(\dst), \fixup) | |
a583158c | 63 | #endif |
1da177e4 LT |
64 | .endm |
65 | ||
66 | /* | |
67 | * memset(void *s, int c, size_t n) | |
68 | * | |
69 | * a0: start of area to clear | |
70 | * a1: char to fill with | |
71 | * a2: size of area to clear | |
72 | */ | |
73 | .set noreorder | |
74 | .align 5 | |
75 | LEAF(memset) | |
76 | beqz a1, 1f | |
77 | move v0, a0 /* result */ | |
78 | ||
79 | andi a1, 0xff /* spread fillword */ | |
a583158c | 80 | LONG_SLL t1, a1, 8 |
1da177e4 | 81 | or a1, t1 |
a583158c AN |
82 | LONG_SLL t1, a1, 16 |
83 | #if LONGSIZE == 8 | |
84 | or a1, t1 | |
85 | LONG_SLL t1, a1, 32 | |
86 | #endif | |
1da177e4 LT |
87 | or a1, t1 |
88 | 1: | |
89 | ||
90 | FEXPORT(__bzero) | |
26c5e07d | 91 | sltiu t0, a2, STORSIZE /* very small region? */ |
c5ec1983 | 92 | bnez t0, .Lsmall_memset |
26c5e07d | 93 | andi t0, a0, STORMASK /* aligned? */ |
1da177e4 | 94 | |
26c5e07d SH |
95 | #ifdef CONFIG_CPU_MICROMIPS |
96 | move t8, a1 /* used by 'swp' instruction */ | |
97 | move t9, a1 | |
98 | #endif | |
619b6e18 | 99 | #ifndef CONFIG_CPU_DADDI_WORKAROUNDS |
1da177e4 | 100 | beqz t0, 1f |
26c5e07d | 101 | PTR_SUBU t0, STORSIZE /* alignment in bytes */ |
619b6e18 MR |
102 | #else |
103 | .set noat | |
26c5e07d | 104 | li AT, STORSIZE |
619b6e18 MR |
105 | beqz t0, 1f |
106 | PTR_SUBU t0, AT /* alignment in bytes */ | |
107 | .set at | |
108 | #endif | |
1da177e4 | 109 | |
930bff88 | 110 | R10KCBARRIER(0(ra)) |
1da177e4 | 111 | #ifdef __MIPSEB__ |
c5ec1983 | 112 | EX(LONG_S_L, a1, (a0), .Lfirst_fixup) /* make word/dword aligned */ |
1da177e4 LT |
113 | #endif |
114 | #ifdef __MIPSEL__ | |
c5ec1983 | 115 | EX(LONG_S_R, a1, (a0), .Lfirst_fixup) /* make word/dword aligned */ |
1da177e4 LT |
116 | #endif |
117 | PTR_SUBU a0, t0 /* long align ptr */ | |
118 | PTR_ADDU a2, t0 /* correct size */ | |
119 | ||
120 | 1: ori t1, a2, 0x3f /* # of full blocks */ | |
121 | xori t1, 0x3f | |
c5ec1983 | 122 | beqz t1, .Lmemset_partial /* no block to fill */ |
26c5e07d | 123 | andi t0, a2, 0x40-STORSIZE |
1da177e4 LT |
124 | |
125 | PTR_ADDU t1, a0 /* end address */ | |
126 | .set reorder | |
127 | 1: PTR_ADDIU a0, 64 | |
930bff88 | 128 | R10KCBARRIER(0(ra)) |
26c5e07d | 129 | f_fill64 a0, -64, FILL64RG, .Lfwd_fixup |
1da177e4 LT |
130 | bne t1, a0, 1b |
131 | .set noreorder | |
132 | ||
c5ec1983 | 133 | .Lmemset_partial: |
930bff88 | 134 | R10KCBARRIER(0(ra)) |
1da177e4 | 135 | PTR_LA t1, 2f /* where to start */ |
26c5e07d SH |
136 | #ifdef CONFIG_CPU_MICROMIPS |
137 | LONG_SRL t7, t0, 1 | |
138 | #endif | |
a583158c | 139 | #if LONGSIZE == 4 |
26c5e07d | 140 | PTR_SUBU t1, FILLPTRG |
a583158c AN |
141 | #else |
142 | .set noat | |
26c5e07d | 143 | LONG_SRL AT, FILLPTRG, 1 |
a583158c | 144 | PTR_SUBU t1, AT |
619b6e18 | 145 | .set at |
a583158c | 146 | #endif |
1da177e4 LT |
147 | jr t1 |
148 | PTR_ADDU a0, t0 /* dest ptr */ | |
149 | ||
150 | .set push | |
151 | .set noreorder | |
152 | .set nomacro | |
26c5e07d | 153 | f_fill64 a0, -64, FILL64RG, .Lpartial_fixup /* ... but first do longs ... */ |
1da177e4 | 154 | 2: .set pop |
26c5e07d | 155 | andi a2, STORMASK /* At most one long to go */ |
1da177e4 LT |
156 | |
157 | beqz a2, 1f | |
158 | PTR_ADDU a0, a2 /* What's left */ | |
930bff88 | 159 | R10KCBARRIER(0(ra)) |
1da177e4 | 160 | #ifdef __MIPSEB__ |
c5ec1983 | 161 | EX(LONG_S_R, a1, -1(a0), .Llast_fixup) |
1da177e4 LT |
162 | #endif |
163 | #ifdef __MIPSEL__ | |
c5ec1983 | 164 | EX(LONG_S_L, a1, -1(a0), .Llast_fixup) |
1da177e4 LT |
165 | #endif |
166 | 1: jr ra | |
167 | move a2, zero | |
168 | ||
c5ec1983 | 169 | .Lsmall_memset: |
1da177e4 LT |
170 | beqz a2, 2f |
171 | PTR_ADDU t1, a0, a2 | |
172 | ||
173 | 1: PTR_ADDIU a0, 1 /* fill bytewise */ | |
930bff88 | 174 | R10KCBARRIER(0(ra)) |
1da177e4 LT |
175 | bne t1, a0, 1b |
176 | sb a1, -1(a0) | |
177 | ||
178 | 2: jr ra /* done */ | |
179 | move a2, zero | |
180 | END(memset) | |
181 | ||
c5ec1983 | 182 | .Lfirst_fixup: |
1da177e4 LT |
183 | jr ra |
184 | nop | |
185 | ||
c5ec1983 | 186 | .Lfwd_fixup: |
1da177e4 | 187 | PTR_L t0, TI_TASK($28) |
1da177e4 | 188 | andi a2, 0x3f |
e5674ad6 | 189 | LONG_L t0, THREAD_BUADDR(t0) |
1da177e4 LT |
190 | LONG_ADDU a2, t1 |
191 | jr ra | |
192 | LONG_SUBU a2, t0 | |
193 | ||
c5ec1983 | 194 | .Lpartial_fixup: |
1da177e4 | 195 | PTR_L t0, TI_TASK($28) |
26c5e07d | 196 | andi a2, STORMASK |
e5674ad6 | 197 | LONG_L t0, THREAD_BUADDR(t0) |
1da177e4 LT |
198 | LONG_ADDU a2, t1 |
199 | jr ra | |
200 | LONG_SUBU a2, t0 | |
201 | ||
c5ec1983 | 202 | .Llast_fixup: |
1da177e4 | 203 | jr ra |
26c5e07d | 204 | andi v1, a2, STORMASK |