1e4b17023SJohn Marino /* Compute different info about registers.
2e4b17023SJohn Marino Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996
3e4b17023SJohn Marino 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
4e4b17023SJohn Marino 2009, 2010, 2011 Free Software Foundation, Inc.
5e4b17023SJohn Marino
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11e4b17023SJohn Marino version.
12e4b17023SJohn Marino
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16e4b17023SJohn Marino for more details.
17e4b17023SJohn Marino
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
21e4b17023SJohn Marino
22e4b17023SJohn Marino
23e4b17023SJohn Marino /* This file contains regscan pass of the compiler and passes for
24e4b17023SJohn Marino dealing with info about modes of pseudo-registers inside
25e4b17023SJohn Marino subregisters. It also defines some tables of information about the
26e4b17023SJohn Marino hardware registers, function init_reg_sets to initialize the
27e4b17023SJohn Marino tables, and other auxiliary functions to deal with info about
28e4b17023SJohn Marino registers and their classes. */
29e4b17023SJohn Marino
30e4b17023SJohn Marino #include "config.h"
31e4b17023SJohn Marino #include "system.h"
32e4b17023SJohn Marino #include "coretypes.h"
33e4b17023SJohn Marino #include "tm.h"
34e4b17023SJohn Marino #include "hard-reg-set.h"
35e4b17023SJohn Marino #include "rtl.h"
36e4b17023SJohn Marino #include "expr.h"
37e4b17023SJohn Marino #include "tm_p.h"
38e4b17023SJohn Marino #include "flags.h"
39e4b17023SJohn Marino #include "basic-block.h"
40e4b17023SJohn Marino #include "regs.h"
41e4b17023SJohn Marino #include "addresses.h"
42e4b17023SJohn Marino #include "function.h"
43e4b17023SJohn Marino #include "insn-config.h"
44e4b17023SJohn Marino #include "recog.h"
45e4b17023SJohn Marino #include "reload.h"
46e4b17023SJohn Marino #include "diagnostic-core.h"
47e4b17023SJohn Marino #include "output.h"
48e4b17023SJohn Marino #include "timevar.h"
49e4b17023SJohn Marino #include "hashtab.h"
50e4b17023SJohn Marino #include "target.h"
51e4b17023SJohn Marino #include "tree-pass.h"
52e4b17023SJohn Marino #include "df.h"
53e4b17023SJohn Marino #include "ira.h"
54e4b17023SJohn Marino
55e4b17023SJohn Marino /* Maximum register number used in this function, plus one. */
56e4b17023SJohn Marino
57e4b17023SJohn Marino int max_regno;
58e4b17023SJohn Marino
59e4b17023SJohn Marino
60e4b17023SJohn Marino struct target_hard_regs default_target_hard_regs;
61e4b17023SJohn Marino struct target_regs default_target_regs;
62e4b17023SJohn Marino #if SWITCHABLE_TARGET
63e4b17023SJohn Marino struct target_hard_regs *this_target_hard_regs = &default_target_hard_regs;
64e4b17023SJohn Marino struct target_regs *this_target_regs = &default_target_regs;
65e4b17023SJohn Marino #endif
66e4b17023SJohn Marino
67e4b17023SJohn Marino /* Data for initializing fixed_regs. */
68e4b17023SJohn Marino static const char initial_fixed_regs[] = FIXED_REGISTERS;
69e4b17023SJohn Marino
70e4b17023SJohn Marino /* Data for initializing call_used_regs. */
71e4b17023SJohn Marino static const char initial_call_used_regs[] = CALL_USED_REGISTERS;
72e4b17023SJohn Marino
73e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
74e4b17023SJohn Marino /* Data for initializing call_really_used_regs. */
75e4b17023SJohn Marino static const char initial_call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
76e4b17023SJohn Marino #endif
77e4b17023SJohn Marino
78e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
79e4b17023SJohn Marino #define CALL_REALLY_USED_REGNO_P(X) call_really_used_regs[X]
80e4b17023SJohn Marino #else
81e4b17023SJohn Marino #define CALL_REALLY_USED_REGNO_P(X) call_used_regs[X]
82e4b17023SJohn Marino #endif
83e4b17023SJohn Marino
84e4b17023SJohn Marino /* Indexed by hard register number, contains 1 for registers
85e4b17023SJohn Marino that are being used for global register decls.
86e4b17023SJohn Marino These must be exempt from ordinary flow analysis
87e4b17023SJohn Marino and are also considered fixed. */
88e4b17023SJohn Marino char global_regs[FIRST_PSEUDO_REGISTER];
89e4b17023SJohn Marino
90e4b17023SJohn Marino /* Declaration for the global register. */
91*95d28233SJohn Marino tree global_regs_decl[FIRST_PSEUDO_REGISTER];
92e4b17023SJohn Marino
93e4b17023SJohn Marino /* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used
94e4b17023SJohn Marino in dataflow more conveniently. */
95e4b17023SJohn Marino regset regs_invalidated_by_call_regset;
96e4b17023SJohn Marino
97e4b17023SJohn Marino /* Same information as FIXED_REG_SET but in regset form. */
98e4b17023SJohn Marino regset fixed_reg_set_regset;
99e4b17023SJohn Marino
100e4b17023SJohn Marino /* The bitmap_obstack is used to hold some static variables that
101e4b17023SJohn Marino should not be reset after each function is compiled. */
102e4b17023SJohn Marino static bitmap_obstack persistent_obstack;
103e4b17023SJohn Marino
104e4b17023SJohn Marino /* Used to initialize reg_alloc_order. */
105e4b17023SJohn Marino #ifdef REG_ALLOC_ORDER
106e4b17023SJohn Marino static int initial_reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER;
107e4b17023SJohn Marino #endif
108e4b17023SJohn Marino
109e4b17023SJohn Marino /* The same information, but as an array of unsigned ints. We copy from
110e4b17023SJohn Marino these unsigned ints to the table above. We do this so the tm.h files
111e4b17023SJohn Marino do not have to be aware of the wordsize for machines with <= 64 regs.
112e4b17023SJohn Marino Note that we hard-code 32 here, not HOST_BITS_PER_INT. */
113e4b17023SJohn Marino #define N_REG_INTS \
114e4b17023SJohn Marino ((FIRST_PSEUDO_REGISTER + (32 - 1)) / 32)
115e4b17023SJohn Marino
116e4b17023SJohn Marino static const unsigned int_reg_class_contents[N_REG_CLASSES][N_REG_INTS]
117e4b17023SJohn Marino = REG_CLASS_CONTENTS;
118e4b17023SJohn Marino
119e4b17023SJohn Marino /* Array containing all of the register names. */
120e4b17023SJohn Marino static const char *const initial_reg_names[] = REGISTER_NAMES;
121e4b17023SJohn Marino
122e4b17023SJohn Marino /* Array containing all of the register class names. */
123e4b17023SJohn Marino const char * reg_class_names[] = REG_CLASS_NAMES;
124e4b17023SJohn Marino
125e4b17023SJohn Marino #define last_mode_for_init_move_cost \
126e4b17023SJohn Marino (this_target_regs->x_last_mode_for_init_move_cost)
127e4b17023SJohn Marino
128e4b17023SJohn Marino /* No more global register variables may be declared; true once
129e4b17023SJohn Marino reginfo has been initialized. */
130e4b17023SJohn Marino static int no_global_reg_vars = 0;
131e4b17023SJohn Marino
132e4b17023SJohn Marino /* Given a register bitmap, turn on the bits in a HARD_REG_SET that
133e4b17023SJohn Marino correspond to the hard registers, if any, set in that map. This
134e4b17023SJohn Marino could be done far more efficiently by having all sorts of special-cases
135e4b17023SJohn Marino with moving single words, but probably isn't worth the trouble. */
136e4b17023SJohn Marino void
reg_set_to_hard_reg_set(HARD_REG_SET * to,const_bitmap from)137e4b17023SJohn Marino reg_set_to_hard_reg_set (HARD_REG_SET *to, const_bitmap from)
138e4b17023SJohn Marino {
139e4b17023SJohn Marino unsigned i;
140e4b17023SJohn Marino bitmap_iterator bi;
141e4b17023SJohn Marino
142e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
143e4b17023SJohn Marino {
144e4b17023SJohn Marino if (i >= FIRST_PSEUDO_REGISTER)
145e4b17023SJohn Marino return;
146e4b17023SJohn Marino SET_HARD_REG_BIT (*to, i);
147e4b17023SJohn Marino }
148e4b17023SJohn Marino }
149e4b17023SJohn Marino
150e4b17023SJohn Marino /* Function called only once per target_globals to initialize the
151e4b17023SJohn Marino target_hard_regs structure. Once this is done, various switches
152e4b17023SJohn Marino may override. */
153e4b17023SJohn Marino void
init_reg_sets(void)154e4b17023SJohn Marino init_reg_sets (void)
155e4b17023SJohn Marino {
156e4b17023SJohn Marino int i, j;
157e4b17023SJohn Marino
158e4b17023SJohn Marino /* First copy the register information from the initial int form into
159e4b17023SJohn Marino the regsets. */
160e4b17023SJohn Marino
161e4b17023SJohn Marino for (i = 0; i < N_REG_CLASSES; i++)
162e4b17023SJohn Marino {
163e4b17023SJohn Marino CLEAR_HARD_REG_SET (reg_class_contents[i]);
164e4b17023SJohn Marino
165e4b17023SJohn Marino /* Note that we hard-code 32 here, not HOST_BITS_PER_INT. */
166e4b17023SJohn Marino for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
167e4b17023SJohn Marino if (int_reg_class_contents[i][j / 32]
168e4b17023SJohn Marino & ((unsigned) 1 << (j % 32)))
169e4b17023SJohn Marino SET_HARD_REG_BIT (reg_class_contents[i], j);
170e4b17023SJohn Marino }
171e4b17023SJohn Marino
172e4b17023SJohn Marino /* Sanity check: make sure the target macros FIXED_REGISTERS and
173e4b17023SJohn Marino CALL_USED_REGISTERS had the right number of initializers. */
174e4b17023SJohn Marino gcc_assert (sizeof fixed_regs == sizeof initial_fixed_regs);
175e4b17023SJohn Marino gcc_assert (sizeof call_used_regs == sizeof initial_call_used_regs);
176e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
177e4b17023SJohn Marino gcc_assert (sizeof call_really_used_regs
178e4b17023SJohn Marino == sizeof initial_call_really_used_regs);
179e4b17023SJohn Marino #endif
180e4b17023SJohn Marino #ifdef REG_ALLOC_ORDER
181e4b17023SJohn Marino gcc_assert (sizeof reg_alloc_order == sizeof initial_reg_alloc_order);
182e4b17023SJohn Marino #endif
183e4b17023SJohn Marino gcc_assert (sizeof reg_names == sizeof initial_reg_names);
184e4b17023SJohn Marino
185e4b17023SJohn Marino memcpy (fixed_regs, initial_fixed_regs, sizeof fixed_regs);
186e4b17023SJohn Marino memcpy (call_used_regs, initial_call_used_regs, sizeof call_used_regs);
187e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
188e4b17023SJohn Marino memcpy (call_really_used_regs, initial_call_really_used_regs,
189e4b17023SJohn Marino sizeof call_really_used_regs);
190e4b17023SJohn Marino #endif
191e4b17023SJohn Marino #ifdef REG_ALLOC_ORDER
192e4b17023SJohn Marino memcpy (reg_alloc_order, initial_reg_alloc_order, sizeof reg_alloc_order);
193e4b17023SJohn Marino #endif
194e4b17023SJohn Marino memcpy (reg_names, initial_reg_names, sizeof reg_names);
195e4b17023SJohn Marino
196e4b17023SJohn Marino SET_HARD_REG_SET (accessible_reg_set);
197e4b17023SJohn Marino SET_HARD_REG_SET (operand_reg_set);
198e4b17023SJohn Marino }
199e4b17023SJohn Marino
200e4b17023SJohn Marino /* Initialize may_move_cost and friends for mode M. */
201e4b17023SJohn Marino void
init_move_cost(enum machine_mode m)202e4b17023SJohn Marino init_move_cost (enum machine_mode m)
203e4b17023SJohn Marino {
204e4b17023SJohn Marino static unsigned short last_move_cost[N_REG_CLASSES][N_REG_CLASSES];
205e4b17023SJohn Marino bool all_match = true;
206e4b17023SJohn Marino unsigned int i, j;
207e4b17023SJohn Marino
208e4b17023SJohn Marino gcc_assert (have_regs_of_mode[m]);
209e4b17023SJohn Marino for (i = 0; i < N_REG_CLASSES; i++)
210e4b17023SJohn Marino if (contains_reg_of_mode[i][m])
211e4b17023SJohn Marino for (j = 0; j < N_REG_CLASSES; j++)
212e4b17023SJohn Marino {
213e4b17023SJohn Marino int cost;
214e4b17023SJohn Marino if (!contains_reg_of_mode[j][m])
215e4b17023SJohn Marino cost = 65535;
216e4b17023SJohn Marino else
217e4b17023SJohn Marino {
218e4b17023SJohn Marino cost = register_move_cost (m, (enum reg_class) i,
219e4b17023SJohn Marino (enum reg_class) j);
220e4b17023SJohn Marino gcc_assert (cost < 65535);
221e4b17023SJohn Marino }
222e4b17023SJohn Marino all_match &= (last_move_cost[i][j] == cost);
223e4b17023SJohn Marino last_move_cost[i][j] = cost;
224e4b17023SJohn Marino }
225e4b17023SJohn Marino if (all_match && last_mode_for_init_move_cost != -1)
226e4b17023SJohn Marino {
227e4b17023SJohn Marino move_cost[m] = move_cost[last_mode_for_init_move_cost];
228e4b17023SJohn Marino may_move_in_cost[m] = may_move_in_cost[last_mode_for_init_move_cost];
229e4b17023SJohn Marino may_move_out_cost[m] = may_move_out_cost[last_mode_for_init_move_cost];
230e4b17023SJohn Marino return;
231e4b17023SJohn Marino }
232e4b17023SJohn Marino last_mode_for_init_move_cost = m;
233e4b17023SJohn Marino move_cost[m] = (move_table *)xmalloc (sizeof (move_table)
234e4b17023SJohn Marino * N_REG_CLASSES);
235e4b17023SJohn Marino may_move_in_cost[m] = (move_table *)xmalloc (sizeof (move_table)
236e4b17023SJohn Marino * N_REG_CLASSES);
237e4b17023SJohn Marino may_move_out_cost[m] = (move_table *)xmalloc (sizeof (move_table)
238e4b17023SJohn Marino * N_REG_CLASSES);
239e4b17023SJohn Marino for (i = 0; i < N_REG_CLASSES; i++)
240e4b17023SJohn Marino if (contains_reg_of_mode[i][m])
241e4b17023SJohn Marino for (j = 0; j < N_REG_CLASSES; j++)
242e4b17023SJohn Marino {
243e4b17023SJohn Marino int cost;
244e4b17023SJohn Marino enum reg_class *p1, *p2;
245e4b17023SJohn Marino
246e4b17023SJohn Marino if (last_move_cost[i][j] == 65535)
247e4b17023SJohn Marino {
248e4b17023SJohn Marino move_cost[m][i][j] = 65535;
249e4b17023SJohn Marino may_move_in_cost[m][i][j] = 65535;
250e4b17023SJohn Marino may_move_out_cost[m][i][j] = 65535;
251e4b17023SJohn Marino }
252e4b17023SJohn Marino else
253e4b17023SJohn Marino {
254e4b17023SJohn Marino cost = last_move_cost[i][j];
255e4b17023SJohn Marino
256e4b17023SJohn Marino for (p2 = ®_class_subclasses[j][0];
257e4b17023SJohn Marino *p2 != LIM_REG_CLASSES; p2++)
258e4b17023SJohn Marino if (*p2 != i && contains_reg_of_mode[*p2][m])
259e4b17023SJohn Marino cost = MAX (cost, move_cost[m][i][*p2]);
260e4b17023SJohn Marino
261e4b17023SJohn Marino for (p1 = ®_class_subclasses[i][0];
262e4b17023SJohn Marino *p1 != LIM_REG_CLASSES; p1++)
263e4b17023SJohn Marino if (*p1 != j && contains_reg_of_mode[*p1][m])
264e4b17023SJohn Marino cost = MAX (cost, move_cost[m][*p1][j]);
265e4b17023SJohn Marino
266e4b17023SJohn Marino gcc_assert (cost <= 65535);
267e4b17023SJohn Marino move_cost[m][i][j] = cost;
268e4b17023SJohn Marino
269e4b17023SJohn Marino if (reg_class_subset_p ((enum reg_class) i, (enum reg_class) j))
270e4b17023SJohn Marino may_move_in_cost[m][i][j] = 0;
271e4b17023SJohn Marino else
272e4b17023SJohn Marino may_move_in_cost[m][i][j] = cost;
273e4b17023SJohn Marino
274e4b17023SJohn Marino if (reg_class_subset_p ((enum reg_class) j, (enum reg_class) i))
275e4b17023SJohn Marino may_move_out_cost[m][i][j] = 0;
276e4b17023SJohn Marino else
277e4b17023SJohn Marino may_move_out_cost[m][i][j] = cost;
278e4b17023SJohn Marino }
279e4b17023SJohn Marino }
280e4b17023SJohn Marino else
281e4b17023SJohn Marino for (j = 0; j < N_REG_CLASSES; j++)
282e4b17023SJohn Marino {
283e4b17023SJohn Marino move_cost[m][i][j] = 65535;
284e4b17023SJohn Marino may_move_in_cost[m][i][j] = 65535;
285e4b17023SJohn Marino may_move_out_cost[m][i][j] = 65535;
286e4b17023SJohn Marino }
287e4b17023SJohn Marino }
288e4b17023SJohn Marino
289e4b17023SJohn Marino /* We need to save copies of some of the register information which
290e4b17023SJohn Marino can be munged by command-line switches so we can restore it during
291e4b17023SJohn Marino subsequent back-end reinitialization. */
292e4b17023SJohn Marino static char saved_fixed_regs[FIRST_PSEUDO_REGISTER];
293e4b17023SJohn Marino static char saved_call_used_regs[FIRST_PSEUDO_REGISTER];
294e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
295e4b17023SJohn Marino static char saved_call_really_used_regs[FIRST_PSEUDO_REGISTER];
296e4b17023SJohn Marino #endif
297e4b17023SJohn Marino static const char *saved_reg_names[FIRST_PSEUDO_REGISTER];
298e4b17023SJohn Marino static HARD_REG_SET saved_accessible_reg_set;
299e4b17023SJohn Marino static HARD_REG_SET saved_operand_reg_set;
300e4b17023SJohn Marino
301e4b17023SJohn Marino /* Save the register information. */
302e4b17023SJohn Marino void
save_register_info(void)303e4b17023SJohn Marino save_register_info (void)
304e4b17023SJohn Marino {
305e4b17023SJohn Marino /* Sanity check: make sure the target macros FIXED_REGISTERS and
306e4b17023SJohn Marino CALL_USED_REGISTERS had the right number of initializers. */
307e4b17023SJohn Marino gcc_assert (sizeof fixed_regs == sizeof saved_fixed_regs);
308e4b17023SJohn Marino gcc_assert (sizeof call_used_regs == sizeof saved_call_used_regs);
309e4b17023SJohn Marino memcpy (saved_fixed_regs, fixed_regs, sizeof fixed_regs);
310e4b17023SJohn Marino memcpy (saved_call_used_regs, call_used_regs, sizeof call_used_regs);
311e4b17023SJohn Marino
312e4b17023SJohn Marino /* Likewise for call_really_used_regs. */
313e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
314e4b17023SJohn Marino gcc_assert (sizeof call_really_used_regs
315e4b17023SJohn Marino == sizeof saved_call_really_used_regs);
316e4b17023SJohn Marino memcpy (saved_call_really_used_regs, call_really_used_regs,
317e4b17023SJohn Marino sizeof call_really_used_regs);
318e4b17023SJohn Marino #endif
319e4b17023SJohn Marino
320e4b17023SJohn Marino /* And similarly for reg_names. */
321e4b17023SJohn Marino gcc_assert (sizeof reg_names == sizeof saved_reg_names);
322e4b17023SJohn Marino memcpy (saved_reg_names, reg_names, sizeof reg_names);
323e4b17023SJohn Marino COPY_HARD_REG_SET (saved_accessible_reg_set, accessible_reg_set);
324e4b17023SJohn Marino COPY_HARD_REG_SET (saved_operand_reg_set, operand_reg_set);
325e4b17023SJohn Marino }
326e4b17023SJohn Marino
327e4b17023SJohn Marino /* Restore the register information. */
328e4b17023SJohn Marino static void
restore_register_info(void)329e4b17023SJohn Marino restore_register_info (void)
330e4b17023SJohn Marino {
331e4b17023SJohn Marino memcpy (fixed_regs, saved_fixed_regs, sizeof fixed_regs);
332e4b17023SJohn Marino memcpy (call_used_regs, saved_call_used_regs, sizeof call_used_regs);
333e4b17023SJohn Marino
334e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
335e4b17023SJohn Marino memcpy (call_really_used_regs, saved_call_really_used_regs,
336e4b17023SJohn Marino sizeof call_really_used_regs);
337e4b17023SJohn Marino #endif
338e4b17023SJohn Marino
339e4b17023SJohn Marino memcpy (reg_names, saved_reg_names, sizeof reg_names);
340e4b17023SJohn Marino COPY_HARD_REG_SET (accessible_reg_set, saved_accessible_reg_set);
341e4b17023SJohn Marino COPY_HARD_REG_SET (operand_reg_set, saved_operand_reg_set);
342e4b17023SJohn Marino }
343e4b17023SJohn Marino
344e4b17023SJohn Marino /* After switches have been processed, which perhaps alter
345e4b17023SJohn Marino `fixed_regs' and `call_used_regs', convert them to HARD_REG_SETs. */
346e4b17023SJohn Marino static void
init_reg_sets_1(void)347e4b17023SJohn Marino init_reg_sets_1 (void)
348e4b17023SJohn Marino {
349e4b17023SJohn Marino unsigned int i, j;
350e4b17023SJohn Marino unsigned int /* enum machine_mode */ m;
351e4b17023SJohn Marino
352e4b17023SJohn Marino restore_register_info ();
353e4b17023SJohn Marino
354e4b17023SJohn Marino #ifdef REG_ALLOC_ORDER
355e4b17023SJohn Marino for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
356e4b17023SJohn Marino inv_reg_alloc_order[reg_alloc_order[i]] = i;
357e4b17023SJohn Marino #endif
358e4b17023SJohn Marino
359e4b17023SJohn Marino /* Let the target tweak things if necessary. */
360e4b17023SJohn Marino
361e4b17023SJohn Marino targetm.conditional_register_usage ();
362e4b17023SJohn Marino
363e4b17023SJohn Marino /* Compute number of hard regs in each class. */
364e4b17023SJohn Marino
365e4b17023SJohn Marino memset (reg_class_size, 0, sizeof reg_class_size);
366e4b17023SJohn Marino for (i = 0; i < N_REG_CLASSES; i++)
367e4b17023SJohn Marino {
368e4b17023SJohn Marino bool any_nonfixed = false;
369e4b17023SJohn Marino for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
370e4b17023SJohn Marino if (TEST_HARD_REG_BIT (reg_class_contents[i], j))
371e4b17023SJohn Marino {
372e4b17023SJohn Marino reg_class_size[i]++;
373e4b17023SJohn Marino if (!fixed_regs[j])
374e4b17023SJohn Marino any_nonfixed = true;
375e4b17023SJohn Marino }
376e4b17023SJohn Marino class_only_fixed_regs[i] = !any_nonfixed;
377e4b17023SJohn Marino }
378e4b17023SJohn Marino
379e4b17023SJohn Marino /* Initialize the table of subunions.
380e4b17023SJohn Marino reg_class_subunion[I][J] gets the largest-numbered reg-class
381e4b17023SJohn Marino that is contained in the union of classes I and J. */
382e4b17023SJohn Marino
383e4b17023SJohn Marino memset (reg_class_subunion, 0, sizeof reg_class_subunion);
384e4b17023SJohn Marino for (i = 0; i < N_REG_CLASSES; i++)
385e4b17023SJohn Marino {
386e4b17023SJohn Marino for (j = 0; j < N_REG_CLASSES; j++)
387e4b17023SJohn Marino {
388e4b17023SJohn Marino HARD_REG_SET c;
389e4b17023SJohn Marino int k;
390e4b17023SJohn Marino
391e4b17023SJohn Marino COPY_HARD_REG_SET (c, reg_class_contents[i]);
392e4b17023SJohn Marino IOR_HARD_REG_SET (c, reg_class_contents[j]);
393e4b17023SJohn Marino for (k = 0; k < N_REG_CLASSES; k++)
394e4b17023SJohn Marino if (hard_reg_set_subset_p (reg_class_contents[k], c)
395e4b17023SJohn Marino && !hard_reg_set_subset_p (reg_class_contents[k],
396e4b17023SJohn Marino reg_class_contents
397e4b17023SJohn Marino [(int) reg_class_subunion[i][j]]))
398e4b17023SJohn Marino reg_class_subunion[i][j] = (enum reg_class) k;
399e4b17023SJohn Marino }
400e4b17023SJohn Marino }
401e4b17023SJohn Marino
402e4b17023SJohn Marino /* Initialize the table of superunions.
403e4b17023SJohn Marino reg_class_superunion[I][J] gets the smallest-numbered reg-class
404e4b17023SJohn Marino containing the union of classes I and J. */
405e4b17023SJohn Marino
406e4b17023SJohn Marino memset (reg_class_superunion, 0, sizeof reg_class_superunion);
407e4b17023SJohn Marino for (i = 0; i < N_REG_CLASSES; i++)
408e4b17023SJohn Marino {
409e4b17023SJohn Marino for (j = 0; j < N_REG_CLASSES; j++)
410e4b17023SJohn Marino {
411e4b17023SJohn Marino HARD_REG_SET c;
412e4b17023SJohn Marino int k;
413e4b17023SJohn Marino
414e4b17023SJohn Marino COPY_HARD_REG_SET (c, reg_class_contents[i]);
415e4b17023SJohn Marino IOR_HARD_REG_SET (c, reg_class_contents[j]);
416e4b17023SJohn Marino for (k = 0; k < N_REG_CLASSES; k++)
417e4b17023SJohn Marino if (hard_reg_set_subset_p (c, reg_class_contents[k]))
418e4b17023SJohn Marino break;
419e4b17023SJohn Marino
420e4b17023SJohn Marino reg_class_superunion[i][j] = (enum reg_class) k;
421e4b17023SJohn Marino }
422e4b17023SJohn Marino }
423e4b17023SJohn Marino
424e4b17023SJohn Marino /* Initialize the tables of subclasses and superclasses of each reg class.
425e4b17023SJohn Marino First clear the whole table, then add the elements as they are found. */
426e4b17023SJohn Marino
427e4b17023SJohn Marino for (i = 0; i < N_REG_CLASSES; i++)
428e4b17023SJohn Marino {
429e4b17023SJohn Marino for (j = 0; j < N_REG_CLASSES; j++)
430e4b17023SJohn Marino reg_class_subclasses[i][j] = LIM_REG_CLASSES;
431e4b17023SJohn Marino }
432e4b17023SJohn Marino
433e4b17023SJohn Marino for (i = 0; i < N_REG_CLASSES; i++)
434e4b17023SJohn Marino {
435e4b17023SJohn Marino if (i == (int) NO_REGS)
436e4b17023SJohn Marino continue;
437e4b17023SJohn Marino
438e4b17023SJohn Marino for (j = i + 1; j < N_REG_CLASSES; j++)
439e4b17023SJohn Marino if (hard_reg_set_subset_p (reg_class_contents[i],
440e4b17023SJohn Marino reg_class_contents[j]))
441e4b17023SJohn Marino {
442e4b17023SJohn Marino /* Reg class I is a subclass of J.
443e4b17023SJohn Marino Add J to the table of superclasses of I. */
444e4b17023SJohn Marino enum reg_class *p;
445e4b17023SJohn Marino
446e4b17023SJohn Marino /* Add I to the table of superclasses of J. */
447e4b17023SJohn Marino p = ®_class_subclasses[j][0];
448e4b17023SJohn Marino while (*p != LIM_REG_CLASSES) p++;
449e4b17023SJohn Marino *p = (enum reg_class) i;
450e4b17023SJohn Marino }
451e4b17023SJohn Marino }
452e4b17023SJohn Marino
453e4b17023SJohn Marino /* Initialize "constant" tables. */
454e4b17023SJohn Marino
455e4b17023SJohn Marino CLEAR_HARD_REG_SET (fixed_reg_set);
456e4b17023SJohn Marino CLEAR_HARD_REG_SET (call_used_reg_set);
457e4b17023SJohn Marino CLEAR_HARD_REG_SET (call_fixed_reg_set);
458e4b17023SJohn Marino CLEAR_HARD_REG_SET (regs_invalidated_by_call);
459e4b17023SJohn Marino if (!regs_invalidated_by_call_regset)
460e4b17023SJohn Marino {
461e4b17023SJohn Marino bitmap_obstack_initialize (&persistent_obstack);
462e4b17023SJohn Marino regs_invalidated_by_call_regset = ALLOC_REG_SET (&persistent_obstack);
463e4b17023SJohn Marino }
464e4b17023SJohn Marino else
465e4b17023SJohn Marino CLEAR_REG_SET (regs_invalidated_by_call_regset);
466e4b17023SJohn Marino if (!fixed_reg_set_regset)
467e4b17023SJohn Marino fixed_reg_set_regset = ALLOC_REG_SET (&persistent_obstack);
468e4b17023SJohn Marino else
469e4b17023SJohn Marino CLEAR_REG_SET (fixed_reg_set_regset);
470e4b17023SJohn Marino
471e4b17023SJohn Marino AND_HARD_REG_SET (operand_reg_set, accessible_reg_set);
472e4b17023SJohn Marino for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
473e4b17023SJohn Marino {
474e4b17023SJohn Marino /* As a special exception, registers whose class is NO_REGS are
475e4b17023SJohn Marino not accepted by `register_operand'. The reason for this change
476e4b17023SJohn Marino is to allow the representation of special architecture artifacts
477e4b17023SJohn Marino (such as a condition code register) without extending the rtl
478e4b17023SJohn Marino definitions. Since registers of class NO_REGS cannot be used
479e4b17023SJohn Marino as registers in any case where register classes are examined,
480e4b17023SJohn Marino it is better to apply this exception in a target-independent way. */
481e4b17023SJohn Marino if (REGNO_REG_CLASS (i) == NO_REGS)
482e4b17023SJohn Marino CLEAR_HARD_REG_BIT (operand_reg_set, i);
483e4b17023SJohn Marino
484e4b17023SJohn Marino /* If a register is too limited to be treated as a register operand,
485e4b17023SJohn Marino then it should never be allocated to a pseudo. */
486e4b17023SJohn Marino if (!TEST_HARD_REG_BIT (operand_reg_set, i))
487e4b17023SJohn Marino {
488e4b17023SJohn Marino fixed_regs[i] = 1;
489e4b17023SJohn Marino call_used_regs[i] = 1;
490e4b17023SJohn Marino }
491e4b17023SJohn Marino
492e4b17023SJohn Marino /* call_used_regs must include fixed_regs. */
493e4b17023SJohn Marino gcc_assert (!fixed_regs[i] || call_used_regs[i]);
494e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
495e4b17023SJohn Marino /* call_used_regs must include call_really_used_regs. */
496e4b17023SJohn Marino gcc_assert (!call_really_used_regs[i] || call_used_regs[i]);
497e4b17023SJohn Marino #endif
498e4b17023SJohn Marino
499e4b17023SJohn Marino if (fixed_regs[i])
500e4b17023SJohn Marino {
501e4b17023SJohn Marino SET_HARD_REG_BIT (fixed_reg_set, i);
502e4b17023SJohn Marino SET_REGNO_REG_SET (fixed_reg_set_regset, i);
503e4b17023SJohn Marino }
504e4b17023SJohn Marino
505e4b17023SJohn Marino if (call_used_regs[i])
506e4b17023SJohn Marino SET_HARD_REG_BIT (call_used_reg_set, i);
507e4b17023SJohn Marino
508e4b17023SJohn Marino /* There are a couple of fixed registers that we know are safe to
509e4b17023SJohn Marino exclude from being clobbered by calls:
510e4b17023SJohn Marino
511e4b17023SJohn Marino The frame pointer is always preserved across calls. The arg
512e4b17023SJohn Marino pointer is if it is fixed. The stack pointer usually is,
513e4b17023SJohn Marino unless TARGET_RETURN_POPS_ARGS, in which case an explicit
514e4b17023SJohn Marino CLOBBER will be present. If we are generating PIC code, the
515e4b17023SJohn Marino PIC offset table register is preserved across calls, though the
516e4b17023SJohn Marino target can override that. */
517e4b17023SJohn Marino
518e4b17023SJohn Marino if (i == STACK_POINTER_REGNUM)
519e4b17023SJohn Marino ;
520e4b17023SJohn Marino else if (global_regs[i])
521e4b17023SJohn Marino {
522e4b17023SJohn Marino SET_HARD_REG_BIT (regs_invalidated_by_call, i);
523e4b17023SJohn Marino SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i);
524e4b17023SJohn Marino }
525e4b17023SJohn Marino else if (i == FRAME_POINTER_REGNUM)
526e4b17023SJohn Marino ;
527e4b17023SJohn Marino #if !HARD_FRAME_POINTER_IS_FRAME_POINTER
528e4b17023SJohn Marino else if (i == HARD_FRAME_POINTER_REGNUM)
529e4b17023SJohn Marino ;
530e4b17023SJohn Marino #endif
531e4b17023SJohn Marino #if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
532e4b17023SJohn Marino else if (i == ARG_POINTER_REGNUM && fixed_regs[i])
533e4b17023SJohn Marino ;
534e4b17023SJohn Marino #endif
535e4b17023SJohn Marino else if (!PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
536e4b17023SJohn Marino && i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i])
537e4b17023SJohn Marino ;
538e4b17023SJohn Marino else if (CALL_REALLY_USED_REGNO_P (i))
539e4b17023SJohn Marino {
540e4b17023SJohn Marino SET_HARD_REG_BIT (regs_invalidated_by_call, i);
541e4b17023SJohn Marino SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i);
542e4b17023SJohn Marino }
543e4b17023SJohn Marino }
544e4b17023SJohn Marino
545e4b17023SJohn Marino COPY_HARD_REG_SET(call_fixed_reg_set, fixed_reg_set);
546e4b17023SJohn Marino
547e4b17023SJohn Marino /* Preserve global registers if called more than once. */
548e4b17023SJohn Marino for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
549e4b17023SJohn Marino {
550e4b17023SJohn Marino if (global_regs[i])
551e4b17023SJohn Marino {
552e4b17023SJohn Marino fixed_regs[i] = call_used_regs[i] = 1;
553e4b17023SJohn Marino SET_HARD_REG_BIT (fixed_reg_set, i);
554e4b17023SJohn Marino SET_HARD_REG_BIT (call_used_reg_set, i);
555e4b17023SJohn Marino SET_HARD_REG_BIT (call_fixed_reg_set, i);
556e4b17023SJohn Marino }
557e4b17023SJohn Marino }
558e4b17023SJohn Marino
559e4b17023SJohn Marino memset (have_regs_of_mode, 0, sizeof (have_regs_of_mode));
560e4b17023SJohn Marino memset (contains_reg_of_mode, 0, sizeof (contains_reg_of_mode));
561e4b17023SJohn Marino for (m = 0; m < (unsigned int) MAX_MACHINE_MODE; m++)
562e4b17023SJohn Marino {
563e4b17023SJohn Marino HARD_REG_SET ok_regs;
564e4b17023SJohn Marino CLEAR_HARD_REG_SET (ok_regs);
565e4b17023SJohn Marino for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
566e4b17023SJohn Marino if (!fixed_regs [j] && HARD_REGNO_MODE_OK (j, (enum machine_mode) m))
567e4b17023SJohn Marino SET_HARD_REG_BIT (ok_regs, j);
568e4b17023SJohn Marino
569e4b17023SJohn Marino for (i = 0; i < N_REG_CLASSES; i++)
570e4b17023SJohn Marino if ((targetm.class_max_nregs ((reg_class_t) i, (enum machine_mode) m)
571e4b17023SJohn Marino <= reg_class_size[i])
572e4b17023SJohn Marino && hard_reg_set_intersect_p (ok_regs, reg_class_contents[i]))
573e4b17023SJohn Marino {
574e4b17023SJohn Marino contains_reg_of_mode [i][m] = 1;
575e4b17023SJohn Marino have_regs_of_mode [m] = 1;
576e4b17023SJohn Marino }
577e4b17023SJohn Marino }
578e4b17023SJohn Marino
579e4b17023SJohn Marino /* Reset move_cost and friends, making sure we only free shared
580e4b17023SJohn Marino table entries once. */
581e4b17023SJohn Marino for (i = 0; i < MAX_MACHINE_MODE; i++)
582e4b17023SJohn Marino if (move_cost[i])
583e4b17023SJohn Marino {
584e4b17023SJohn Marino for (j = 0; j < i && move_cost[i] != move_cost[j]; j++)
585e4b17023SJohn Marino ;
586e4b17023SJohn Marino if (i == j)
587e4b17023SJohn Marino {
588e4b17023SJohn Marino free (move_cost[i]);
589e4b17023SJohn Marino free (may_move_in_cost[i]);
590e4b17023SJohn Marino free (may_move_out_cost[i]);
591e4b17023SJohn Marino }
592e4b17023SJohn Marino }
593e4b17023SJohn Marino memset (move_cost, 0, sizeof move_cost);
594e4b17023SJohn Marino memset (may_move_in_cost, 0, sizeof may_move_in_cost);
595e4b17023SJohn Marino memset (may_move_out_cost, 0, sizeof may_move_out_cost);
596e4b17023SJohn Marino last_mode_for_init_move_cost = -1;
597e4b17023SJohn Marino }
598e4b17023SJohn Marino
599e4b17023SJohn Marino /* Compute the table of register modes.
600e4b17023SJohn Marino These values are used to record death information for individual registers
601e4b17023SJohn Marino (as opposed to a multi-register mode).
602e4b17023SJohn Marino This function might be invoked more than once, if the target has support
603e4b17023SJohn Marino for changing register usage conventions on a per-function basis.
604e4b17023SJohn Marino */
605e4b17023SJohn Marino void
init_reg_modes_target(void)606e4b17023SJohn Marino init_reg_modes_target (void)
607e4b17023SJohn Marino {
608e4b17023SJohn Marino int i, j;
609e4b17023SJohn Marino
610e4b17023SJohn Marino for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
611e4b17023SJohn Marino for (j = 0; j < MAX_MACHINE_MODE; j++)
612e4b17023SJohn Marino hard_regno_nregs[i][j] = HARD_REGNO_NREGS(i, (enum machine_mode)j);
613e4b17023SJohn Marino
614e4b17023SJohn Marino for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
615e4b17023SJohn Marino {
616e4b17023SJohn Marino reg_raw_mode[i] = choose_hard_reg_mode (i, 1, false);
617e4b17023SJohn Marino
618e4b17023SJohn Marino /* If we couldn't find a valid mode, just use the previous mode
619e4b17023SJohn Marino if it is suitable, otherwise fall back on word_mode. */
620e4b17023SJohn Marino if (reg_raw_mode[i] == VOIDmode)
621e4b17023SJohn Marino {
622e4b17023SJohn Marino if (i > 0 && hard_regno_nregs[i][reg_raw_mode[i - 1]] == 1)
623e4b17023SJohn Marino reg_raw_mode[i] = reg_raw_mode[i - 1];
624e4b17023SJohn Marino else
625e4b17023SJohn Marino reg_raw_mode[i] = word_mode;
626e4b17023SJohn Marino }
627e4b17023SJohn Marino }
628e4b17023SJohn Marino }
629e4b17023SJohn Marino
630e4b17023SJohn Marino /* Finish initializing the register sets and initialize the register modes.
631e4b17023SJohn Marino This function might be invoked more than once, if the target has support
632e4b17023SJohn Marino for changing register usage conventions on a per-function basis.
633e4b17023SJohn Marino */
634e4b17023SJohn Marino void
init_regs(void)635e4b17023SJohn Marino init_regs (void)
636e4b17023SJohn Marino {
637e4b17023SJohn Marino /* This finishes what was started by init_reg_sets, but couldn't be done
638e4b17023SJohn Marino until after register usage was specified. */
639e4b17023SJohn Marino init_reg_sets_1 ();
640e4b17023SJohn Marino }
641e4b17023SJohn Marino
642e4b17023SJohn Marino /* The same as previous function plus initializing IRA. */
643e4b17023SJohn Marino void
reinit_regs(void)644e4b17023SJohn Marino reinit_regs (void)
645e4b17023SJohn Marino {
646e4b17023SJohn Marino init_regs ();
647e4b17023SJohn Marino /* caller_save needs to be re-initialized. */
648e4b17023SJohn Marino caller_save_initialized_p = false;
649e4b17023SJohn Marino ira_init ();
650e4b17023SJohn Marino }
651e4b17023SJohn Marino
652e4b17023SJohn Marino /* Initialize some fake stack-frame MEM references for use in
653e4b17023SJohn Marino memory_move_secondary_cost. */
654e4b17023SJohn Marino void
init_fake_stack_mems(void)655e4b17023SJohn Marino init_fake_stack_mems (void)
656e4b17023SJohn Marino {
657e4b17023SJohn Marino int i;
658e4b17023SJohn Marino
659e4b17023SJohn Marino for (i = 0; i < MAX_MACHINE_MODE; i++)
660e4b17023SJohn Marino top_of_stack[i] = gen_rtx_MEM ((enum machine_mode) i, stack_pointer_rtx);
661e4b17023SJohn Marino }
662e4b17023SJohn Marino
663e4b17023SJohn Marino
664e4b17023SJohn Marino /* Compute cost of moving data from a register of class FROM to one of
665e4b17023SJohn Marino TO, using MODE. */
666e4b17023SJohn Marino
667e4b17023SJohn Marino int
register_move_cost(enum machine_mode mode,reg_class_t from,reg_class_t to)668e4b17023SJohn Marino register_move_cost (enum machine_mode mode, reg_class_t from, reg_class_t to)
669e4b17023SJohn Marino {
670e4b17023SJohn Marino return targetm.register_move_cost (mode, from, to);
671e4b17023SJohn Marino }
672e4b17023SJohn Marino
673e4b17023SJohn Marino /* Compute cost of moving registers to/from memory. */
674e4b17023SJohn Marino
675e4b17023SJohn Marino int
memory_move_cost(enum machine_mode mode,reg_class_t rclass,bool in)676e4b17023SJohn Marino memory_move_cost (enum machine_mode mode, reg_class_t rclass, bool in)
677e4b17023SJohn Marino {
678e4b17023SJohn Marino return targetm.memory_move_cost (mode, rclass, in);
679e4b17023SJohn Marino }
680e4b17023SJohn Marino
681e4b17023SJohn Marino /* Compute extra cost of moving registers to/from memory due to reloads.
682e4b17023SJohn Marino Only needed if secondary reloads are required for memory moves. */
683e4b17023SJohn Marino int
memory_move_secondary_cost(enum machine_mode mode,reg_class_t rclass,bool in)684e4b17023SJohn Marino memory_move_secondary_cost (enum machine_mode mode, reg_class_t rclass,
685e4b17023SJohn Marino bool in)
686e4b17023SJohn Marino {
687e4b17023SJohn Marino reg_class_t altclass;
688e4b17023SJohn Marino int partial_cost = 0;
689e4b17023SJohn Marino /* We need a memory reference to feed to SECONDARY... macros. */
690e4b17023SJohn Marino /* mem may be unused even if the SECONDARY_ macros are defined. */
691e4b17023SJohn Marino rtx mem ATTRIBUTE_UNUSED = top_of_stack[(int) mode];
692e4b17023SJohn Marino
693e4b17023SJohn Marino altclass = secondary_reload_class (in ? 1 : 0, rclass, mode, mem);
694e4b17023SJohn Marino
695e4b17023SJohn Marino if (altclass == NO_REGS)
696e4b17023SJohn Marino return 0;
697e4b17023SJohn Marino
698e4b17023SJohn Marino if (in)
699e4b17023SJohn Marino partial_cost = register_move_cost (mode, altclass, rclass);
700e4b17023SJohn Marino else
701e4b17023SJohn Marino partial_cost = register_move_cost (mode, rclass, altclass);
702e4b17023SJohn Marino
703e4b17023SJohn Marino if (rclass == altclass)
704e4b17023SJohn Marino /* This isn't simply a copy-to-temporary situation. Can't guess
705e4b17023SJohn Marino what it is, so TARGET_MEMORY_MOVE_COST really ought not to be
706e4b17023SJohn Marino calling here in that case.
707e4b17023SJohn Marino
708e4b17023SJohn Marino I'm tempted to put in an assert here, but returning this will
709e4b17023SJohn Marino probably only give poor estimates, which is what we would've
710e4b17023SJohn Marino had before this code anyways. */
711e4b17023SJohn Marino return partial_cost;
712e4b17023SJohn Marino
713e4b17023SJohn Marino /* Check if the secondary reload register will also need a
714e4b17023SJohn Marino secondary reload. */
715e4b17023SJohn Marino return memory_move_secondary_cost (mode, altclass, in) + partial_cost;
716e4b17023SJohn Marino }
717e4b17023SJohn Marino
718e4b17023SJohn Marino /* Return a machine mode that is legitimate for hard reg REGNO and large
719e4b17023SJohn Marino enough to save nregs. If we can't find one, return VOIDmode.
720e4b17023SJohn Marino If CALL_SAVED is true, only consider modes that are call saved. */
721e4b17023SJohn Marino enum machine_mode
choose_hard_reg_mode(unsigned int regno ATTRIBUTE_UNUSED,unsigned int nregs,bool call_saved)722e4b17023SJohn Marino choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
723e4b17023SJohn Marino unsigned int nregs, bool call_saved)
724e4b17023SJohn Marino {
725e4b17023SJohn Marino unsigned int /* enum machine_mode */ m;
726e4b17023SJohn Marino enum machine_mode found_mode = VOIDmode, mode;
727e4b17023SJohn Marino
728e4b17023SJohn Marino /* We first look for the largest integer mode that can be validly
729e4b17023SJohn Marino held in REGNO. If none, we look for the largest floating-point mode.
730e4b17023SJohn Marino If we still didn't find a valid mode, try CCmode. */
731e4b17023SJohn Marino
732e4b17023SJohn Marino for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
733e4b17023SJohn Marino mode != VOIDmode;
734e4b17023SJohn Marino mode = GET_MODE_WIDER_MODE (mode))
735e4b17023SJohn Marino if ((unsigned) hard_regno_nregs[regno][mode] == nregs
736e4b17023SJohn Marino && HARD_REGNO_MODE_OK (regno, mode)
737e4b17023SJohn Marino && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
738e4b17023SJohn Marino found_mode = mode;
739e4b17023SJohn Marino
740e4b17023SJohn Marino if (found_mode != VOIDmode)
741e4b17023SJohn Marino return found_mode;
742e4b17023SJohn Marino
743e4b17023SJohn Marino for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
744e4b17023SJohn Marino mode != VOIDmode;
745e4b17023SJohn Marino mode = GET_MODE_WIDER_MODE (mode))
746e4b17023SJohn Marino if ((unsigned) hard_regno_nregs[regno][mode] == nregs
747e4b17023SJohn Marino && HARD_REGNO_MODE_OK (regno, mode)
748e4b17023SJohn Marino && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
749e4b17023SJohn Marino found_mode = mode;
750e4b17023SJohn Marino
751e4b17023SJohn Marino if (found_mode != VOIDmode)
752e4b17023SJohn Marino return found_mode;
753e4b17023SJohn Marino
754e4b17023SJohn Marino for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
755e4b17023SJohn Marino mode != VOIDmode;
756e4b17023SJohn Marino mode = GET_MODE_WIDER_MODE (mode))
757e4b17023SJohn Marino if ((unsigned) hard_regno_nregs[regno][mode] == nregs
758e4b17023SJohn Marino && HARD_REGNO_MODE_OK (regno, mode)
759e4b17023SJohn Marino && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
760e4b17023SJohn Marino found_mode = mode;
761e4b17023SJohn Marino
762e4b17023SJohn Marino if (found_mode != VOIDmode)
763e4b17023SJohn Marino return found_mode;
764e4b17023SJohn Marino
765e4b17023SJohn Marino for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
766e4b17023SJohn Marino mode != VOIDmode;
767e4b17023SJohn Marino mode = GET_MODE_WIDER_MODE (mode))
768e4b17023SJohn Marino if ((unsigned) hard_regno_nregs[regno][mode] == nregs
769e4b17023SJohn Marino && HARD_REGNO_MODE_OK (regno, mode)
770e4b17023SJohn Marino && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
771e4b17023SJohn Marino found_mode = mode;
772e4b17023SJohn Marino
773e4b17023SJohn Marino if (found_mode != VOIDmode)
774e4b17023SJohn Marino return found_mode;
775e4b17023SJohn Marino
776e4b17023SJohn Marino /* Iterate over all of the CCmodes. */
777e4b17023SJohn Marino for (m = (unsigned int) CCmode; m < (unsigned int) NUM_MACHINE_MODES; ++m)
778e4b17023SJohn Marino {
779e4b17023SJohn Marino mode = (enum machine_mode) m;
780e4b17023SJohn Marino if ((unsigned) hard_regno_nregs[regno][mode] == nregs
781e4b17023SJohn Marino && HARD_REGNO_MODE_OK (regno, mode)
782e4b17023SJohn Marino && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
783e4b17023SJohn Marino return mode;
784e4b17023SJohn Marino }
785e4b17023SJohn Marino
786e4b17023SJohn Marino /* We can't find a mode valid for this register. */
787e4b17023SJohn Marino return VOIDmode;
788e4b17023SJohn Marino }
789e4b17023SJohn Marino
790e4b17023SJohn Marino /* Specify the usage characteristics of the register named NAME.
791e4b17023SJohn Marino It should be a fixed register if FIXED and a
792e4b17023SJohn Marino call-used register if CALL_USED. */
793e4b17023SJohn Marino void
fix_register(const char * name,int fixed,int call_used)794e4b17023SJohn Marino fix_register (const char *name, int fixed, int call_used)
795e4b17023SJohn Marino {
796e4b17023SJohn Marino int i;
797e4b17023SJohn Marino int reg, nregs;
798e4b17023SJohn Marino
799e4b17023SJohn Marino /* Decode the name and update the primary form of
800e4b17023SJohn Marino the register info. */
801e4b17023SJohn Marino
802e4b17023SJohn Marino if ((reg = decode_reg_name_and_count (name, &nregs)) >= 0)
803e4b17023SJohn Marino {
804e4b17023SJohn Marino gcc_assert (nregs >= 1);
805e4b17023SJohn Marino for (i = reg; i < reg + nregs; i++)
806e4b17023SJohn Marino {
807e4b17023SJohn Marino if ((i == STACK_POINTER_REGNUM
808e4b17023SJohn Marino #ifdef HARD_FRAME_POINTER_REGNUM
809e4b17023SJohn Marino || i == HARD_FRAME_POINTER_REGNUM
810e4b17023SJohn Marino #else
811e4b17023SJohn Marino || i == FRAME_POINTER_REGNUM
812e4b17023SJohn Marino #endif
813e4b17023SJohn Marino )
814e4b17023SJohn Marino && (fixed == 0 || call_used == 0))
815e4b17023SJohn Marino {
816e4b17023SJohn Marino switch (fixed)
817e4b17023SJohn Marino {
818e4b17023SJohn Marino case 0:
819e4b17023SJohn Marino switch (call_used)
820e4b17023SJohn Marino {
821e4b17023SJohn Marino case 0:
822e4b17023SJohn Marino error ("can%'t use %qs as a call-saved register", name);
823e4b17023SJohn Marino break;
824e4b17023SJohn Marino
825e4b17023SJohn Marino case 1:
826e4b17023SJohn Marino error ("can%'t use %qs as a call-used register", name);
827e4b17023SJohn Marino break;
828e4b17023SJohn Marino
829e4b17023SJohn Marino default:
830e4b17023SJohn Marino gcc_unreachable ();
831e4b17023SJohn Marino }
832e4b17023SJohn Marino break;
833e4b17023SJohn Marino
834e4b17023SJohn Marino case 1:
835e4b17023SJohn Marino switch (call_used)
836e4b17023SJohn Marino {
837e4b17023SJohn Marino case 1:
838e4b17023SJohn Marino error ("can%'t use %qs as a fixed register", name);
839e4b17023SJohn Marino break;
840e4b17023SJohn Marino
841e4b17023SJohn Marino case 0:
842e4b17023SJohn Marino default:
843e4b17023SJohn Marino gcc_unreachable ();
844e4b17023SJohn Marino }
845e4b17023SJohn Marino break;
846e4b17023SJohn Marino
847e4b17023SJohn Marino default:
848e4b17023SJohn Marino gcc_unreachable ();
849e4b17023SJohn Marino }
850e4b17023SJohn Marino }
851e4b17023SJohn Marino else
852e4b17023SJohn Marino {
853e4b17023SJohn Marino fixed_regs[i] = fixed;
854e4b17023SJohn Marino call_used_regs[i] = call_used;
855e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
856e4b17023SJohn Marino if (fixed == 0)
857e4b17023SJohn Marino call_really_used_regs[i] = call_used;
858e4b17023SJohn Marino #endif
859e4b17023SJohn Marino }
860e4b17023SJohn Marino }
861e4b17023SJohn Marino }
862e4b17023SJohn Marino else
863e4b17023SJohn Marino {
864e4b17023SJohn Marino warning (0, "unknown register name: %s", name);
865e4b17023SJohn Marino }
866e4b17023SJohn Marino }
867e4b17023SJohn Marino
868e4b17023SJohn Marino /* Mark register number I as global. */
869e4b17023SJohn Marino void
globalize_reg(tree decl,int i)870e4b17023SJohn Marino globalize_reg (tree decl, int i)
871e4b17023SJohn Marino {
872e4b17023SJohn Marino location_t loc = DECL_SOURCE_LOCATION (decl);
873e4b17023SJohn Marino
874e4b17023SJohn Marino #ifdef STACK_REGS
875e4b17023SJohn Marino if (IN_RANGE (i, FIRST_STACK_REG, LAST_STACK_REG))
876e4b17023SJohn Marino {
877e4b17023SJohn Marino error ("stack register used for global register variable");
878e4b17023SJohn Marino return;
879e4b17023SJohn Marino }
880e4b17023SJohn Marino #endif
881e4b17023SJohn Marino
882e4b17023SJohn Marino if (fixed_regs[i] == 0 && no_global_reg_vars)
883e4b17023SJohn Marino error_at (loc, "global register variable follows a function definition");
884e4b17023SJohn Marino
885e4b17023SJohn Marino if (global_regs[i])
886e4b17023SJohn Marino {
887e4b17023SJohn Marino warning_at (loc, 0,
888e4b17023SJohn Marino "register of %qD used for multiple global register variables",
889e4b17023SJohn Marino decl);
890e4b17023SJohn Marino inform (DECL_SOURCE_LOCATION (global_regs_decl[i]),
891e4b17023SJohn Marino "conflicts with %qD", global_regs_decl[i]);
892e4b17023SJohn Marino return;
893e4b17023SJohn Marino }
894e4b17023SJohn Marino
895e4b17023SJohn Marino if (call_used_regs[i] && ! fixed_regs[i])
896e4b17023SJohn Marino warning_at (loc, 0, "call-clobbered register used for global register variable");
897e4b17023SJohn Marino
898e4b17023SJohn Marino global_regs[i] = 1;
899e4b17023SJohn Marino global_regs_decl[i] = decl;
900e4b17023SJohn Marino
901e4b17023SJohn Marino /* If we're globalizing the frame pointer, we need to set the
902e4b17023SJohn Marino appropriate regs_invalidated_by_call bit, even if it's already
903e4b17023SJohn Marino set in fixed_regs. */
904e4b17023SJohn Marino if (i != STACK_POINTER_REGNUM)
905e4b17023SJohn Marino {
906e4b17023SJohn Marino SET_HARD_REG_BIT (regs_invalidated_by_call, i);
907e4b17023SJohn Marino SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i);
908e4b17023SJohn Marino }
909e4b17023SJohn Marino
910e4b17023SJohn Marino /* If already fixed, nothing else to do. */
911e4b17023SJohn Marino if (fixed_regs[i])
912e4b17023SJohn Marino return;
913e4b17023SJohn Marino
914e4b17023SJohn Marino fixed_regs[i] = call_used_regs[i] = 1;
915e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
916e4b17023SJohn Marino call_really_used_regs[i] = 1;
917e4b17023SJohn Marino #endif
918e4b17023SJohn Marino
919e4b17023SJohn Marino SET_HARD_REG_BIT (fixed_reg_set, i);
920e4b17023SJohn Marino SET_HARD_REG_BIT (call_used_reg_set, i);
921e4b17023SJohn Marino SET_HARD_REG_BIT (call_fixed_reg_set, i);
922e4b17023SJohn Marino
923e4b17023SJohn Marino reinit_regs ();
924e4b17023SJohn Marino }
925e4b17023SJohn Marino
926e4b17023SJohn Marino
927e4b17023SJohn Marino /* Structure used to record preferences of given pseudo. */
928e4b17023SJohn Marino struct reg_pref
929e4b17023SJohn Marino {
930e4b17023SJohn Marino /* (enum reg_class) prefclass is the preferred class. May be
931e4b17023SJohn Marino NO_REGS if no class is better than memory. */
932e4b17023SJohn Marino char prefclass;
933e4b17023SJohn Marino
934e4b17023SJohn Marino /* altclass is a register class that we should use for allocating
935e4b17023SJohn Marino pseudo if no register in the preferred class is available.
936e4b17023SJohn Marino If no register in this class is available, memory is preferred.
937e4b17023SJohn Marino
938e4b17023SJohn Marino It might appear to be more general to have a bitmask of classes here,
939e4b17023SJohn Marino but since it is recommended that there be a class corresponding to the
940e4b17023SJohn Marino union of most major pair of classes, that generality is not required. */
941e4b17023SJohn Marino char altclass;
942e4b17023SJohn Marino
943e4b17023SJohn Marino /* allocnoclass is a register class that IRA uses for allocating
944e4b17023SJohn Marino the pseudo. */
945e4b17023SJohn Marino char allocnoclass;
946e4b17023SJohn Marino };
947e4b17023SJohn Marino
948e4b17023SJohn Marino /* Record preferences of each pseudo. This is available after RA is
949e4b17023SJohn Marino run. */
950e4b17023SJohn Marino static struct reg_pref *reg_pref;
951e4b17023SJohn Marino
952e4b17023SJohn Marino /* Current size of reg_info. */
953e4b17023SJohn Marino static int reg_info_size;
954e4b17023SJohn Marino
955e4b17023SJohn Marino /* Return the reg_class in which pseudo reg number REGNO is best allocated.
956e4b17023SJohn Marino This function is sometimes called before the info has been computed.
957e4b17023SJohn Marino When that happens, just return GENERAL_REGS, which is innocuous. */
958e4b17023SJohn Marino enum reg_class
reg_preferred_class(int regno)959e4b17023SJohn Marino reg_preferred_class (int regno)
960e4b17023SJohn Marino {
961e4b17023SJohn Marino if (reg_pref == 0)
962e4b17023SJohn Marino return GENERAL_REGS;
963e4b17023SJohn Marino
964e4b17023SJohn Marino return (enum reg_class) reg_pref[regno].prefclass;
965e4b17023SJohn Marino }
966e4b17023SJohn Marino
967e4b17023SJohn Marino enum reg_class
reg_alternate_class(int regno)968e4b17023SJohn Marino reg_alternate_class (int regno)
969e4b17023SJohn Marino {
970e4b17023SJohn Marino if (reg_pref == 0)
971e4b17023SJohn Marino return ALL_REGS;
972e4b17023SJohn Marino
973e4b17023SJohn Marino return (enum reg_class) reg_pref[regno].altclass;
974e4b17023SJohn Marino }
975e4b17023SJohn Marino
976e4b17023SJohn Marino /* Return the reg_class which is used by IRA for its allocation. */
977e4b17023SJohn Marino enum reg_class
reg_allocno_class(int regno)978e4b17023SJohn Marino reg_allocno_class (int regno)
979e4b17023SJohn Marino {
980e4b17023SJohn Marino if (reg_pref == 0)
981e4b17023SJohn Marino return NO_REGS;
982e4b17023SJohn Marino
983e4b17023SJohn Marino return (enum reg_class) reg_pref[regno].allocnoclass;
984e4b17023SJohn Marino }
985e4b17023SJohn Marino
986e4b17023SJohn Marino
987e4b17023SJohn Marino
988e4b17023SJohn Marino /* Allocate space for reg info. */
989e4b17023SJohn Marino static void
allocate_reg_info(void)990e4b17023SJohn Marino allocate_reg_info (void)
991e4b17023SJohn Marino {
992e4b17023SJohn Marino reg_info_size = max_reg_num ();
993e4b17023SJohn Marino gcc_assert (! reg_pref && ! reg_renumber);
994e4b17023SJohn Marino reg_renumber = XNEWVEC (short, reg_info_size);
995e4b17023SJohn Marino reg_pref = XCNEWVEC (struct reg_pref, reg_info_size);
996e4b17023SJohn Marino memset (reg_renumber, -1, reg_info_size * sizeof (short));
997e4b17023SJohn Marino }
998e4b17023SJohn Marino
999e4b17023SJohn Marino
1000e4b17023SJohn Marino /* Resize reg info. The new elements will be uninitialized. Return
1001e4b17023SJohn Marino TRUE if new elements (for new pseudos) were added. */
1002e4b17023SJohn Marino bool
resize_reg_info(void)1003e4b17023SJohn Marino resize_reg_info (void)
1004e4b17023SJohn Marino {
1005e4b17023SJohn Marino int old;
1006e4b17023SJohn Marino
1007e4b17023SJohn Marino if (reg_pref == NULL)
1008e4b17023SJohn Marino {
1009e4b17023SJohn Marino allocate_reg_info ();
1010e4b17023SJohn Marino return true;
1011e4b17023SJohn Marino }
1012e4b17023SJohn Marino if (reg_info_size == max_reg_num ())
1013e4b17023SJohn Marino return false;
1014e4b17023SJohn Marino old = reg_info_size;
1015e4b17023SJohn Marino reg_info_size = max_reg_num ();
1016e4b17023SJohn Marino gcc_assert (reg_pref && reg_renumber);
1017e4b17023SJohn Marino reg_renumber = XRESIZEVEC (short, reg_renumber, reg_info_size);
1018e4b17023SJohn Marino reg_pref = XRESIZEVEC (struct reg_pref, reg_pref, reg_info_size);
1019e4b17023SJohn Marino memset (reg_pref + old, -1,
1020e4b17023SJohn Marino (reg_info_size - old) * sizeof (struct reg_pref));
1021e4b17023SJohn Marino memset (reg_renumber + old, -1, (reg_info_size - old) * sizeof (short));
1022e4b17023SJohn Marino return true;
1023e4b17023SJohn Marino }
1024e4b17023SJohn Marino
1025e4b17023SJohn Marino
1026e4b17023SJohn Marino /* Free up the space allocated by allocate_reg_info. */
1027e4b17023SJohn Marino void
free_reg_info(void)1028e4b17023SJohn Marino free_reg_info (void)
1029e4b17023SJohn Marino {
1030e4b17023SJohn Marino if (reg_pref)
1031e4b17023SJohn Marino {
1032e4b17023SJohn Marino free (reg_pref);
1033e4b17023SJohn Marino reg_pref = NULL;
1034e4b17023SJohn Marino }
1035e4b17023SJohn Marino
1036e4b17023SJohn Marino if (reg_renumber)
1037e4b17023SJohn Marino {
1038e4b17023SJohn Marino free (reg_renumber);
1039e4b17023SJohn Marino reg_renumber = NULL;
1040e4b17023SJohn Marino }
1041e4b17023SJohn Marino }
1042e4b17023SJohn Marino
1043e4b17023SJohn Marino /* Initialize some global data for this pass. */
1044e4b17023SJohn Marino static unsigned int
reginfo_init(void)1045e4b17023SJohn Marino reginfo_init (void)
1046e4b17023SJohn Marino {
1047e4b17023SJohn Marino if (df)
1048e4b17023SJohn Marino df_compute_regs_ever_live (true);
1049e4b17023SJohn Marino
1050e4b17023SJohn Marino /* This prevents dump_flow_info from losing if called
1051e4b17023SJohn Marino before reginfo is run. */
1052e4b17023SJohn Marino reg_pref = NULL;
1053e4b17023SJohn Marino /* No more global register variables may be declared. */
1054e4b17023SJohn Marino no_global_reg_vars = 1;
1055e4b17023SJohn Marino return 1;
1056e4b17023SJohn Marino }
1057e4b17023SJohn Marino
1058e4b17023SJohn Marino struct rtl_opt_pass pass_reginfo_init =
1059e4b17023SJohn Marino {
1060e4b17023SJohn Marino {
1061e4b17023SJohn Marino RTL_PASS,
1062e4b17023SJohn Marino "reginfo", /* name */
1063e4b17023SJohn Marino NULL, /* gate */
1064e4b17023SJohn Marino reginfo_init, /* execute */
1065e4b17023SJohn Marino NULL, /* sub */
1066e4b17023SJohn Marino NULL, /* next */
1067e4b17023SJohn Marino 0, /* static_pass_number */
1068e4b17023SJohn Marino TV_NONE, /* tv_id */
1069e4b17023SJohn Marino 0, /* properties_required */
1070e4b17023SJohn Marino 0, /* properties_provided */
1071e4b17023SJohn Marino 0, /* properties_destroyed */
1072e4b17023SJohn Marino 0, /* todo_flags_start */
1073e4b17023SJohn Marino 0 /* todo_flags_finish */
1074e4b17023SJohn Marino }
1075e4b17023SJohn Marino };
1076e4b17023SJohn Marino
1077e4b17023SJohn Marino
1078e4b17023SJohn Marino
1079e4b17023SJohn Marino /* Set up preferred, alternate, and cover classes for REGNO as
1080e4b17023SJohn Marino PREFCLASS, ALTCLASS, and ALLOCNOCLASS. */
1081e4b17023SJohn Marino void
setup_reg_classes(int regno,enum reg_class prefclass,enum reg_class altclass,enum reg_class allocnoclass)1082e4b17023SJohn Marino setup_reg_classes (int regno,
1083e4b17023SJohn Marino enum reg_class prefclass, enum reg_class altclass,
1084e4b17023SJohn Marino enum reg_class allocnoclass)
1085e4b17023SJohn Marino {
1086e4b17023SJohn Marino if (reg_pref == NULL)
1087e4b17023SJohn Marino return;
1088e4b17023SJohn Marino gcc_assert (reg_info_size == max_reg_num ());
1089e4b17023SJohn Marino reg_pref[regno].prefclass = prefclass;
1090e4b17023SJohn Marino reg_pref[regno].altclass = altclass;
1091e4b17023SJohn Marino reg_pref[regno].allocnoclass = allocnoclass;
1092e4b17023SJohn Marino }
1093e4b17023SJohn Marino
1094e4b17023SJohn Marino
1095e4b17023SJohn Marino /* This is the `regscan' pass of the compiler, run just before cse and
1096e4b17023SJohn Marino again just before loop. It finds the first and last use of each
1097e4b17023SJohn Marino pseudo-register. */
1098e4b17023SJohn Marino
1099e4b17023SJohn Marino static void reg_scan_mark_refs (rtx, rtx);
1100e4b17023SJohn Marino
1101e4b17023SJohn Marino void
reg_scan(rtx f,unsigned int nregs ATTRIBUTE_UNUSED)1102e4b17023SJohn Marino reg_scan (rtx f, unsigned int nregs ATTRIBUTE_UNUSED)
1103e4b17023SJohn Marino {
1104e4b17023SJohn Marino rtx insn;
1105e4b17023SJohn Marino
1106e4b17023SJohn Marino timevar_push (TV_REG_SCAN);
1107e4b17023SJohn Marino
1108e4b17023SJohn Marino for (insn = f; insn; insn = NEXT_INSN (insn))
1109e4b17023SJohn Marino if (INSN_P (insn))
1110e4b17023SJohn Marino {
1111e4b17023SJohn Marino reg_scan_mark_refs (PATTERN (insn), insn);
1112e4b17023SJohn Marino if (REG_NOTES (insn))
1113e4b17023SJohn Marino reg_scan_mark_refs (REG_NOTES (insn), insn);
1114e4b17023SJohn Marino }
1115e4b17023SJohn Marino
1116e4b17023SJohn Marino timevar_pop (TV_REG_SCAN);
1117e4b17023SJohn Marino }
1118e4b17023SJohn Marino
1119e4b17023SJohn Marino
1120e4b17023SJohn Marino /* X is the expression to scan. INSN is the insn it appears in.
1121e4b17023SJohn Marino NOTE_FLAG is nonzero if X is from INSN's notes rather than its body.
1122e4b17023SJohn Marino We should only record information for REGs with numbers
1123e4b17023SJohn Marino greater than or equal to MIN_REGNO. */
1124e4b17023SJohn Marino static void
reg_scan_mark_refs(rtx x,rtx insn)1125e4b17023SJohn Marino reg_scan_mark_refs (rtx x, rtx insn)
1126e4b17023SJohn Marino {
1127e4b17023SJohn Marino enum rtx_code code;
1128e4b17023SJohn Marino rtx dest;
1129e4b17023SJohn Marino rtx note;
1130e4b17023SJohn Marino
1131e4b17023SJohn Marino if (!x)
1132e4b17023SJohn Marino return;
1133e4b17023SJohn Marino code = GET_CODE (x);
1134e4b17023SJohn Marino switch (code)
1135e4b17023SJohn Marino {
1136e4b17023SJohn Marino case CONST:
1137e4b17023SJohn Marino case CONST_INT:
1138e4b17023SJohn Marino case CONST_DOUBLE:
1139e4b17023SJohn Marino case CONST_FIXED:
1140e4b17023SJohn Marino case CONST_VECTOR:
1141e4b17023SJohn Marino case CC0:
1142e4b17023SJohn Marino case PC:
1143e4b17023SJohn Marino case SYMBOL_REF:
1144e4b17023SJohn Marino case LABEL_REF:
1145e4b17023SJohn Marino case ADDR_VEC:
1146e4b17023SJohn Marino case ADDR_DIFF_VEC:
1147e4b17023SJohn Marino case REG:
1148e4b17023SJohn Marino return;
1149e4b17023SJohn Marino
1150e4b17023SJohn Marino case EXPR_LIST:
1151e4b17023SJohn Marino if (XEXP (x, 0))
1152e4b17023SJohn Marino reg_scan_mark_refs (XEXP (x, 0), insn);
1153e4b17023SJohn Marino if (XEXP (x, 1))
1154e4b17023SJohn Marino reg_scan_mark_refs (XEXP (x, 1), insn);
1155e4b17023SJohn Marino break;
1156e4b17023SJohn Marino
1157e4b17023SJohn Marino case INSN_LIST:
1158e4b17023SJohn Marino if (XEXP (x, 1))
1159e4b17023SJohn Marino reg_scan_mark_refs (XEXP (x, 1), insn);
1160e4b17023SJohn Marino break;
1161e4b17023SJohn Marino
1162e4b17023SJohn Marino case CLOBBER:
1163e4b17023SJohn Marino if (MEM_P (XEXP (x, 0)))
1164e4b17023SJohn Marino reg_scan_mark_refs (XEXP (XEXP (x, 0), 0), insn);
1165e4b17023SJohn Marino break;
1166e4b17023SJohn Marino
1167e4b17023SJohn Marino case SET:
1168e4b17023SJohn Marino /* Count a set of the destination if it is a register. */
1169e4b17023SJohn Marino for (dest = SET_DEST (x);
1170e4b17023SJohn Marino GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
1171e4b17023SJohn Marino || GET_CODE (dest) == ZERO_EXTEND;
1172e4b17023SJohn Marino dest = XEXP (dest, 0))
1173e4b17023SJohn Marino ;
1174e4b17023SJohn Marino
1175e4b17023SJohn Marino /* If this is setting a pseudo from another pseudo or the sum of a
1176e4b17023SJohn Marino pseudo and a constant integer and the other pseudo is known to be
1177e4b17023SJohn Marino a pointer, set the destination to be a pointer as well.
1178e4b17023SJohn Marino
1179e4b17023SJohn Marino Likewise if it is setting the destination from an address or from a
1180e4b17023SJohn Marino value equivalent to an address or to the sum of an address and
1181e4b17023SJohn Marino something else.
1182e4b17023SJohn Marino
1183e4b17023SJohn Marino But don't do any of this if the pseudo corresponds to a user
1184e4b17023SJohn Marino variable since it should have already been set as a pointer based
1185e4b17023SJohn Marino on the type. */
1186e4b17023SJohn Marino
1187e4b17023SJohn Marino if (REG_P (SET_DEST (x))
1188e4b17023SJohn Marino && REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER
1189e4b17023SJohn Marino /* If the destination pseudo is set more than once, then other
1190e4b17023SJohn Marino sets might not be to a pointer value (consider access to a
1191e4b17023SJohn Marino union in two threads of control in the presence of global
1192e4b17023SJohn Marino optimizations). So only set REG_POINTER on the destination
1193e4b17023SJohn Marino pseudo if this is the only set of that pseudo. */
1194e4b17023SJohn Marino && DF_REG_DEF_COUNT (REGNO (SET_DEST (x))) == 1
1195e4b17023SJohn Marino && ! REG_USERVAR_P (SET_DEST (x))
1196e4b17023SJohn Marino && ! REG_POINTER (SET_DEST (x))
1197e4b17023SJohn Marino && ((REG_P (SET_SRC (x))
1198e4b17023SJohn Marino && REG_POINTER (SET_SRC (x)))
1199e4b17023SJohn Marino || ((GET_CODE (SET_SRC (x)) == PLUS
1200e4b17023SJohn Marino || GET_CODE (SET_SRC (x)) == LO_SUM)
1201e4b17023SJohn Marino && CONST_INT_P (XEXP (SET_SRC (x), 1))
1202e4b17023SJohn Marino && REG_P (XEXP (SET_SRC (x), 0))
1203e4b17023SJohn Marino && REG_POINTER (XEXP (SET_SRC (x), 0)))
1204e4b17023SJohn Marino || GET_CODE (SET_SRC (x)) == CONST
1205e4b17023SJohn Marino || GET_CODE (SET_SRC (x)) == SYMBOL_REF
1206e4b17023SJohn Marino || GET_CODE (SET_SRC (x)) == LABEL_REF
1207e4b17023SJohn Marino || (GET_CODE (SET_SRC (x)) == HIGH
1208e4b17023SJohn Marino && (GET_CODE (XEXP (SET_SRC (x), 0)) == CONST
1209e4b17023SJohn Marino || GET_CODE (XEXP (SET_SRC (x), 0)) == SYMBOL_REF
1210e4b17023SJohn Marino || GET_CODE (XEXP (SET_SRC (x), 0)) == LABEL_REF))
1211e4b17023SJohn Marino || ((GET_CODE (SET_SRC (x)) == PLUS
1212e4b17023SJohn Marino || GET_CODE (SET_SRC (x)) == LO_SUM)
1213e4b17023SJohn Marino && (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST
1214e4b17023SJohn Marino || GET_CODE (XEXP (SET_SRC (x), 1)) == SYMBOL_REF
1215e4b17023SJohn Marino || GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF))
1216e4b17023SJohn Marino || ((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
1217e4b17023SJohn Marino && (GET_CODE (XEXP (note, 0)) == CONST
1218e4b17023SJohn Marino || GET_CODE (XEXP (note, 0)) == SYMBOL_REF
1219e4b17023SJohn Marino || GET_CODE (XEXP (note, 0)) == LABEL_REF))))
1220e4b17023SJohn Marino REG_POINTER (SET_DEST (x)) = 1;
1221e4b17023SJohn Marino
1222e4b17023SJohn Marino /* If this is setting a register from a register or from a simple
1223e4b17023SJohn Marino conversion of a register, propagate REG_EXPR. */
1224e4b17023SJohn Marino if (REG_P (dest) && !REG_ATTRS (dest))
1225e4b17023SJohn Marino {
1226e4b17023SJohn Marino rtx src = SET_SRC (x);
1227e4b17023SJohn Marino
1228e4b17023SJohn Marino while (GET_CODE (src) == SIGN_EXTEND
1229e4b17023SJohn Marino || GET_CODE (src) == ZERO_EXTEND
1230e4b17023SJohn Marino || GET_CODE (src) == TRUNCATE
1231e4b17023SJohn Marino || (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)))
1232e4b17023SJohn Marino src = XEXP (src, 0);
1233e4b17023SJohn Marino
1234e4b17023SJohn Marino set_reg_attrs_from_value (dest, src);
1235e4b17023SJohn Marino }
1236e4b17023SJohn Marino
1237e4b17023SJohn Marino /* ... fall through ... */
1238e4b17023SJohn Marino
1239e4b17023SJohn Marino default:
1240e4b17023SJohn Marino {
1241e4b17023SJohn Marino const char *fmt = GET_RTX_FORMAT (code);
1242e4b17023SJohn Marino int i;
1243e4b17023SJohn Marino for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1244e4b17023SJohn Marino {
1245e4b17023SJohn Marino if (fmt[i] == 'e')
1246e4b17023SJohn Marino reg_scan_mark_refs (XEXP (x, i), insn);
1247e4b17023SJohn Marino else if (fmt[i] == 'E' && XVEC (x, i) != 0)
1248e4b17023SJohn Marino {
1249e4b17023SJohn Marino int j;
1250e4b17023SJohn Marino for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1251e4b17023SJohn Marino reg_scan_mark_refs (XVECEXP (x, i, j), insn);
1252e4b17023SJohn Marino }
1253e4b17023SJohn Marino }
1254e4b17023SJohn Marino }
1255e4b17023SJohn Marino }
1256e4b17023SJohn Marino }
1257e4b17023SJohn Marino
1258e4b17023SJohn Marino
1259e4b17023SJohn Marino /* Return nonzero if C1 is a subset of C2, i.e., if every register in C1
1260e4b17023SJohn Marino is also in C2. */
1261e4b17023SJohn Marino int
reg_class_subset_p(reg_class_t c1,reg_class_t c2)1262e4b17023SJohn Marino reg_class_subset_p (reg_class_t c1, reg_class_t c2)
1263e4b17023SJohn Marino {
1264e4b17023SJohn Marino return (c1 == c2
1265e4b17023SJohn Marino || c2 == ALL_REGS
1266e4b17023SJohn Marino || hard_reg_set_subset_p (reg_class_contents[(int) c1],
1267e4b17023SJohn Marino reg_class_contents[(int) c2]));
1268e4b17023SJohn Marino }
1269e4b17023SJohn Marino
1270e4b17023SJohn Marino /* Return nonzero if there is a register that is in both C1 and C2. */
1271e4b17023SJohn Marino int
reg_classes_intersect_p(reg_class_t c1,reg_class_t c2)1272e4b17023SJohn Marino reg_classes_intersect_p (reg_class_t c1, reg_class_t c2)
1273e4b17023SJohn Marino {
1274e4b17023SJohn Marino return (c1 == c2
1275e4b17023SJohn Marino || c1 == ALL_REGS
1276e4b17023SJohn Marino || c2 == ALL_REGS
1277e4b17023SJohn Marino || hard_reg_set_intersect_p (reg_class_contents[(int) c1],
1278e4b17023SJohn Marino reg_class_contents[(int) c2]));
1279e4b17023SJohn Marino }
1280e4b17023SJohn Marino
1281e4b17023SJohn Marino
1282e4b17023SJohn Marino
1283e4b17023SJohn Marino /* Passes for keeping and updating info about modes of registers
1284e4b17023SJohn Marino inside subregisters. */
1285e4b17023SJohn Marino
1286e4b17023SJohn Marino #ifdef CANNOT_CHANGE_MODE_CLASS
1287e4b17023SJohn Marino
1288e4b17023SJohn Marino static bitmap invalid_mode_changes;
1289e4b17023SJohn Marino
1290e4b17023SJohn Marino static void
record_subregs_of_mode(rtx subreg,bitmap subregs_of_mode)1291e4b17023SJohn Marino record_subregs_of_mode (rtx subreg, bitmap subregs_of_mode)
1292e4b17023SJohn Marino {
1293e4b17023SJohn Marino enum machine_mode mode;
1294e4b17023SJohn Marino unsigned int regno;
1295e4b17023SJohn Marino
1296e4b17023SJohn Marino if (!REG_P (SUBREG_REG (subreg)))
1297e4b17023SJohn Marino return;
1298e4b17023SJohn Marino
1299e4b17023SJohn Marino regno = REGNO (SUBREG_REG (subreg));
1300e4b17023SJohn Marino mode = GET_MODE (subreg);
1301e4b17023SJohn Marino
1302e4b17023SJohn Marino if (regno < FIRST_PSEUDO_REGISTER)
1303e4b17023SJohn Marino return;
1304e4b17023SJohn Marino
1305e4b17023SJohn Marino if (bitmap_set_bit (subregs_of_mode,
1306e4b17023SJohn Marino regno * NUM_MACHINE_MODES + (unsigned int) mode))
1307e4b17023SJohn Marino {
1308e4b17023SJohn Marino unsigned int rclass;
1309e4b17023SJohn Marino for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
1310e4b17023SJohn Marino if (!bitmap_bit_p (invalid_mode_changes,
1311e4b17023SJohn Marino regno * N_REG_CLASSES + rclass)
1312e4b17023SJohn Marino && CANNOT_CHANGE_MODE_CLASS (PSEUDO_REGNO_MODE (regno),
1313e4b17023SJohn Marino mode, (enum reg_class) rclass))
1314e4b17023SJohn Marino bitmap_set_bit (invalid_mode_changes,
1315e4b17023SJohn Marino regno * N_REG_CLASSES + rclass);
1316e4b17023SJohn Marino }
1317e4b17023SJohn Marino }
1318e4b17023SJohn Marino
1319e4b17023SJohn Marino /* Call record_subregs_of_mode for all the subregs in X. */
1320e4b17023SJohn Marino static void
find_subregs_of_mode(rtx x,bitmap subregs_of_mode)1321e4b17023SJohn Marino find_subregs_of_mode (rtx x, bitmap subregs_of_mode)
1322e4b17023SJohn Marino {
1323e4b17023SJohn Marino enum rtx_code code = GET_CODE (x);
1324e4b17023SJohn Marino const char * const fmt = GET_RTX_FORMAT (code);
1325e4b17023SJohn Marino int i;
1326e4b17023SJohn Marino
1327e4b17023SJohn Marino if (code == SUBREG)
1328e4b17023SJohn Marino record_subregs_of_mode (x, subregs_of_mode);
1329e4b17023SJohn Marino
1330e4b17023SJohn Marino /* Time for some deep diving. */
1331e4b17023SJohn Marino for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1332e4b17023SJohn Marino {
1333e4b17023SJohn Marino if (fmt[i] == 'e')
1334e4b17023SJohn Marino find_subregs_of_mode (XEXP (x, i), subregs_of_mode);
1335e4b17023SJohn Marino else if (fmt[i] == 'E')
1336e4b17023SJohn Marino {
1337e4b17023SJohn Marino int j;
1338e4b17023SJohn Marino for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1339e4b17023SJohn Marino find_subregs_of_mode (XVECEXP (x, i, j), subregs_of_mode);
1340e4b17023SJohn Marino }
1341e4b17023SJohn Marino }
1342e4b17023SJohn Marino }
1343e4b17023SJohn Marino
1344e4b17023SJohn Marino void
init_subregs_of_mode(void)1345e4b17023SJohn Marino init_subregs_of_mode (void)
1346e4b17023SJohn Marino {
1347e4b17023SJohn Marino basic_block bb;
1348e4b17023SJohn Marino rtx insn;
1349e4b17023SJohn Marino bitmap_obstack srom_obstack;
1350e4b17023SJohn Marino bitmap subregs_of_mode;
1351e4b17023SJohn Marino
1352e4b17023SJohn Marino gcc_assert (invalid_mode_changes == NULL);
1353e4b17023SJohn Marino invalid_mode_changes = BITMAP_ALLOC (NULL);
1354e4b17023SJohn Marino bitmap_obstack_initialize (&srom_obstack);
1355e4b17023SJohn Marino subregs_of_mode = BITMAP_ALLOC (&srom_obstack);
1356e4b17023SJohn Marino
1357e4b17023SJohn Marino FOR_EACH_BB (bb)
1358e4b17023SJohn Marino FOR_BB_INSNS (bb, insn)
1359e4b17023SJohn Marino if (NONDEBUG_INSN_P (insn))
1360e4b17023SJohn Marino find_subregs_of_mode (PATTERN (insn), subregs_of_mode);
1361e4b17023SJohn Marino
1362e4b17023SJohn Marino BITMAP_FREE (subregs_of_mode);
1363e4b17023SJohn Marino bitmap_obstack_release (&srom_obstack);
1364e4b17023SJohn Marino }
1365e4b17023SJohn Marino
1366e4b17023SJohn Marino /* Return 1 if REGNO has had an invalid mode change in CLASS from FROM
1367e4b17023SJohn Marino mode. */
1368e4b17023SJohn Marino bool
invalid_mode_change_p(unsigned int regno,enum reg_class rclass)1369e4b17023SJohn Marino invalid_mode_change_p (unsigned int regno,
1370e4b17023SJohn Marino enum reg_class rclass)
1371e4b17023SJohn Marino {
1372e4b17023SJohn Marino return bitmap_bit_p (invalid_mode_changes,
1373e4b17023SJohn Marino regno * N_REG_CLASSES + (unsigned) rclass);
1374e4b17023SJohn Marino }
1375e4b17023SJohn Marino
1376e4b17023SJohn Marino void
finish_subregs_of_mode(void)1377e4b17023SJohn Marino finish_subregs_of_mode (void)
1378e4b17023SJohn Marino {
1379e4b17023SJohn Marino BITMAP_FREE (invalid_mode_changes);
1380e4b17023SJohn Marino }
1381e4b17023SJohn Marino #else
1382e4b17023SJohn Marino void
init_subregs_of_mode(void)1383e4b17023SJohn Marino init_subregs_of_mode (void)
1384e4b17023SJohn Marino {
1385e4b17023SJohn Marino }
1386e4b17023SJohn Marino void
finish_subregs_of_mode(void)1387e4b17023SJohn Marino finish_subregs_of_mode (void)
1388e4b17023SJohn Marino {
1389e4b17023SJohn Marino }
1390e4b17023SJohn Marino
1391e4b17023SJohn Marino #endif /* CANNOT_CHANGE_MODE_CLASS */
1392