diff options
author | Harald Freudenberger <freude@linux.ibm.com> | 2021-07-05 18:22:56 +0200 |
---|---|---|
committer | Vasily Gorbik <gor@linux.ibm.com> | 2021-07-08 22:12:17 +0200 |
commit | 4516f355c55f6da231c494c6d2be7d863d02f13c (patch) | |
tree | a367c568e4ab14b907f9d2eea089b4f70e0f0ebd /arch | |
parent | d26a357fe88e3875bcdf4a167d4182228c7e8964 (diff) |
s390/ap: get rid of register asm in ap_dqap()
This is the second part of the cleanup for the header file ap.h
to remove the register asm statements. This patch deals with
the inline ap_dqap() function where within the assembler code
an odd register of an register pair is to be addressed.
[hca@linux.ibm.com: this intentionally breaks compilation with any
clang compilers prior to llvm-project commit 458eac257377 ("[SystemZ]
Support the 'N' code for the odd register in inline-asm.").
This is hopefully the last clang kernel compile breakage caused by
incompatibilities between gcc and clang.]
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/include/asm/ap.h | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/arch/s390/include/asm/ap.h b/arch/s390/include/asm/ap.h index 3c619aeddbc7..3afbee21dc1f 100644 --- a/arch/s390/include/asm/ap.h +++ b/arch/s390/include/asm/ap.h @@ -379,28 +379,34 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid, size_t *reslength, unsigned long *resgr0) { - register unsigned long reg0 asm("0") = - resgr0 && *resgr0 ? *resgr0 : qid | 0x80000000UL; - register struct ap_queue_status reg1 asm ("1"); - register unsigned long reg2 asm("2") = 0UL; - register unsigned long reg4 asm("4") = (unsigned long) msg; - register unsigned long reg5 asm("5") = (unsigned long) length; - register unsigned long reg6 asm("6") = 0UL; - register unsigned long reg7 asm("7") = 0UL; + unsigned long reg0 = resgr0 && *resgr0 ? *resgr0 : qid | 0x80000000UL; + struct ap_queue_status reg1; + unsigned long reg2; + union register_pair rp1, rp2; + + rp1.even = 0UL; + rp1.odd = 0UL; + rp2.even = (unsigned long)msg; + rp2.odd = (unsigned long)length; asm volatile( - "0: ltgr %[bl],%[bl]\n" /* if avail. buf len is 0 then */ - " jz 2f\n" /* go out of this asm block */ - "1: .long 0xb2ae0064\n" /* DQAP */ - " brc 6,0b\n" /* if partially do again */ - "2:\n" - : "+d" (reg0), "=d" (reg1), "+d" (reg2), - "+d" (reg4), [bl] "+d" (reg5), "+d" (reg6), "+d" (reg7) - : : "cc", "memory"); + " lgr 0,%[reg0]\n" /* qid param into gr0 */ + " lghi 2,0\n" /* 0 into gr2 (res length) */ + "0: ltgr %N[rp2],%N[rp2]\n" /* check buf len */ + " jz 2f\n" /* go out if buf len is 0 */ + "1: .insn rre,0xb2ae0000,%[rp1],%[rp2]\n" + " brc 6,0b\n" /* handle partial complete */ + "2: lgr %[reg0],0\n" /* gr0 (qid + info) into reg0 */ + " lgr %[reg1],1\n" /* gr1 (status) into reg1 */ + " lgr %[reg2],2\n" /* gr2 (res length) into reg2 */ + : [reg0] "+&d" (reg0), [reg1] "=&d" (reg1), [reg2] "=&d" (reg2), + [rp1] "+&d" (rp1.pair), [rp2] "+&d" (rp2.pair) + : + : "cc", "memory", "0", "1", "2"); if (reslength) *reslength = reg2; - if (reg2 != 0 && reg5 == 0) { + if (reg2 != 0 && rp2.odd == 0) { /* * Partially complete, status in gr1 is not set. * Signal the caller that this dqap is only partially received @@ -410,7 +416,7 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid, if (resgr0) *resgr0 = reg0; } else { - *psmid = (((unsigned long long) reg6) << 32) + reg7; + *psmid = (((unsigned long long)rp1.even) << 32) + rp1.odd; if (resgr0) *resgr0 = 0; } |