diff mbox

[6/9,AArch64] Add builtins support for pac/aut/xpac

Message ID 0d2340f4-de89-8618-ed97-e19a0eb10981@foss.arm.com
State New
Headers show

Commit Message

Jiong Wang Nov. 11, 2016, 6:35 p.m. UTC
This patch implements a few ARMv8.3-A new builtins for pointer sign and
authentication instructions.

Currently, these builtins are supposed to be used by libgcc EH unwinder
only.  They are not public interface to external user.

OK to install?

gcc/
2016-11-11  Jiong Wang<jiong.wang@arm.com>

         * config/aarch64/aarch64-builtins.c (enum aarch64_builtins): New entries
         for AARCH64_PAUTH_BUILTIN_PACI1716, AARCH64_PAUTH_BUILTIN_AUTIA1716,
         AARCH64_PAUTH_BUILTIN_AUTIB1716, AARCH64_PAUTH_BUILTIN_XPACLRI.
         (aarch64_init_v8_3_builtins): New.
         (aarch64_init_builtins): Call aarch64_init_builtins.
         (arch64_expand_builtin): Expand new builtins.
diff mbox

Patch

diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index 9136910cd324a391de929ea9d1a13419dbcfb8bc..20679a5d3f6138f4c55b84f3aff5dfd0341e6787 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -353,6 +353,11 @@  enum aarch64_builtins
   AARCH64_CRC32_BUILTIN_BASE,
   AARCH64_CRC32_BUILTINS
   AARCH64_CRC32_BUILTIN_MAX,
+  /* ARMv8.3-A Pointer Authentication Builtins.  */
+  AARCH64_PAUTH_BUILTIN_AUTIA1716,
+  AARCH64_PAUTH_BUILTIN_AUTIB1716,
+  AARCH64_PAUTH_BUILTIN_XPACLRI,
+  AARCH64_PAUTH_BUILTIN_PACI1716,
   AARCH64_BUILTIN_MAX
 };
 
@@ -900,6 +905,37 @@  aarch64_init_fp16_types (void)
   aarch64_fp16_ptr_type_node = build_pointer_type (aarch64_fp16_type_node);
 }
 
+/* Pointer authentication builtins that will become NOP on legacy platform.
+   Currently, these builtins are for internal use only (libgcc EH unwinder).  */
+
+void
+aarch64_init_pauth_hint_builtins (void)
+{
+  /* Pointer Authentication builtins.  */
+  tree ftype_pointer_auth
+    = build_function_type_list (ptr_type_node, ptr_type_node,
+				unsigned_intDI_type_node, NULL_TREE);
+  tree ftype_pointer_strip
+    = build_function_type_list (ptr_type_node, ptr_type_node, NULL_TREE);
+
+  aarch64_builtin_decls[AARCH64_PAUTH_BUILTIN_AUTIA1716]
+    = add_builtin_function ("__builtin_aarch64_autia1716", ftype_pointer_auth,
+			    AARCH64_PAUTH_BUILTIN_AUTIA1716, BUILT_IN_MD, NULL,
+			    NULL_TREE);
+  aarch64_builtin_decls[AARCH64_PAUTH_BUILTIN_AUTIB1716]
+    = add_builtin_function ("__builtin_aarch64_autib1716", ftype_pointer_auth,
+			    AARCH64_PAUTH_BUILTIN_AUTIB1716, BUILT_IN_MD, NULL,
+			    NULL_TREE);
+  aarch64_builtin_decls[AARCH64_PAUTH_BUILTIN_XPACLRI]
+    = add_builtin_function ("__builtin_aarch64_xpaclri", ftype_pointer_strip,
+			    AARCH64_PAUTH_BUILTIN_XPACLRI, BUILT_IN_MD, NULL,
+			    NULL_TREE);
+  aarch64_builtin_decls[AARCH64_PAUTH_BUILTIN_PACI1716]
+    = add_builtin_function ("__builtin_aarch64_paci1716", ftype_pointer_auth,
+			    AARCH64_PAUTH_BUILTIN_PACI1716, BUILT_IN_MD, NULL,
+			    NULL_TREE);
+}
+
 void
 aarch64_init_builtins (void)
 {
@@ -928,6 +964,10 @@  aarch64_init_builtins (void)
 
   aarch64_init_crc32_builtins ();
   aarch64_init_builtin_rsqrt ();
+
+/* Initialize pointer authentication builtins which are backed by instructions
+   in NOP encoding space.  */
+  aarch64_init_pauth_hint_builtins ();
 }
 
 tree
@@ -1270,6 +1310,76 @@  aarch64_expand_builtin (tree exp,
 	}
       emit_insn (pat);
       return target;
+    case AARCH64_PAUTH_BUILTIN_AUTIA1716:
+    case AARCH64_PAUTH_BUILTIN_AUTIB1716:
+    case AARCH64_PAUTH_BUILTIN_PACI1716:
+    case AARCH64_PAUTH_BUILTIN_XPACLRI:
+      arg0 = CALL_EXPR_ARG (exp, 0);
+      op0 = force_reg (Pmode, expand_normal (arg0));
+
+      if (!target)
+	target = gen_reg_rtx (Pmode);
+      else
+	target = force_reg (Pmode, target);
+
+      emit_move_insn (target, op0);
+
+      if (fcode == AARCH64_PAUTH_BUILTIN_XPACLRI)
+	{
+	  rtx lr_reg = gen_rtx_REG (Pmode, R30_REGNUM);
+	  icode = CODE_FOR_strip_lr_sign;
+	  emit_move_insn (lr_reg, op0);
+	  emit_insn (GEN_FCN (icode) (const0_rtx));
+	  emit_move_insn (target, lr_reg);
+	}
+      else
+	{
+	  tree arg1 = CALL_EXPR_ARG (exp, 1);
+	  rtx op1 = expand_normal (arg1);
+	  bool sign_op_p = (fcode == AARCH64_PAUTH_BUILTIN_PACI1716);
+
+	  bool x1716_op_p = (fcode == AARCH64_PAUTH_BUILTIN_AUTIA1716
+			     || fcode == AARCH64_PAUTH_BUILTIN_AUTIB1716
+			     || fcode == AARCH64_PAUTH_BUILTIN_PACI1716);
+
+	  bool a_key_p = (fcode == AARCH64_PAUTH_BUILTIN_AUTIA1716
+			  || (aarch64_pauth_key == AARCH64_PAUTH_IKEY_A
+			      && fcode == AARCH64_PAUTH_BUILTIN_PACI1716));
+	  HOST_WIDE_INT key_index =
+	    a_key_p ? AARCH64_PAUTH_IKEY_A : AARCH64_PAUTH_IKEY_B;
+
+	  if (sign_op_p)
+	    {
+	      if (x1716_op_p)
+		icode = CODE_FOR_sign_reg1716;
+	      else
+		icode = CODE_FOR_sign_reg;
+	    }
+	  else
+	    {
+	      if (x1716_op_p)
+		icode = CODE_FOR_auth_reg1716;
+	      else
+		icode = CODE_FOR_auth_reg;;
+	    }
+
+	  op1 = force_reg (Pmode, op1);
+
+	  if (x1716_op_p)
+	    {
+	      rtx x16_reg = gen_rtx_REG (Pmode, R16_REGNUM);
+	      rtx x17_reg = gen_rtx_REG (Pmode, R17_REGNUM);
+	      emit_move_insn (x17_reg, op0);
+	      emit_move_insn (x16_reg, op1);
+	      emit_insn (GEN_FCN (icode) (GEN_INT (key_index), const0_rtx));
+	      emit_move_insn (target, x17_reg);
+	    }
+	  else
+	    emit_insn (GEN_FCN (icode) (target, target, op1,
+					GEN_INT (key_index), const0_rtx));
+	}
+
+      return target;
     }
 
   if (fcode >= AARCH64_SIMD_BUILTIN_BASE && fcode <= AARCH64_SIMD_BUILTIN_MAX)