public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/ppalka/heads/integer_class_type)] [PATCH, GCC/ARM, 7/10] Clear all VFP regs inline in hardfloat nscall functions
@ 2020-01-16 20:38 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2020-01-16 20:38 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:1e4f3696a24aa0fcdca2dcadc2c7fc83ba6b2e5d

commit 1e4f3696a24aa0fcdca2dcadc2c7fc83ba6b2e5d
Author: Mihail Ionescu <mihail.ionescu@arm.com>
Date:   Wed Jan 15 11:33:30 2020 +0000

    [PATCH, GCC/ARM, 7/10] Clear all VFP regs inline in hardfloat nscall functions
    
    The patch is fairly straightforward in its approach and consist of the
    following 3 logical changes:
    - abstract the number of floating-point register to clear in
      max_fp_regno
    - use max_fp_regno to decide how many registers to clear so that the
      same code works for Armv8-M and Armv8.1-M Mainline
    - emit vpush and vpop instruction respectively before and after a
      nonsecure call
    
    Note that as in the patch to clear GPRs inline, debug information has to
    be disabled for VPUSH and VPOP due to VPOP adding CFA adjustment note
    for SP when R7 is sometimes used as CFA.
    
    ChangeLog entries are as follows:
    
    *** gcc/ChangeLog ***
    
    2020-01-16  Mihail-Calin Ionescu  <mihail.ionescu@arm.com>
    2020-01-16  Thomas Preud'homme  <thomas.preudhomme@arm.com>
    
    	* config/arm/arm.c (vfp_emit_fstmd): Declare early.
    	(arm_emit_vfp_multi_reg_pop): Likewise.
    	(cmse_nonsecure_call_inline_register_clear): Abstract number of VFP
    	registers to clear in max_fp_regno.  Emit VPUSH and VPOP to save and
    	restore callee-saved VFP registers.
    
    *** gcc/testsuite/ChangeLog ***
    
    2020-01-16  Mihail-Calin Ionescu  <mihail.ionescu@arm.com>
    2020-01-16  Thomas Preud'homme  <thomas.preudhomme@arm.com>
    
    	* gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-13.c: Add check for
    	VPUSH and VPOP and update expectation for VSCCLRM.
    	* gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-7.c: Likewise.
    	* gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-8.c: Likewise.
    	* gcc.target/arm/cmse/mainline/8_1m/hard/cmse-13.c: Likewise.
    	* gcc.target/arm/cmse/mainline/8_1m/hard/cmse-7.c: Likewise.
    	* gcc.target/arm/cmse/mainline/8_1m/hard/cmse-8.c: Likewise.

Diff:
---
 gcc/ChangeLog                                      |  9 +++++
 gcc/config/arm/arm.c                               | 42 +++++++++++++++++++---
 gcc/testsuite/ChangeLog                            | 11 ++++++
 .../arm/cmse/mainline/8_1m/hard-sp/cmse-13.c       |  4 ++-
 .../arm/cmse/mainline/8_1m/hard-sp/cmse-7.c        |  4 ++-
 .../arm/cmse/mainline/8_1m/hard-sp/cmse-8.c        |  4 ++-
 .../arm/cmse/mainline/8_1m/hard/cmse-13.c          |  4 ++-
 .../arm/cmse/mainline/8_1m/hard/cmse-7.c           |  4 ++-
 .../arm/cmse/mainline/8_1m/hard/cmse-8.c           |  4 ++-
 9 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 18767f5..11938ef 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,15 @@
 2020-01-16  Mihail-Calin Ionescu <mihail.ionescu@arm.com>
 2020-01-16  Thomas Preud'homme <thomas.preudhomme@arm.com>
 
+	* config/arm/arm.c (vfp_emit_fstmd): Declare early.
+	(arm_emit_vfp_multi_reg_pop): Likewise.
+	(cmse_nonsecure_call_inline_register_clear): Abstract number of VFP
+	registers to clear in max_fp_regno.  Emit VPUSH and VPOP to save and
+	restore callee-saved VFP registers.
+
+2020-01-16  Mihail-Calin Ionescu  <mihail.ionescu@arm.com>
+2020-01-16  Thomas Preud'homme  <thomas.preudhomme@arm.com>
+
 	* config/arm/arm.c (arm_emit_multi_reg_pop): Declare early.
 	(cmse_nonsecure_call_clear_caller_saved): Rename into ...
 	(cmse_nonsecure_call_inline_register_clear): This.  Save and clear
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 907e92d..2cb2b8e 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -188,6 +188,8 @@ static void emit_constant_insn (rtx cond, rtx pattern);
 static rtx_insn *emit_set_insn (rtx, rtx);
 static rtx emit_multi_reg_push (unsigned long, unsigned long);
 static void arm_emit_multi_reg_pop (unsigned long);
+static int vfp_emit_fstmd (int, int);
+static void arm_emit_vfp_multi_reg_pop (int, int, rtx);
 static int arm_arg_partial_bytes (cumulative_args_t,
 				  const function_arg_info &);
 static rtx arm_function_arg (cumulative_args_t, const function_arg_info &);
@@ -18287,8 +18289,10 @@ cmse_nonsecure_call_inline_register_clear (void)
 	  unsigned address_regnum, regno;
 	  unsigned max_int_regno
 	    = clear_callee_saved ? IP_REGNUM : LAST_ARG_REGNUM;
+	  unsigned max_fp_regno
+	    = TARGET_HAVE_FPCXT_CMSE ? LAST_VFP_REGNUM : D7_VFP_REGNUM;
 	  unsigned maxregno
-	    = TARGET_HARD_FLOAT_ABI ? D7_VFP_REGNUM : max_int_regno;
+	    = TARGET_HARD_FLOAT_ABI ? max_fp_regno : max_int_regno;
 	  auto_sbitmap to_clear_bitmap (maxregno + 1);
 	  rtx_insn *seq;
 	  rtx pat, call, unspec, clearing_reg, ip_reg, shift;
@@ -18336,7 +18340,7 @@ cmse_nonsecure_call_inline_register_clear (void)
 
 	      bitmap_clear (float_bitmap);
 	      bitmap_set_range (float_bitmap, FIRST_VFP_REGNUM,
-				D7_VFP_REGNUM - FIRST_VFP_REGNUM + 1);
+				max_fp_regno - FIRST_VFP_REGNUM + 1);
 	      bitmap_ior (to_clear_bitmap, to_clear_bitmap, float_bitmap);
 	    }
 
@@ -18413,6 +18417,16 @@ cmse_nonsecure_call_inline_register_clear (void)
 	      /* Disable frame debug info in push because it needs to be
 		 disabled for pop (see below).  */
 	      RTX_FRAME_RELATED_P (push_insn) = 0;
+
+	      /* Save VFP callee-saved registers.  */
+	      if (TARGET_HARD_FLOAT_ABI)
+		{
+		  vfp_emit_fstmd (D7_VFP_REGNUM + 1,
+				  (max_fp_regno - D7_VFP_REGNUM) / 2);
+		  /* Disable frame debug info in push because it needs to be
+		     disabled for vpop (see below).  */
+		  RTX_FRAME_RELATED_P (get_last_insn ()) = 0;
+		}
 	    }
 
 	  /* Clear caller-saved registers that leak before doing a non-secure
@@ -18427,9 +18441,25 @@ cmse_nonsecure_call_inline_register_clear (void)
 
 	  if (TARGET_HAVE_FPCXT_CMSE)
 	    {
-	      rtx_insn *next, *pop_insn, *after = insn;
+	      rtx_insn *next, *last, *pop_insn, *after = insn;
 
 	      start_sequence ();
+
+	      /* Restore VFP callee-saved registers.  */
+	      if (TARGET_HARD_FLOAT_ABI)
+		{
+		  int nb_callee_saved_vfp_regs =
+		    (max_fp_regno - D7_VFP_REGNUM) / 2;
+		  arm_emit_vfp_multi_reg_pop (D7_VFP_REGNUM + 1,
+					      nb_callee_saved_vfp_regs,
+					      stack_pointer_rtx);
+		  /* Disable frame debug info in vpop because the SP adjustment
+		     is made using a CFA adjustment note while CFA used is
+		     sometimes R7.  This then causes an assert failure in the
+		     CFI note creation code.  */
+		  RTX_FRAME_RELATED_P (get_last_insn ()) = 0;
+		}
+
 	      arm_emit_multi_reg_pop (callee_saved_mask);
 	      pop_insn = get_last_insn ();
 
@@ -18446,13 +18476,15 @@ cmse_nonsecure_call_inline_register_clear (void)
 		 not reliable.  */
 	      RTX_FRAME_RELATED_P (pop_insn) = 0;
 
+	      seq = get_insns ();
+	      last = get_last_insn ();
 	      end_sequence ();
 
-	      emit_insn_after (pop_insn, after);
+	      emit_insn_after (seq, after);
 
 	      /* Skip pop we have just inserted after nonsecure call, we know
 		 it does not contain a nonsecure call.  */
-	      insn = pop_insn;
+	      insn = last;
 	    }
 	}
     }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 07fd7ff..24ebfcb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,6 +1,17 @@
 2020-01-16  Mihail-Calin Ionescu <mihail.ionescu@arm.com>
 2020-01-16  Thomas Preud'homme <thomas.preudhomme@arm.com>
 
+	* gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-13.c: Add check for
+	VPUSH and VPOP and update expectation for VSCCLRM.
+	* gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-7.c: Likewise.
+	* gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-8.c: Likewise.
+	* gcc.target/arm/cmse/mainline/8_1m/hard/cmse-13.c: Likewise.
+	* gcc.target/arm/cmse/mainline/8_1m/hard/cmse-7.c: Likewise.
+	* gcc.target/arm/cmse/mainline/8_1m/hard/cmse-8.c: Likewise.
+
+2020-01-16  Mihail-Calin Ionescu  <mihail.ionescu@arm.com>
+2020-01-16  Thomas Preud'homme  <thomas.preudhomme@arm.com>
+
 	* gcc.target/arm/cmse/cmse-1.c: Add check for PUSH and POP and update
 	CLRM check.
 	* gcc.target/arm/cmse/cmse-14.c: Likewise.
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-13.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-13.c
index 67ced09..e759db2 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-13.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-13.c
@@ -9,12 +9,14 @@
 /* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
 /* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
 /* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "vpush.64\t\{d8, d9, d10, d11, d12, d13, d14, d15\}" } } */
 /* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
 /* { dg-final { scan-assembler-not "vmov\.f32\ts0, #1\.0" } } */
 /* { dg-final { scan-assembler-not "vmov\.f32\ts2, #1\.0" } } */
 /* { dg-final { scan-assembler-not "vmov\.f32\ts3, #1\.0" } } */
 /* { dg-final { scan-assembler "vscclrm\t\{s1, VPR\}" } } */
-/* { dg-final { scan-assembler "vscclrm\t\{s4-s15, VPR\}" } } */
+/* { dg-final { scan-assembler "vscclrm\t\{s4-s31, VPR\}" } } */
+/* { dg-final { scan-assembler "vldm\tsp!, \{d8-d15\}" } } */
 /* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
 
 /* Now we check that we use the correct intrinsic to call.  */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-7.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-7.c
index a6d9d14..9df7b5d 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-7.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-7.c
@@ -9,8 +9,10 @@
 /* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
 /* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
 /* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "vpush.64\t\{d8, d9, d10, d11, d12, d13, d14, d15\}" } } */
 /* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
-/* { dg-final { scan-assembler "vscclrm\t\{s0-s15, VPR\}" } } */
+/* { dg-final { scan-assembler "vscclrm\t\{s0-s31, VPR\}" } } */
+/* { dg-final { scan-assembler "vldm\tsp!, \{d8-d15\}" } } */
 /* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
 
 /* Now we check that we use the correct intrinsic to call.  */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-8.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-8.c
index ff47635..b36ff73 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-8.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-8.c
@@ -9,10 +9,12 @@
 /* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
 /* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
 /* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "vpush.64\t\{d8, d9, d10, d11, d12, d13, d14, d15\}" } } */
 /* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
 /* { dg-final { scan-assembler-not "vmov\.f32\ts0, #1\.0" } } */
 /* { dg-final { scan-assembler-not "vmov\.f32\ts1, #1\.0" } } */
-/* { dg-final { scan-assembler "vscclrm\t\{s2-s15, VPR\}" } } */
+/* { dg-final { scan-assembler "vscclrm\t\{s2-s31, VPR\}" } } */
+/* { dg-final { scan-assembler "vldm\tsp!, \{d8-d15\}" } } */
 /* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
 
 /* Now we check that we use the correct intrinsic to call.  */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-13.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-13.c
index 952010b..72493f0 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-13.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-13.c
@@ -9,6 +9,7 @@
 /* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
 /* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
 /* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "vpush.64\t\{d8, d9, d10, d11, d12, d13, d14, d15\}" } } */
 /* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
 /* { dg-final { scan-assembler-not "vmov\.f32\ts0, #1\.0" } } */
 /* { dg-final { scan-assembler-not "vmov\.f64\td0, #1\.0" } } */
@@ -16,7 +17,8 @@
 /* { dg-final { scan-assembler-not "vmov\.f32\ts2, #1\.0" } } */
 /* { dg-final { scan-assembler-not "vmov\.f32\ts3, #1\.0" } } */
 /* { dg-final { scan-assembler "vscclrm\t\{s1, VPR\}" } } */
-/* { dg-final { scan-assembler "vscclrm\t\{s4-s15, VPR\}" } } */
+/* { dg-final { scan-assembler "vscclrm\t\{s4-s31, VPR\}" } } */
+/* { dg-final { scan-assembler "vldm\tsp!, \{d8-d15\}" } } */
 /* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
 
 /* Now we check that we use the correct intrinsic to call.  */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-7.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-7.c
index ec12841..112ed78 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-7.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-7.c
@@ -9,8 +9,10 @@
 /* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
 /* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
 /* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "vpush.64\t\{d8, d9, d10, d11, d12, d13, d14, d15\}" } } */
 /* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
-/* { dg-final { scan-assembler "vscclrm\t\{s0-s15, VPR\}" } } */
+/* { dg-final { scan-assembler "vscclrm\t\{s0-s31, VPR\}" } } */
+/* { dg-final { scan-assembler "vldm\tsp!, \{d8-d15\}" } } */
 /* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
 
 /* Now we check that we use the correct intrinsic to call.  */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-8.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-8.c
index d70a58a..f48e8a0 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-8.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-8.c
@@ -9,9 +9,11 @@
 /* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
 /* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
 /* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "vpush.64\t\{d8, d9, d10, d11, d12, d13, d14, d15\}" } } */
 /* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
 /* { dg-final { scan-assembler-not "vmov\.f64\td0, #1\.0" } } */
-/* { dg-final { scan-assembler "vscclrm\t\{s2-s15, VPR\}" } } */
+/* { dg-final { scan-assembler "vscclrm\t\{s2-s31, VPR\}" } } */
+/* { dg-final { scan-assembler "vldm\tsp!, \{d8-d15\}" } } */
 /* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
 
 /* Now we check that we use the correct intrinsic to call.  */


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-01-16 20:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-16 20:38 [gcc(refs/users/ppalka/heads/integer_class_type)] [PATCH, GCC/ARM, 7/10] Clear all VFP regs inline in hardfloat nscall functions Patrick Palka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).