aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/config/rs6000/rs6000.c28
-rw-r--r--gcc/doc/tm.texi9
-rw-r--r--gcc/dwarf2out.c78
-rw-r--r--gcc/hooks.c7
-rw-r--r--gcc/hooks.h1
-rw-r--r--gcc/target-def.h3
-rw-r--r--gcc/target.h8
8 files changed, 149 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e3e5cb4..9d1c880 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,23 @@
+2003-03-05 Aldy Hernandez <aldyh@redhat.com>
+
+ * doc/tm.texi: Document TARGET_DWARF_REGISTER_SPAN.
+
+ * config/rs6000/rs6000.c (rs6000_dwarf_register_span): New.
+
+ * hooks.c (hook_rtx_rtx_null): New.
+
+ * hooks.h (hook_rtx_rtx_null): Protoize.
+
+ * target-def.h (TARGET_DWARF_REGISTER_SPAN): New macro.
+ (TARGET_INITIALIZER): Add TARGET_DWARF_REGISTER_SPAN.
+
+ * target.h (struct gcc_target): Add dwarf_register_span.
+
+ * dwarf2out.c (multiple_reg_loc_descriptor): New.
+ (one_reg_loc_descriptor): New.
+ (reg_loc_descriptor): Add support for values that span more than
+ one register.
+
Wed Mar 5 23:16:57 CET 2003 Jan Hubicka <jh@suse.cz>
* Makefile.in (calls.o, toplev.o alias.o): Depend on cgraph.h
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ca99979..8f57f94 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -268,6 +268,7 @@ static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));
static int easy_vector_constant PARAMS ((rtx));
static bool is_ev64_opaque_type PARAMS ((tree));
+static rtx rs6000_dwarf_register_span PARAMS ((rtx));
/* Hash table stuff for keeping track of TOC entries. */
@@ -421,6 +422,9 @@ static const char alt_reg_names[][8] =
#undef TARGET_VECTOR_OPAQUE_P
#define TARGET_VECTOR_OPAQUE_P is_ev64_opaque_type
+#undef TARGET_DWARF_REGISTER_SPAN
+#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Override command line options. Mostly we process the processor
@@ -13601,4 +13605,28 @@ is_ev64_opaque_type (type)
"__ev64_opaque__") == 0);
}
+static rtx
+rs6000_dwarf_register_span (reg)
+ rtx reg;
+{
+ unsigned regno;
+
+ if (!TARGET_SPE || !SPE_VECTOR_MODE (GET_MODE (reg)))
+ return NULL_RTX;
+
+ regno = REGNO (reg);
+
+ /* The duality of the SPE register size wreaks all kinds of havoc.
+ This is a way of distinguishing r0 in 32-bits from r0 in
+ 64-bits. */
+ return
+ gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec (2,
+ gen_rtx_REG (SImode, regno),
+ /* Who, where, what? 1200? This
+ will get changed to a sane value
+ when the SPE ABI finalizes. */
+ gen_rtx_REG (SImode, regno + 1200)));
+}
+
#include "gt-rs6000.h"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 2d20c4f..25db005 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -7610,6 +7610,15 @@ Default value is false if @code{EH_FRAME_SECTION_NAME} is defined, and
true otherwise.
@end deftypevar
+@deftypefn {Target Hook} rtx TARGET_DWARF_REGISTER_SPAN (rtx @var{reg})
+Given a register, this hook should return a parallel of registers to
+represent where to find the register pieces. Define this hook if the
+register and its mode are represented in Dwarf in non-contiguous
+locations, or if the register should be represented in more than one
+register in Dwarf. Otherwise, this hook should return @code{NULL_RTX}.
+If not defined, the default is to return @code{NULL_RTX}.
+@end deftypefn
+
@node Alignment Output
@subsection Assembler Commands for Alignment
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index b75481c..5a515e3 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3752,6 +3752,8 @@ static dw_die_ref modified_type_die PARAMS ((tree, int, int, dw_die_ref));
static int type_is_enum PARAMS ((tree));
static unsigned int reg_number PARAMS ((rtx));
static dw_loc_descr_ref reg_loc_descriptor PARAMS ((rtx));
+static dw_loc_descr_ref one_reg_loc_descriptor PARAMS ((unsigned int));
+static dw_loc_descr_ref multiple_reg_loc_descriptor PARAMS ((rtx, rtx));
static dw_loc_descr_ref int_loc_descriptor PARAMS ((HOST_WIDE_INT));
static dw_loc_descr_ref based_loc_descr PARAMS ((unsigned, long));
static int is_based_loc PARAMS ((rtx));
@@ -8155,24 +8157,90 @@ reg_number (rtl)
}
/* Return a location descriptor that designates a machine register or
- zero if there is no such. */
+ zero if there is none. */
static dw_loc_descr_ref
reg_loc_descriptor (rtl)
rtx rtl;
{
- dw_loc_descr_ref loc_result = NULL;
unsigned reg;
+ rtx regs;
if (REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
return 0;
reg = reg_number (rtl);
- if (reg <= 31)
- loc_result = new_loc_descr (DW_OP_reg0 + reg, 0, 0);
+ regs = (*targetm.dwarf_register_span) (rtl);
+
+ if (HARD_REGNO_NREGS (reg, GET_MODE (rtl)) > 1
+ || regs)
+ return multiple_reg_loc_descriptor (rtl, regs);
+ else
+ return one_reg_loc_descriptor (reg);
+}
+
+/* Return a location descriptor that designates a machine register for
+ a given hard register number. */
+
+static dw_loc_descr_ref
+one_reg_loc_descriptor (regno)
+ unsigned int regno;
+{
+ if (regno <= 31)
+ return new_loc_descr (DW_OP_reg0 + regno, 0, 0);
else
- loc_result = new_loc_descr (DW_OP_regx, reg, 0);
+ return new_loc_descr (DW_OP_regx, regno, 0);
+}
+
+/* Given an RTL of a register, return a location descriptor that
+ designates a value that spans more than one register. */
+
+static dw_loc_descr_ref
+multiple_reg_loc_descriptor (rtl, regs)
+ rtx rtl, regs;
+{
+ int nregs, size, i;
+ unsigned reg;
+ dw_loc_descr_ref loc_result = NULL;
+ reg = reg_number (rtl);
+ nregs = HARD_REGNO_NREGS (reg, GET_MODE (rtl));
+
+ /* Simple, contiguous registers. */
+ if (regs == NULL_RTX)
+ {
+ size = GET_MODE_SIZE (GET_MODE (rtl)) / nregs;
+
+ loc_result = NULL;
+ while (nregs--)
+ {
+ dw_loc_descr_ref t;
+
+ ++reg;
+ t = one_reg_loc_descriptor (reg);
+ add_loc_descr (&loc_result, t);
+ add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
+ }
+ return loc_result;
+ }
+
+ /* Now onto stupid register sets in non contiguous locations. */
+
+ if (GET_CODE (regs) != PARALLEL)
+ abort ();
+
+ size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
+ loc_result = NULL;
+
+ for (i = 0; i < XVECLEN (regs, 0); ++i)
+ {
+ dw_loc_descr_ref t;
+
+ t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)));
+ add_loc_descr (&loc_result, t);
+ size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
+ add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
+ }
return loc_result;
}
diff --git a/gcc/hooks.c b/gcc/hooks.c
index 8926638..1ec6725 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -157,3 +157,10 @@ hook_rtx_rtx_identity (x)
return x;
}
+/* Generic hook that takes an rtx and returns NULL_RTX. */
+rtx
+hook_rtx_rtx_null (x)
+ rtx x ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
diff --git a/gcc/hooks.h b/gcc/hooks.h
index f7a4d6d..5866da7 100644
--- a/gcc/hooks.h
+++ b/gcc/hooks.h
@@ -46,5 +46,6 @@ bool default_can_output_mi_thunk_no_vcall
bool hook_bool_tree_tree_false PARAMS ((tree, tree));
rtx hook_rtx_rtx_identity PARAMS ((rtx));
+rtx hook_rtx_rtx_null PARAMS ((rtx));
#endif
diff --git a/gcc/target-def.h b/gcc/target-def.h
index a7f84c1..86774c1 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -140,6 +140,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#endif
#endif
+#define TARGET_DWARF_REGISTER_SPAN hook_rtx_rtx_null
+
#ifndef TARGET_ASM_EXCEPTION_SECTION
#define TARGET_ASM_EXCEPTION_SECTION default_exception_section
#endif
@@ -310,6 +312,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_VECTOR_OPAQUE_P, \
TARGET_RTX_COSTS, \
TARGET_ADDRESS_COST, \
+ TARGET_DWARF_REGISTER_SPAN, \
TARGET_HAVE_NAMED_SECTIONS, \
TARGET_HAVE_CTORS_DTORS, \
TARGET_HAVE_TLS, \
diff --git a/gcc/target.h b/gcc/target.h
index 95c97b4..22558e9 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -334,6 +334,14 @@ struct gcc_target
invalid addresses. */
int (* address_cost) PARAMS ((rtx x));
+ /* Given a register, this hook should return a parallel of registers
+ to represent where to find the register pieces. Define this hook
+ if the register and its mode are represented in Dwarf in
+ non-contiguous locations, or if the register should be
+ represented in more than one register in Dwarf. Otherwise, this
+ hook should return NULL_RTX. */
+ rtx (* dwarf_register_span) PARAMS ((rtx));
+
/* Leave the boolean fields at the end. */
/* True if arbitrary sections are supported. */