summaryrefslogtreecommitdiff
path: root/gcc/dwarf2out.c
diff options
context:
space:
mode:
authoraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>2003-03-05 22:37:52 +0000
committeraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>2003-03-05 22:37:52 +0000
commit9754a2f03286d083cbf8bcb64b6e603bd2b25974 (patch)
tree374e685d8676bc7828b9b030e68b5e0b0435ab14 /gcc/dwarf2out.c
parentf015a9e2a24b4770a019ff6301c75d0d9c8d0c40 (diff)
downloadgcc-9754a2f03286d083cbf8bcb64b6e603bd2b25974.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@63870 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r--gcc/dwarf2out.c78
1 files changed, 73 insertions, 5 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index b75481c2411..5a515e3fb41 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;
}