]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
s390: Fix operand modifier c
authorStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>
Fri, 9 Jan 2026 14:23:29 +0000 (15:23 +0100)
committerStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>
Fri, 9 Jan 2026 14:23:29 +0000 (15:23 +0100)
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.

gcc/config/s390/s390.cc
gcc/config/s390/s390.md
gcc/testsuite/gcc.target/s390/asm-constant-1.c [new file with mode: 0644]

index 28a025be4e8d2b2fa4a3238c366086d1a0588950..7b2da25ea6494e329f0c03598cbfaa06a6ec2e89 100644 (file)
@@ -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;
index 21730950edeb205d85963b9878b3425aa78fd215..263e2a7defb4c4ce6fee934c56fb378e74fa9da9 100644 (file)
@@ -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 (file)
index 0000000..980bea1
--- /dev/null
@@ -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
+}