diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2017-12-10 00:18:47 -0500 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2017-12-10 17:48:53 -0500 |
commit | 0013aceb307482ba83a5b6a29f6ba1791be0d32b (patch) | |
tree | 63f0312a68e62d0f52212ce7bdab9d75e4ee6ead | |
parent | 2da03d4114b2587f0e8e45f4862074e34daee64e (diff) |
xtensa: clean up fixups in assembly code
Remove duplicate definitions of EX() and similar TRY/CATCH and SRC/DST
macros from assembly sources and put single definition into asm/asmmacro.h
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
-rw-r--r-- | arch/xtensa/include/asm/asmmacro.h | 7 | ||||
-rw-r--r-- | arch/xtensa/kernel/entry.S | 33 | ||||
-rw-r--r-- | arch/xtensa/lib/checksum.S | 74 | ||||
-rw-r--r-- | arch/xtensa/lib/memset.S | 36 | ||||
-rw-r--r-- | arch/xtensa/lib/strncpy_user.S | 52 | ||||
-rw-r--r-- | arch/xtensa/lib/strnlen_user.S | 19 | ||||
-rw-r--r-- | arch/xtensa/lib/usercopy.S | 106 |
7 files changed, 133 insertions, 194 deletions
diff --git a/arch/xtensa/include/asm/asmmacro.h b/arch/xtensa/include/asm/asmmacro.h index 746dcc8b5abc..d2a4415a4c08 100644 --- a/arch/xtensa/include/asm/asmmacro.h +++ b/arch/xtensa/include/asm/asmmacro.h | |||
@@ -150,5 +150,12 @@ | |||
150 | __endl \ar \as | 150 | __endl \ar \as |
151 | .endm | 151 | .endm |
152 | 152 | ||
153 | /* Load or store instructions that may cause exceptions use the EX macro. */ | ||
154 | |||
155 | #define EX(handler) \ | ||
156 | .section __ex_table, "a"; \ | ||
157 | .word 97f, handler; \ | ||
158 | .previous \ | ||
159 | 97: | ||
153 | 160 | ||
154 | #endif /* _XTENSA_ASMMACRO_H */ | 161 | #endif /* _XTENSA_ASMMACRO_H */ |
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 5a2110bb5902..a27a9a65635b 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include <linux/linkage.h> | 15 | #include <linux/linkage.h> |
16 | #include <asm/asm-offsets.h> | 16 | #include <asm/asm-offsets.h> |
17 | #include <asm/asmmacro.h> | ||
17 | #include <asm/processor.h> | 18 | #include <asm/processor.h> |
18 | #include <asm/coprocessor.h> | 19 | #include <asm/coprocessor.h> |
19 | #include <asm/thread_info.h> | 20 | #include <asm/thread_info.h> |
@@ -1094,35 +1095,12 @@ ENDPROC(fast_syscall_unrecoverable) | |||
1094 | * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception | 1095 | * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception |
1095 | * | 1096 | * |
1096 | * Note: we don't have to save a2; a2 holds the return value | 1097 | * Note: we don't have to save a2; a2 holds the return value |
1097 | * | ||
1098 | * We use the two macros TRY and CATCH: | ||
1099 | * | ||
1100 | * TRY adds an entry to the __ex_table fixup table for the immediately | ||
1101 | * following instruction. | ||
1102 | * | ||
1103 | * CATCH catches any exception that occurred at one of the preceding TRY | ||
1104 | * statements and continues from there | ||
1105 | * | ||
1106 | * Usage TRY l32i a0, a1, 0 | ||
1107 | * <other code> | ||
1108 | * done: rfe | ||
1109 | * CATCH <set return code> | ||
1110 | * j done | ||
1111 | */ | 1098 | */ |
1112 | 1099 | ||
1113 | .literal_position | 1100 | .literal_position |
1114 | 1101 | ||
1115 | #ifdef CONFIG_FAST_SYSCALL_XTENSA | 1102 | #ifdef CONFIG_FAST_SYSCALL_XTENSA |
1116 | 1103 | ||
1117 | #define TRY \ | ||
1118 | .section __ex_table, "a"; \ | ||
1119 | .word 66f, 67f; \ | ||
1120 | .text; \ | ||
1121 | 66: | ||
1122 | |||
1123 | #define CATCH \ | ||
1124 | 67: | ||
1125 | |||
1126 | ENTRY(fast_syscall_xtensa) | 1104 | ENTRY(fast_syscall_xtensa) |
1127 | 1105 | ||
1128 | s32i a7, a2, PT_AREG7 # we need an additional register | 1106 | s32i a7, a2, PT_AREG7 # we need an additional register |
@@ -1136,9 +1114,9 @@ ENTRY(fast_syscall_xtensa) | |||
1136 | 1114 | ||
1137 | .Lswp: /* Atomic compare and swap */ | 1115 | .Lswp: /* Atomic compare and swap */ |
1138 | 1116 | ||
1139 | TRY l32i a0, a3, 0 # read old value | 1117 | EX(.Leac) l32i a0, a3, 0 # read old value |
1140 | bne a0, a4, 1f # same as old value? jump | 1118 | bne a0, a4, 1f # same as old value? jump |
1141 | TRY s32i a5, a3, 0 # different, modify value | 1119 | EX(.Leac) s32i a5, a3, 0 # different, modify value |
1142 | l32i a7, a2, PT_AREG7 # restore a7 | 1120 | l32i a7, a2, PT_AREG7 # restore a7 |
1143 | l32i a0, a2, PT_AREG0 # restore a0 | 1121 | l32i a0, a2, PT_AREG0 # restore a0 |
1144 | movi a2, 1 # and return 1 | 1122 | movi a2, 1 # and return 1 |
@@ -1151,12 +1129,12 @@ TRY s32i a5, a3, 0 # different, modify value | |||
1151 | 1129 | ||
1152 | .Lnswp: /* Atomic set, add, and exg_add. */ | 1130 | .Lnswp: /* Atomic set, add, and exg_add. */ |
1153 | 1131 | ||
1154 | TRY l32i a7, a3, 0 # orig | 1132 | EX(.Leac) l32i a7, a3, 0 # orig |
1155 | addi a6, a6, -SYS_XTENSA_ATOMIC_SET | 1133 | addi a6, a6, -SYS_XTENSA_ATOMIC_SET |
1156 | add a0, a4, a7 # + arg | 1134 | add a0, a4, a7 # + arg |
1157 | moveqz a0, a4, a6 # set | 1135 | moveqz a0, a4, a6 # set |
1158 | addi a6, a6, SYS_XTENSA_ATOMIC_SET | 1136 | addi a6, a6, SYS_XTENSA_ATOMIC_SET |
1159 | TRY s32i a0, a3, 0 # write new value | 1137 | EX(.Leac) s32i a0, a3, 0 # write new value |
1160 | 1138 | ||
1161 | mov a0, a2 | 1139 | mov a0, a2 |
1162 | mov a2, a7 | 1140 | mov a2, a7 |
@@ -1164,7 +1142,6 @@ TRY s32i a0, a3, 0 # write new value | |||
1164 | l32i a0, a0, PT_AREG0 # restore a0 | 1142 | l32i a0, a0, PT_AREG0 # restore a0 |
1165 | rfe | 1143 | rfe |
1166 | 1144 | ||
1167 | CATCH | ||
1168 | .Leac: l32i a7, a2, PT_AREG7 # restore a7 | 1145 | .Leac: l32i a7, a2, PT_AREG7 # restore a7 |
1169 | l32i a0, a2, PT_AREG0 # restore a0 | 1146 | l32i a0, a2, PT_AREG0 # restore a0 |
1170 | movi a2, -EFAULT | 1147 | movi a2, -EFAULT |
diff --git a/arch/xtensa/lib/checksum.S b/arch/xtensa/lib/checksum.S index 4eb573d2720e..528fe0dd9339 100644 --- a/arch/xtensa/lib/checksum.S +++ b/arch/xtensa/lib/checksum.S | |||
@@ -14,9 +14,10 @@ | |||
14 | * 2 of the License, or (at your option) any later version. | 14 | * 2 of the License, or (at your option) any later version. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <asm/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <linux/linkage.h> | 18 | #include <linux/linkage.h> |
19 | #include <variant/core.h> | 19 | #include <variant/core.h> |
20 | #include <asm/asmmacro.h> | ||
20 | 21 | ||
21 | /* | 22 | /* |
22 | * computes a partial checksum, e.g. for TCP/UDP fragments | 23 | * computes a partial checksum, e.g. for TCP/UDP fragments |
@@ -175,23 +176,8 @@ ENDPROC(csum_partial) | |||
175 | 176 | ||
176 | /* | 177 | /* |
177 | * Copy from ds while checksumming, otherwise like csum_partial | 178 | * Copy from ds while checksumming, otherwise like csum_partial |
178 | * | ||
179 | * The macros SRC and DST specify the type of access for the instruction. | ||
180 | * thus we can call a custom exception handler for each access type. | ||
181 | */ | 179 | */ |
182 | 180 | ||
183 | #define SRC(y...) \ | ||
184 | 9999: y; \ | ||
185 | .section __ex_table, "a"; \ | ||
186 | .long 9999b, 6001f ; \ | ||
187 | .previous | ||
188 | |||
189 | #define DST(y...) \ | ||
190 | 9999: y; \ | ||
191 | .section __ex_table, "a"; \ | ||
192 | .long 9999b, 6002f ; \ | ||
193 | .previous | ||
194 | |||
195 | /* | 181 | /* |
196 | unsigned int csum_partial_copy_generic (const char *src, char *dst, int len, | 182 | unsigned int csum_partial_copy_generic (const char *src, char *dst, int len, |
197 | int sum, int *src_err_ptr, int *dst_err_ptr) | 183 | int sum, int *src_err_ptr, int *dst_err_ptr) |
@@ -244,28 +230,28 @@ ENTRY(csum_partial_copy_generic) | |||
244 | add a10, a10, a2 /* a10 = end of last 32-byte src chunk */ | 230 | add a10, a10, a2 /* a10 = end of last 32-byte src chunk */ |
245 | .Loop5: | 231 | .Loop5: |
246 | #endif | 232 | #endif |
247 | SRC( l32i a9, a2, 0 ) | 233 | EX(10f) l32i a9, a2, 0 |
248 | SRC( l32i a8, a2, 4 ) | 234 | EX(10f) l32i a8, a2, 4 |
249 | DST( s32i a9, a3, 0 ) | 235 | EX(11f) s32i a9, a3, 0 |
250 | DST( s32i a8, a3, 4 ) | 236 | EX(11f) s32i a8, a3, 4 |
251 | ONES_ADD(a5, a9) | 237 | ONES_ADD(a5, a9) |
252 | ONES_ADD(a5, a8) | 238 | ONES_ADD(a5, a8) |
253 | SRC( l32i a9, a2, 8 ) | 239 | EX(10f) l32i a9, a2, 8 |
254 | SRC( l32i a8, a2, 12 ) | 240 | EX(10f) l32i a8, a2, 12 |
255 | DST( s32i a9, a3, 8 ) | 241 | EX(11f) s32i a9, a3, 8 |
256 | DST( s32i a8, a3, 12 ) | 242 | EX(11f) s32i a8, a3, 12 |
257 | ONES_ADD(a5, a9) | 243 | ONES_ADD(a5, a9) |
258 | ONES_ADD(a5, a8) | 244 | ONES_ADD(a5, a8) |
259 | SRC( l32i a9, a2, 16 ) | 245 | EX(10f) l32i a9, a2, 16 |
260 | SRC( l32i a8, a2, 20 ) | 246 | EX(10f) l32i a8, a2, 20 |
261 | DST( s32i a9, a3, 16 ) | 247 | EX(11f) s32i a9, a3, 16 |
262 | DST( s32i a8, a3, 20 ) | 248 | EX(11f) s32i a8, a3, 20 |
263 | ONES_ADD(a5, a9) | 249 | ONES_ADD(a5, a9) |
264 | ONES_ADD(a5, a8) | 250 | ONES_ADD(a5, a8) |
265 | SRC( l32i a9, a2, 24 ) | 251 | EX(10f) l32i a9, a2, 24 |
266 | SRC( l32i a8, a2, 28 ) | 252 | EX(10f) l32i a8, a2, 28 |
267 | DST( s32i a9, a3, 24 ) | 253 | EX(11f) s32i a9, a3, 24 |
268 | DST( s32i a8, a3, 28 ) | 254 | EX(11f) s32i a8, a3, 28 |
269 | ONES_ADD(a5, a9) | 255 | ONES_ADD(a5, a9) |
270 | ONES_ADD(a5, a8) | 256 | ONES_ADD(a5, a8) |
271 | addi a2, a2, 32 | 257 | addi a2, a2, 32 |
@@ -284,8 +270,8 @@ DST( s32i a8, a3, 28 ) | |||
284 | add a10, a10, a2 /* a10 = end of last 4-byte src chunk */ | 270 | add a10, a10, a2 /* a10 = end of last 4-byte src chunk */ |
285 | .Loop6: | 271 | .Loop6: |
286 | #endif | 272 | #endif |
287 | SRC( l32i a9, a2, 0 ) | 273 | EX(10f) l32i a9, a2, 0 |
288 | DST( s32i a9, a3, 0 ) | 274 | EX(11f) s32i a9, a3, 0 |
289 | ONES_ADD(a5, a9) | 275 | ONES_ADD(a5, a9) |
290 | addi a2, a2, 4 | 276 | addi a2, a2, 4 |
291 | addi a3, a3, 4 | 277 | addi a3, a3, 4 |
@@ -315,8 +301,8 @@ DST( s32i a9, a3, 0 ) | |||
315 | add a10, a10, a2 /* a10 = end of last 2-byte src chunk */ | 301 | add a10, a10, a2 /* a10 = end of last 2-byte src chunk */ |
316 | .Loop7: | 302 | .Loop7: |
317 | #endif | 303 | #endif |
318 | SRC( l16ui a9, a2, 0 ) | 304 | EX(10f) l16ui a9, a2, 0 |
319 | DST( s16i a9, a3, 0 ) | 305 | EX(11f) s16i a9, a3, 0 |
320 | ONES_ADD(a5, a9) | 306 | ONES_ADD(a5, a9) |
321 | addi a2, a2, 2 | 307 | addi a2, a2, 2 |
322 | addi a3, a3, 2 | 308 | addi a3, a3, 2 |
@@ -326,8 +312,8 @@ DST( s16i a9, a3, 0 ) | |||
326 | 4: | 312 | 4: |
327 | /* This section processes a possible trailing odd byte. */ | 313 | /* This section processes a possible trailing odd byte. */ |
328 | _bbci.l a4, 0, 8f /* 1-byte chunk */ | 314 | _bbci.l a4, 0, 8f /* 1-byte chunk */ |
329 | SRC( l8ui a9, a2, 0 ) | 315 | EX(10f) l8ui a9, a2, 0 |
330 | DST( s8i a9, a3, 0 ) | 316 | EX(11f) s8i a9, a3, 0 |
331 | #ifdef __XTENSA_EB__ | 317 | #ifdef __XTENSA_EB__ |
332 | slli a9, a9, 8 /* shift byte to bits 8..15 */ | 318 | slli a9, a9, 8 /* shift byte to bits 8..15 */ |
333 | #endif | 319 | #endif |
@@ -350,10 +336,10 @@ DST( s8i a9, a3, 0 ) | |||
350 | add a10, a10, a2 /* a10 = end of last odd-aligned, 2-byte src chunk */ | 336 | add a10, a10, a2 /* a10 = end of last odd-aligned, 2-byte src chunk */ |
351 | .Loop8: | 337 | .Loop8: |
352 | #endif | 338 | #endif |
353 | SRC( l8ui a9, a2, 0 ) | 339 | EX(10f) l8ui a9, a2, 0 |
354 | SRC( l8ui a8, a2, 1 ) | 340 | EX(10f) l8ui a8, a2, 1 |
355 | DST( s8i a9, a3, 0 ) | 341 | EX(11f) s8i a9, a3, 0 |
356 | DST( s8i a8, a3, 1 ) | 342 | EX(11f) s8i a8, a3, 1 |
357 | #ifdef __XTENSA_EB__ | 343 | #ifdef __XTENSA_EB__ |
358 | slli a9, a9, 8 /* combine into a single 16-bit value */ | 344 | slli a9, a9, 8 /* combine into a single 16-bit value */ |
359 | #else /* for checksum computation */ | 345 | #else /* for checksum computation */ |
@@ -381,7 +367,7 @@ ENDPROC(csum_partial_copy_generic) | |||
381 | a12 = original dst for exception handling | 367 | a12 = original dst for exception handling |
382 | */ | 368 | */ |
383 | 369 | ||
384 | 6001: | 370 | 10: |
385 | _movi a2, -EFAULT | 371 | _movi a2, -EFAULT |
386 | s32i a2, a6, 0 /* src_err_ptr */ | 372 | s32i a2, a6, 0 /* src_err_ptr */ |
387 | 373 | ||
@@ -403,7 +389,7 @@ ENDPROC(csum_partial_copy_generic) | |||
403 | 2: | 389 | 2: |
404 | retw | 390 | retw |
405 | 391 | ||
406 | 6002: | 392 | 11: |
407 | movi a2, -EFAULT | 393 | movi a2, -EFAULT |
408 | s32i a2, a7, 0 /* dst_err_ptr */ | 394 | s32i a2, a7, 0 /* dst_err_ptr */ |
409 | movi a2, 0 | 395 | movi a2, 0 |
diff --git a/arch/xtensa/lib/memset.S b/arch/xtensa/lib/memset.S index 10b8c400f175..7a724edaf4f1 100644 --- a/arch/xtensa/lib/memset.S +++ b/arch/xtensa/lib/memset.S | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <variant/core.h> | 14 | #include <variant/core.h> |
15 | #include <asm/asmmacro.h> | ||
15 | 16 | ||
16 | /* | 17 | /* |
17 | * void *memset(void *dst, int c, size_t length) | 18 | * void *memset(void *dst, int c, size_t length) |
@@ -28,15 +29,6 @@ | |||
28 | * the alignment labels). | 29 | * the alignment labels). |
29 | */ | 30 | */ |
30 | 31 | ||
31 | /* Load or store instructions that may cause exceptions use the EX macro. */ | ||
32 | |||
33 | #define EX(insn,reg1,reg2,offset,handler) \ | ||
34 | 9: insn reg1, reg2, offset; \ | ||
35 | .section __ex_table, "a"; \ | ||
36 | .word 9b, handler; \ | ||
37 | .previous | ||
38 | |||
39 | |||
40 | .text | 32 | .text |
41 | .align 4 | 33 | .align 4 |
42 | .global memset | 34 | .global memset |
@@ -73,10 +65,10 @@ memset: | |||
73 | add a6, a6, a5 # a6 = end of last 16B chunk | 65 | add a6, a6, a5 # a6 = end of last 16B chunk |
74 | #endif /* !XCHAL_HAVE_LOOPS */ | 66 | #endif /* !XCHAL_HAVE_LOOPS */ |
75 | .Loop1: | 67 | .Loop1: |
76 | EX(s32i, a3, a5, 0, memset_fixup) | 68 | EX(10f) s32i a3, a5, 0 |
77 | EX(s32i, a3, a5, 4, memset_fixup) | 69 | EX(10f) s32i a3, a5, 4 |
78 | EX(s32i, a3, a5, 8, memset_fixup) | 70 | EX(10f) s32i a3, a5, 8 |
79 | EX(s32i, a3, a5, 12, memset_fixup) | 71 | EX(10f) s32i a3, a5, 12 |
80 | addi a5, a5, 16 | 72 | addi a5, a5, 16 |
81 | #if !XCHAL_HAVE_LOOPS | 73 | #if !XCHAL_HAVE_LOOPS |
82 | blt a5, a6, .Loop1 | 74 | blt a5, a6, .Loop1 |
@@ -84,23 +76,23 @@ memset: | |||
84 | .Loop1done: | 76 | .Loop1done: |
85 | bbci.l a4, 3, .L2 | 77 | bbci.l a4, 3, .L2 |
86 | # set 8 bytes | 78 | # set 8 bytes |
87 | EX(s32i, a3, a5, 0, memset_fixup) | 79 | EX(10f) s32i a3, a5, 0 |
88 | EX(s32i, a3, a5, 4, memset_fixup) | 80 | EX(10f) s32i a3, a5, 4 |
89 | addi a5, a5, 8 | 81 | addi a5, a5, 8 |
90 | .L2: | 82 | .L2: |
91 | bbci.l a4, 2, .L3 | 83 | bbci.l a4, 2, .L3 |
92 | # set 4 bytes | 84 | # set 4 bytes |
93 | EX(s32i, a3, a5, 0, memset_fixup) | 85 | EX(10f) s32i a3, a5, 0 |
94 | addi a5, a5, 4 | 86 | addi a5, a5, 4 |
95 | .L3: | 87 | .L3: |
96 | bbci.l a4, 1, .L4 | 88 | bbci.l a4, 1, .L4 |
97 | # set 2 bytes | 89 | # set 2 bytes |
98 | EX(s16i, a3, a5, 0, memset_fixup) | 90 | EX(10f) s16i a3, a5, 0 |
99 | addi a5, a5, 2 | 91 | addi a5, a5, 2 |
100 | .L4: | 92 | .L4: |
101 | bbci.l a4, 0, .L5 | 93 | bbci.l a4, 0, .L5 |
102 | # set 1 byte | 94 | # set 1 byte |
103 | EX(s8i, a3, a5, 0, memset_fixup) | 95 | EX(10f) s8i a3, a5, 0 |
104 | .L5: | 96 | .L5: |
105 | .Lret1: | 97 | .Lret1: |
106 | retw | 98 | retw |
@@ -114,7 +106,7 @@ memset: | |||
114 | bbci.l a5, 0, .L20 # branch if dst alignment half-aligned | 106 | bbci.l a5, 0, .L20 # branch if dst alignment half-aligned |
115 | # dst is only byte aligned | 107 | # dst is only byte aligned |
116 | # set 1 byte | 108 | # set 1 byte |
117 | EX(s8i, a3, a5, 0, memset_fixup) | 109 | EX(10f) s8i a3, a5, 0 |
118 | addi a5, a5, 1 | 110 | addi a5, a5, 1 |
119 | addi a4, a4, -1 | 111 | addi a4, a4, -1 |
120 | # now retest if dst aligned | 112 | # now retest if dst aligned |
@@ -122,7 +114,7 @@ memset: | |||
122 | .L20: | 114 | .L20: |
123 | # dst half-aligned | 115 | # dst half-aligned |
124 | # set 2 bytes | 116 | # set 2 bytes |
125 | EX(s16i, a3, a5, 0, memset_fixup) | 117 | EX(10f) s16i a3, a5, 0 |
126 | addi a5, a5, 2 | 118 | addi a5, a5, 2 |
127 | addi a4, a4, -2 | 119 | addi a4, a4, -2 |
128 | j .L0 # dst is now aligned, return to main algorithm | 120 | j .L0 # dst is now aligned, return to main algorithm |
@@ -141,7 +133,7 @@ memset: | |||
141 | add a6, a5, a4 # a6 = ending address | 133 | add a6, a5, a4 # a6 = ending address |
142 | #endif /* !XCHAL_HAVE_LOOPS */ | 134 | #endif /* !XCHAL_HAVE_LOOPS */ |
143 | .Lbyteloop: | 135 | .Lbyteloop: |
144 | EX(s8i, a3, a5, 0, memset_fixup) | 136 | EX(10f) s8i a3, a5, 0 |
145 | addi a5, a5, 1 | 137 | addi a5, a5, 1 |
146 | #if !XCHAL_HAVE_LOOPS | 138 | #if !XCHAL_HAVE_LOOPS |
147 | blt a5, a6, .Lbyteloop | 139 | blt a5, a6, .Lbyteloop |
@@ -155,6 +147,6 @@ memset: | |||
155 | 147 | ||
156 | /* We return zero if a failure occurred. */ | 148 | /* We return zero if a failure occurred. */ |
157 | 149 | ||
158 | memset_fixup: | 150 | 10: |
159 | movi a2, 0 | 151 | movi a2, 0 |
160 | retw | 152 | retw |
diff --git a/arch/xtensa/lib/strncpy_user.S b/arch/xtensa/lib/strncpy_user.S index 1ad0ecf45368..827e1b393f3f 100644 --- a/arch/xtensa/lib/strncpy_user.S +++ b/arch/xtensa/lib/strncpy_user.S | |||
@@ -11,16 +11,9 @@ | |||
11 | * Copyright (C) 2002 Tensilica Inc. | 11 | * Copyright (C) 2002 Tensilica Inc. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <variant/core.h> | ||
15 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
16 | 15 | #include <variant/core.h> | |
17 | /* Load or store instructions that may cause exceptions use the EX macro. */ | 16 | #include <asm/asmmacro.h> |
18 | |||
19 | #define EX(insn,reg1,reg2,offset,handler) \ | ||
20 | 9: insn reg1, reg2, offset; \ | ||
21 | .section __ex_table, "a"; \ | ||
22 | .word 9b, handler; \ | ||
23 | .previous | ||
24 | 17 | ||
25 | /* | 18 | /* |
26 | * char *__strncpy_user(char *dst, const char *src, size_t len) | 19 | * char *__strncpy_user(char *dst, const char *src, size_t len) |
@@ -75,9 +68,9 @@ __strncpy_user: | |||
75 | j .Ldstunaligned | 68 | j .Ldstunaligned |
76 | 69 | ||
77 | .Lsrc1mod2: # src address is odd | 70 | .Lsrc1mod2: # src address is odd |
78 | EX(l8ui, a9, a3, 0, fixup_l) # get byte 0 | 71 | EX(11f) l8ui a9, a3, 0 # get byte 0 |
79 | addi a3, a3, 1 # advance src pointer | 72 | addi a3, a3, 1 # advance src pointer |
80 | EX(s8i, a9, a11, 0, fixup_s) # store byte 0 | 73 | EX(10f) s8i a9, a11, 0 # store byte 0 |
81 | beqz a9, .Lret # if byte 0 is zero | 74 | beqz a9, .Lret # if byte 0 is zero |
82 | addi a11, a11, 1 # advance dst pointer | 75 | addi a11, a11, 1 # advance dst pointer |
83 | addi a4, a4, -1 # decrement len | 76 | addi a4, a4, -1 # decrement len |
@@ -85,16 +78,16 @@ __strncpy_user: | |||
85 | bbci.l a3, 1, .Lsrcaligned # if src is now word-aligned | 78 | bbci.l a3, 1, .Lsrcaligned # if src is now word-aligned |
86 | 79 | ||
87 | .Lsrc2mod4: # src address is 2 mod 4 | 80 | .Lsrc2mod4: # src address is 2 mod 4 |
88 | EX(l8ui, a9, a3, 0, fixup_l) # get byte 0 | 81 | EX(11f) l8ui a9, a3, 0 # get byte 0 |
89 | /* 1-cycle interlock */ | 82 | /* 1-cycle interlock */ |
90 | EX(s8i, a9, a11, 0, fixup_s) # store byte 0 | 83 | EX(10f) s8i a9, a11, 0 # store byte 0 |
91 | beqz a9, .Lret # if byte 0 is zero | 84 | beqz a9, .Lret # if byte 0 is zero |
92 | addi a11, a11, 1 # advance dst pointer | 85 | addi a11, a11, 1 # advance dst pointer |
93 | addi a4, a4, -1 # decrement len | 86 | addi a4, a4, -1 # decrement len |
94 | beqz a4, .Lret # if len is zero | 87 | beqz a4, .Lret # if len is zero |
95 | EX(l8ui, a9, a3, 1, fixup_l) # get byte 0 | 88 | EX(11f) l8ui a9, a3, 1 # get byte 0 |
96 | addi a3, a3, 2 # advance src pointer | 89 | addi a3, a3, 2 # advance src pointer |
97 | EX(s8i, a9, a11, 0, fixup_s) # store byte 0 | 90 | EX(10f) s8i a9, a11, 0 # store byte 0 |
98 | beqz a9, .Lret # if byte 0 is zero | 91 | beqz a9, .Lret # if byte 0 is zero |
99 | addi a11, a11, 1 # advance dst pointer | 92 | addi a11, a11, 1 # advance dst pointer |
100 | addi a4, a4, -1 # decrement len | 93 | addi a4, a4, -1 # decrement len |
@@ -117,12 +110,12 @@ __strncpy_user: | |||
117 | add a12, a12, a11 # a12 = end of last 4B chunck | 110 | add a12, a12, a11 # a12 = end of last 4B chunck |
118 | #endif | 111 | #endif |
119 | .Loop1: | 112 | .Loop1: |
120 | EX(l32i, a9, a3, 0, fixup_l) # get word from src | 113 | EX(11f) l32i a9, a3, 0 # get word from src |
121 | addi a3, a3, 4 # advance src pointer | 114 | addi a3, a3, 4 # advance src pointer |
122 | bnone a9, a5, .Lz0 # if byte 0 is zero | 115 | bnone a9, a5, .Lz0 # if byte 0 is zero |
123 | bnone a9, a6, .Lz1 # if byte 1 is zero | 116 | bnone a9, a6, .Lz1 # if byte 1 is zero |
124 | bnone a9, a7, .Lz2 # if byte 2 is zero | 117 | bnone a9, a7, .Lz2 # if byte 2 is zero |
125 | EX(s32i, a9, a11, 0, fixup_s) # store word to dst | 118 | EX(10f) s32i a9, a11, 0 # store word to dst |
126 | bnone a9, a8, .Lz3 # if byte 3 is zero | 119 | bnone a9, a8, .Lz3 # if byte 3 is zero |
127 | addi a11, a11, 4 # advance dst pointer | 120 | addi a11, a11, 4 # advance dst pointer |
128 | #if !XCHAL_HAVE_LOOPS | 121 | #if !XCHAL_HAVE_LOOPS |
@@ -132,7 +125,7 @@ __strncpy_user: | |||
132 | .Loop1done: | 125 | .Loop1done: |
133 | bbci.l a4, 1, .L100 | 126 | bbci.l a4, 1, .L100 |
134 | # copy 2 bytes | 127 | # copy 2 bytes |
135 | EX(l16ui, a9, a3, 0, fixup_l) | 128 | EX(11f) l16ui a9, a3, 0 |
136 | addi a3, a3, 2 # advance src pointer | 129 | addi a3, a3, 2 # advance src pointer |
137 | #ifdef __XTENSA_EB__ | 130 | #ifdef __XTENSA_EB__ |
138 | bnone a9, a7, .Lz0 # if byte 2 is zero | 131 | bnone a9, a7, .Lz0 # if byte 2 is zero |
@@ -141,13 +134,13 @@ __strncpy_user: | |||
141 | bnone a9, a5, .Lz0 # if byte 0 is zero | 134 | bnone a9, a5, .Lz0 # if byte 0 is zero |
142 | bnone a9, a6, .Lz1 # if byte 1 is zero | 135 | bnone a9, a6, .Lz1 # if byte 1 is zero |
143 | #endif | 136 | #endif |
144 | EX(s16i, a9, a11, 0, fixup_s) | 137 | EX(10f) s16i a9, a11, 0 |
145 | addi a11, a11, 2 # advance dst pointer | 138 | addi a11, a11, 2 # advance dst pointer |
146 | .L100: | 139 | .L100: |
147 | bbci.l a4, 0, .Lret | 140 | bbci.l a4, 0, .Lret |
148 | EX(l8ui, a9, a3, 0, fixup_l) | 141 | EX(11f) l8ui a9, a3, 0 |
149 | /* slot */ | 142 | /* slot */ |
150 | EX(s8i, a9, a11, 0, fixup_s) | 143 | EX(10f) s8i a9, a11, 0 |
151 | beqz a9, .Lret # if byte is zero | 144 | beqz a9, .Lret # if byte is zero |
152 | addi a11, a11, 1-3 # advance dst ptr 1, but also cancel | 145 | addi a11, a11, 1-3 # advance dst ptr 1, but also cancel |
153 | # the effect of adding 3 in .Lz3 code | 146 | # the effect of adding 3 in .Lz3 code |
@@ -161,14 +154,14 @@ __strncpy_user: | |||
161 | #ifdef __XTENSA_EB__ | 154 | #ifdef __XTENSA_EB__ |
162 | movi a9, 0 | 155 | movi a9, 0 |
163 | #endif /* __XTENSA_EB__ */ | 156 | #endif /* __XTENSA_EB__ */ |
164 | EX(s8i, a9, a11, 0, fixup_s) | 157 | EX(10f) s8i a9, a11, 0 |
165 | sub a2, a11, a2 # compute strlen | 158 | sub a2, a11, a2 # compute strlen |
166 | retw | 159 | retw |
167 | .Lz1: # byte 1 is zero | 160 | .Lz1: # byte 1 is zero |
168 | #ifdef __XTENSA_EB__ | 161 | #ifdef __XTENSA_EB__ |
169 | extui a9, a9, 16, 16 | 162 | extui a9, a9, 16, 16 |
170 | #endif /* __XTENSA_EB__ */ | 163 | #endif /* __XTENSA_EB__ */ |
171 | EX(s16i, a9, a11, 0, fixup_s) | 164 | EX(10f) s16i a9, a11, 0 |
172 | addi a11, a11, 1 # advance dst pointer | 165 | addi a11, a11, 1 # advance dst pointer |
173 | sub a2, a11, a2 # compute strlen | 166 | sub a2, a11, a2 # compute strlen |
174 | retw | 167 | retw |
@@ -176,9 +169,9 @@ __strncpy_user: | |||
176 | #ifdef __XTENSA_EB__ | 169 | #ifdef __XTENSA_EB__ |
177 | extui a9, a9, 16, 16 | 170 | extui a9, a9, 16, 16 |
178 | #endif /* __XTENSA_EB__ */ | 171 | #endif /* __XTENSA_EB__ */ |
179 | EX(s16i, a9, a11, 0, fixup_s) | 172 | EX(10f) s16i a9, a11, 0 |
180 | movi a9, 0 | 173 | movi a9, 0 |
181 | EX(s8i, a9, a11, 2, fixup_s) | 174 | EX(10f) s8i a9, a11, 2 |
182 | addi a11, a11, 2 # advance dst pointer | 175 | addi a11, a11, 2 # advance dst pointer |
183 | sub a2, a11, a2 # compute strlen | 176 | sub a2, a11, a2 # compute strlen |
184 | retw | 177 | retw |
@@ -196,9 +189,9 @@ __strncpy_user: | |||
196 | add a12, a11, a4 # a12 = ending address | 189 | add a12, a11, a4 # a12 = ending address |
197 | #endif /* XCHAL_HAVE_LOOPS */ | 190 | #endif /* XCHAL_HAVE_LOOPS */ |
198 | .Lnextbyte: | 191 | .Lnextbyte: |
199 | EX(l8ui, a9, a3, 0, fixup_l) | 192 | EX(11f) l8ui a9, a3, 0 |
200 | addi a3, a3, 1 | 193 | addi a3, a3, 1 |
201 | EX(s8i, a9, a11, 0, fixup_s) | 194 | EX(10f) s8i a9, a11, 0 |
202 | beqz a9, .Lunalignedend | 195 | beqz a9, .Lunalignedend |
203 | addi a11, a11, 1 | 196 | addi a11, a11, 1 |
204 | #if !XCHAL_HAVE_LOOPS | 197 | #if !XCHAL_HAVE_LOOPS |
@@ -218,8 +211,7 @@ __strncpy_user: | |||
218 | * implementation in memset(). Thus, we differentiate between | 211 | * implementation in memset(). Thus, we differentiate between |
219 | * load/store fixups. */ | 212 | * load/store fixups. */ |
220 | 213 | ||
221 | fixup_s: | 214 | 10: |
222 | fixup_l: | 215 | 11: |
223 | movi a2, -EFAULT | 216 | movi a2, -EFAULT |
224 | retw | 217 | retw |
225 | |||
diff --git a/arch/xtensa/lib/strnlen_user.S b/arch/xtensa/lib/strnlen_user.S index 4c03b1e581e9..9404ac46ce4c 100644 --- a/arch/xtensa/lib/strnlen_user.S +++ b/arch/xtensa/lib/strnlen_user.S | |||
@@ -12,14 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <variant/core.h> | 14 | #include <variant/core.h> |
15 | 15 | #include <asm/asmmacro.h> | |
16 | /* Load or store instructions that may cause exceptions use the EX macro. */ | ||
17 | |||
18 | #define EX(insn,reg1,reg2,offset,handler) \ | ||
19 | 9: insn reg1, reg2, offset; \ | ||
20 | .section __ex_table, "a"; \ | ||
21 | .word 9b, handler; \ | ||
22 | .previous | ||
23 | 16 | ||
24 | /* | 17 | /* |
25 | * size_t __strnlen_user(const char *s, size_t len) | 18 | * size_t __strnlen_user(const char *s, size_t len) |
@@ -77,7 +70,7 @@ __strnlen_user: | |||
77 | add a10, a10, a4 # a10 = end of last 4B chunk | 70 | add a10, a10, a4 # a10 = end of last 4B chunk |
78 | #endif /* XCHAL_HAVE_LOOPS */ | 71 | #endif /* XCHAL_HAVE_LOOPS */ |
79 | .Loop: | 72 | .Loop: |
80 | EX(l32i, a9, a4, 4, lenfixup) # get next word of string | 73 | EX(10f) l32i a9, a4, 4 # get next word of string |
81 | addi a4, a4, 4 # advance string pointer | 74 | addi a4, a4, 4 # advance string pointer |
82 | bnone a9, a5, .Lz0 # if byte 0 is zero | 75 | bnone a9, a5, .Lz0 # if byte 0 is zero |
83 | bnone a9, a6, .Lz1 # if byte 1 is zero | 76 | bnone a9, a6, .Lz1 # if byte 1 is zero |
@@ -88,7 +81,7 @@ __strnlen_user: | |||
88 | #endif | 81 | #endif |
89 | 82 | ||
90 | .Ldone: | 83 | .Ldone: |
91 | EX(l32i, a9, a4, 4, lenfixup) # load 4 bytes for remaining checks | 84 | EX(10f) l32i a9, a4, 4 # load 4 bytes for remaining checks |
92 | 85 | ||
93 | bbci.l a3, 1, .L100 | 86 | bbci.l a3, 1, .L100 |
94 | # check two more bytes (bytes 0, 1 of word) | 87 | # check two more bytes (bytes 0, 1 of word) |
@@ -125,14 +118,14 @@ __strnlen_user: | |||
125 | retw | 118 | retw |
126 | 119 | ||
127 | .L1mod2: # address is odd | 120 | .L1mod2: # address is odd |
128 | EX(l8ui, a9, a4, 4, lenfixup) # get byte 0 | 121 | EX(10f) l8ui a9, a4, 4 # get byte 0 |
129 | addi a4, a4, 1 # advance string pointer | 122 | addi a4, a4, 1 # advance string pointer |
130 | beqz a9, .Lz3 # if byte 0 is zero | 123 | beqz a9, .Lz3 # if byte 0 is zero |
131 | bbci.l a4, 1, .Laligned # if string pointer is now word-aligned | 124 | bbci.l a4, 1, .Laligned # if string pointer is now word-aligned |
132 | 125 | ||
133 | .L2mod4: # address is 2 mod 4 | 126 | .L2mod4: # address is 2 mod 4 |
134 | addi a4, a4, 2 # advance ptr for aligned access | 127 | addi a4, a4, 2 # advance ptr for aligned access |
135 | EX(l32i, a9, a4, 0, lenfixup) # get word with first two bytes of string | 128 | EX(10f) l32i a9, a4, 0 # get word with first two bytes of string |
136 | bnone a9, a7, .Lz2 # if byte 2 (of word, not string) is zero | 129 | bnone a9, a7, .Lz2 # if byte 2 (of word, not string) is zero |
137 | bany a9, a8, .Laligned # if byte 3 (of word, not string) is nonzero | 130 | bany a9, a8, .Laligned # if byte 3 (of word, not string) is nonzero |
138 | # byte 3 is zero | 131 | # byte 3 is zero |
@@ -142,6 +135,6 @@ __strnlen_user: | |||
142 | 135 | ||
143 | .section .fixup, "ax" | 136 | .section .fixup, "ax" |
144 | .align 4 | 137 | .align 4 |
145 | lenfixup: | 138 | 10: |
146 | movi a2, 0 | 139 | movi a2, 0 |
147 | retw | 140 | retw |
diff --git a/arch/xtensa/lib/usercopy.S b/arch/xtensa/lib/usercopy.S index d9cd766bde3e..4172b73b0364 100644 --- a/arch/xtensa/lib/usercopy.S +++ b/arch/xtensa/lib/usercopy.S | |||
@@ -54,6 +54,7 @@ | |||
54 | */ | 54 | */ |
55 | 55 | ||
56 | #include <variant/core.h> | 56 | #include <variant/core.h> |
57 | #include <asm/asmmacro.h> | ||
57 | 58 | ||
58 | #ifdef __XTENSA_EB__ | 59 | #ifdef __XTENSA_EB__ |
59 | #define ALIGN(R, W0, W1) src R, W0, W1 | 60 | #define ALIGN(R, W0, W1) src R, W0, W1 |
@@ -63,15 +64,6 @@ | |||
63 | #define SSA8(R) ssa8l R | 64 | #define SSA8(R) ssa8l R |
64 | #endif | 65 | #endif |
65 | 66 | ||
66 | /* Load or store instructions that may cause exceptions use the EX macro. */ | ||
67 | |||
68 | #define EX(insn,reg1,reg2,offset,handler) \ | ||
69 | 9: insn reg1, reg2, offset; \ | ||
70 | .section __ex_table, "a"; \ | ||
71 | .word 9b, handler; \ | ||
72 | .previous | ||
73 | |||
74 | |||
75 | .text | 67 | .text |
76 | .align 4 | 68 | .align 4 |
77 | .global __xtensa_copy_user | 69 | .global __xtensa_copy_user |
@@ -102,9 +94,9 @@ __xtensa_copy_user: | |||
102 | bltui a4, 7, .Lbytecopy # do short copies byte by byte | 94 | bltui a4, 7, .Lbytecopy # do short copies byte by byte |
103 | 95 | ||
104 | # copy 1 byte | 96 | # copy 1 byte |
105 | EX(l8ui, a6, a3, 0, fixup) | 97 | EX(10f) l8ui a6, a3, 0 |
106 | addi a3, a3, 1 | 98 | addi a3, a3, 1 |
107 | EX(s8i, a6, a5, 0, fixup) | 99 | EX(10f) s8i a6, a5, 0 |
108 | addi a5, a5, 1 | 100 | addi a5, a5, 1 |
109 | addi a4, a4, -1 | 101 | addi a4, a4, -1 |
110 | bbci.l a5, 1, .Ldstaligned # if dst is now aligned, then | 102 | bbci.l a5, 1, .Ldstaligned # if dst is now aligned, then |
@@ -112,11 +104,11 @@ __xtensa_copy_user: | |||
112 | .Ldst2mod4: # dst 16-bit aligned | 104 | .Ldst2mod4: # dst 16-bit aligned |
113 | # copy 2 bytes | 105 | # copy 2 bytes |
114 | bltui a4, 6, .Lbytecopy # do short copies byte by byte | 106 | bltui a4, 6, .Lbytecopy # do short copies byte by byte |
115 | EX(l8ui, a6, a3, 0, fixup) | 107 | EX(10f) l8ui a6, a3, 0 |
116 | EX(l8ui, a7, a3, 1, fixup) | 108 | EX(10f) l8ui a7, a3, 1 |
117 | addi a3, a3, 2 | 109 | addi a3, a3, 2 |
118 | EX(s8i, a6, a5, 0, fixup) | 110 | EX(10f) s8i a6, a5, 0 |
119 | EX(s8i, a7, a5, 1, fixup) | 111 | EX(10f) s8i a7, a5, 1 |
120 | addi a5, a5, 2 | 112 | addi a5, a5, 2 |
121 | addi a4, a4, -2 | 113 | addi a4, a4, -2 |
122 | j .Ldstaligned # dst is now aligned, return to main algorithm | 114 | j .Ldstaligned # dst is now aligned, return to main algorithm |
@@ -135,9 +127,9 @@ __xtensa_copy_user: | |||
135 | add a7, a3, a4 # a7 = end address for source | 127 | add a7, a3, a4 # a7 = end address for source |
136 | #endif /* !XCHAL_HAVE_LOOPS */ | 128 | #endif /* !XCHAL_HAVE_LOOPS */ |
137 | .Lnextbyte: | 129 | .Lnextbyte: |
138 | EX(l8ui, a6, a3, 0, fixup) | 130 | EX(10f) l8ui a6, a3, 0 |
139 | addi a3, a3, 1 | 131 | addi a3, a3, 1 |
140 | EX(s8i, a6, a5, 0, fixup) | 132 | EX(10f) s8i a6, a5, 0 |
141 | addi a5, a5, 1 | 133 | addi a5, a5, 1 |
142 | #if !XCHAL_HAVE_LOOPS | 134 | #if !XCHAL_HAVE_LOOPS |
143 | blt a3, a7, .Lnextbyte | 135 | blt a3, a7, .Lnextbyte |
@@ -161,15 +153,15 @@ __xtensa_copy_user: | |||
161 | add a8, a8, a3 # a8 = end of last 16B source chunk | 153 | add a8, a8, a3 # a8 = end of last 16B source chunk |
162 | #endif /* !XCHAL_HAVE_LOOPS */ | 154 | #endif /* !XCHAL_HAVE_LOOPS */ |
163 | .Loop1: | 155 | .Loop1: |
164 | EX(l32i, a6, a3, 0, fixup) | 156 | EX(10f) l32i a6, a3, 0 |
165 | EX(l32i, a7, a3, 4, fixup) | 157 | EX(10f) l32i a7, a3, 4 |
166 | EX(s32i, a6, a5, 0, fixup) | 158 | EX(10f) s32i a6, a5, 0 |
167 | EX(l32i, a6, a3, 8, fixup) | 159 | EX(10f) l32i a6, a3, 8 |
168 | EX(s32i, a7, a5, 4, fixup) | 160 | EX(10f) s32i a7, a5, 4 |
169 | EX(l32i, a7, a3, 12, fixup) | 161 | EX(10f) l32i a7, a3, 12 |
170 | EX(s32i, a6, a5, 8, fixup) | 162 | EX(10f) s32i a6, a5, 8 |
171 | addi a3, a3, 16 | 163 | addi a3, a3, 16 |
172 | EX(s32i, a7, a5, 12, fixup) | 164 | EX(10f) s32i a7, a5, 12 |
173 | addi a5, a5, 16 | 165 | addi a5, a5, 16 |
174 | #if !XCHAL_HAVE_LOOPS | 166 | #if !XCHAL_HAVE_LOOPS |
175 | blt a3, a8, .Loop1 | 167 | blt a3, a8, .Loop1 |
@@ -177,31 +169,31 @@ __xtensa_copy_user: | |||
177 | .Loop1done: | 169 | .Loop1done: |
178 | bbci.l a4, 3, .L2 | 170 | bbci.l a4, 3, .L2 |
179 | # copy 8 bytes | 171 | # copy 8 bytes |
180 | EX(l32i, a6, a3, 0, fixup) | 172 | EX(10f) l32i a6, a3, 0 |
181 | EX(l32i, a7, a3, 4, fixup) | 173 | EX(10f) l32i a7, a3, 4 |
182 | addi a3, a3, 8 | 174 | addi a3, a3, 8 |
183 | EX(s32i, a6, a5, 0, fixup) | 175 | EX(10f) s32i a6, a5, 0 |
184 | EX(s32i, a7, a5, 4, fixup) | 176 | EX(10f) s32i a7, a5, 4 |
185 | addi a5, a5, 8 | 177 | addi a5, a5, 8 |
186 | .L2: | 178 | .L2: |
187 | bbci.l a4, 2, .L3 | 179 | bbci.l a4, 2, .L3 |
188 | # copy 4 bytes | 180 | # copy 4 bytes |
189 | EX(l32i, a6, a3, 0, fixup) | 181 | EX(10f) l32i a6, a3, 0 |
190 | addi a3, a3, 4 | 182 | addi a3, a3, 4 |
191 | EX(s32i, a6, a5, 0, fixup) | 183 | EX(10f) s32i a6, a5, 0 |
192 | addi a5, a5, 4 | 184 | addi a5, a5, 4 |
193 | .L3: | 185 | .L3: |
194 | bbci.l a4, 1, .L4 | 186 | bbci.l a4, 1, .L4 |
195 | # copy 2 bytes | 187 | # copy 2 bytes |
196 | EX(l16ui, a6, a3, 0, fixup) | 188 | EX(10f) l16ui a6, a3, 0 |
197 | addi a3, a3, 2 | 189 | addi a3, a3, 2 |
198 | EX(s16i, a6, a5, 0, fixup) | 190 | EX(10f) s16i a6, a5, 0 |
199 | addi a5, a5, 2 | 191 | addi a5, a5, 2 |
200 | .L4: | 192 | .L4: |
201 | bbci.l a4, 0, .L5 | 193 | bbci.l a4, 0, .L5 |
202 | # copy 1 byte | 194 | # copy 1 byte |
203 | EX(l8ui, a6, a3, 0, fixup) | 195 | EX(10f) l8ui a6, a3, 0 |
204 | EX(s8i, a6, a5, 0, fixup) | 196 | EX(10f) s8i a6, a5, 0 |
205 | .L5: | 197 | .L5: |
206 | movi a2, 0 # return success for len bytes copied | 198 | movi a2, 0 # return success for len bytes copied |
207 | retw | 199 | retw |
@@ -217,7 +209,7 @@ __xtensa_copy_user: | |||
217 | # copy 16 bytes per iteration for word-aligned dst and unaligned src | 209 | # copy 16 bytes per iteration for word-aligned dst and unaligned src |
218 | and a10, a3, a8 # save unalignment offset for below | 210 | and a10, a3, a8 # save unalignment offset for below |
219 | sub a3, a3, a10 # align a3 (to avoid sim warnings only; not needed for hardware) | 211 | sub a3, a3, a10 # align a3 (to avoid sim warnings only; not needed for hardware) |
220 | EX(l32i, a6, a3, 0, fixup) # load first word | 212 | EX(10f) l32i a6, a3, 0 # load first word |
221 | #if XCHAL_HAVE_LOOPS | 213 | #if XCHAL_HAVE_LOOPS |
222 | loopnez a7, .Loop2done | 214 | loopnez a7, .Loop2done |
223 | #else /* !XCHAL_HAVE_LOOPS */ | 215 | #else /* !XCHAL_HAVE_LOOPS */ |
@@ -226,19 +218,19 @@ __xtensa_copy_user: | |||
226 | add a12, a12, a3 # a12 = end of last 16B source chunk | 218 | add a12, a12, a3 # a12 = end of last 16B source chunk |
227 | #endif /* !XCHAL_HAVE_LOOPS */ | 219 | #endif /* !XCHAL_HAVE_LOOPS */ |
228 | .Loop2: | 220 | .Loop2: |
229 | EX(l32i, a7, a3, 4, fixup) | 221 | EX(10f) l32i a7, a3, 4 |
230 | EX(l32i, a8, a3, 8, fixup) | 222 | EX(10f) l32i a8, a3, 8 |
231 | ALIGN( a6, a6, a7) | 223 | ALIGN( a6, a6, a7) |
232 | EX(s32i, a6, a5, 0, fixup) | 224 | EX(10f) s32i a6, a5, 0 |
233 | EX(l32i, a9, a3, 12, fixup) | 225 | EX(10f) l32i a9, a3, 12 |
234 | ALIGN( a7, a7, a8) | 226 | ALIGN( a7, a7, a8) |
235 | EX(s32i, a7, a5, 4, fixup) | 227 | EX(10f) s32i a7, a5, 4 |
236 | EX(l32i, a6, a3, 16, fixup) | 228 | EX(10f) l32i a6, a3, 16 |
237 | ALIGN( a8, a8, a9) | 229 | ALIGN( a8, a8, a9) |
238 | EX(s32i, a8, a5, 8, fixup) | 230 | EX(10f) s32i a8, a5, 8 |
239 | addi a3, a3, 16 | 231 | addi a3, a3, 16 |
240 | ALIGN( a9, a9, a6) | 232 | ALIGN( a9, a9, a6) |
241 | EX(s32i, a9, a5, 12, fixup) | 233 | EX(10f) s32i a9, a5, 12 |
242 | addi a5, a5, 16 | 234 | addi a5, a5, 16 |
243 | #if !XCHAL_HAVE_LOOPS | 235 | #if !XCHAL_HAVE_LOOPS |
244 | blt a3, a12, .Loop2 | 236 | blt a3, a12, .Loop2 |
@@ -246,39 +238,39 @@ __xtensa_copy_user: | |||
246 | .Loop2done: | 238 | .Loop2done: |
247 | bbci.l a4, 3, .L12 | 239 | bbci.l a4, 3, .L12 |
248 | # copy 8 bytes | 240 | # copy 8 bytes |
249 | EX(l32i, a7, a3, 4, fixup) | 241 | EX(10f) l32i a7, a3, 4 |
250 | EX(l32i, a8, a3, 8, fixup) | 242 | EX(10f) l32i a8, a3, 8 |
251 | ALIGN( a6, a6, a7) | 243 | ALIGN( a6, a6, a7) |
252 | EX(s32i, a6, a5, 0, fixup) | 244 | EX(10f) s32i a6, a5, 0 |
253 | addi a3, a3, 8 | 245 | addi a3, a3, 8 |
254 | ALIGN( a7, a7, a8) | 246 | ALIGN( a7, a7, a8) |
255 | EX(s32i, a7, a5, 4, fixup) | 247 | EX(10f) s32i a7, a5, 4 |
256 | addi a5, a5, 8 | 248 | addi a5, a5, 8 |
257 | mov a6, a8 | 249 | mov a6, a8 |
258 | .L12: | 250 | .L12: |
259 | bbci.l a4, 2, .L13 | 251 | bbci.l a4, 2, .L13 |
260 | # copy 4 bytes | 252 | # copy 4 bytes |
261 | EX(l32i, a7, a3, 4, fixup) | 253 | EX(10f) l32i a7, a3, 4 |
262 | addi a3, a3, 4 | 254 | addi a3, a3, 4 |
263 | ALIGN( a6, a6, a7) | 255 | ALIGN( a6, a6, a7) |
264 | EX(s32i, a6, a5, 0, fixup) | 256 | EX(10f) s32i a6, a5, 0 |
265 | addi a5, a5, 4 | 257 | addi a5, a5, 4 |
266 | mov a6, a7 | 258 | mov a6, a7 |
267 | .L13: | 259 | .L13: |
268 | add a3, a3, a10 # readjust a3 with correct misalignment | 260 | add a3, a3, a10 # readjust a3 with correct misalignment |
269 | bbci.l a4, 1, .L14 | 261 | bbci.l a4, 1, .L14 |
270 | # copy 2 bytes | 262 | # copy 2 bytes |
271 | EX(l8ui, a6, a3, 0, fixup) | 263 | EX(10f) l8ui a6, a3, 0 |
272 | EX(l8ui, a7, a3, 1, fixup) | 264 | EX(10f) l8ui a7, a3, 1 |
273 | addi a3, a3, 2 | 265 | addi a3, a3, 2 |
274 | EX(s8i, a6, a5, 0, fixup) | 266 | EX(10f) s8i a6, a5, 0 |
275 | EX(s8i, a7, a5, 1, fixup) | 267 | EX(10f) s8i a7, a5, 1 |
276 | addi a5, a5, 2 | 268 | addi a5, a5, 2 |
277 | .L14: | 269 | .L14: |
278 | bbci.l a4, 0, .L15 | 270 | bbci.l a4, 0, .L15 |
279 | # copy 1 byte | 271 | # copy 1 byte |
280 | EX(l8ui, a6, a3, 0, fixup) | 272 | EX(10f) l8ui a6, a3, 0 |
281 | EX(s8i, a6, a5, 0, fixup) | 273 | EX(10f) s8i a6, a5, 0 |
282 | .L15: | 274 | .L15: |
283 | movi a2, 0 # return success for len bytes copied | 275 | movi a2, 0 # return success for len bytes copied |
284 | retw | 276 | retw |
@@ -294,7 +286,7 @@ __xtensa_copy_user: | |||
294 | */ | 286 | */ |
295 | 287 | ||
296 | 288 | ||
297 | fixup: | 289 | 10: |
298 | sub a2, a5, a2 /* a2 <-- bytes copied */ | 290 | sub a2, a5, a2 /* a2 <-- bytes copied */ |
299 | sub a2, a11, a2 /* a2 <-- bytes not copied */ | 291 | sub a2, a11, a2 /* a2 <-- bytes not copied */ |
300 | retw | 292 | retw |