diff options
author | aldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-03-05 22:37:52 +0000 |
---|---|---|
committer | aldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-03-05 22:37:52 +0000 |
commit | 9754a2f03286d083cbf8bcb64b6e603bd2b25974 (patch) | |
tree | 374e685d8676bc7828b9b030e68b5e0b0435ab14 /gcc/dwarf2out.c | |
parent | f015a9e2a24b4770a019ff6301c75d0d9c8d0c40 (diff) | |
download | gcc-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.c | 78 |
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; } |