diff mbox series

[GCC/ARM] Use bitmap to control cmse_nonsecure_call register clearing

Message ID 28e77f12-9596-e398-8957-98c711ed637a@foss.arm.com
State New
Headers show
Series [GCC/ARM] Use bitmap to control cmse_nonsecure_call register clearing | expand

Commit Message

Thomas Preudhomme Nov. 15, 2017, 5:08 p.m. UTC
Hi,

As part of r253256, cmse_nonsecure_entry_clear_before_return has been
rewritten to use auto_sbitmap instead of an integer bitfield to control
which register needs to be cleared. This commit continue this work in
cmse_nonsecure_call_clear_caller_saved.

ChangeLog entry is as follows:

*** gcc/ChangeLog ***

2017-10-16  Thomas Preud'homme  <thomas.preudhomme@arm.com>

	* config/arm/arm.c (cmse_nonsecure_call_clear_caller_saved): Use
	auto_sbitap instead of integer bitfield to control register needing
	clearing.

Testing: bootstrapped on arm-linux-gnueabihf and no regression in the
testsuite.

Is this ok for trunk?

Best regards,

Thomas

Comments

Kyrill Tkachov Nov. 22, 2017, 11:57 a.m. UTC | #1
Hi Thomas,

On 15/11/17 17:08, Thomas Preudhomme wrote:
> Hi,
>
> As part of r253256, cmse_nonsecure_entry_clear_before_return has been
> rewritten to use auto_sbitmap instead of an integer bitfield to control
> which register needs to be cleared. This commit continue this work in
> cmse_nonsecure_call_clear_caller_saved.
>
> ChangeLog entry is as follows:
>
> *** gcc/ChangeLog ***
>
> 2017-10-16  Thomas Preud'homme <thomas.preudhomme@arm.com>
>
>         * config/arm/arm.c (cmse_nonsecure_call_clear_caller_saved): Use
>         auto_sbitap instead of integer bitfield to control register 
> needing
>         clearing.
>
> Testing: bootstrapped on arm-linux-gnueabihf and no regression in the
> testsuite.
>
> Is this ok for trunk?
>

Ok for trunk.
Thanks for this conversion. It's much easier to understand the code
without having to think about the bitmasks and shifts.

Kyrill

> Best regards,
>
> Thomas
Thomas Preudhomme Nov. 22, 2017, 1:34 p.m. UTC | #2
Thanks Kyrill.

Committed the attached rebased patch (same patch but without the last hunk 
because a better fix was done in an earlier commit).

Best regards,

Thomas

On 22/11/17 11:57, Kyrill Tkachov wrote:
> Hi Thomas,
> 
> On 15/11/17 17:08, Thomas Preudhomme wrote:
>> Hi,
>>
>> As part of r253256, cmse_nonsecure_entry_clear_before_return has been
>> rewritten to use auto_sbitmap instead of an integer bitfield to control
>> which register needs to be cleared. This commit continue this work in
>> cmse_nonsecure_call_clear_caller_saved.
>>
>> ChangeLog entry is as follows:
>>
>> *** gcc/ChangeLog ***
>>
>> 2017-10-16  Thomas Preud'homme <thomas.preudhomme@arm.com>
>>
>>         * config/arm/arm.c (cmse_nonsecure_call_clear_caller_saved): Use
>>         auto_sbitap instead of integer bitfield to control register needing
>>         clearing.
>>
>> Testing: bootstrapped on arm-linux-gnueabihf and no regression in the
>> testsuite.
>>
>> Is this ok for trunk?
>>
> 
> Ok for trunk.
> Thanks for this conversion. It's much easier to understand the code
> without having to think about the bitmasks and shifts.
> 
> Kyrill
> 
>> Best regards,
>>
>> Thomas
>
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 106e3edce0d6f2518eb391c436c5213a78d1275b..092cd61d49382101bce9b8c5f04de31965dcdc77 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -17007,10 +17007,11 @@ cmse_nonsecure_call_clear_caller_saved (void)
 
       FOR_BB_INSNS (bb, insn)
 	{
-	  uint64_t to_clear_mask, float_mask;
+	  unsigned address_regnum, regno, maxregno =
+	    TARGET_HARD_FLOAT_ABI ? D7_VFP_REGNUM : NUM_ARG_REGS - 1;
+	  auto_sbitmap to_clear_bitmap (maxregno + 1);
 	  rtx_insn *seq;
 	  rtx pat, call, unspec, reg, cleared_reg, tmp;
-	  unsigned int regno, maxregno;
 	  rtx address;
 	  CUMULATIVE_ARGS args_so_far_v;
 	  cumulative_args_t args_so_far;
@@ -17041,18 +17042,21 @@ cmse_nonsecure_call_clear_caller_saved (void)
 	    continue;
 
 	  /* Determine the caller-saved registers we need to clear.  */
-	  to_clear_mask = (1LL << (NUM_ARG_REGS)) - 1;
-	  maxregno = NUM_ARG_REGS - 1;
+	  bitmap_clear (to_clear_bitmap);
+	  bitmap_set_range (to_clear_bitmap, R0_REGNUM, NUM_ARG_REGS);
+
 	  /* Only look at the caller-saved floating point registers in case of
 	     -mfloat-abi=hard.  For -mfloat-abi=softfp we will be using the
 	     lazy store and loads which clear both caller- and callee-saved
 	     registers.  */
 	  if (TARGET_HARD_FLOAT_ABI)
 	    {
-	      float_mask = (1LL << (D7_VFP_REGNUM + 1)) - 1;
-	      float_mask &= ~((1LL << FIRST_VFP_REGNUM) - 1);
-	      to_clear_mask |= float_mask;
-	      maxregno = D7_VFP_REGNUM;
+	      auto_sbitmap float_bitmap (maxregno + 1);
+
+	      bitmap_clear (float_bitmap);
+	      bitmap_set_range (float_bitmap, FIRST_VFP_REGNUM,
+				D7_VFP_REGNUM - FIRST_VFP_REGNUM + 1);
+	      bitmap_ior (to_clear_bitmap, to_clear_bitmap, float_bitmap);
 	    }
 
 	  /* Make sure the register used to hold the function address is not
@@ -17060,7 +17064,9 @@ cmse_nonsecure_call_clear_caller_saved (void)
 	  address = RTVEC_ELT (XVEC (unspec, 0), 0);
 	  gcc_assert (MEM_P (address));
 	  gcc_assert (REG_P (XEXP (address, 0)));
-	  to_clear_mask &= ~(1LL << REGNO (XEXP (address, 0)));
+	  address_regnum = REGNO (XEXP (address, 0));
+	  if (address_regnum < R0_REGNUM + NUM_ARG_REGS)
+	    bitmap_clear_bit (to_clear_bitmap, address_regnum);
 
 	  /* Set basic block of call insn so that df rescan is performed on
 	     insns inserted here.  */
@@ -17081,6 +17087,7 @@ cmse_nonsecure_call_clear_caller_saved (void)
 	  FOREACH_FUNCTION_ARGS (fntype, arg_type, args_iter)
 	    {
 	      rtx arg_rtx;
+	      uint64_t to_clear_args_mask;
 	      machine_mode arg_mode = TYPE_MODE (arg_type);
 
 	      if (VOID_TYPE_P (arg_type))
@@ -17093,10 +17100,18 @@ cmse_nonsecure_call_clear_caller_saved (void)
 	      arg_rtx = arm_function_arg (args_so_far, arg_mode, arg_type,
 					  true);
 	      gcc_assert (REG_P (arg_rtx));
-	      to_clear_mask
-		&= ~compute_not_to_clear_mask (arg_type, arg_rtx,
-					       REGNO (arg_rtx),
-					       padding_bits_to_clear_ptr);
+	      to_clear_args_mask
+		= compute_not_to_clear_mask (arg_type, arg_rtx,
+					     REGNO (arg_rtx),
+					     padding_bits_to_clear_ptr);
+	      if (to_clear_args_mask)
+		{
+		  for (regno = R0_REGNUM; regno <= maxregno; regno++)
+		    {
+		      if (to_clear_args_mask & (1ULL << regno))
+			bitmap_clear_bit (to_clear_bitmap, regno);
+		    }
+		}
 
 	      first_param = false;
 	    }
@@ -17155,7 +17170,7 @@ cmse_nonsecure_call_clear_caller_saved (void)
 	     call.  */
 	  for (regno = R0_REGNUM; regno <= maxregno; regno++)
 	    {
-	      if (!(to_clear_mask & (1LL << regno)))
+	      if (!bitmap_bit_p (to_clear_bitmap, regno))
 		continue;
 
 	      /* If regno is an even vfp register and its successor is also to
@@ -17164,7 +17179,7 @@ cmse_nonsecure_call_clear_caller_saved (void)
 		{
 		  if (TARGET_VFP_DOUBLE
 		      && VFP_REGNO_OK_FOR_DOUBLE (regno)
-		      && to_clear_mask & (1LL << (regno + 1)))
+		      && bitmap_bit_p (to_clear_bitmap, (regno + 1)))
 		    emit_move_insn (gen_rtx_REG (DFmode, regno++),
 				    CONST0_RTX (DFmode));
 		  else
@@ -17178,7 +17193,6 @@ cmse_nonsecure_call_clear_caller_saved (void)
 	  seq = get_insns ();
 	  end_sequence ();
 	  emit_insn_before (seq, insn);
-
 	}
     }
 }
diff mbox series

Patch

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 9919f54242d9317125a104f9777d76a85de80e9b..7384b96fea0179334a6010b099df68c8e2a0fc32 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -16990,10 +16990,11 @@  cmse_nonsecure_call_clear_caller_saved (void)
 
       FOR_BB_INSNS (bb, insn)
 	{
-	  uint64_t to_clear_mask, float_mask;
+	  unsigned address_regnum, regno, maxregno =
+	    TARGET_HARD_FLOAT_ABI ? D7_VFP_REGNUM : NUM_ARG_REGS - 1;
+	  auto_sbitmap to_clear_bitmap (maxregno + 1);
 	  rtx_insn *seq;
 	  rtx pat, call, unspec, reg, cleared_reg, tmp;
-	  unsigned int regno, maxregno;
 	  rtx address;
 	  CUMULATIVE_ARGS args_so_far_v;
 	  cumulative_args_t args_so_far;
@@ -17024,18 +17025,21 @@  cmse_nonsecure_call_clear_caller_saved (void)
 	    continue;
 
 	  /* Determine the caller-saved registers we need to clear.  */
-	  to_clear_mask = (1LL << (NUM_ARG_REGS)) - 1;
-	  maxregno = NUM_ARG_REGS - 1;
+	  bitmap_clear (to_clear_bitmap);
+	  bitmap_set_range (to_clear_bitmap, R0_REGNUM, NUM_ARG_REGS);
+
 	  /* Only look at the caller-saved floating point registers in case of
 	     -mfloat-abi=hard.  For -mfloat-abi=softfp we will be using the
 	     lazy store and loads which clear both caller- and callee-saved
 	     registers.  */
 	  if (TARGET_HARD_FLOAT_ABI)
 	    {
-	      float_mask = (1LL << (D7_VFP_REGNUM + 1)) - 1;
-	      float_mask &= ~((1LL << FIRST_VFP_REGNUM) - 1);
-	      to_clear_mask |= float_mask;
-	      maxregno = D7_VFP_REGNUM;
+	      auto_sbitmap float_bitmap (maxregno + 1);
+
+	      bitmap_clear (float_bitmap);
+	      bitmap_set_range (float_bitmap, FIRST_VFP_REGNUM,
+				D7_VFP_REGNUM - FIRST_VFP_REGNUM + 1);
+	      bitmap_ior (to_clear_bitmap, to_clear_bitmap, float_bitmap);
 	    }
 
 	  /* Make sure the register used to hold the function address is not
@@ -17043,7 +17047,9 @@  cmse_nonsecure_call_clear_caller_saved (void)
 	  address = RTVEC_ELT (XVEC (unspec, 0), 0);
 	  gcc_assert (MEM_P (address));
 	  gcc_assert (REG_P (XEXP (address, 0)));
-	  to_clear_mask &= ~(1LL << REGNO (XEXP (address, 0)));
+	  address_regnum = REGNO (XEXP (address, 0));
+	  if (address_regnum < R0_REGNUM + NUM_ARG_REGS)
+	    bitmap_clear_bit (to_clear_bitmap, address_regnum);
 
 	  /* Set basic block of call insn so that df rescan is performed on
 	     insns inserted here.  */
@@ -17064,6 +17070,7 @@  cmse_nonsecure_call_clear_caller_saved (void)
 	  FOREACH_FUNCTION_ARGS (fntype, arg_type, args_iter)
 	    {
 	      rtx arg_rtx;
+	      uint64_t to_clear_args_mask;
 	      machine_mode arg_mode = TYPE_MODE (arg_type);
 
 	      if (VOID_TYPE_P (arg_type))
@@ -17076,10 +17083,18 @@  cmse_nonsecure_call_clear_caller_saved (void)
 	      arg_rtx = arm_function_arg (args_so_far, arg_mode, arg_type,
 					  true);
 	      gcc_assert (REG_P (arg_rtx));
-	      to_clear_mask
-		&= ~compute_not_to_clear_mask (arg_type, arg_rtx,
-					       REGNO (arg_rtx),
-					       padding_bits_to_clear_ptr);
+	      to_clear_args_mask
+		= compute_not_to_clear_mask (arg_type, arg_rtx,
+					     REGNO (arg_rtx),
+					     padding_bits_to_clear_ptr);
+	      if (to_clear_args_mask)
+		{
+		  for (regno = R0_REGNUM; regno <= maxregno; regno++)
+		    {
+		      if (to_clear_args_mask & (1ULL << regno))
+			bitmap_clear_bit (to_clear_bitmap, regno);
+		    }
+		}
 
 	      first_param = false;
 	    }
@@ -17138,7 +17153,7 @@  cmse_nonsecure_call_clear_caller_saved (void)
 	     call.  */
 	  for (regno = R0_REGNUM; regno <= maxregno; regno++)
 	    {
-	      if (!(to_clear_mask & (1LL << regno)))
+	      if (!bitmap_bit_p (to_clear_bitmap, regno))
 		continue;
 
 	      /* If regno is an even vfp register and its successor is also to
@@ -17147,7 +17162,7 @@  cmse_nonsecure_call_clear_caller_saved (void)
 		{
 		  if (TARGET_VFP_DOUBLE
 		      && VFP_REGNO_OK_FOR_DOUBLE (regno)
-		      && to_clear_mask & (1LL << (regno + 1)))
+		      && bitmap_bit_p (to_clear_bitmap, (regno + 1)))
 		    emit_move_insn (gen_rtx_REG (DFmode, regno++),
 				    CONST0_RTX (DFmode));
 		  else
@@ -17161,7 +17176,6 @@  cmse_nonsecure_call_clear_caller_saved (void)
 	  seq = get_insns ();
 	  end_sequence ();
 	  emit_insn_before (seq, insn);
-
 	}
     }
 }
@@ -25188,7 +25202,7 @@  cmse_nonsecure_entry_clear_before_return (void)
   if (padding_bits_to_clear != 0)
     {
       rtx reg_rtx;
-      auto_sbitmap to_clear_arg_regs_bitmap (R0_REGNUM + NUM_ARG_REGS);
+      auto_sbitmap to_clear_arg_regs_bitmap (maxregno + 1);
 
       /* Padding bits to clear is not 0 so we know we are dealing with
 	 returning a composite type, which only uses r0.  Let's make sure that