public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] [morello] Further updates to Morello DWARF debug info generation
@ 2022-02-28 12:08 Matthew Malcomson
  0 siblings, 0 replies; only message in thread
From: Matthew Malcomson @ 2022-02-28 12:08 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:f30724eac73a0b70f10426ee2806a3e5ef43bb46

commit f30724eac73a0b70f10426ee2806a3e5ef43bb46
Author: Stam Markianos-Wright <stam.markianos-wright@arm.com>
Date:   Wed Jan 26 17:11:14 2022 +0000

    [morello] Further updates to Morello DWARF debug info generation
    
    This patch brings out DWARF debug information closer to what
    is described in the Morello DWARF specification:
    https://developer.arm.com/documentation/102215/latest
    
    The three issues and document sections addressed by this patch are:
    
    -Using the new DWARF register numbers 198-228 for capabilities (5.1)
    -Marking DW_ADDR_capability on true capability pointers (5.4.1)
    -Using the DW_ATE_CHERI_* base types for __{u}intcap_t types (5.4.2)
    
    In order to do this there were a number of places where we needed
    to distinguish between pure-capability and fake-capability (or
    pure+hybrid capability and fake-capability) modes, so this patch
    also introduces a new target hook called "capabilities_in_hardware"
    which returns TARGET_CAPABILITY_PURE || TARGET_CAPABILITY_HYBRID.
    
    So in the various `if` conditions we see:
    
     - targetm.capability_mode().exists()
          && targetm.capabilities_in_hardware()
          && targetm.capability_mode().require() == Pmode
       is true only for pure-cap.
     - targetm.capability_mode().exists()
          && !targetm.capabilities_in_hardware()
       is true only for fake-cap
     - targetm.capability_mode().exists()
          && targetm.capabilities_in_hardware()
       is true for pure-cap and hybrid.

Diff:
---
 gcc/config/aarch64/aarch64-protos.h              |   4 +-
 gcc/config/aarch64/aarch64.c                     |  36 +++++-
 gcc/config/aarch64/aarch64.h                     |  10 +-
 gcc/doc/tm.texi                                  |  18 ++-
 gcc/doc/tm.texi.in                               |   4 +-
 gcc/dwarf2cfi.c                                  |  17 +--
 gcc/dwarf2out.c                                  | 138 ++++++++++++-----------
 gcc/except.c                                     |   4 +-
 gcc/target.def                                   |  24 +++-
 gcc/testsuite/gcc.target/aarch64/dwarf-cfa-reg.c |   6 +-
 gcc/varasm.c                                     |   7 ++
 include/dwarf2.h                                 |   1 +
 12 files changed, 167 insertions(+), 102 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index ca27b0caaa9..cff310d407b 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -470,7 +470,7 @@ const unsigned int AARCH64_BUILTIN_SHIFT = 1;
 /* Mask that selects the aarch64_builtin_class part of a function code.  */
 const unsigned int AARCH64_BUILTIN_CLASS = (1 << AARCH64_BUILTIN_SHIFT) - 1;
 
-void aarch64_post_cfi_startproc (void);
+void aarch64_do_cfi_startproc (void);
 poly_int64 aarch64_initial_elimination_offset (unsigned, unsigned);
 int aarch64_get_condition_code (rtx);
 bool aarch64_address_valid_for_prefetch_p (rtx, bool);
@@ -594,7 +594,7 @@ rtx aarch64_simd_vect_par_cnst_half (machine_mode, int, bool);
 rtx aarch64_gen_stepped_int_parallel (unsigned int, int, int);
 bool aarch64_stepped_int_parallel_p (rtx, int);
 rtx aarch64_tls_get_addr (void);
-unsigned aarch64_dbx_register_number (unsigned);
+unsigned aarch64_dbx_register_number (unsigned, machine_mode);
 unsigned aarch64_trampoline_size (void);
 void aarch64_asm_output_labelref (FILE *, const char *);
 void aarch64_cpu_cpp_builtins (cpp_reader *);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 17d17a140b6..a3d1aaf786f 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -2194,10 +2194,18 @@ aarch64_reassociation_width (unsigned opc, machine_mode mode)
 
 /* Provide a mapping from gcc register numbers to dwarf register numbers.  */
 unsigned
-aarch64_dbx_register_number (unsigned regno)
+aarch64_dbx_register_number (unsigned regno, machine_mode mode)
 {
+  /* For Morello capabilities we use a separate set of DWARF registers
+     in the range of 198-228 (for the c0-c30 GP registers).  */
    if (GP_REGNUM_P (regno))
-     return AARCH64_DWARF_R0 + regno - R0_REGNUM;
+     return (CAPABILITY_MODE_P (mode) ? 198 : 0)
+	      + AARCH64_DWARF_R0 + regno - R0_REGNUM;
+    /* MORELLO TODO:
+    I believe we do not need to do anything here for the PCC (r230) or the
+    DDC (r231). IIUC we'll never get here with those and if in the future we
+    want to generate debug information for operations that use the DDC, that
+    will probably have to be bespoke.  */
    else if (regno == SP_REGNUM)
      return AARCH64_DWARF_SP;
    else if (FP_REGNUM_P (regno))
@@ -20384,8 +20392,14 @@ aarch64_asm_output_external (FILE *stream, tree decl, const char* name)
    function with the B key.  */
 
 void
-aarch64_post_cfi_startproc (FILE *f, tree ignored ATTRIBUTE_UNUSED)
+aarch64_do_cfi_startproc (FILE *f, tree ignored ATTRIBUTE_UNUSED)
 {
+  /* For the CHERI Purecap ABI we need to emit a `.cfi_startproc purecap`.  */
+  if (TARGET_CAPABILITY_PURE)
+    asm_fprintf (f, "\t.cfi_startproc purecap\n");
+  else
+    asm_fprintf (f, "\t.cfi_startproc\n");
+
   if (cfun->machine->frame.laid_out && aarch64_return_address_signing_enabled ()
       && aarch64_ra_sign_key == AARCH64_KEY_B)
 	asm_fprintf (f, "\t.cfi_b_key_frame\n");
@@ -24726,6 +24740,15 @@ aarch64_adjust_label_expansion (rtx x)
   return x;
 }
 
+bool
+aarch64_capabilities_in_hardware (void)
+{
+  if (TARGET_CAPABILITY_PURE || TARGET_CAPABILITY_HYBRID)
+    return true;
+  else
+    return false;
+}
+
 /* Target-specific selftests.  */
 
 #if CHECKING_P
@@ -25321,8 +25344,8 @@ aarch64_libgcc_floating_mode_supported_p
 #define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests
 #endif /* #if CHECKING_P */
 
-#undef TARGET_ASM_POST_CFI_STARTPROC
-#define TARGET_ASM_POST_CFI_STARTPROC aarch64_post_cfi_startproc
+#undef TARGET_ASM_DO_CFI_STARTPROC
+#define TARGET_ASM_DO_CFI_STARTPROC aarch64_do_cfi_startproc
 
 #undef TARGET_STRICT_ARGUMENT_NAMING
 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
@@ -25345,6 +25368,9 @@ aarch64_libgcc_floating_mode_supported_p
 #undef TARGET_ADJUST_LABEL_EXPANSION
 #define TARGET_ADJUST_LABEL_EXPANSION aarch64_adjust_label_expansion
 
+#undef TARGET_CAPABILITIES_IN_HARDWARE
+#define TARGET_CAPABILITIES_IN_HARDWARE aarch64_capabilities_in_hardware
+
 #undef TARGET_ASM_DECLARE_CONSTANT_NAME
 #define TARGET_ASM_DECLARE_CONSTANT_NAME aarch64_declare_constant_name
 
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 0a60d78b289..4bd00bcc498 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -613,15 +613,15 @@ extern unsigned aarch64_architecture_version;
    DWARF_ALT_FRAME_RETURN_COLUMN.  */
 #define DWARF_FRAME_REGISTERS           (DWARF_ALT_FRAME_RETURN_COLUMN + 1)
 
-
-#define DBX_REGISTER_NUMBER(REGNO)	aarch64_dbx_register_number (REGNO)
+#define DBX_REGISTER_NUMBER(REGNO, MODE)   \
+  aarch64_dbx_register_number (REGNO, MODE)
 /* Provide a definition of DWARF_FRAME_REGNUM here so that fallback unwinders
    can use DWARF_ALT_FRAME_RETURN_COLUMN defined below.  This is just the same
    as the default definition in dwarf2out.c.  */
 #undef DWARF_FRAME_REGNUM
-#define DWARF_FRAME_REGNUM(REGNO)	DBX_REGISTER_NUMBER (REGNO)
+#define DWARF_FRAME_REGNUM(REGNO, MODE)	DBX_REGISTER_NUMBER (REGNO, MODE)
 
-#define DWARF_FRAME_RETURN_COLUMN	DWARF_FRAME_REGNUM (LR_REGNUM)
+#define DWARF_FRAME_RETURN_COLUMN  DWARF_FRAME_REGNUM (LR_REGNUM, VOIDmode)
 
 #define DWARF2_UNWIND_INFO 1
 
@@ -685,7 +685,7 @@ extern unsigned aarch64_architecture_version;
   aarch64_asm_output_external (STR, DECL, NAME)
 
 /* Output assembly strings after .cfi_startproc is emitted.  */
-#define ASM_POST_CFI_STARTPROC  aarch64_post_cfi_startproc
+#define ASM_DO_CFI_STARTPROC  aarch64_do_cfi_startproc
 
 /* For EH returns X4 contains the stack adjustment.  */
 #define EH_RETURN_STACKADJ_RTX	gen_rtx_REG (POmode, R4_REGNUM)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index e42f913c468..019a2dc7fc6 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -8272,6 +8272,14 @@ Most targets do not need to implement this hook.  The default returns
 AArch64 needs to set the LSB of labels depending on the processor state.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_CAPABILITIES_IN_HARDWARE (void)
+A target hook that is used to distinguish between different ABIs for
+capability architectures. This hook returns true if the target hardware
+supports capabilities.
+Currently only implemented for Arm Morello, where it returns true for the
+PureCap and Hybrid AAPCS ABIs, but false in "fake-capability" compilation.
+@end deftypefn
+
 @deftypefn {Target Hook} void TARGET_ASM_DECL_END (void)
 Define this hook if the target assembler requires a special marker to
 terminate an initialized variable declaration.
@@ -9621,13 +9629,13 @@ If this macro is not defined, nothing special is output at the end of
 the jump-table.
 @end defmac
 
-@deftypefn {Target Hook} void TARGET_ASM_POST_CFI_STARTPROC (FILE *@var{}, @var{tree})
-This target hook is used to emit assembly strings required by the target
-after the .cfi_startproc directive.  The first argument is the file stream to
+@deftypefn {Target Hook} void TARGET_ASM_DO_CFI_STARTPROC (FILE *@var{}, @var{tree})
+This target hook is used to emit any assembly strings required by the target
+for the .cfi_startproc directive.  The first argument is the file stream to
 write the strings to and the second argument is the function's declaration.  The
-expected use is to add more .cfi_* directives.
+expected use is to add more or non-standard .cfi_* directives.
 
-The default is to not output any assembly strings.
+The default is to output a single ".cfi_startproc"
 @end deftypefn
 
 @deftypefn {Target Hook} void TARGET_ASM_EMIT_UNWIND_LABEL (FILE *@var{stream}, tree @var{decl}, int @var{for_eh}, int @var{empty})
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index a95fe9ed2ac..151491e4479 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5236,6 +5236,8 @@ It must not be modified by command-line option processing.
 
 @hook TARGET_ADJUST_LABEL_EXPANSION
 
+@hook TARGET_CAPABILITIES_IN_HARDWARE
+
 @hook TARGET_ASM_DECL_END
 
 @hook TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
@@ -6477,7 +6479,7 @@ If this macro is not defined, nothing special is output at the end of
 the jump-table.
 @end defmac
 
-@hook TARGET_ASM_POST_CFI_STARTPROC
+@hook TARGET_ASM_DO_CFI_STARTPROC
 
 @hook TARGET_ASM_EMIT_UNWIND_LABEL
 
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 650fd7e03bf..5d78d60e27a 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -158,6 +158,7 @@ struct dw_trace_info
   bool args_size_defined_for_eh;
 };
 
+static inline unsigned dwf_regno (const_rtx reg);
 
 /* Hashtable helpers.  */
 
@@ -237,7 +238,7 @@ static unsigned dw_frame_pointer_regnum;
 rtx
 expand_builtin_dwarf_sp_column (void)
 {
-  unsigned int dwarf_regnum = DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM);
+  unsigned int dwarf_regnum = dwf_regno (stack_pointer_rtx);
   return GEN_INT (DWARF2_FRAME_REG_OUT (dwarf_regnum, 1));
 }
 
@@ -279,7 +280,7 @@ void init_one_dwarf_reg_size (int regno, machine_mode regmode,
 			      rtx table, machine_mode slotmode,
 			      init_one_dwarf_reg_state *init_state)
 {
-  const unsigned int dnum = DWARF_FRAME_REGNUM (regno);
+  const unsigned int dnum = DWARF_FRAME_REGNUM (regno, regmode);
   const unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
   const unsigned int dcol = DWARF_REG_TO_UNWIND_COLUMN (rnum);
   
@@ -288,10 +289,10 @@ void init_one_dwarf_reg_size (int regno, machine_mode regmode,
 
   init_state->processed_regno[regno] = true;
 
-  if (rnum >= DWARF_FRAME_REGISTERS)
+  if (dcol >= DWARF_FRAME_REGISTERS)
     return;
 
-  if (dnum == DWARF_FRAME_RETURN_COLUMN)
+  if (dcol == DWARF_FRAME_RETURN_COLUMN)
     {
       if (regmode == VOIDmode)
 	return;
@@ -1015,7 +1016,7 @@ static inline unsigned
 dwf_regno (const_rtx reg)
 {
   gcc_assert (REGNO (reg) < FIRST_PSEUDO_REGISTER);
-  return DWARF_FRAME_REGNUM (REGNO (reg));
+  return DWARF_FRAME_REGNUM (REGNO (reg), GET_MODE (reg));
 }
 
 /* Compare X and Y for equivalence.  The inputs may be REGs or PC_RTX.  */
@@ -3053,7 +3054,7 @@ create_cie_data (void)
   dw_cfa_location loc;
   dw_trace_info cie_trace;
 
-  dw_stack_pointer_regnum = DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM);
+  dw_stack_pointer_regnum = dwf_regno (stack_pointer_rtx);
 
   memset (&cie_trace, 0, sizeof (cie_trace));
   cur_trace = &cie_trace;
@@ -3111,8 +3112,8 @@ create_cie_data (void)
 static unsigned int
 execute_dwarf2_frame (void)
 {
-  /* Different HARD_FRAME_POINTER_REGNUM might coexist in the same file.  */
-  dw_frame_pointer_regnum = DWARF_FRAME_REGNUM (HARD_FRAME_POINTER_REGNUM);
+  /* Initialise dw_frame_pointer_regnum for this file.  */
+  dw_frame_pointer_regnum = dwf_regno (hard_frame_pointer_rtx);
 
   /* The first time we're called, compute the incoming frame state.  */
   if (cie_cfi_vec == NULL)
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 2e3ff1134db..8e560f6c0d8 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -286,6 +286,8 @@ static GTY(()) bool do_eh_frame = false;
 /* .debug_rnglists next index.  */
 static unsigned int rnglist_idx;
 
+static unsigned int dbx_reg_number (const_rtx);
+
 /* Data and reference forms for relocatable data.  */
 #define DW_FORM_data (DWARF_OFFSET_SIZE == 8 ? DW_FORM_data8 : DW_FORM_data4)
 #define DW_FORM_ref (DWARF_OFFSET_SIZE == 8 ? DW_FORM_ref8 : DW_FORM_ref4)
@@ -970,14 +972,7 @@ dwarf2out_do_cfi_startproc (bool second)
   int enc;
   rtx ref;
 
-  /* MORELLO TODO
-     Need to tell whether the current function is targetting purecap or not and
-     emit a `.cfi_startproc purecap` if it is.  Since we need to distinguish
-     between purecap and fake-capability in other places too this is starting
-     to look like something we need a hook for.  */
-  fprintf (asm_out_file, "\t.cfi_startproc\n");
-
-  targetm.asm_out.post_cfi_startproc (asm_out_file, current_function_decl);
+  targetm.asm_out.do_cfi_startproc (asm_out_file, current_function_decl);
 
   /* .cfi_personality and .cfi_lsda are only relevant to DWARF2
      eh unwinders.  */
@@ -2764,7 +2759,7 @@ build_cfa_aligned_loc (dw_cfa_location *cfa,
 {
   struct dw_loc_descr_node *head;
   unsigned int dwarf_fp
-    = DWARF_FRAME_REGNUM (HARD_FRAME_POINTER_REGNUM);
+    = dbx_reg_number (hard_frame_pointer_rtx);
 
   /* When CFA is defined as FP+OFFSET, emulate stack alignment.  */
   if (cfa->reg == HARD_FRAME_POINTER_REGNUM && cfa->indirect == 0)
@@ -3781,7 +3776,6 @@ static int decl_quals (const_tree);
 static dw_die_ref modified_type_die (tree, int, bool, dw_die_ref);
 static dw_die_ref generic_parameter_die (tree, tree, bool, dw_die_ref);
 static dw_die_ref template_parameter_pack_die (tree, tree, dw_die_ref);
-static unsigned int dbx_reg_number (const_rtx);
 static void add_loc_descr_op_piece (dw_loc_descr_ref *, int);
 static dw_loc_descr_ref reg_loc_descriptor (rtx, enum var_init_status);
 static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int,
@@ -12877,6 +12871,8 @@ base_type_die (tree type, bool reverse)
       break;
 
     case INTCAP_TYPE:
+      gcc_assert (targetm.capability_mode().exists()
+		  && targetm.capabilities_in_hardware());
       if (TYPE_UNSIGNED (type))
 	encoding = DW_ATE_CHERI_unsigned_intcap;
       else
@@ -12976,12 +12972,15 @@ is_base_type (tree type)
 {
   switch (TREE_CODE (type))
     {
-    /* MORELLO TODO Need to say "yes" for INTCAP_TYPE if not targetting at fake-capability.
-	Looks like we may need a way to distinguish the overall target (unless
-	would never have fake-capability and pure capability functionality in the same
-	compiler).  */
+    /* For Capability Architectures that support an INTCAP_TYPE we need to
+       distinguish between "true" capability compilation and the "fake"
+       capability mode supported for Arm Morello.  */
     case INTCAP_TYPE:
-      return 0;
+      if (targetm.capability_mode().exists()
+	  && targetm.capabilities_in_hardware())
+	return 1;
+      else
+	return 0;
 
     case INTEGER_TYPE:
     case REAL_TYPE:
@@ -13420,24 +13419,31 @@ modified_type_die (tree type, int cv_quals, bool reverse,
       item_type = TREE_TYPE (type);
 
       addr_space_t as = TYPE_ADDR_SPACE (item_type);
-      /* MORELLO TODO
-	 This seems to be somewhere we would want to emit the
-	 DW_AT_address_class of DW_ADDR_capability for capability pointer types.  */
+      int action = 0;
       if (!ADDR_SPACE_GENERIC_P (as))
+	action = targetm.addr_space.debug (as);
+      /* For Capability architectures we want to set a  DW_AT_address_class
+	 of DW_ADDR_capability (encoded as 0x1) for capability pointer
+	 types.  */
+      if (capability_type_p (type) && targetm.capabilities_in_hardware())
 	{
-	  int action = targetm.addr_space.debug (as);
-	  if (action >= 0)
-	    {
-	      /* Positive values indicate an address_class.  */
-	      add_AT_unsigned (mod_type_die, DW_AT_address_class, action);
-	    }
-	  else
-	    {
-	      /* Negative values indicate an (inverted) segment base reg.  */
-	      dw_loc_descr_ref d
-		= one_reg_loc_descriptor (~action, VAR_INIT_STATUS_INITIALIZED);
-	      add_AT_loc (mod_type_die, DW_AT_segment, d);
-	    }
+	  /* For all known capability architectures the above address space
+	     hook is expected to have returned 0, so assert for that and then
+	     set the DW_AT_address_class value to 1 for DW_ADDR_capability.  */
+	  gcc_assert (action == 0);
+	  action = 1;
+	}
+      if (action > 0)
+	{
+	  /* Positive values indicate an address_class.  */
+	  add_AT_unsigned (mod_type_die, DW_AT_address_class, action);
+	}
+      else if (action < 0)
+	{
+	  /* Negative values indicate an (inverted) segment base reg.  */
+	  dw_loc_descr_ref d
+	    = one_reg_loc_descriptor (~action, VAR_INIT_STATUS_INITIALIZED);
+	  add_AT_loc (mod_type_die, DW_AT_segment, d);
 	}
     }
   else if (code == INTEGER_TYPE
@@ -13490,9 +13496,17 @@ modified_type_die (tree type, int cv_quals, bool reverse,
 	      return lookup_type_die (t);
 	  return lookup_type_die (type);
 	}
-      else if (TREE_CODE (type) == INTCAP_TYPE /* && MORELLO TODO is fake-capability */)
-	return modified_type_die (TREE_TYPE (type), cv_quals, reverse,
-				  context_die);
+      /* For CHERI "fake-capability" mode we look into the TREE_TYPE.
+	 For Purecap and Hybrid, INTCAPs are a base_type, so they have already
+	 been handled above, because is_base_type(type) is true.  */
+      else if (TREE_CODE (type) == INTCAP_TYPE)
+	{
+	  gcc_assert (targetm.capability_mode().exists()
+		      && !targetm.capabilities_in_hardware());
+	  return modified_type_die (TREE_TYPE (type), cv_quals, reverse,
+				    context_die);
+	}
+
       else if (TREE_CODE (type) != VECTOR_TYPE
 	       && TREE_CODE (type) != ARRAY_TYPE)
 	return lookup_type_die (type_main_variant (type));
@@ -13768,8 +13782,7 @@ dbx_reg_number (const_rtx rtl)
     }
 #endif
 
-  regno = DBX_REGISTER_NUMBER (regno);
-  gcc_assert (regno != INVALID_REGNUM);
+  regno = DBX_REGISTER_NUMBER (regno, GET_MODE (rtl));
   return regno;
 }
 
@@ -13883,7 +13896,8 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs,
 	}
 #endif
 
-      gcc_assert ((unsigned) DBX_REGISTER_NUMBER (reg) == dbx_reg_number (rtl));
+      gcc_assert ((unsigned) DBX_REGISTER_NUMBER (reg, GET_MODE (rtl))
+		   == dbx_reg_number (rtl));
       nregs = REG_NREGS (rtl);
 
       /* At present we only track constant-sized pieces.  */
@@ -13896,7 +13910,7 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs,
 	{
 	  dw_loc_descr_ref t;
 
-	  t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg),
+	  t = one_reg_loc_descriptor (dbx_reg_number (rtl),
 				      VAR_INIT_STATUS_INITIALIZED);
 	  add_loc_descr (&loc_result, t);
 	  add_loc_descr_op_piece (&loc_result, size);
@@ -14367,11 +14381,6 @@ based_loc_descr (rtx reg, poly_int64 offset,
   unsigned int regno;
   dw_loc_descr_ref result;
   dw_fde_ref fde = cfun->fde;
-  /* MORELLO TODO
-     Need to handle choosing between dwarf registers based on mode.
-     Capability registers have a different number than non-capability
-     registers, and the backend does not as yet get told about that.  */
-
   /* We only use "frame base" when we're sure we're talking about the
      post-prologue local stack frame.  We do this by *not* running
      register elimination until this point, and recognizing the special
@@ -14400,9 +14409,10 @@ based_loc_descr (rtx reg, poly_int64 offset,
 	      && reg == frame_pointer_rtx)
 	    {
 	      int base_reg
-		= DWARF_FRAME_REGNUM ((fde && fde->drap_reg != INVALID_REGNUM)
-				      ? HARD_FRAME_POINTER_REGNUM
-				      : REGNO (elim));
+		= dbx_reg_number ((fde && fde->drap_reg != INVALID_REGNUM)
+				      ? hard_frame_pointer_rtx
+				      : elim);
+
 	      return new_reg_loc_descr (base_reg, offset);
 	    }
 
@@ -14429,7 +14439,7 @@ based_loc_descr (rtx reg, poly_int64 offset,
 	regno = (unsigned) leaf_reg;
     }
 #endif
-  regno = DWARF_FRAME_REGNUM (regno);
+  regno = dbx_reg_number (reg);
 
   HOST_WIDE_INT const_offset;
   if (!optimize && fde
@@ -15898,9 +15908,6 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
 				      VOIDmode, VAR_INIT_STATUS_INITIALIZED);
 	  else
 	    {
-	      /* MORELLO TODO For purecap need to choose capability registers
-	       * when the value is a capability.  Hence dbx_regnum will need to be updated.
-	       * */
               unsigned int dbx_regnum = dbx_reg_number (ENTRY_VALUE_EXP (rtl));
 	      if (dbx_regnum == IGNORED_DWARF_REGNUM)
 		return NULL;
@@ -22153,7 +22160,7 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
 {
   dw_die_ref type_die = lookup_type_die (type);
   dw_die_ref orig_type_die = type_die;
-
+  gcc_assert (!capability_type_p (type));
   if (type_die == NULL)
     {
       type_die = new_die (DW_TAG_enumeration_type,
@@ -25731,26 +25738,25 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
 	 type is recursive.  Recursive types are possible in Ada.  */
       /* ??? We could perhaps do this for all types before the switch
 	 statement.  */
-      TREE_ASM_WRITTEN (type) = 1;
-
-      /* fallthrough */
-    /* MORELLO TODO
-       When emitting debug information for `fake-cap`, selecting the TREE_TYPE
-	of an INTCAP_TYPE is exactly what we want.  For pure capability we need to emit
-	a DWA_ATE_CHERI_signed_intcap or DWA_ATE_CHERI_unsigned_intcap base type node
-	instead.
-
-	That node is not available on a standard AArch64 linux distro, so we
-	want to avoid using it for `fake-capability`.  Hence this bit needs an `if:
-	(fake-capability)` clause of some sort.  See the comments in
-	dwarf2out_do_cfi_startproc and is_base_type for other places this is needed.
-	*/
-    case INTCAP_TYPE:
       /* For these types, all that is required is that we output a DIE (or a
 	 set of DIEs) to represent the "basis" type.  */
+      TREE_ASM_WRITTEN (type) = 1;
       gen_type_die_with_usage (TREE_TYPE (type), context_die,
 			       DINFO_USAGE_IND_USE);
       break;
+    case INTCAP_TYPE:
+    /* For Capability Architectures with an INTCAP_TYPE we need to distinguish
+       between "true" capability compilation and the "fake" capability mode
+       supported for Arm Morello.
+       For "fake capability" compilation we simply select the TREE_TYPE	of the
+       INTCAP_TYPE.
+       For pure capability we instead need to emit one of the new base type
+       nodes DWA_ATE_CHERI_signed_intcap or DWA_ATE_CHERI_unsigned_intcap.  */
+      if (targetm.capability_mode().exists()
+	  && !targetm.capabilities_in_hardware())
+	gen_type_die_with_usage (TREE_TYPE (type), context_die,
+				 DINFO_USAGE_IND_USE);
+      break;
 
     case OFFSET_TYPE:
       /* This code is used for C++ pointer-to-data-member types.
diff --git a/gcc/except.c b/gcc/except.c
index 22715ce06e1..03d7d529958 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -2173,9 +2173,9 @@ expand_builtin_eh_return_data_regno (tree exp)
     return constm1_rtx;
 
 #ifdef DWARF_FRAME_REGNUM
-  iwhich = DWARF_FRAME_REGNUM (iwhich);
+  iwhich = DWARF_FRAME_REGNUM (iwhich, VOIDmode);
 #else
-  iwhich = DBX_REGISTER_NUMBER (iwhich);
+  iwhich = DBX_REGISTER_NUMBER (iwhich, VOIDmode);
 #endif
 
   return GEN_INT (iwhich);
diff --git a/gcc/target.def b/gcc/target.def
index 040ceb0af43..a5960e6f8d2 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -110,15 +110,15 @@ this function will be given that code, so it must be handled by this hook.",
 
 /* Assembly strings required after the .cfi_startproc label.  */
 DEFHOOK
-(post_cfi_startproc,
-  "This target hook is used to emit assembly strings required by the target\n\
-after the .cfi_startproc directive.  The first argument is the file stream to\n\
+(do_cfi_startproc,
+  "This target hook is used to emit any assembly strings required by the target\n\
+for the .cfi_startproc directive.  The first argument is the file stream to\n\
 write the strings to and the second argument is the function\'s declaration.  The\n\
-expected use is to add more .cfi_* directives.\n\
+expected use is to add more or non-standard .cfi_* directives.\n\
 \n\
-The default is to not output any assembly strings.",
+The default is to output a single \".cfi_startproc\"",
   void, (FILE *, tree),
-  hook_void_FILEptr_tree)
+  default_do_cfi_startproc)
 
 /* Notify the backend that we have completed emitting the data for a
    decl.  */
@@ -3274,6 +3274,18 @@ DEFHOOK
  opt_scalar_addr_mode.  This is the default.",
  opt_scalar_addr_mode, (), default_capability_mode)
 
+/* Disambiguate with errno.  */
+DEFHOOK
+(capabilities_in_hardware,
+ "\
+A target hook that is used to distinguish between different ABIs for\n\
+capability architectures. This hook returns true if the target hardware\n\
+supports capabilities.\n\
+Currently only implemented for Arm Morello, where it returns true for the\n\
+PureCap and Hybrid AAPCS ABIs, but false in \"fake-capability\" compilation.\
+",
+ bool, (void), hook_bool_void_false)
+
 /* Machine specific adjustments when expanding a label.  */
 DEFHOOK
 (adjust_label_expansion,
diff --git a/gcc/testsuite/gcc.target/aarch64/dwarf-cfa-reg.c b/gcc/testsuite/gcc.target/aarch64/dwarf-cfa-reg.c
index ae5b3797021..3d0ddee16ee 100644
--- a/gcc/testsuite/gcc.target/aarch64/dwarf-cfa-reg.c
+++ b/gcc/testsuite/gcc.target/aarch64/dwarf-cfa-reg.c
@@ -1,8 +1,10 @@
 /* Verify that CFA register is restored to SP after FP is restored.  */
 /* { dg-do compile } */
 /* { dg-options "-O0 -gdwarf-2" } */
-/* { dg-final { scan-assembler ".cfi_restore 30" } } */
-/* { dg-final { scan-assembler ".cfi_restore 29" } } */
+/* { dg-final { scan-assembler ".cfi_restore 30" { target { ! { cheri_capability_pure } } } } } */
+/* { dg-final { scan-assembler ".cfi_restore 29" { target { ! { cheri_capability_pure } } } } } */
+/* { dg-final { scan-assembler ".cfi_restore 228" { target { cheri_capability_pure } } } } */
+/* { dg-final { scan-assembler ".cfi_restore 227" { target { cheri_capability_pure } } } } */
 /* { dg-final { scan-assembler ".cfi_def_cfa_offset 0" } } */
 /* { dg-final { scan-assembler "ret" } } */
 
diff --git a/gcc/varasm.c b/gcc/varasm.c
index e36d9197c9a..0301966f484 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -7590,6 +7590,13 @@ default_emit_except_table_label (FILE * stream ATTRIBUTE_UNUSED)
 {
 }
 
+/* Default function to output a ".cfi_startproc" directive.  */
+void
+default_do_cfi_startproc (FILE *f, tree ignored ATTRIBUTE_UNUSED)
+{
+  asm_fprintf (f, "\t.cfi_startproc\n");
+}
+
 /* This is how to output an internal numbered label where PREFIX is
    the class of label and LABELNO is the number within the class.  */
 
diff --git a/include/dwarf2.h b/include/dwarf2.h
index 0b6facfd4cf..57b5210c881 100644
--- a/include/dwarf2.h
+++ b/include/dwarf2.h
@@ -324,6 +324,7 @@ enum dwarf_location_list_entry_type
 #define DW_CHILDREN_yes		     0x01
 
 #define DW_ADDR_none		0
+#define DW_ADDR_capability	1
 
 /* Source language names and codes.  */
 enum dwarf_source_language


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

only message in thread, other threads:[~2022-02-28 12:08 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-28 12:08 [gcc(refs/vendors/ARM/heads/morello)] [morello] Further updates to Morello DWARF debug info generation Matthew Malcomson

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).