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