blob: 557dab0f31f0a912e33281a14698d9bbe0526a5d [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001From 4fd39f1329379e00f958394adde6be96f0caf21f Mon Sep 17 00:00:00 2001
2From: hainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4>
3Date: Fri, 5 Dec 2014 16:53:22 +0000
4Subject: [PATCH] 2014-12-05 Olivier Hainque <hainque@adacore.com>
5
6 * dwarf2cfi.c (init_one_dwarf_reg_size): New helper, processing
7 one particular reg for expand_builtin_init_dwarf_reg_sizes.
8 (expand_builtin_init_dwarf_reg_sizes): Rework to use helper and
9 account for dwarf register spans.
10
11
12
13git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@218428 138bc75d-0d04-0410-961f-82ee72b054a4
14
15Signed-off-by: Khem Raj <raj.khem@gmail.com>
16Upstream-Status: Backport [gcc 5.0]
17
18---
19 gcc/ChangeLog | 7 +++++
20 gcc/dwarf2cfi.c | 98 +++++++++++++++++++++++++++++++++++++++++++++------------
21 2 files changed, 85 insertions(+), 20 deletions(-)
22
23Index: gcc-4.9.2/gcc/dwarf2cfi.c
24===================================================================
25--- gcc-4.9.2.orig/gcc/dwarf2cfi.c
26+++ gcc-4.9.2/gcc/dwarf2cfi.c
27@@ -252,7 +252,59 @@ init_return_column_size (enum machine_mo
28 gen_int_mode (size, mode));
29 }
30
31-/* Generate code to initialize the register size table. */
32+/* Datastructure used by expand_builtin_init_dwarf_reg_sizes and
33+ init_one_dwarf_reg_size to communicate on what has been done by the
34+ latter. */
35+
36+typedef struct
37+{
38+ /* Whether the dwarf return column was initialized. */
39+ bool wrote_return_column;
40+
41+ /* For each hard register REGNO, whether init_one_dwarf_reg_size
42+ was given REGNO to process already. */
43+ bool processed_regno [FIRST_PSEUDO_REGISTER];
44+
45+} init_one_dwarf_reg_state;
46+
47+/* Helper for expand_builtin_init_dwarf_reg_sizes. Generate code to
48+ initialize the dwarf register size table entry corresponding to register
49+ REGNO in REGMODE. TABLE is the table base address, SLOTMODE is the mode to
50+ use for the size entry to initialize, and INIT_STATE is the communication
51+ datastructure conveying what we're doing to our caller. */
52+
53+static
54+void init_one_dwarf_reg_size (int regno, machine_mode regmode,
55+ rtx table, machine_mode slotmode,
56+ init_one_dwarf_reg_state *init_state)
57+{
58+ const unsigned int dnum = DWARF_FRAME_REGNUM (regno);
59+ const unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
60+
61+ const HOST_WIDE_INT slotoffset = rnum * GET_MODE_SIZE (slotmode);
62+ const HOST_WIDE_INT regsize = GET_MODE_SIZE (regmode);
63+
64+ init_state->processed_regno[regno] = true;
65+
66+ if (rnum >= DWARF_FRAME_REGISTERS)
67+ return;
68+
69+ if (dnum == DWARF_FRAME_RETURN_COLUMN)
70+ {
71+ if (regmode == VOIDmode)
72+ return;
73+ init_state->wrote_return_column = true;
74+ }
75+
76+ if (slotoffset < 0)
77+ return;
78+
79+ emit_move_insn (adjust_address (table, slotmode, slotoffset),
80+ gen_int_mode (regsize, slotmode));
81+}
82+
83+/* Generate code to initialize the dwarf register size table located
84+ at the provided ADDRESS. */
85
86 void
87 expand_builtin_init_dwarf_reg_sizes (tree address)
88@@ -261,35 +313,40 @@ expand_builtin_init_dwarf_reg_sizes (tre
89 enum machine_mode mode = TYPE_MODE (char_type_node);
90 rtx addr = expand_normal (address);
91 rtx mem = gen_rtx_MEM (BLKmode, addr);
92- bool wrote_return_column = false;
93+
94+ init_one_dwarf_reg_state init_state;
95+
96+ memset ((char *)&init_state, 0, sizeof (init_state));
97
98 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
99 {
100- unsigned int dnum = DWARF_FRAME_REGNUM (i);
101- unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
102-
103- if (rnum < DWARF_FRAME_REGISTERS)
104- {
105- HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (mode);
106- HOST_WIDE_INT size;
107- enum machine_mode save_mode = targetm.dwarf_frame_reg_mode (i);
108+ machine_mode save_mode;
109+ rtx span;
110
111- if (dnum == DWARF_FRAME_RETURN_COLUMN)
112+ /* No point in processing a register multiple times. This could happen
113+ with register spans, e.g. when a reg is first processed as a piece of
114+ a span, then as a register on its own later on. */
115+
116+ if (init_state.processed_regno[i])
117+ continue;
118+
119+ save_mode = targetm.dwarf_frame_reg_mode (i);
120+ span = targetm.dwarf_register_span (gen_rtx_REG (save_mode, i));
121+ if (!span)
122+ init_one_dwarf_reg_size (i, save_mode, mem, mode, &init_state);
123+ else
124+ {
125+ for (int si = 0; si < XVECLEN (span, 0); si++)
126 {
127- if (save_mode == VOIDmode)
128- continue;
129- wrote_return_column = true;
130- }
131- size = GET_MODE_SIZE (save_mode);
132- if (offset < 0)
133- continue;
134+ rtx reg = XVECEXP (span, 0, si);
135+ init_one_dwarf_reg_size
136+ (REGNO (reg), GET_MODE (reg), mem, mode, &init_state);
137+ }
138
139- emit_move_insn (adjust_address (mem, mode, offset),
140- gen_int_mode (size, mode));
141 }
142 }
143
144- if (!wrote_return_column)
145+ if (!init_state.wrote_return_column)
146 init_return_column_size (mode, mem, DWARF_FRAME_RETURN_COLUMN);
147
148 #ifdef DWARF_ALT_FRAME_RETURN_COLUMN