]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/arm/arm.md
ARMv8-M Security Extension's cmse_nonsecure_call: use __gnu_cmse_nonsecure_call
[thirdparty/gcc.git] / gcc / config / arm / arm.md
index 5523baf5099cb7c35a6ad3c8a39e5c31efd32f17..d561a4b5d1be9a7bd159f51b50ec736bd89f8fd1 100644 (file)
   "
   {
     rtx callee, pat;
+    tree addr = MEM_EXPR (operands[0]);
     
     /* In an untyped call, we can get NULL for operand 2.  */
     if (operands[2] == NULL_RTX)
        : !REG_P (callee))
       XEXP (operands[0], 0) = force_reg (Pmode, callee);
 
-    pat = gen_call_internal (operands[0], operands[1], operands[2]);
-    arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
+    if (detect_cmse_nonsecure_call (addr))
+      {
+       pat = gen_nonsecure_call_internal (operands[0], operands[1],
+                                          operands[2]);
+       emit_call_insn (pat);
+      }
+    else
+      {
+       pat = gen_call_internal (operands[0], operands[1], operands[2]);
+       arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
+      }
     DONE;
   }"
 )
              (use (match_operand 2 "" ""))
              (clobber (reg:SI LR_REGNUM))])])
 
+(define_expand "nonsecure_call_internal"
+  [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
+                              UNSPEC_NONSECURE_MEM)
+                   (match_operand 1 "general_operand" ""))
+             (use (match_operand 2 "" ""))
+             (clobber (reg:SI LR_REGNUM))
+             (clobber (reg:SI 4))])]
+  "use_cmse"
+  "
+  {
+    rtx tmp;
+    tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
+                                gen_rtx_REG (SImode, 4),
+                                SImode);
+
+    operands[0] = replace_equiv_address (operands[0], tmp);
+  }")
+
 (define_insn "*call_reg_armv5"
   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
          (match_operand 1 "" ""))
   "
   {
     rtx pat, callee;
+    tree addr = MEM_EXPR (operands[1]);
     
     /* In an untyped call, we can get NULL for operand 2.  */
     if (operands[3] == 0)
        : !REG_P (callee))
       XEXP (operands[1], 0) = force_reg (Pmode, callee);
 
-    pat = gen_call_value_internal (operands[0], operands[1],
-                                  operands[2], operands[3]);
-    arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
+    if (detect_cmse_nonsecure_call (addr))
+      {
+       pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
+                                                operands[2], operands[3]);
+       emit_call_insn (pat);
+      }
+    else
+      {
+       pat = gen_call_value_internal (operands[0], operands[1],
+                                      operands[2], operands[3]);
+       arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
+      }
     DONE;
   }"
 )
              (use (match_operand 3 "" ""))
              (clobber (reg:SI LR_REGNUM))])])
 
+(define_expand "nonsecure_call_value_internal"
+  [(parallel [(set (match_operand       0 "" "")
+                  (call (unspec:SI [(match_operand 1 "memory_operand" "")]
+                                   UNSPEC_NONSECURE_MEM)
+                        (match_operand 2 "general_operand" "")))
+             (use (match_operand 3 "" ""))
+             (clobber (reg:SI LR_REGNUM))
+             (clobber (reg:SI 4))])]
+  "use_cmse"
+  "
+  {
+    rtx tmp;
+    tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
+                                gen_rtx_REG (SImode, 4),
+                                SImode);
+
+    operands[1] = replace_equiv_address (operands[1], tmp);
+  }")
+
 (define_insn "*call_value_reg_armv5"
   [(set (match_operand 0 "" "")
         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))