--- gcc/config/i386/i386.c | 21 +++++++++++++++++++++ gcc/doc/tm.texi | 7 +++++++ gcc/doc/tm.texi.in | 2 ++ gcc/dwarf2out.c | 48 +++++++++++++++++++++++++++++------------------- gcc/target.def | 10 ++++++++++ gcc/targhooks.c | 8 ++++++++ gcc/targhooks.h | 1 + 7 files changed, 78 insertions(+), 19 deletions(-)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 8f833d1..9fb0fac 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -53707,6 +53707,27 @@ ix86_addr_space_convert (rtx op, tree from_type, tree to_type) #undef TARGET_ADDR_SPACE_CONVERT #define TARGET_ADDR_SPACE_CONVERT ix86_addr_space_convert +static int +ix86_addr_space_debug (addr_space_t as) +{ + /* Represent debugging for address spaces with DW_AT_segment, + and the dwarf register for fsbase/gsbase. */ + if (as == ADDR_SPACE_SEG_TLS) + as = DEFAULT_TLS_SEG_REG; + + /* ??? These register numbers are defined in the x86-64 abi, + but there is no corresponding definition for the i386 abi. + That said, {58,59} appear to be reserved, so perhaps best + to use the same numbers in the 32-bit abi. */ + if (as == ADDR_SPACE_SEG_FS) + return ~58; /* dwarf fsbase */ + else if (as == ADDR_SPACE_SEG_GS) + return ~59; /* dwarf gsbase */ + gcc_unreachable (); +} +#undef TARGET_ADDR_SPACE_DEBUG +#define TARGET_ADDR_SPACE_DEBUG ix86_addr_space_debug + /* All use of segmentation is assumed to make address 0 valid. */ static bool diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index d530a9c..79a0d01 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10330,6 +10330,13 @@ guaranteed that one of the two address spaces is a subset of the other, as determined by the @code{TARGET_ADDR_SPACE_SUBSET_P} target hook. @end deftypefn +@deftypefn {Target Hook} int TARGET_ADDR_SPACE_DEBUG (addr_space_t @var{as}) +Define this to define how the address space is encoded in dwarf. +The result, @var{r}, should be positive to indicate +@code{DW_AT_address_class @var{r}} should be emitted; or negative +to indicate @code{DW_AT_segment} with location in register @code{~@var{r}}. +@end deftypefn + @node Misc @section Miscellaneous Parameters @cindex parameters, miscellaneous diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index f8dad76..b57310c 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -7438,6 +7438,8 @@ c_register_addr_space ("__ea", ADDR_SPACE_EA); @hook TARGET_ADDR_SPACE_CONVERT +@hook TARGET_ADDR_SPACE_DEBUG + @node Misc @section Miscellaneous Parameters @cindex parameters, miscellaneous diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index c1b7c7b..013e03f 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -10912,29 +10912,39 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die) mod_type_die = d; } } - else if (code == POINTER_TYPE) + else if (code == POINTER_TYPE || code == REFERENCE_TYPE) { - mod_type_die = new_die (DW_TAG_pointer_type, mod_scope, type); - add_AT_unsigned (mod_type_die, DW_AT_byte_size, - simple_type_size_in_bits (type) / BITS_PER_UNIT); - item_type = TREE_TYPE (type); - if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (item_type))) - add_AT_unsigned (mod_type_die, DW_AT_address_class, - TYPE_ADDR_SPACE (item_type)); - } - else if (code == REFERENCE_TYPE) - { - if (TYPE_REF_IS_RVALUE (type) && dwarf_version >= 4) - mod_type_die = new_die (DW_TAG_rvalue_reference_type, mod_scope, - type); - else - mod_type_die = new_die (DW_TAG_reference_type, mod_scope, type); + dwarf_tag tag = DW_TAG_pointer_type; + if (code == REFERENCE_TYPE) + { + if (TYPE_REF_IS_RVALUE (type) && dwarf_version >= 4) + tag = DW_TAG_rvalue_reference_type; + else + tag = DW_TAG_reference_type; + } + mod_type_die = new_die (tag, mod_scope, type); + add_AT_unsigned (mod_type_die, DW_AT_byte_size, simple_type_size_in_bits (type) / BITS_PER_UNIT); item_type = TREE_TYPE (type); - if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (item_type))) - add_AT_unsigned (mod_type_die, DW_AT_address_class, - TYPE_ADDR_SPACE (item_type)); + + addr_space_t as = TYPE_ADDR_SPACE (item_type); + if (!ADDR_SPACE_GENERIC_P (as)) + { + 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); + } + } } else if (code == INTEGER_TYPE && TREE_TYPE (type) != NULL_TREE diff --git a/gcc/target.def b/gcc/target.def index e33c87f..ed9f9c5 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -3206,6 +3206,16 @@ as determined by the @code{TARGET_ADDR_SPACE_SUBSET_P} target hook.", rtx, (rtx op, tree from_type, tree to_type), default_addr_space_convert) +/* Function to encode an address space into dwarf. */ +DEFHOOK +(debug, + "Define this to define how the address space is encoded in dwarf.\n\ +The result, @var{r}, should be positive to indicate\n\ +@code{DW_AT_address_class @var{r}} should be emitted; or negative\n\ +to indicate @code{DW_AT_segment} with location in register @code{~@var{r}}.", + int, (addr_space_t as), + default_addr_space_debug) + HOOK_VECTOR_END (addr_space) #undef HOOK_PREFIX diff --git a/gcc/targhooks.c b/gcc/targhooks.c index d221d20..fd99460 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1265,6 +1265,14 @@ default_addr_space_zero_address_valid (addr_space_t as ATTRIBUTE_UNUSED) return false; } +/* The default hook for debugging the address space is to return the + (positive) address space number to indicate DW_AT_address_class. */ +int +default_addr_space_debug (addr_space_t as) +{ + return as; +} + /* The default hook for TARGET_ADDR_SPACE_CONVERT. This hook should never be called for targets with only a generic address space. */ diff --git a/gcc/targhooks.h b/gcc/targhooks.h index ade3327..2bb2d1e 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -174,6 +174,7 @@ extern rtx default_addr_space_legitimize_address (rtx, rtx, machine_mode, addr_space_t); extern bool default_addr_space_subset_p (addr_space_t, addr_space_t); extern bool default_addr_space_zero_address_valid (addr_space_t); +extern int default_addr_space_debug (addr_space_t); extern rtx default_addr_space_convert (rtx, tree, tree); extern unsigned int default_case_values_threshold (void); extern bool default_have_conditional_execution (void); -- 2.4.3