From: Andreas Arnez Date: Mon, 29 Sep 2025 14:11:04 +0000 (+0200) Subject: s390x: Fix inline assembly for STFLE X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=69e975e759c81a7790eb1f0e58881cef64c560c6;p=thirdparty%2Fvalgrind.git s390x: Fix inline assembly for STFLE The inline assembly for emitting the STFLE instruction changes GPR 0, but fails to mention it in the clobber list. Depending on the compiler's mood, this may result in wrong code. A simple fix would be to just add "0" to the clobber list, but for readability it also helps to move the inline assembly to a separate function. So do that. In that function, use an "asm" variable for GPR 0 instead of moving the value back and forth between registers. --- diff --git a/coregrind/m_extension/extension-s390x.c b/coregrind/m_extension/extension-s390x.c index 98b825d9b..a0c2913d4 100644 --- a/coregrind/m_extension/extension-s390x.c +++ b/coregrind/m_extension/extension-s390x.c @@ -902,6 +902,20 @@ static UWord do_extension_DFLTCC(ThreadState* tst, ULong variant) /*--- STFLE (store facility list extended) ---*/ /*---------------------------------------------------------------*/ +static int do_STFLE_insn(void* addr, ULong nwords, ULong* gpr0) +{ + register ULong reg0 asm("0") = *gpr0; + Int cc; + + asm(".insn s,0xb2b00000,%[out]\n" /* stfle */ + "ipm %[cc]\n" + : [out] "=Q"(*(ULong(*)[nwords])addr), [r0] "+d"(reg0), [cc] "=d"(cc) + : + : "cc"); + *gpr0 = reg0; + return cc >> 28; +} + static enum ExtensionError do_extension_STFLE(ThreadState* tst, ULong variant) { Int cc = 0; @@ -972,15 +986,8 @@ static enum ExtensionError do_extension_STFLE(ThreadState* tst, ULong variant) /* 195: unassigned */ | S390_SETBITS(196, 197)), }; - asm("lgr 0,%[r0]\n" - ".insn s,0xb2b00000,%[out]\n" /* stfle */ - "lgr %[r0],0\n" - "ipm %[cc]\n" - "srl %[cc],28\n" - : [out] "=Q"(*(ULong(*)[last_dw + 1])(void*)addr), [r0] "+d"(gpr0), - [cc] "=d"(cc) - : - : "cc"); + + cc = do_STFLE_insn((void*)addr, last_dw + 1, &gpr0); WRITE_GPR(tst, 0, gpr0); if (last_dw > (gpr0 & 0xff))