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 /drivers/s390/cio/qdio.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 'drivers/s390/cio/qdio.h')
-rw-r--r-- | drivers/s390/cio/qdio.h | 192 |
1 files changed, 49 insertions, 143 deletions
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 124569362f02..49bb9e371c32 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
@@ -274,12 +274,11 @@ do_sqbs(unsigned long sch, unsigned char state, int queue, | |||
274 | register unsigned long _sch asm ("1") = sch; | 274 | register unsigned long _sch asm ("1") = sch; |
275 | unsigned long _queuestart = ((unsigned long)queue << 32) | *start; | 275 | unsigned long _queuestart = ((unsigned long)queue << 32) | *start; |
276 | 276 | ||
277 | asm volatile ( | 277 | asm volatile( |
278 | " .insn rsy,0xeb000000008A,%1,0,0(%2)\n\t" | 278 | " .insn rsy,0xeb000000008A,%1,0,0(%2)" |
279 | : "+d" (_ccq), "+d" (_queuestart) | 279 | : "+d" (_ccq), "+d" (_queuestart) |
280 | : "d" ((unsigned long)state), "d" (_sch) | 280 | : "d" ((unsigned long)state), "d" (_sch) |
281 | : "memory", "cc" | 281 | : "memory", "cc"); |
282 | ); | ||
283 | *count = _ccq & 0xff; | 282 | *count = _ccq & 0xff; |
284 | *start = _queuestart & 0xff; | 283 | *start = _queuestart & 0xff; |
285 | 284 | ||
@@ -299,12 +298,11 @@ do_eqbs(unsigned long sch, unsigned char *state, int queue, | |||
299 | unsigned long _queuestart = ((unsigned long)queue << 32) | *start; | 298 | unsigned long _queuestart = ((unsigned long)queue << 32) | *start; |
300 | unsigned long _state = 0; | 299 | unsigned long _state = 0; |
301 | 300 | ||
302 | asm volatile ( | 301 | asm volatile( |
303 | " .insn rrf,0xB99c0000,%1,%2,0,0 \n\t" | 302 | " .insn rrf,0xB99c0000,%1,%2,0,0" |
304 | : "+d" (_ccq), "+d" (_queuestart), "+d" (_state) | 303 | : "+d" (_ccq), "+d" (_queuestart), "+d" (_state) |
305 | : "d" (_sch) | 304 | : "d" (_sch) |
306 | : "memory", "cc" | 305 | : "memory", "cc" ); |
307 | ); | ||
308 | *count = _ccq & 0xff; | 306 | *count = _ccq & 0xff; |
309 | *start = _queuestart & 0xff; | 307 | *start = _queuestart & 0xff; |
310 | *state = _state & 0xff; | 308 | *state = _state & 0xff; |
@@ -319,69 +317,35 @@ do_eqbs(unsigned long sch, unsigned char *state, int queue, | |||
319 | static inline int | 317 | static inline int |
320 | do_siga_sync(struct subchannel_id schid, unsigned int mask1, unsigned int mask2) | 318 | do_siga_sync(struct subchannel_id schid, unsigned int mask1, unsigned int mask2) |
321 | { | 319 | { |
320 | register unsigned long reg0 asm ("0") = 2; | ||
321 | register struct subchannel_id reg1 asm ("1") = schid; | ||
322 | register unsigned long reg2 asm ("2") = mask1; | ||
323 | register unsigned long reg3 asm ("3") = mask2; | ||
322 | int cc; | 324 | int cc; |
323 | 325 | ||
324 | #ifndef CONFIG_64BIT | 326 | asm volatile( |
325 | asm volatile ( | 327 | " siga 0\n" |
326 | "lhi 0,2 \n\t" | 328 | " ipm %0\n" |
327 | "lr 1,%1 \n\t" | 329 | " srl %0,28\n" |
328 | "lr 2,%2 \n\t" | ||
329 | "lr 3,%3 \n\t" | ||
330 | "siga 0 \n\t" | ||
331 | "ipm %0 \n\t" | ||
332 | "srl %0,28 \n\t" | ||
333 | : "=d" (cc) | 330 | : "=d" (cc) |
334 | : "d" (schid), "d" (mask1), "d" (mask2) | 331 | : "d" (reg0), "d" (reg1), "d" (reg2), "d" (reg3) : "cc"); |
335 | : "cc", "0", "1", "2", "3" | ||
336 | ); | ||
337 | #else /* CONFIG_64BIT */ | ||
338 | asm volatile ( | ||
339 | "lghi 0,2 \n\t" | ||
340 | "llgfr 1,%1 \n\t" | ||
341 | "llgfr 2,%2 \n\t" | ||
342 | "llgfr 3,%3 \n\t" | ||
343 | "siga 0 \n\t" | ||
344 | "ipm %0 \n\t" | ||
345 | "srl %0,28 \n\t" | ||
346 | : "=d" (cc) | ||
347 | : "d" (schid), "d" (mask1), "d" (mask2) | ||
348 | : "cc", "0", "1", "2", "3" | ||
349 | ); | ||
350 | #endif /* CONFIG_64BIT */ | ||
351 | return cc; | 332 | return cc; |
352 | } | 333 | } |
353 | 334 | ||
354 | static inline int | 335 | static inline int |
355 | do_siga_input(struct subchannel_id schid, unsigned int mask) | 336 | do_siga_input(struct subchannel_id schid, unsigned int mask) |
356 | { | 337 | { |
338 | register unsigned long reg0 asm ("0") = 1; | ||
339 | register struct subchannel_id reg1 asm ("1") = schid; | ||
340 | register unsigned long reg2 asm ("2") = mask; | ||
357 | int cc; | 341 | int cc; |
358 | 342 | ||
359 | #ifndef CONFIG_64BIT | 343 | asm volatile( |
360 | asm volatile ( | 344 | " siga 0\n" |
361 | "lhi 0,1 \n\t" | 345 | " ipm %0\n" |
362 | "lr 1,%1 \n\t" | 346 | " srl %0,28\n" |
363 | "lr 2,%2 \n\t" | ||
364 | "siga 0 \n\t" | ||
365 | "ipm %0 \n\t" | ||
366 | "srl %0,28 \n\t" | ||
367 | : "=d" (cc) | ||
368 | : "d" (schid), "d" (mask) | ||
369 | : "cc", "0", "1", "2", "memory" | ||
370 | ); | ||
371 | #else /* CONFIG_64BIT */ | ||
372 | asm volatile ( | ||
373 | "lghi 0,1 \n\t" | ||
374 | "llgfr 1,%1 \n\t" | ||
375 | "llgfr 2,%2 \n\t" | ||
376 | "siga 0 \n\t" | ||
377 | "ipm %0 \n\t" | ||
378 | "srl %0,28 \n\t" | ||
379 | : "=d" (cc) | 347 | : "=d" (cc) |
380 | : "d" (schid), "d" (mask) | 348 | : "d" (reg0), "d" (reg1), "d" (reg2) : "cc", "memory"); |
381 | : "cc", "0", "1", "2", "memory" | ||
382 | ); | ||
383 | #endif /* CONFIG_64BIT */ | ||
384 | |||
385 | return cc; | 349 | return cc; |
386 | } | 350 | } |
387 | 351 | ||
@@ -389,93 +353,35 @@ static inline int | |||
389 | do_siga_output(unsigned long schid, unsigned long mask, __u32 *bb, | 353 | do_siga_output(unsigned long schid, unsigned long mask, __u32 *bb, |
390 | unsigned int fc) | 354 | unsigned int fc) |
391 | { | 355 | { |
356 | register unsigned long __fc asm("0") = fc; | ||
357 | register unsigned long __schid asm("1") = schid; | ||
358 | register unsigned long __mask asm("2") = mask; | ||
392 | int cc; | 359 | int cc; |
393 | __u32 busy_bit; | 360 | |
394 | 361 | asm volatile( | |
395 | #ifndef CONFIG_64BIT | 362 | " siga 0\n" |
396 | asm volatile ( | 363 | "0: ipm %0\n" |
397 | "lhi 0,0 \n\t" | 364 | " srl %0,28\n" |
398 | "lr 1,%2 \n\t" | 365 | "1:\n" |
399 | "lr 2,%3 \n\t" | 366 | EX_TABLE(0b,1b) |
400 | "siga 0 \n\t" | 367 | : "=d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask) |
401 | "0:" | 368 | : "0" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) |
402 | "ipm %0 \n\t" | 369 | : "cc", "memory"); |
403 | "srl %0,28 \n\t" | 370 | (*bb) = ((unsigned int) __fc) >> 31; |
404 | "srl 0,31 \n\t" | ||
405 | "lr %1,0 \n\t" | ||
406 | "1: \n\t" | ||
407 | ".section .fixup,\"ax\"\n\t" | ||
408 | "2: \n\t" | ||
409 | "lhi %0,%4 \n\t" | ||
410 | "bras 1,3f \n\t" | ||
411 | ".long 1b \n\t" | ||
412 | "3: \n\t" | ||
413 | "l 1,0(1) \n\t" | ||
414 | "br 1 \n\t" | ||
415 | ".previous \n\t" | ||
416 | ".section __ex_table,\"a\"\n\t" | ||
417 | ".align 4 \n\t" | ||
418 | ".long 0b,2b \n\t" | ||
419 | ".previous \n\t" | ||
420 | : "=d" (cc), "=d" (busy_bit) | ||
421 | : "d" (schid), "d" (mask), | ||
422 | "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) | ||
423 | : "cc", "0", "1", "2", "memory" | ||
424 | ); | ||
425 | #else /* CONFIG_64BIT */ | ||
426 | asm volatile ( | ||
427 | "llgfr 0,%5 \n\t" | ||
428 | "lgr 1,%2 \n\t" | ||
429 | "llgfr 2,%3 \n\t" | ||
430 | "siga 0 \n\t" | ||
431 | "0:" | ||
432 | "ipm %0 \n\t" | ||
433 | "srl %0,28 \n\t" | ||
434 | "srl 0,31 \n\t" | ||
435 | "llgfr %1,0 \n\t" | ||
436 | "1: \n\t" | ||
437 | ".section .fixup,\"ax\"\n\t" | ||
438 | "lghi %0,%4 \n\t" | ||
439 | "jg 1b \n\t" | ||
440 | ".previous\n\t" | ||
441 | ".section __ex_table,\"a\"\n\t" | ||
442 | ".align 8 \n\t" | ||
443 | ".quad 0b,1b \n\t" | ||
444 | ".previous \n\t" | ||
445 | : "=d" (cc), "=d" (busy_bit) | ||
446 | : "d" (schid), "d" (mask), | ||
447 | "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION), "d" (fc) | ||
448 | : "cc", "0", "1", "2", "memory" | ||
449 | ); | ||
450 | #endif /* CONFIG_64BIT */ | ||
451 | |||
452 | (*bb) = busy_bit; | ||
453 | return cc; | 371 | return cc; |
454 | } | 372 | } |
455 | 373 | ||
456 | static inline unsigned long | 374 | static inline unsigned long |
457 | do_clear_global_summary(void) | 375 | do_clear_global_summary(void) |
458 | { | 376 | { |
459 | 377 | register unsigned long __fn asm("1") = 3; | |
460 | unsigned long time; | 378 | register unsigned long __tmp asm("2"); |
461 | 379 | register unsigned long __time asm("3"); | |
462 | #ifndef CONFIG_64BIT | 380 | |
463 | asm volatile ( | 381 | asm volatile( |
464 | "lhi 1,3 \n\t" | 382 | " .insn rre,0xb2650000,2,0" |
465 | ".insn rre,0xb2650000,2,0 \n\t" | 383 | : "+d" (__fn), "=d" (__tmp), "=d" (__time)); |
466 | "lr %0,3 \n\t" | 384 | return __time; |
467 | : "=d" (time) : : "cc", "1", "2", "3" | ||
468 | ); | ||
469 | #else /* CONFIG_64BIT */ | ||
470 | asm volatile ( | ||
471 | "lghi 1,3 \n\t" | ||
472 | ".insn rre,0xb2650000,2,0 \n\t" | ||
473 | "lgr %0,3 \n\t" | ||
474 | : "=d" (time) : : "cc", "1", "2", "3" | ||
475 | ); | ||
476 | #endif /* CONFIG_64BIT */ | ||
477 | |||
478 | return time; | ||
479 | } | 385 | } |
480 | 386 | ||
481 | /* | 387 | /* |