The testcase fails on lfedora1.lf-dev.marist.edu with gcc 15.2.1 and binutils 2.44-6 Here is the reproducer: int main(void) { asm volatile ("csch"); // begin mark: do not remove asm volatile("clfxbr %r9,3,%f0,0"); // 128-bit BFP --> 32-bit unsigned int asm volatile("ipm %r1"); asm volatile ("lghi %r1,1"); // __NR_exit asm volatile ("lghi %r2,0"); // return code = 0 asm volatile ("svc 0"); // terminate process asm volatile ("csch"); // end mark: do not remove return 0; } $ auxprogs/s390-runone -b foo.c $ ./vg-in-place --tool=none ./foo ==2533622== Process terminating with default action of signal 4 (SIGILL) ==2533622== Illegal operand at address 0x80014127A In the trace we see this: if (always) s390_calculate_cc{0x8001406A0}(r2, r3, r4, r5) with r2 == 38 (S390_CC_OP_BFP_128_TO_UINT_32) In s390_calculate_cc: case S390_CC_OP_BFP_128_TO_UINT_32: return S390_CC_FOR_BFP128_UCONVERT(".insn rrf,0xb39e0000", cc_dep1, cc_dep2, cc_ndep); which expands for rounding_mode == 3 to: case S390_BFP_ROUND_PREPARE_SHORT: \ cc = S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,3); \ cc = S390_CC_FOR_BFP_UCONVERT_AUX(opcode,cc_dep1,3); \ break; There is a dead assignment which is highly suspicious. As obvious when inspecting context, the 2nd one needs to go. And it is that macro which is responsible for the build failure. It gets passed an opcode that wants to read 128 bit but only 64 are provided. Removing that macro fixes the problem. However: #define S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,hi,lo,rounding_mode) \ ({ \ union s390x_F128 op = { .i = { hi, lo } }; \ ULong tmp; \ __asm__ volatile ( \ opcode ",%[tmp],%[op]," #rounding_mode ",0\n\t" \ "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=d"(tmp) \ : [op] "f"(op.f) \ : "cc");\ psw >> 28; /* cc */ \ }) This also looks suspicious. How does the compiler know that op.f needs to be put in a register that is valid to identify a floating point register pair ??? There is no gcc constraint for register pairs on s390 AFAICT.
Fixed in 95cf5eed209f38b8d3e1bc61a68278be420c2778. I'm leaving this open. Likely the .insn opcode specification needs to be replaced with the mnemonic.
(In reply to Florian Krohm from comment #0) [...] > This also looks suspicious. How does the compiler know that op.f needs to be > put in > a register that is valid to identify a floating point register pair ??? > There is no gcc constraint for register pairs on s390 AFAICT. No, that should be OK. The compiler knows that the data type of `op.f', Float128 (== long double) requires a register pair when storing it in floating-point registers.
OK, good. Thanks for the explanation. Closing this now.