diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-09-28 10:56:43 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-09-28 10:56:43 -0400 |
commit | 94c12cc7d196bab34aaa98d38521549fa1e5ef76 (patch) | |
tree | 8e0cec0ed44445d74a2cb5160303d6b4dfb1bc31 /include/asm-s390/bitops.h | |
parent | 25d83cbfaa44e1b9170c0941c3ef52ca39f54ccc (diff) |
[S390] Inline assembly cleanup.
Major cleanup of all s390 inline assemblies. They now have a common
coding style. Quite a few have been shortened, mainly by using register
asm variables. Use of the EX_TABLE macro helps as well. The atomic ops,
bit ops and locking inlines new use the Q-constraint if a newer gcc
is used. That results in slightly better code.
Thanks to Christian Borntraeger for proof reading the changes.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'include/asm-s390/bitops.h')
-rw-r--r-- | include/asm-s390/bitops.h | 626 |
1 files changed, 289 insertions, 337 deletions
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h index 0ddcdba79e4a..f79c9b792af1 100644 --- a/include/asm-s390/bitops.h +++ b/include/asm-s390/bitops.h | |||
@@ -67,16 +67,35 @@ extern const char _sb_findmap[]; | |||
67 | #define __BITOPS_AND "nr" | 67 | #define __BITOPS_AND "nr" |
68 | #define __BITOPS_XOR "xr" | 68 | #define __BITOPS_XOR "xr" |
69 | 69 | ||
70 | #define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ | 70 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
71 | __asm__ __volatile__(" l %0,0(%4)\n" \ | 71 | |
72 | "0: lr %1,%0\n" \ | 72 | #define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ |
73 | __op_string " %1,%3\n" \ | 73 | asm volatile( \ |
74 | " cs %0,%1,0(%4)\n" \ | 74 | " l %0,%2\n" \ |
75 | " jl 0b" \ | 75 | "0: lr %1,%0\n" \ |
76 | : "=&d" (__old), "=&d" (__new), \ | 76 | __op_string " %1,%3\n" \ |
77 | "=m" (*(unsigned long *) __addr) \ | 77 | " cs %0,%1,%2\n" \ |
78 | : "d" (__val), "a" (__addr), \ | 78 | " jl 0b" \ |
79 | "m" (*(unsigned long *) __addr) : "cc" ); | 79 | : "=&d" (__old), "=&d" (__new), \ |
80 | "=Q" (*(unsigned long *) __addr) \ | ||
81 | : "d" (__val), "Q" (*(unsigned long *) __addr) \ | ||
82 | : "cc"); | ||
83 | |||
84 | #else /* __GNUC__ */ | ||
85 | |||
86 | #define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ | ||
87 | asm volatile( \ | ||
88 | " l %0,0(%4)\n" \ | ||
89 | "0: lr %1,%0\n" \ | ||
90 | __op_string " %1,%3\n" \ | ||
91 | " cs %0,%1,0(%4)\n" \ | ||
92 | " jl 0b" \ | ||
93 | : "=&d" (__old), "=&d" (__new), \ | ||
94 | "=m" (*(unsigned long *) __addr) \ | ||
95 | : "d" (__val), "a" (__addr), \ | ||
96 | "m" (*(unsigned long *) __addr) : "cc"); | ||
97 | |||
98 | #endif /* __GNUC__ */ | ||
80 | 99 | ||
81 | #else /* __s390x__ */ | 100 | #else /* __s390x__ */ |
82 | 101 | ||
@@ -86,21 +105,41 @@ extern const char _sb_findmap[]; | |||
86 | #define __BITOPS_AND "ngr" | 105 | #define __BITOPS_AND "ngr" |
87 | #define __BITOPS_XOR "xgr" | 106 | #define __BITOPS_XOR "xgr" |
88 | 107 | ||
89 | #define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ | 108 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
90 | __asm__ __volatile__(" lg %0,0(%4)\n" \ | 109 | |
91 | "0: lgr %1,%0\n" \ | 110 | #define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ |
92 | __op_string " %1,%3\n" \ | 111 | asm volatile( \ |
93 | " csg %0,%1,0(%4)\n" \ | 112 | " lg %0,%2\n" \ |
94 | " jl 0b" \ | 113 | "0: lgr %1,%0\n" \ |
95 | : "=&d" (__old), "=&d" (__new), \ | 114 | __op_string " %1,%3\n" \ |
96 | "=m" (*(unsigned long *) __addr) \ | 115 | " csg %0,%1,%2\n" \ |
97 | : "d" (__val), "a" (__addr), \ | 116 | " jl 0b" \ |
98 | "m" (*(unsigned long *) __addr) : "cc" ); | 117 | : "=&d" (__old), "=&d" (__new), \ |
118 | "=Q" (*(unsigned long *) __addr) \ | ||
119 | : "d" (__val), "Q" (*(unsigned long *) __addr) \ | ||
120 | : "cc"); | ||
121 | |||
122 | #else /* __GNUC__ */ | ||
123 | |||
124 | #define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ | ||
125 | asm volatile( \ | ||
126 | " lg %0,0(%4)\n" \ | ||
127 | "0: lgr %1,%0\n" \ | ||
128 | __op_string " %1,%3\n" \ | ||
129 | " csg %0,%1,0(%4)\n" \ | ||
130 | " jl 0b" \ | ||
131 | : "=&d" (__old), "=&d" (__new), \ | ||
132 | "=m" (*(unsigned long *) __addr) \ | ||
133 | : "d" (__val), "a" (__addr), \ | ||
134 | "m" (*(unsigned long *) __addr) : "cc"); | ||
135 | |||
136 | |||
137 | #endif /* __GNUC__ */ | ||
99 | 138 | ||
100 | #endif /* __s390x__ */ | 139 | #endif /* __s390x__ */ |
101 | 140 | ||
102 | #define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE) | 141 | #define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE) |
103 | #define __BITOPS_BARRIER() __asm__ __volatile__ ( "" : : : "memory" ) | 142 | #define __BITOPS_BARRIER() asm volatile("" : : : "memory") |
104 | 143 | ||
105 | #ifdef CONFIG_SMP | 144 | #ifdef CONFIG_SMP |
106 | /* | 145 | /* |
@@ -217,10 +256,10 @@ static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr) | |||
217 | unsigned long addr; | 256 | unsigned long addr; |
218 | 257 | ||
219 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 258 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); |
220 | asm volatile("oc 0(1,%1),0(%2)" | 259 | asm volatile( |
221 | : "=m" (*(char *) addr) | 260 | " oc 0(1,%1),0(%2)" |
222 | : "a" (addr), "a" (_oi_bitmap + (nr & 7)), | 261 | : "=m" (*(char *) addr) : "a" (addr), |
223 | "m" (*(char *) addr) : "cc" ); | 262 | "a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" ); |
224 | } | 263 | } |
225 | 264 | ||
226 | static inline void | 265 | static inline void |
@@ -229,40 +268,7 @@ __constant_set_bit(const unsigned long nr, volatile unsigned long *ptr) | |||
229 | unsigned long addr; | 268 | unsigned long addr; |
230 | 269 | ||
231 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 270 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); |
232 | switch (nr&7) { | 271 | *(unsigned char *) addr |= 1 << (nr & 7); |
233 | case 0: | ||
234 | asm volatile ("oi 0(%1),0x01" : "=m" (*(char *) addr) | ||
235 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
236 | break; | ||
237 | case 1: | ||
238 | asm volatile ("oi 0(%1),0x02" : "=m" (*(char *) addr) | ||
239 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
240 | break; | ||
241 | case 2: | ||
242 | asm volatile ("oi 0(%1),0x04" : "=m" (*(char *) addr) | ||
243 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
244 | break; | ||
245 | case 3: | ||
246 | asm volatile ("oi 0(%1),0x08" : "=m" (*(char *) addr) | ||
247 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
248 | break; | ||
249 | case 4: | ||
250 | asm volatile ("oi 0(%1),0x10" : "=m" (*(char *) addr) | ||
251 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
252 | break; | ||
253 | case 5: | ||
254 | asm volatile ("oi 0(%1),0x20" : "=m" (*(char *) addr) | ||
255 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
256 | break; | ||
257 | case 6: | ||
258 | asm volatile ("oi 0(%1),0x40" : "=m" (*(char *) addr) | ||
259 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
260 | break; | ||
261 | case 7: | ||
262 | asm volatile ("oi 0(%1),0x80" : "=m" (*(char *) addr) | ||
263 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
264 | break; | ||
265 | } | ||
266 | } | 272 | } |
267 | 273 | ||
268 | #define set_bit_simple(nr,addr) \ | 274 | #define set_bit_simple(nr,addr) \ |
@@ -279,10 +285,10 @@ __clear_bit(unsigned long nr, volatile unsigned long *ptr) | |||
279 | unsigned long addr; | 285 | unsigned long addr; |
280 | 286 | ||
281 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 287 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); |
282 | asm volatile("nc 0(1,%1),0(%2)" | 288 | asm volatile( |
283 | : "=m" (*(char *) addr) | 289 | " nc 0(1,%1),0(%2)" |
284 | : "a" (addr), "a" (_ni_bitmap + (nr & 7)), | 290 | : "=m" (*(char *) addr) : "a" (addr), |
285 | "m" (*(char *) addr) : "cc" ); | 291 | "a" (_ni_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc"); |
286 | } | 292 | } |
287 | 293 | ||
288 | static inline void | 294 | static inline void |
@@ -291,40 +297,7 @@ __constant_clear_bit(const unsigned long nr, volatile unsigned long *ptr) | |||
291 | unsigned long addr; | 297 | unsigned long addr; |
292 | 298 | ||
293 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 299 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); |
294 | switch (nr&7) { | 300 | *(unsigned char *) addr &= ~(1 << (nr & 7)); |
295 | case 0: | ||
296 | asm volatile ("ni 0(%1),0xFE" : "=m" (*(char *) addr) | ||
297 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
298 | break; | ||
299 | case 1: | ||
300 | asm volatile ("ni 0(%1),0xFD": "=m" (*(char *) addr) | ||
301 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
302 | break; | ||
303 | case 2: | ||
304 | asm volatile ("ni 0(%1),0xFB" : "=m" (*(char *) addr) | ||
305 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
306 | break; | ||
307 | case 3: | ||
308 | asm volatile ("ni 0(%1),0xF7" : "=m" (*(char *) addr) | ||
309 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
310 | break; | ||
311 | case 4: | ||
312 | asm volatile ("ni 0(%1),0xEF" : "=m" (*(char *) addr) | ||
313 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
314 | break; | ||
315 | case 5: | ||
316 | asm volatile ("ni 0(%1),0xDF" : "=m" (*(char *) addr) | ||
317 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
318 | break; | ||
319 | case 6: | ||
320 | asm volatile ("ni 0(%1),0xBF" : "=m" (*(char *) addr) | ||
321 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
322 | break; | ||
323 | case 7: | ||
324 | asm volatile ("ni 0(%1),0x7F" : "=m" (*(char *) addr) | ||
325 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
326 | break; | ||
327 | } | ||
328 | } | 301 | } |
329 | 302 | ||
330 | #define clear_bit_simple(nr,addr) \ | 303 | #define clear_bit_simple(nr,addr) \ |
@@ -340,10 +313,10 @@ static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr) | |||
340 | unsigned long addr; | 313 | unsigned long addr; |
341 | 314 | ||
342 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 315 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); |
343 | asm volatile("xc 0(1,%1),0(%2)" | 316 | asm volatile( |
344 | : "=m" (*(char *) addr) | 317 | " xc 0(1,%1),0(%2)" |
345 | : "a" (addr), "a" (_oi_bitmap + (nr & 7)), | 318 | : "=m" (*(char *) addr) : "a" (addr), |
346 | "m" (*(char *) addr) : "cc" ); | 319 | "a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" ); |
347 | } | 320 | } |
348 | 321 | ||
349 | static inline void | 322 | static inline void |
@@ -352,40 +325,7 @@ __constant_change_bit(const unsigned long nr, volatile unsigned long *ptr) | |||
352 | unsigned long addr; | 325 | unsigned long addr; |
353 | 326 | ||
354 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 327 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); |
355 | switch (nr&7) { | 328 | *(unsigned char *) addr ^= 1 << (nr & 7); |
356 | case 0: | ||
357 | asm volatile ("xi 0(%1),0x01" : "=m" (*(char *) addr) | ||
358 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
359 | break; | ||
360 | case 1: | ||
361 | asm volatile ("xi 0(%1),0x02" : "=m" (*(char *) addr) | ||
362 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
363 | break; | ||
364 | case 2: | ||
365 | asm volatile ("xi 0(%1),0x04" : "=m" (*(char *) addr) | ||
366 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
367 | break; | ||
368 | case 3: | ||
369 | asm volatile ("xi 0(%1),0x08" : "=m" (*(char *) addr) | ||
370 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
371 | break; | ||
372 | case 4: | ||
373 | asm volatile ("xi 0(%1),0x10" : "=m" (*(char *) addr) | ||
374 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
375 | break; | ||
376 | case 5: | ||
377 | asm volatile ("xi 0(%1),0x20" : "=m" (*(char *) addr) | ||
378 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
379 | break; | ||
380 | case 6: | ||
381 | asm volatile ("xi 0(%1),0x40" : "=m" (*(char *) addr) | ||
382 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
383 | break; | ||
384 | case 7: | ||
385 | asm volatile ("xi 0(%1),0x80" : "=m" (*(char *) addr) | ||
386 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
387 | break; | ||
388 | } | ||
389 | } | 329 | } |
390 | 330 | ||
391 | #define change_bit_simple(nr,addr) \ | 331 | #define change_bit_simple(nr,addr) \ |
@@ -404,10 +344,11 @@ test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr) | |||
404 | 344 | ||
405 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 345 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); |
406 | ch = *(unsigned char *) addr; | 346 | ch = *(unsigned char *) addr; |
407 | asm volatile("oc 0(1,%1),0(%2)" | 347 | asm volatile( |
408 | : "=m" (*(char *) addr) | 348 | " oc 0(1,%1),0(%2)" |
409 | : "a" (addr), "a" (_oi_bitmap + (nr & 7)), | 349 | : "=m" (*(char *) addr) |
410 | "m" (*(char *) addr) : "cc", "memory" ); | 350 | : "a" (addr), "a" (_oi_bitmap + (nr & 7)), |
351 | "m" (*(char *) addr) : "cc", "memory"); | ||
411 | return (ch >> (nr & 7)) & 1; | 352 | return (ch >> (nr & 7)) & 1; |
412 | } | 353 | } |
413 | #define __test_and_set_bit(X,Y) test_and_set_bit_simple(X,Y) | 354 | #define __test_and_set_bit(X,Y) test_and_set_bit_simple(X,Y) |
@@ -423,10 +364,11 @@ test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr) | |||
423 | 364 | ||
424 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 365 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); |
425 | ch = *(unsigned char *) addr; | 366 | ch = *(unsigned char *) addr; |
426 | asm volatile("nc 0(1,%1),0(%2)" | 367 | asm volatile( |
427 | : "=m" (*(char *) addr) | 368 | " nc 0(1,%1),0(%2)" |
428 | : "a" (addr), "a" (_ni_bitmap + (nr & 7)), | 369 | : "=m" (*(char *) addr) |
429 | "m" (*(char *) addr) : "cc", "memory" ); | 370 | : "a" (addr), "a" (_ni_bitmap + (nr & 7)), |
371 | "m" (*(char *) addr) : "cc", "memory"); | ||
430 | return (ch >> (nr & 7)) & 1; | 372 | return (ch >> (nr & 7)) & 1; |
431 | } | 373 | } |
432 | #define __test_and_clear_bit(X,Y) test_and_clear_bit_simple(X,Y) | 374 | #define __test_and_clear_bit(X,Y) test_and_clear_bit_simple(X,Y) |
@@ -442,10 +384,11 @@ test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr) | |||
442 | 384 | ||
443 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 385 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); |
444 | ch = *(unsigned char *) addr; | 386 | ch = *(unsigned char *) addr; |
445 | asm volatile("xc 0(1,%1),0(%2)" | 387 | asm volatile( |
446 | : "=m" (*(char *) addr) | 388 | " xc 0(1,%1),0(%2)" |
447 | : "a" (addr), "a" (_oi_bitmap + (nr & 7)), | 389 | : "=m" (*(char *) addr) |
448 | "m" (*(char *) addr) : "cc", "memory" ); | 390 | : "a" (addr), "a" (_oi_bitmap + (nr & 7)), |
391 | "m" (*(char *) addr) : "cc", "memory"); | ||
449 | return (ch >> (nr & 7)) & 1; | 392 | return (ch >> (nr & 7)) & 1; |
450 | } | 393 | } |
451 | #define __test_and_change_bit(X,Y) test_and_change_bit_simple(X,Y) | 394 | #define __test_and_change_bit(X,Y) test_and_change_bit_simple(X,Y) |
@@ -557,35 +500,36 @@ find_first_zero_bit(const unsigned long * addr, unsigned long size) | |||
557 | 500 | ||
558 | if (!size) | 501 | if (!size) |
559 | return 0; | 502 | return 0; |
560 | __asm__(" lhi %1,-1\n" | 503 | asm volatile( |
561 | " lr %2,%3\n" | 504 | " lhi %1,-1\n" |
562 | " slr %0,%0\n" | 505 | " lr %2,%3\n" |
563 | " ahi %2,31\n" | 506 | " slr %0,%0\n" |
564 | " srl %2,5\n" | 507 | " ahi %2,31\n" |
565 | "0: c %1,0(%0,%4)\n" | 508 | " srl %2,5\n" |
566 | " jne 1f\n" | 509 | "0: c %1,0(%0,%4)\n" |
567 | " la %0,4(%0)\n" | 510 | " jne 1f\n" |
568 | " brct %2,0b\n" | 511 | " la %0,4(%0)\n" |
569 | " lr %0,%3\n" | 512 | " brct %2,0b\n" |
570 | " j 4f\n" | 513 | " lr %0,%3\n" |
571 | "1: l %2,0(%0,%4)\n" | 514 | " j 4f\n" |
572 | " sll %0,3\n" | 515 | "1: l %2,0(%0,%4)\n" |
573 | " lhi %1,0xff\n" | 516 | " sll %0,3\n" |
574 | " tml %2,0xffff\n" | 517 | " lhi %1,0xff\n" |
575 | " jno 2f\n" | 518 | " tml %2,0xffff\n" |
576 | " ahi %0,16\n" | 519 | " jno 2f\n" |
577 | " srl %2,16\n" | 520 | " ahi %0,16\n" |
578 | "2: tml %2,0x00ff\n" | 521 | " srl %2,16\n" |
579 | " jno 3f\n" | 522 | "2: tml %2,0x00ff\n" |
580 | " ahi %0,8\n" | 523 | " jno 3f\n" |
581 | " srl %2,8\n" | 524 | " ahi %0,8\n" |
582 | "3: nr %2,%1\n" | 525 | " srl %2,8\n" |
583 | " ic %2,0(%2,%5)\n" | 526 | "3: nr %2,%1\n" |
584 | " alr %0,%2\n" | 527 | " ic %2,0(%2,%5)\n" |
585 | "4:" | 528 | " alr %0,%2\n" |
586 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | 529 | "4:" |
587 | : "a" (size), "a" (addr), "a" (&_zb_findmap), | 530 | : "=&a" (res), "=&d" (cmp), "=&a" (count) |
588 | "m" (*(addrtype *) addr) : "cc" ); | 531 | : "a" (size), "a" (addr), "a" (&_zb_findmap), |
532 | "m" (*(addrtype *) addr) : "cc"); | ||
589 | return (res < size) ? res : size; | 533 | return (res < size) ? res : size; |
590 | } | 534 | } |
591 | 535 | ||
@@ -598,35 +542,36 @@ find_first_bit(const unsigned long * addr, unsigned long size) | |||
598 | 542 | ||
599 | if (!size) | 543 | if (!size) |
600 | return 0; | 544 | return 0; |
601 | __asm__(" slr %1,%1\n" | 545 | asm volatile( |
602 | " lr %2,%3\n" | 546 | " slr %1,%1\n" |
603 | " slr %0,%0\n" | 547 | " lr %2,%3\n" |
604 | " ahi %2,31\n" | 548 | " slr %0,%0\n" |
605 | " srl %2,5\n" | 549 | " ahi %2,31\n" |
606 | "0: c %1,0(%0,%4)\n" | 550 | " srl %2,5\n" |
607 | " jne 1f\n" | 551 | "0: c %1,0(%0,%4)\n" |
608 | " la %0,4(%0)\n" | 552 | " jne 1f\n" |
609 | " brct %2,0b\n" | 553 | " la %0,4(%0)\n" |
610 | " lr %0,%3\n" | 554 | " brct %2,0b\n" |
611 | " j 4f\n" | 555 | " lr %0,%3\n" |
612 | "1: l %2,0(%0,%4)\n" | 556 | " j 4f\n" |
613 | " sll %0,3\n" | 557 | "1: l %2,0(%0,%4)\n" |
614 | " lhi %1,0xff\n" | 558 | " sll %0,3\n" |
615 | " tml %2,0xffff\n" | 559 | " lhi %1,0xff\n" |
616 | " jnz 2f\n" | 560 | " tml %2,0xffff\n" |
617 | " ahi %0,16\n" | 561 | " jnz 2f\n" |
618 | " srl %2,16\n" | 562 | " ahi %0,16\n" |
619 | "2: tml %2,0x00ff\n" | 563 | " srl %2,16\n" |
620 | " jnz 3f\n" | 564 | "2: tml %2,0x00ff\n" |
621 | " ahi %0,8\n" | 565 | " jnz 3f\n" |
622 | " srl %2,8\n" | 566 | " ahi %0,8\n" |
623 | "3: nr %2,%1\n" | 567 | " srl %2,8\n" |
624 | " ic %2,0(%2,%5)\n" | 568 | "3: nr %2,%1\n" |
625 | " alr %0,%2\n" | 569 | " ic %2,0(%2,%5)\n" |
626 | "4:" | 570 | " alr %0,%2\n" |
627 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | 571 | "4:" |
628 | : "a" (size), "a" (addr), "a" (&_sb_findmap), | 572 | : "=&a" (res), "=&d" (cmp), "=&a" (count) |
629 | "m" (*(addrtype *) addr) : "cc" ); | 573 | : "a" (size), "a" (addr), "a" (&_sb_findmap), |
574 | "m" (*(addrtype *) addr) : "cc"); | ||
630 | return (res < size) ? res : size; | 575 | return (res < size) ? res : size; |
631 | } | 576 | } |
632 | 577 | ||
@@ -640,39 +585,40 @@ find_first_zero_bit(const unsigned long * addr, unsigned long size) | |||
640 | 585 | ||
641 | if (!size) | 586 | if (!size) |
642 | return 0; | 587 | return 0; |
643 | __asm__(" lghi %1,-1\n" | 588 | asm volatile( |
644 | " lgr %2,%3\n" | 589 | " lghi %1,-1\n" |
645 | " slgr %0,%0\n" | 590 | " lgr %2,%3\n" |
646 | " aghi %2,63\n" | 591 | " slgr %0,%0\n" |
647 | " srlg %2,%2,6\n" | 592 | " aghi %2,63\n" |
648 | "0: cg %1,0(%0,%4)\n" | 593 | " srlg %2,%2,6\n" |
649 | " jne 1f\n" | 594 | "0: cg %1,0(%0,%4)\n" |
650 | " la %0,8(%0)\n" | 595 | " jne 1f\n" |
651 | " brct %2,0b\n" | 596 | " la %0,8(%0)\n" |
652 | " lgr %0,%3\n" | 597 | " brct %2,0b\n" |
653 | " j 5f\n" | 598 | " lgr %0,%3\n" |
654 | "1: lg %2,0(%0,%4)\n" | 599 | " j 5f\n" |
655 | " sllg %0,%0,3\n" | 600 | "1: lg %2,0(%0,%4)\n" |
656 | " clr %2,%1\n" | 601 | " sllg %0,%0,3\n" |
657 | " jne 2f\n" | 602 | " clr %2,%1\n" |
658 | " aghi %0,32\n" | 603 | " jne 2f\n" |
659 | " srlg %2,%2,32\n" | 604 | " aghi %0,32\n" |
660 | "2: lghi %1,0xff\n" | 605 | " srlg %2,%2,32\n" |
661 | " tmll %2,0xffff\n" | 606 | "2: lghi %1,0xff\n" |
662 | " jno 3f\n" | 607 | " tmll %2,0xffff\n" |
663 | " aghi %0,16\n" | 608 | " jno 3f\n" |
664 | " srl %2,16\n" | 609 | " aghi %0,16\n" |
665 | "3: tmll %2,0x00ff\n" | 610 | " srl %2,16\n" |
666 | " jno 4f\n" | 611 | "3: tmll %2,0x00ff\n" |
667 | " aghi %0,8\n" | 612 | " jno 4f\n" |
668 | " srl %2,8\n" | 613 | " aghi %0,8\n" |
669 | "4: ngr %2,%1\n" | 614 | " srl %2,8\n" |
670 | " ic %2,0(%2,%5)\n" | 615 | "4: ngr %2,%1\n" |
671 | " algr %0,%2\n" | 616 | " ic %2,0(%2,%5)\n" |
672 | "5:" | 617 | " algr %0,%2\n" |
673 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | 618 | "5:" |
619 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | ||
674 | : "a" (size), "a" (addr), "a" (&_zb_findmap), | 620 | : "a" (size), "a" (addr), "a" (&_zb_findmap), |
675 | "m" (*(addrtype *) addr) : "cc" ); | 621 | "m" (*(addrtype *) addr) : "cc"); |
676 | return (res < size) ? res : size; | 622 | return (res < size) ? res : size; |
677 | } | 623 | } |
678 | 624 | ||
@@ -684,39 +630,40 @@ find_first_bit(const unsigned long * addr, unsigned long size) | |||
684 | 630 | ||
685 | if (!size) | 631 | if (!size) |
686 | return 0; | 632 | return 0; |
687 | __asm__(" slgr %1,%1\n" | 633 | asm volatile( |
688 | " lgr %2,%3\n" | 634 | " slgr %1,%1\n" |
689 | " slgr %0,%0\n" | 635 | " lgr %2,%3\n" |
690 | " aghi %2,63\n" | 636 | " slgr %0,%0\n" |
691 | " srlg %2,%2,6\n" | 637 | " aghi %2,63\n" |
692 | "0: cg %1,0(%0,%4)\n" | 638 | " srlg %2,%2,6\n" |
693 | " jne 1f\n" | 639 | "0: cg %1,0(%0,%4)\n" |
694 | " aghi %0,8\n" | 640 | " jne 1f\n" |
695 | " brct %2,0b\n" | 641 | " aghi %0,8\n" |
696 | " lgr %0,%3\n" | 642 | " brct %2,0b\n" |
697 | " j 5f\n" | 643 | " lgr %0,%3\n" |
698 | "1: lg %2,0(%0,%4)\n" | 644 | " j 5f\n" |
699 | " sllg %0,%0,3\n" | 645 | "1: lg %2,0(%0,%4)\n" |
700 | " clr %2,%1\n" | 646 | " sllg %0,%0,3\n" |
701 | " jne 2f\n" | 647 | " clr %2,%1\n" |
702 | " aghi %0,32\n" | 648 | " jne 2f\n" |
703 | " srlg %2,%2,32\n" | 649 | " aghi %0,32\n" |
704 | "2: lghi %1,0xff\n" | 650 | " srlg %2,%2,32\n" |
705 | " tmll %2,0xffff\n" | 651 | "2: lghi %1,0xff\n" |
706 | " jnz 3f\n" | 652 | " tmll %2,0xffff\n" |
707 | " aghi %0,16\n" | 653 | " jnz 3f\n" |
708 | " srl %2,16\n" | 654 | " aghi %0,16\n" |
709 | "3: tmll %2,0x00ff\n" | 655 | " srl %2,16\n" |
710 | " jnz 4f\n" | 656 | "3: tmll %2,0x00ff\n" |
711 | " aghi %0,8\n" | 657 | " jnz 4f\n" |
712 | " srl %2,8\n" | 658 | " aghi %0,8\n" |
713 | "4: ngr %2,%1\n" | 659 | " srl %2,8\n" |
714 | " ic %2,0(%2,%5)\n" | 660 | "4: ngr %2,%1\n" |
715 | " algr %0,%2\n" | 661 | " ic %2,0(%2,%5)\n" |
716 | "5:" | 662 | " algr %0,%2\n" |
717 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | 663 | "5:" |
664 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | ||
718 | : "a" (size), "a" (addr), "a" (&_sb_findmap), | 665 | : "a" (size), "a" (addr), "a" (&_sb_findmap), |
719 | "m" (*(addrtype *) addr) : "cc" ); | 666 | "m" (*(addrtype *) addr) : "cc"); |
720 | return (res < size) ? res : size; | 667 | return (res < size) ? res : size; |
721 | } | 668 | } |
722 | 669 | ||
@@ -832,36 +779,37 @@ ext2_find_first_zero_bit(void *vaddr, unsigned int size) | |||
832 | 779 | ||
833 | if (!size) | 780 | if (!size) |
834 | return 0; | 781 | return 0; |
835 | __asm__(" lhi %1,-1\n" | 782 | asm volatile( |
836 | " lr %2,%3\n" | 783 | " lhi %1,-1\n" |
837 | " ahi %2,31\n" | 784 | " lr %2,%3\n" |
838 | " srl %2,5\n" | 785 | " ahi %2,31\n" |
839 | " slr %0,%0\n" | 786 | " srl %2,5\n" |
840 | "0: cl %1,0(%0,%4)\n" | 787 | " slr %0,%0\n" |
841 | " jne 1f\n" | 788 | "0: cl %1,0(%0,%4)\n" |
842 | " ahi %0,4\n" | 789 | " jne 1f\n" |
843 | " brct %2,0b\n" | 790 | " ahi %0,4\n" |
844 | " lr %0,%3\n" | 791 | " brct %2,0b\n" |
845 | " j 4f\n" | 792 | " lr %0,%3\n" |
846 | "1: l %2,0(%0,%4)\n" | 793 | " j 4f\n" |
847 | " sll %0,3\n" | 794 | "1: l %2,0(%0,%4)\n" |
848 | " ahi %0,24\n" | 795 | " sll %0,3\n" |
849 | " lhi %1,0xff\n" | 796 | " ahi %0,24\n" |
850 | " tmh %2,0xffff\n" | 797 | " lhi %1,0xff\n" |
851 | " jo 2f\n" | 798 | " tmh %2,0xffff\n" |
852 | " ahi %0,-16\n" | 799 | " jo 2f\n" |
853 | " srl %2,16\n" | 800 | " ahi %0,-16\n" |
854 | "2: tml %2,0xff00\n" | 801 | " srl %2,16\n" |
855 | " jo 3f\n" | 802 | "2: tml %2,0xff00\n" |
856 | " ahi %0,-8\n" | 803 | " jo 3f\n" |
857 | " srl %2,8\n" | 804 | " ahi %0,-8\n" |
858 | "3: nr %2,%1\n" | 805 | " srl %2,8\n" |
859 | " ic %2,0(%2,%5)\n" | 806 | "3: nr %2,%1\n" |
860 | " alr %0,%2\n" | 807 | " ic %2,0(%2,%5)\n" |
861 | "4:" | 808 | " alr %0,%2\n" |
862 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | 809 | "4:" |
863 | : "a" (size), "a" (vaddr), "a" (&_zb_findmap), | 810 | : "=&a" (res), "=&d" (cmp), "=&a" (count) |
864 | "m" (*(addrtype *) vaddr) : "cc" ); | 811 | : "a" (size), "a" (vaddr), "a" (&_zb_findmap), |
812 | "m" (*(addrtype *) vaddr) : "cc"); | ||
865 | return (res < size) ? res : size; | 813 | return (res < size) ? res : size; |
866 | } | 814 | } |
867 | 815 | ||
@@ -875,39 +823,40 @@ ext2_find_first_zero_bit(void *vaddr, unsigned long size) | |||
875 | 823 | ||
876 | if (!size) | 824 | if (!size) |
877 | return 0; | 825 | return 0; |
878 | __asm__(" lghi %1,-1\n" | 826 | asm volatile( |
879 | " lgr %2,%3\n" | 827 | " lghi %1,-1\n" |
880 | " aghi %2,63\n" | 828 | " lgr %2,%3\n" |
881 | " srlg %2,%2,6\n" | 829 | " aghi %2,63\n" |
882 | " slgr %0,%0\n" | 830 | " srlg %2,%2,6\n" |
883 | "0: clg %1,0(%0,%4)\n" | 831 | " slgr %0,%0\n" |
884 | " jne 1f\n" | 832 | "0: clg %1,0(%0,%4)\n" |
885 | " aghi %0,8\n" | 833 | " jne 1f\n" |
886 | " brct %2,0b\n" | 834 | " aghi %0,8\n" |
887 | " lgr %0,%3\n" | 835 | " brct %2,0b\n" |
888 | " j 5f\n" | 836 | " lgr %0,%3\n" |
889 | "1: cl %1,0(%0,%4)\n" | 837 | " j 5f\n" |
890 | " jne 2f\n" | 838 | "1: cl %1,0(%0,%4)\n" |
891 | " aghi %0,4\n" | 839 | " jne 2f\n" |
892 | "2: l %2,0(%0,%4)\n" | 840 | " aghi %0,4\n" |
893 | " sllg %0,%0,3\n" | 841 | "2: l %2,0(%0,%4)\n" |
894 | " aghi %0,24\n" | 842 | " sllg %0,%0,3\n" |
895 | " lghi %1,0xff\n" | 843 | " aghi %0,24\n" |
896 | " tmlh %2,0xffff\n" | 844 | " lghi %1,0xff\n" |
897 | " jo 3f\n" | 845 | " tmlh %2,0xffff\n" |
898 | " aghi %0,-16\n" | 846 | " jo 3f\n" |
899 | " srl %2,16\n" | 847 | " aghi %0,-16\n" |
900 | "3: tmll %2,0xff00\n" | 848 | " srl %2,16\n" |
901 | " jo 4f\n" | 849 | "3: tmll %2,0xff00\n" |
902 | " aghi %0,-8\n" | 850 | " jo 4f\n" |
903 | " srl %2,8\n" | 851 | " aghi %0,-8\n" |
904 | "4: ngr %2,%1\n" | 852 | " srl %2,8\n" |
905 | " ic %2,0(%2,%5)\n" | 853 | "4: ngr %2,%1\n" |
906 | " algr %0,%2\n" | 854 | " ic %2,0(%2,%5)\n" |
907 | "5:" | 855 | " algr %0,%2\n" |
908 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | 856 | "5:" |
857 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | ||
909 | : "a" (size), "a" (vaddr), "a" (&_zb_findmap), | 858 | : "a" (size), "a" (vaddr), "a" (&_zb_findmap), |
910 | "m" (*(addrtype *) vaddr) : "cc" ); | 859 | "m" (*(addrtype *) vaddr) : "cc"); |
911 | return (res < size) ? res : size; | 860 | return (res < size) ? res : size; |
912 | } | 861 | } |
913 | 862 | ||
@@ -927,13 +876,16 @@ ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset) | |||
927 | p = addr + offset / __BITOPS_WORDSIZE; | 876 | p = addr + offset / __BITOPS_WORDSIZE; |
928 | if (bit) { | 877 | if (bit) { |
929 | #ifndef __s390x__ | 878 | #ifndef __s390x__ |
930 | asm(" ic %0,0(%1)\n" | 879 | asm volatile( |
931 | " icm %0,2,1(%1)\n" | 880 | " ic %0,0(%1)\n" |
932 | " icm %0,4,2(%1)\n" | 881 | " icm %0,2,1(%1)\n" |
933 | " icm %0,8,3(%1)" | 882 | " icm %0,4,2(%1)\n" |
934 | : "=&a" (word) : "a" (p), "m" (*p) : "cc" ); | 883 | " icm %0,8,3(%1)" |
884 | : "=&a" (word) : "a" (p), "m" (*p) : "cc"); | ||
935 | #else | 885 | #else |
936 | asm(" lrvg %0,%1" : "=a" (word) : "m" (*p) ); | 886 | asm volatile( |
887 | " lrvg %0,%1" | ||
888 | : "=a" (word) : "m" (*p) ); | ||
937 | #endif | 889 | #endif |
938 | /* | 890 | /* |
939 | * s390 version of ffz returns __BITOPS_WORDSIZE | 891 | * s390 version of ffz returns __BITOPS_WORDSIZE |