https://gcc.gnu.org/g:a40666202d19f2b7dd1290e1c2b0d5e2a010335e
commit r16-6649-ga40666202d19f2b7dd1290e1c2b0d5e2a010335e Author: Stefan Schulze Frielinghaus <[email protected]> Date: Fri Jan 9 15:23:29 2026 +0100 s390: Fix operand modifier c Currently, operand modifier c truncates and extends any integer constant to a signed 8-bit constant whereas the common code implementation just prints the constant unmodified. The modifier was introduced in r0-87728-g963fc8d00baeca matching the new constraint C which ensures that a constant is an 8-bit signed integer. In the machine description, operand modifier c is only used for operands with constraint C. Therefore, there is no immediate need for some special constant printing. Since print_operand() is also used by output_asm_insn(), inline asm is also affected by this. Note, in output_asm_insn() we cannot utilize output_addr_const() since not every CONST_INT is a valid address, i.e., we have up to 32-bit immediates and at most 20-bit (long) displacements. In fact, %cN should behave the same as %N for any CONST_INT operand N, although, this literally means that the output modifier accepts and prints immediates which might be larger than any instruction accepts. Though, regarding accepting or rejecting immediates, this is what constraints et al. are for. Therefore, align %cN and %N. gcc/ChangeLog: * config/s390/s390.cc (print_operand): Align %cN with %N. * config/s390/s390.md: Remove comment. gcc/testsuite/ChangeLog: * gcc.target/s390/asm-constant-1.c: New test. Diff: --- gcc/config/s390/s390.cc | 5 +---- gcc/config/s390/s390.md | 1 - gcc/testsuite/gcc.target/s390/asm-constant-1.c | 27 ++++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index 28a025be4e8d..7b2da25ea649 100644 --- a/gcc/config/s390/s390.cc +++ b/gcc/config/s390/s390.cc @@ -8895,7 +8895,6 @@ print_operand_address (FILE *file, rtx addr) operand). 'b': print integer X as if it's an unsigned byte. - 'c': print integer X as if it's an signed byte. 'e': "end" contiguous bitmask X in either DImode or vector inner mode. 'f': "end" contiguous bitmask X in SImode. 'h': print integer X as if it's a signed halfword. @@ -9190,13 +9189,11 @@ print_operand (FILE *file, rtx x, int code) switch (code) { case 0: + case 'c': break; case 'b': ival &= 0xff; break; - case 'c': - ival = ((ival & 0xff) ^ 0x80) - 0x80; - break; case 'x': ival &= 0xffff; break; diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 21730950edeb..263e2a7defb4 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -38,7 +38,6 @@ ;; %Y: print shift count operand. ;; ;; %b: print integer X as if it's an unsigned byte. -;; %c: print integer X as if it's an signed byte. ;; %x: print integer X as if it's an unsigned halfword. ;; %h: print integer X as if it's a signed halfword. ;; %i: print the first nonzero HImode part of X. diff --git a/gcc/testsuite/gcc.target/s390/asm-constant-1.c b/gcc/testsuite/gcc.target/s390/asm-constant-1.c new file mode 100644 index 000000000000..980bea1cfab0 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/asm-constant-1.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-final { scan-assembler {# 127 127 128 128 32767 32767 32768 32768 2147483647 2147483647 -2147483648 -2147483648} { target { ! lp64 } } } } */ +/* { dg-final { scan-assembler {# 127 127 128 128 32767 32767 32768 32768 2147483647 2147483647 2147483648 2147483648 9223372036854775807 9223372036854775807 -9223372036854775808 -9223372036854775808} { target lp64 } } } */ + +void +test (void) +{ +#ifdef __s390x__ + __asm__ __volatile__ ("# %0 %c0 %1 %c1 %2 %c2 %3 %c3 %4 %c4 %5 %c5 %6 %c6 %7 %c7" :: + "i" (0x7f), + "i" (0x80), + "i" (0x7fff), + "i" (0x8000), + "i" (0x7fffffff), + "i" (0x80000000L), + "i" (0x7fffffffffffffffL), + "i" (0x8000000000000000L)); +#else + __asm__ __volatile__ ("# %0 %c0 %1 %c1 %2 %c2 %3 %c3 %4 %c4 %5 %c5" :: + "i" (0x7f), + "i" (0x80), + "i" (0x7fff), + "i" (0x8000), + "i" (0x7fffffff), + "i" (0x80000000L)); +#endif +}
