diff options
Diffstat (limited to 'arch/mips/lib/memset.S')
-rw-r--r-- | arch/mips/lib/memset.S | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S index 3f8b8b3d0b23..77dc3b20110a 100644 --- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S | |||
@@ -5,6 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 1998, 1999, 2000 by Ralf Baechle | 6 | * Copyright (C) 1998, 1999, 2000 by Ralf Baechle |
7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
8 | * Copyright (C) 2007 Maciej W. Rozycki | ||
8 | */ | 9 | */ |
9 | #include <asm/asm.h> | 10 | #include <asm/asm.h> |
10 | #include <asm/asm-offsets.h> | 11 | #include <asm/asm-offsets.h> |
@@ -71,34 +72,45 @@ LEAF(memset) | |||
71 | 72 | ||
72 | FEXPORT(__bzero) | 73 | FEXPORT(__bzero) |
73 | sltiu t0, a2, LONGSIZE /* very small region? */ | 74 | sltiu t0, a2, LONGSIZE /* very small region? */ |
74 | bnez t0, small_memset | 75 | bnez t0, .Lsmall_memset |
75 | andi t0, a0, LONGMASK /* aligned? */ | 76 | andi t0, a0, LONGMASK /* aligned? */ |
76 | 77 | ||
78 | #ifndef CONFIG_CPU_DADDI_WORKAROUNDS | ||
77 | beqz t0, 1f | 79 | beqz t0, 1f |
78 | PTR_SUBU t0, LONGSIZE /* alignment in bytes */ | 80 | PTR_SUBU t0, LONGSIZE /* alignment in bytes */ |
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 | ||
79 | 88 | ||
89 | R10KCBARRIER(0(ra)) | ||
80 | #ifdef __MIPSEB__ | 90 | #ifdef __MIPSEB__ |
81 | EX(LONG_S_L, a1, (a0), first_fixup) /* make word/dword aligned */ | 91 | EX(LONG_S_L, a1, (a0), .Lfirst_fixup) /* make word/dword aligned */ |
82 | #endif | 92 | #endif |
83 | #ifdef __MIPSEL__ | 93 | #ifdef __MIPSEL__ |
84 | EX(LONG_S_R, a1, (a0), first_fixup) /* make word/dword aligned */ | 94 | EX(LONG_S_R, a1, (a0), .Lfirst_fixup) /* make word/dword aligned */ |
85 | #endif | 95 | #endif |
86 | PTR_SUBU a0, t0 /* long align ptr */ | 96 | PTR_SUBU a0, t0 /* long align ptr */ |
87 | PTR_ADDU a2, t0 /* correct size */ | 97 | PTR_ADDU a2, t0 /* correct size */ |
88 | 98 | ||
89 | 1: ori t1, a2, 0x3f /* # of full blocks */ | 99 | 1: ori t1, a2, 0x3f /* # of full blocks */ |
90 | xori t1, 0x3f | 100 | xori t1, 0x3f |
91 | beqz t1, memset_partial /* no block to fill */ | 101 | beqz t1, .Lmemset_partial /* no block to fill */ |
92 | andi t0, a2, 0x40-LONGSIZE | 102 | andi t0, a2, 0x40-LONGSIZE |
93 | 103 | ||
94 | PTR_ADDU t1, a0 /* end address */ | 104 | PTR_ADDU t1, a0 /* end address */ |
95 | .set reorder | 105 | .set reorder |
96 | 1: PTR_ADDIU a0, 64 | 106 | 1: PTR_ADDIU a0, 64 |
97 | f_fill64 a0, -64, a1, fwd_fixup | 107 | R10KCBARRIER(0(ra)) |
108 | f_fill64 a0, -64, a1, .Lfwd_fixup | ||
98 | bne t1, a0, 1b | 109 | bne t1, a0, 1b |
99 | .set noreorder | 110 | .set noreorder |
100 | 111 | ||
101 | memset_partial: | 112 | .Lmemset_partial: |
113 | R10KCBARRIER(0(ra)) | ||
102 | PTR_LA t1, 2f /* where to start */ | 114 | PTR_LA t1, 2f /* where to start */ |
103 | #if LONGSIZE == 4 | 115 | #if LONGSIZE == 4 |
104 | PTR_SUBU t1, t0 | 116 | PTR_SUBU t1, t0 |
@@ -106,7 +118,7 @@ memset_partial: | |||
106 | .set noat | 118 | .set noat |
107 | LONG_SRL AT, t0, 1 | 119 | LONG_SRL AT, t0, 1 |
108 | PTR_SUBU t1, AT | 120 | PTR_SUBU t1, AT |
109 | .set noat | 121 | .set at |
110 | #endif | 122 | #endif |
111 | jr t1 | 123 | jr t1 |
112 | PTR_ADDU a0, t0 /* dest ptr */ | 124 | PTR_ADDU a0, t0 /* dest ptr */ |
@@ -114,26 +126,28 @@ memset_partial: | |||
114 | .set push | 126 | .set push |
115 | .set noreorder | 127 | .set noreorder |
116 | .set nomacro | 128 | .set nomacro |
117 | f_fill64 a0, -64, a1, partial_fixup /* ... but first do longs ... */ | 129 | f_fill64 a0, -64, a1, .Lpartial_fixup /* ... but first do longs ... */ |
118 | 2: .set pop | 130 | 2: .set pop |
119 | andi a2, LONGMASK /* At most one long to go */ | 131 | andi a2, LONGMASK /* At most one long to go */ |
120 | 132 | ||
121 | beqz a2, 1f | 133 | beqz a2, 1f |
122 | PTR_ADDU a0, a2 /* What's left */ | 134 | PTR_ADDU a0, a2 /* What's left */ |
135 | R10KCBARRIER(0(ra)) | ||
123 | #ifdef __MIPSEB__ | 136 | #ifdef __MIPSEB__ |
124 | EX(LONG_S_R, a1, -1(a0), last_fixup) | 137 | EX(LONG_S_R, a1, -1(a0), .Llast_fixup) |
125 | #endif | 138 | #endif |
126 | #ifdef __MIPSEL__ | 139 | #ifdef __MIPSEL__ |
127 | EX(LONG_S_L, a1, -1(a0), last_fixup) | 140 | EX(LONG_S_L, a1, -1(a0), .Llast_fixup) |
128 | #endif | 141 | #endif |
129 | 1: jr ra | 142 | 1: jr ra |
130 | move a2, zero | 143 | move a2, zero |
131 | 144 | ||
132 | small_memset: | 145 | .Lsmall_memset: |
133 | beqz a2, 2f | 146 | beqz a2, 2f |
134 | PTR_ADDU t1, a0, a2 | 147 | PTR_ADDU t1, a0, a2 |
135 | 148 | ||
136 | 1: PTR_ADDIU a0, 1 /* fill bytewise */ | 149 | 1: PTR_ADDIU a0, 1 /* fill bytewise */ |
150 | R10KCBARRIER(0(ra)) | ||
137 | bne t1, a0, 1b | 151 | bne t1, a0, 1b |
138 | sb a1, -1(a0) | 152 | sb a1, -1(a0) |
139 | 153 | ||
@@ -141,11 +155,11 @@ small_memset: | |||
141 | move a2, zero | 155 | move a2, zero |
142 | END(memset) | 156 | END(memset) |
143 | 157 | ||
144 | first_fixup: | 158 | .Lfirst_fixup: |
145 | jr ra | 159 | jr ra |
146 | nop | 160 | nop |
147 | 161 | ||
148 | fwd_fixup: | 162 | .Lfwd_fixup: |
149 | PTR_L t0, TI_TASK($28) | 163 | PTR_L t0, TI_TASK($28) |
150 | LONG_L t0, THREAD_BUADDR(t0) | 164 | LONG_L t0, THREAD_BUADDR(t0) |
151 | andi a2, 0x3f | 165 | andi a2, 0x3f |
@@ -153,7 +167,7 @@ fwd_fixup: | |||
153 | jr ra | 167 | jr ra |
154 | LONG_SUBU a2, t0 | 168 | LONG_SUBU a2, t0 |
155 | 169 | ||
156 | partial_fixup: | 170 | .Lpartial_fixup: |
157 | PTR_L t0, TI_TASK($28) | 171 | PTR_L t0, TI_TASK($28) |
158 | LONG_L t0, THREAD_BUADDR(t0) | 172 | LONG_L t0, THREAD_BUADDR(t0) |
159 | andi a2, LONGMASK | 173 | andi a2, LONGMASK |
@@ -161,6 +175,6 @@ partial_fixup: | |||
161 | jr ra | 175 | jr ra |
162 | LONG_SUBU a2, t0 | 176 | LONG_SUBU a2, t0 |
163 | 177 | ||
164 | last_fixup: | 178 | .Llast_fixup: |
165 | jr ra | 179 | jr ra |
166 | andi v1, a2, LONGMASK | 180 | andi v1, a2, LONGMASK |