arm: Fixes for asm-flags vs thumb1 and ilp32
authorRichard Henderson <richard.henderson@linaro.org>
Tue, 19 Nov 2019 13:14:20 +0000 (13:14 +0000)
committerRichard Henderson <rth@gcc.gnu.org>
Tue, 19 Nov 2019 13:14:20 +0000 (05:14 -0800)
Thumb1 cannot support asm-flags currently, because we don't expose the
flags register to the compiler.  Disable the support for that case.

Adjust the asm-flag-6 test for aarch64 ilp32 correctness.

gcc/
* config/arm/arm-c.c (arm_cpu_builtins): Use def_or_undef_macro
to define __GCC_ASM_FLAG_OUTPUTS__.
* config/arm/arm.c (thumb1_md_asm_adjust): New function.
(arm_option_params_internal): Swap out targetm.md_asm_adjust
depending on TARGET_THUMB1.
* doc/extend.texi (FlagOutputOperands): Document thumb1 restriction.

gcc/testsuite/
* testsuite/gcc.target/arm/asm-flag-3.c: Skip for thumb1.
* testsuite/gcc.target/arm/asm-flag-5.c: Likewise.
* testsuite/gcc.target/arm/asm-flag-6.c: Likewise.
* testsuite/gcc.target/arm/asm-flag-4.c: New test.

* testsuite/gcc.target/aarch64/asm-flag-6.c: Use %w for
asm inputs to cmp instruction for ILP32.

From-SVN: r278443

gcc/ChangeLog
gcc/config/arm/arm-c.c
gcc/config/arm/arm.c
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/asm-flag-6.c
gcc/testsuite/gcc.target/arm/asm-flag-1.c
gcc/testsuite/gcc.target/arm/asm-flag-3.c
gcc/testsuite/gcc.target/arm/asm-flag-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/asm-flag-5.c
gcc/testsuite/gcc.target/arm/asm-flag-6.c

index df949f1..1449ea4 100644 (file)
@@ -1,3 +1,12 @@
+2019-11-19  Richard Henderson  <richard.henderson@linaro.org>
+
+       * config/arm/arm-c.c (arm_cpu_builtins): Use def_or_undef_macro
+       to define __GCC_ASM_FLAG_OUTPUTS__.
+       * config/arm/arm.c (thumb1_md_asm_adjust): New function.
+       (arm_option_params_internal): Swap out targetm.md_asm_adjust
+       depending on TARGET_THUMB1.
+       * doc/extend.texi (FlagOutputOperands): Document thumb1 restriction.
+
 2019-11-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/92549
index c4485ce..546b35a 100644 (file)
@@ -122,7 +122,8 @@ arm_cpu_builtins (struct cpp_reader* pfile)
   if (arm_arch_notm)
     builtin_define ("__ARM_ARCH_ISA_ARM");
   builtin_define ("__APCS_32__");
-  builtin_define ("__GCC_ASM_FLAG_OUTPUTS__");
+
+  def_or_undef_macro (pfile, "__GCC_ASM_FLAG_OUTPUTS__", !TARGET_THUMB1);
 
   def_or_undef_macro (pfile, "__thumb__", TARGET_THUMB);
   def_or_undef_macro (pfile, "__thumb2__", TARGET_THUMB2);
index 1fd30c2..a6b401b 100644 (file)
@@ -325,6 +325,9 @@ static unsigned int arm_hard_regno_nregs (unsigned int, machine_mode);
 static bool arm_hard_regno_mode_ok (unsigned int, machine_mode);
 static bool arm_modes_tieable_p (machine_mode, machine_mode);
 static HOST_WIDE_INT arm_constant_alignment (const_tree, HOST_WIDE_INT);
+static rtx_insn * thumb1_md_asm_adjust (vec<rtx> &, vec<rtx> &,
+                                       vec<const char *> &, vec<rtx> &,
+                                       HARD_REG_SET &);
 \f
 /* Table of machine attributes.  */
 static const struct attribute_spec arm_attribute_table[] =
@@ -2941,6 +2944,11 @@ arm_option_params_internal (void)
   /* For THUMB2, we limit the conditional sequence to one IT block.  */
   if (TARGET_THUMB2)
     max_insns_skipped = MIN (max_insns_skipped, MAX_INSN_PER_IT_BLOCK);
+
+  if (TARGET_THUMB1)
+    targetm.md_asm_adjust = thumb1_md_asm_adjust;
+  else
+    targetm.md_asm_adjust = arm_md_asm_adjust;
 }
 
 /* True if -mflip-thumb should next add an attribute for the default
@@ -32528,6 +32536,23 @@ arm_run_selftests (void)
 #define TARGET_RUN_TARGET_SELFTESTS selftest::arm_run_selftests
 #endif /* CHECKING_P */
 
+/* Worker function for TARGET_MD_ASM_ADJUST, while in thumb1 mode.
+   Unlike the arm version, we do NOT implement asm flag outputs.  */
+
+rtx_insn *
+thumb1_md_asm_adjust (vec<rtx> &outputs, vec<rtx> &/*inputs*/,
+                     vec<const char *> &constraints,
+                     vec<rtx> &/*clobbers*/, HARD_REG_SET &/*clobbered_regs*/)
+{
+  for (unsigned i = 0, n = outputs.length (); i < n; ++i)
+    if (strncmp (constraints[i], "=@cc", 4) == 0)
+      {
+       sorry ("asm flags not supported in thumb1 mode");
+       break;
+      }
+  return NULL;
+}
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-arm.h"
index 1c8ae0d..62a98e9 100644 (file)
@@ -9810,6 +9810,8 @@ signed greater than
 signed less than equal
 @end table
 
+The flag output constraints are not supported in thumb1 mode.
+
 @item x86 family
 The flag output constraints for the x86 family are of the form
 @samp{=@@cc@var{cond}} where @var{cond} is one of the standard
index 51e8e1f..1eb5f3c 100644 (file)
@@ -1,3 +1,13 @@
+2019-11-19  Richard Henderson  <richard.henderson@linaro.org>
+
+       * testsuite/gcc.target/arm/asm-flag-3.c: Skip for thumb1.
+       * testsuite/gcc.target/arm/asm-flag-5.c: Likewise.
+       * testsuite/gcc.target/arm/asm-flag-6.c: Likewise.
+       * testsuite/gcc.target/arm/asm-flag-4.c: New test.
+
+       * testsuite/gcc.target/aarch64/asm-flag-6.c: Use %w for
+       asm inputs to cmp instruction for ILP32.
+
 2019-11-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/92549
index 963b5a4..54d7fbf 100644 (file)
@@ -1,6 +1,12 @@
 /* Executable testcase for 'output flags.'  */
 /* { dg-do run } */
 
+#ifdef __LP64__
+#define W ""
+#else
+#define W "w"
+#endif
+
 int test_bits (long nzcv)
 {
   long n, z, c, v;
@@ -16,7 +22,7 @@ int test_cmps (long x, long y)
 {
   long gt, lt, ge, le;
 
-  __asm__ ("cmp %[x], %[y]"
+  __asm__ ("cmp %"W"[x], %"W"[y]"
           : "=@ccgt"(gt), "=@cclt"(lt), "=@ccge"(ge), "=@ccle"(le)
           : [x] "r"(x), [y] "r"(y));
 
@@ -30,7 +36,7 @@ int test_cmpu (unsigned long x, unsigned long y)
 {
   long gt, lt, ge, le;
 
-  __asm__ ("cmp %[x], %[y]"
+  __asm__ ("cmp %"W"[x], %"W"[y]"
           : "=@cchi"(gt), "=@cclo"(lt), "=@cchs"(ge), "=@ccls"(le)
           : [x] "r"(x), [y] "r"(y));
 
index 9707ebf..97104d3 100644 (file)
@@ -1,6 +1,7 @@
 /* Test the valid @cc<cc> asm flag outputs.  */
 /* { dg-do compile } */
 /* { dg-options "-O" } */
+/* { dg-skip-if "" { arm_thumb1 } } */
 
 #ifndef __GCC_ASM_FLAG_OUTPUTS__
 #error "missing preprocessor define"
index e84e343..e2d6160 100644 (file)
@@ -1,6 +1,7 @@
 /* Test some of the valid @cc<cc> asm flag outputs.  */
 /* { dg-do compile } */
 /* { dg-options "-O" } */
+/* { dg-skip-if "" { arm_thumb1 } } */
 
 #define DO(C) \
 void f##C(void) { char x; asm("" : "=@cc"#C(x)); if (!x) asm(""); asm(""); }
diff --git a/gcc/testsuite/gcc.target/arm/asm-flag-4.c b/gcc/testsuite/gcc.target/arm/asm-flag-4.c
new file mode 100644 (file)
index 0000000..3791cad
--- /dev/null
@@ -0,0 +1,13 @@
+/* Test that we do not ice in thumb1 mode */
+/* { dg-do compile } */
+/* { dg-options "-march=armv4t" } */
+
+void __attribute__((target("arm"))) f(char *out)
+{
+  asm("" : "=@ccne"(out[0]));
+}
+
+void __attribute__((target("thumb"))) g(char *out)
+{
+  asm("" : "=@ccne"(out[0]));  /* { dg-error asm flags not supported } */
+}
index 4d4394e..9a8ff58 100644 (file)
@@ -1,6 +1,7 @@
 /* Test error conditions of asm flag outputs.  */
 /* { dg-do compile } */
 /* { dg-options "" } */
+/* { dg-skip-if "" { arm_thumb1 } } */
 
 void f_B(void) { _Bool x; asm("" : "=@cccc"(x)); }
 void f_c(void) { char x; asm("" : "=@cccc"(x)); }
index 09174e0..d862db4 100644 (file)
@@ -1,5 +1,6 @@
 /* Executable testcase for 'output flags.'  */
 /* { dg-do run } */
+/* { dg-skip-if "" { arm_thumb1 } } */
 
 int test_bits (long nzcv)
 {