diff mbox series

[GCC/ARM] Do no clobber r4 in Armv8-M nonsecure call

Message ID ab2a5412-7111-af15-00aa-1164b97c2d2e@foss.arm.com
State New
Headers show
Series [GCC/ARM] Do no clobber r4 in Armv8-M nonsecure call | expand

Commit Message

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

Expanders for Armv8-M nonsecure call unnecessarily clobber r4 despite
the libcall they perform not writing to r4.  Furthermore, the
requirement for the branch target address to be in r4 as expected by
the libcall is modeled in a convoluted way in the define_insn patterns:
the address is a register match_operand constrained by the match_dup
for the clobber which is guaranteed to be r4 due to the expander.

This patch simplifies all this by simply requiring the address to be in
r4 and removing the clobbers. Expanders are left alone because
cmse_nonsecure_call_clear_caller_saved relies on branch target memory
attributes which would be lost if expanding to reg:SI R4_REGNUM.

ChangeLog entry is as follows:

*** gcc/ChangeLog ***

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

	* config/arm/arm.md (R4_REGNUM): Define constant.
	(nonsecure_call_internal): Remove r4 clobber.
	(nonsecure_call_value_internal): Likewise.
	* config/arm/thumb1.md (nonsecure_call_reg_thumb1_v5): Remove second
	clobber and resequence match_operands.
	(nonsecure_call_value_reg_thumb1_v5): Likewise.
	* config/arm/thumb2.md (nonsecure_call_reg_thumb2): Likewise.
	(nonsecure_call_value_reg_thumb2): Likewise.

Testing: Bootstrapped on arm-linux-gnueabihf and testsuite shows no
regression.

Is this ok for trunk?

Best regards,

Thomas

Comments

Kyrill Tkachov Nov. 17, 2017, 3:29 p.m. UTC | #1
Hi Thomas,

On 15/11/17 17:14, Thomas Preudhomme wrote:
> Hi,
>
> Expanders for Armv8-M nonsecure call unnecessarily clobber r4 despite
> the libcall they perform not writing to r4.  Furthermore, the
> requirement for the branch target address to be in r4 as expected by
> the libcall is modeled in a convoluted way in the define_insn patterns:
> the address is a register match_operand constrained by the match_dup
> for the clobber which is guaranteed to be r4 due to the expander.
>
> This patch simplifies all this by simply requiring the address to be in
> r4 and removing the clobbers. Expanders are left alone because
> cmse_nonsecure_call_clear_caller_saved relies on branch target memory
> attributes which would be lost if expanding to reg:SI R4_REGNUM.
>
> ChangeLog entry is as follows:
>
> *** gcc/ChangeLog ***
>
> 2017-10-24  Thomas Preud'homme <thomas.preudhomme@arm.com>
>
>         * config/arm/arm.md (R4_REGNUM): Define constant.
>         (nonsecure_call_internal): Remove r4 clobber.
>         (nonsecure_call_value_internal): Likewise.
>         * config/arm/thumb1.md (nonsecure_call_reg_thumb1_v5): Remove 
> second
>         clobber and resequence match_operands.
>         (nonsecure_call_value_reg_thumb1_v5): Likewise.
>         * config/arm/thumb2.md (nonsecure_call_reg_thumb2): Likewise.
>         (nonsecure_call_value_reg_thumb2): Likewise.
>
> Testing: Bootstrapped on arm-linux-gnueabihf and testsuite shows no
> regression.
>
> Is this ok for trunk?
>

Ok.
Thanks,
Kyrill

> Best regards,
>
> Thomas
diff mbox series

Patch

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index ddb9d8f359007c1d86d497aef0ff5fc0e4061813..6b0794ede9fbc5a4f41e1f4a92acb9b649a277bc 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -30,6 +30,7 @@ 
 (define_constants
   [(R0_REGNUM         0)	; First CORE register
    (R1_REGNUM	      1)	; Second CORE register
+   (R4_REGNUM	      4)	; Fifth CORE register
    (IP_REGNUM	     12)	; Scratch register
    (SP_REGNUM	     13)	; Stack pointer
    (LR_REGNUM        14)	; Return address register
@@ -8118,14 +8119,13 @@ 
 			       UNSPEC_NONSECURE_MEM)
 		    (match_operand 1 "general_operand" ""))
 	      (use (match_operand 2 "" ""))
-	      (clobber (reg:SI LR_REGNUM))
-	      (clobber (reg:SI 4))])]
+	      (clobber (reg:SI LR_REGNUM))])]
   "use_cmse"
   "
   {
     rtx tmp;
     tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
-				 gen_rtx_REG (SImode, 4),
+				 gen_rtx_REG (SImode, R4_REGNUM),
 				 SImode);
 
     operands[0] = replace_equiv_address (operands[0], tmp);
@@ -8210,14 +8210,13 @@ 
 				    UNSPEC_NONSECURE_MEM)
 			 (match_operand 2 "general_operand" "")))
 	      (use (match_operand 3 "" ""))
-	      (clobber (reg:SI LR_REGNUM))
-	      (clobber (reg:SI 4))])]
+	      (clobber (reg:SI LR_REGNUM))])]
   "use_cmse"
   "
   {
     rtx tmp;
     tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
-				 gen_rtx_REG (SImode, 4),
+				 gen_rtx_REG (SImode, R4_REGNUM),
 				 SImode);
 
     operands[1] = replace_equiv_address (operands[1], tmp);
diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
index 5d196a673355a7acf7d0ed30f21b997b815913f5..f91659386bf240172bd9a3076722683c8a50dff4 100644
--- a/gcc/config/arm/thumb1.md
+++ b/gcc/config/arm/thumb1.md
@@ -1732,12 +1732,11 @@ 
 )
 
 (define_insn "*nonsecure_call_reg_thumb1_v5"
-  [(call (unspec:SI [(mem:SI (match_operand:SI 0 "register_operand" "l*r"))]
+  [(call (unspec:SI [(mem:SI (reg:SI R4_REGNUM))]
 		    UNSPEC_NONSECURE_MEM)
-	 (match_operand 1 "" ""))
-   (use (match_operand 2 "" ""))
-   (clobber (reg:SI LR_REGNUM))
-   (clobber (match_dup 0))]
+	 (match_operand 0 "" ""))
+   (use (match_operand 1 "" ""))
+   (clobber (reg:SI LR_REGNUM))]
   "TARGET_THUMB1 && use_cmse && !SIBLING_CALL_P (insn)"
   "bl\\t__gnu_cmse_nonsecure_call"
   [(set_attr "length" "4")
@@ -1779,12 +1778,11 @@ 
 (define_insn "*nonsecure_call_value_reg_thumb1_v5"
   [(set (match_operand 0 "" "")
 	(call (unspec:SI
-	       [(mem:SI (match_operand:SI 1 "register_operand" "l*r"))]
+	       [(mem:SI (reg:SI R4_REGNUM))]
 	       UNSPEC_NONSECURE_MEM)
-	      (match_operand 2 "" "")))
-   (use (match_operand 3 "" ""))
-   (clobber (reg:SI LR_REGNUM))
-   (clobber (match_dup 1))]
+	      (match_operand 1 "" "")))
+   (use (match_operand 2 "" ""))
+   (clobber (reg:SI LR_REGNUM))]
   "TARGET_THUMB1 && use_cmse"
   "bl\\t__gnu_cmse_nonsecure_call"
   [(set_attr "length" "4")
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index 776d611d2538e790a5f504995050ffdfc51d7193..d56a8bd167575263edc2a4b3f66bda34a4a7a72a 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -555,12 +555,11 @@ 
 )
 
 (define_insn "*nonsecure_call_reg_thumb2"
-  [(call (unspec:SI [(mem:SI (match_operand:SI 0 "s_register_operand" "r"))]
+  [(call (unspec:SI [(mem:SI (reg:SI R4_REGNUM))]
 		    UNSPEC_NONSECURE_MEM)
-	 (match_operand 1 "" ""))
-   (use (match_operand 2 "" ""))
-   (clobber (reg:SI LR_REGNUM))
-   (clobber (match_dup 0))]
+	 (match_operand 0 "" ""))
+   (use (match_operand 1 "" ""))
+   (clobber (reg:SI LR_REGNUM))]
   "TARGET_THUMB2 && use_cmse"
   "bl\\t__gnu_cmse_nonsecure_call"
   [(set_attr "length" "4")
@@ -581,12 +580,11 @@ 
 (define_insn "*nonsecure_call_value_reg_thumb2"
   [(set (match_operand 0 "" "")
 	(call
-	 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "l*r"))]
+	 (unspec:SI [(mem:SI (reg:SI R4_REGNUM))]
 		    UNSPEC_NONSECURE_MEM)
-	 (match_operand 2 "" "")))
-   (use (match_operand 3 "" ""))
-   (clobber (reg:SI LR_REGNUM))
-   (clobber (match_dup 1))]
+	 (match_operand 1 "" "")))
+   (use (match_operand 2 "" ""))
+   (clobber (reg:SI LR_REGNUM))]
   "TARGET_THUMB2 && use_cmse"
   "bl\t__gnu_cmse_nonsecure_call"
   [(set_attr "length" "4")