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