]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/sh/sh-protos.h
Update copyright years.
[thirdparty/gcc.git] / gcc / config / sh / sh-protos.h
CommitLineData
c8f0269d 1/* Definitions of target machine for GNU compiler for Renesas / SuperH SH.
a5544970 2 Copyright (C) 1993-2019 Free Software Foundation, Inc.
318881c0
KG
3 Contributed by Steve Chamberlain (sac@cygnus.com).
4 Improved by Jim Wilson (wilson@cygnus.com).
5
7ec022b2 6This file is part of GCC.
318881c0 7
7ec022b2 8GCC is free software; you can redistribute it and/or modify
318881c0 9it under the terms of the GNU General Public License as published by
2f83c7d6 10the Free Software Foundation; either version 3, or (at your option)
318881c0
KG
11any later version.
12
7ec022b2 13GCC is distributed in the hope that it will be useful,
318881c0
KG
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
2f83c7d6
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
318881c0 21
8b97c5f8
ZW
22#ifndef GCC_SH_PROTOS_H
23#define GCC_SH_PROTOS_H
24
73a4d10b
R
25enum sh_function_kind {
26 /* A function with normal C ABI */
27 FUNCTION_ORDINARY,
28 /* A special function that guarantees that some otherwise call-clobbered
29 registers are not clobbered. These can't go through the SH5 resolver,
30 because it only saves argument passing registers. */
31 SFUNC_GOT,
32 /* A special function that should be linked statically. These are typically
33 smaller or not much larger than a PLT entry.
34 Some also have a non-standard ABI which precludes dynamic linking. */
35 SFUNC_STATIC
36};
37
318881c0 38#ifdef RTX_CODE
312209c6 39extern rtx sh_fsca_sf2int (void);
312209c6 40extern rtx sh_fsca_int2sf (void);
318881c0
KG
41
42/* Declare functions defined in sh.c and used in templates. */
a981b743 43extern bool sh_lra_p (void);
318881c0 44
84034c69 45extern const char *output_branch (int, rtx_insn *, rtx *);
6cb7eb41
DM
46extern const char *output_ieee_ccmpeq (rtx_insn *, rtx *);
47extern const char *output_branchy_insn (enum rtx_code, const char *,
48 rtx_insn *, rtx *);
ef4bddc2
RS
49extern const char *output_movedouble (rtx, rtx[], machine_mode);
50extern const char *output_movepcrel (rtx, rtx[], machine_mode);
6cb7eb41 51extern const char *output_far_jump (rtx_insn *, rtx);
318881c0 52
84034c69 53extern rtx sfunc_uses_reg (rtx_insn *);
b32d5189 54extern int barrier_align (rtx_insn *);
647d790d 55extern int sh_loop_align (rtx_insn *);
aaf701c5
OE
56extern bool fp_zero_operand (rtx);
57extern bool fp_one_operand (rtx);
ef4bddc2
RS
58extern bool sh_legitimate_index_p (machine_mode, rtx, bool, bool);
59extern bool sh_legitimize_reload_address (rtx *, machine_mode, int, int);
60extern rtx legitimize_pic_address (rtx, machine_mode, rtx);
aaf701c5 61extern bool nonpic_symbol_mentioned_p (rtx);
cf277499 62extern void output_pic_addr_const (FILE *, rtx);
aaf701c5 63extern bool expand_block_move (rtx *);
ef4bddc2 64extern void prepare_move_operands (rtx[], machine_mode mode);
8e701300 65extern bool sh_expand_cmpstr (rtx *);
ca494b8d 66extern bool sh_expand_cmpnstr (rtx *);
3a1a7897 67extern bool sh_expand_strlen (rtx *);
fa1aecc1 68extern void sh_expand_setmem (rtx *);
ef4bddc2 69extern enum rtx_code prepare_cbranch_operands (rtx *, machine_mode mode,
78d310c2 70 enum rtx_code comparison);
5fa396ad 71extern void expand_cbranchsi4 (rtx *operands, enum rtx_code comparison);
78d310c2 72extern bool expand_cbranchdi4 (rtx *operands, enum rtx_code comparison);
f90b7a5a 73extern void sh_emit_scc_to_t (enum rtx_code, rtx, rtx);
ef4bddc2
RS
74extern void sh_emit_compare_and_branch (rtx *, machine_mode);
75extern void sh_emit_compare_and_set (rtx *, machine_mode);
70d4736c 76extern bool sh_ashlsi_clobbers_t_reg_p (rtx);
5592815a 77extern bool sh_lshrsi_clobbers_t_reg_p (rtx);
cf277499
SB
78extern void gen_shifty_op (int, rtx *);
79extern void gen_shifty_hi_op (int, rtx *);
aaf701c5
OE
80extern bool expand_ashiftrt (rtx *);
81extern bool sh_dynamicalize_shift_p (rtx);
cf277499
SB
82extern int shl_and_kind (rtx, rtx, int *);
83extern int shl_and_length (rtx);
84extern int shl_and_scr_length (rtx);
aaf701c5 85extern bool gen_shl_and (rtx, rtx, rtx, rtx);
cf277499
SB
86extern int shl_sext_kind (rtx, rtx, int *);
87extern int shl_sext_length (rtx);
aaf701c5 88extern bool gen_shl_sext (rtx, rtx, rtx, rtx);
cf277499 89extern int regs_used (rtx, int);
b32d5189 90extern void fixup_addr_diff_vecs (rtx_insn *);
4dea3bff 91extern int get_dest_uid (rtx_insn *, int);
6cb7eb41 92extern void final_prescan_insn (rtx_insn *, rtx *, int);
ef4bddc2
RS
93extern enum tls_model tls_symbolic_operand (rtx, machine_mode);
94extern bool system_reg_operand (rtx, machine_mode);
b32d5189 95extern bool reg_unused_after (rtx, rtx_insn *);
6cb7eb41 96extern int sh_insn_length_adjustment (rtx_insn *);
10c17a58 97extern bool sh_expand_t_scc (rtx *);
ef4bddc2
RS
98extern rtx sh_gen_truncate (machine_mode, rtx, int);
99extern bool sh_vector_mode_supported_p (machine_mode);
d16202ba 100extern bool sh_cfun_trap_exit_p (void);
4eac9c2b 101extern rtx sh_find_equiv_gbr_addr (rtx_insn* cur_insn, rtx mem);
b4eca9c8 102extern int sh_eval_treg_value (rtx op);
91f65b12
OE
103extern HOST_WIDE_INT sh_disp_addr_displacement (rtx mem_op);
104extern int sh_max_mov_insn_displacement (machine_mode mode, bool consider_sh2a);
6efc6b7f 105extern bool sh_movsf_ie_ra_split_p (rtx, rtx, rtx);
fbce972a 106extern void sh_expand_sym_label2reg (rtx, rtx, rtx, bool);
26943929
OE
107
108/* Result value of sh_find_set_of_reg. */
109struct set_of_reg
110{
111 /* The insn where sh_find_set_of_reg stopped looking.
112 Can be NULL_RTX if the end of the insn list was reached. */
355e9975 113 rtx_insn* insn;
26943929
OE
114
115 /* The set rtx of the specified reg if found, NULL_RTX otherwise. */
116 const_rtx set_rtx;
117
118 /* The set source rtx of the specified reg if found, NULL_RTX otherwise.
119 Usually, this is the most interesting return value. */
120 rtx set_src;
121};
122
c483db37
AO
123/* Given a reg rtx and a start insn, try to find the insn that sets
124 the specified reg by using the specified insn stepping function,
125 such as 'prev_nonnote_nondebug_insn_bb'. When the insn is found,
126 try to extract the rtx of the reg set. */
355e9975 127template <typename F> inline set_of_reg
83e3f98b
OE
128sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc,
129 bool ignore_reg_reg_copies = false)
355e9975
OE
130{
131 set_of_reg result;
132 result.insn = insn;
133 result.set_rtx = NULL_RTX;
134 result.set_src = NULL_RTX;
135
136 if (!REG_P (reg) || insn == NULL_RTX)
137 return result;
138
f6ba5bb2 139 for (rtx_insn* i = stepfunc (insn); i != NULL_RTX; i = stepfunc (i))
355e9975 140 {
f6ba5bb2 141 if (BARRIER_P (i))
b151091d 142 break;
f6ba5bb2
OE
143 if (!INSN_P (i) || DEBUG_INSN_P (i))
144 continue;
145 if (reg_set_p (reg, i))
355e9975 146 {
f6ba5bb2
OE
147 if (CALL_P (i))
148 break;
149
150 result.insn = i;
151 result.set_rtx = set_of (reg, i);
355e9975
OE
152
153 if (result.set_rtx == NULL_RTX || GET_CODE (result.set_rtx) != SET)
b151091d 154 break;
355e9975
OE
155
156 result.set_src = XEXP (result.set_rtx, 1);
83e3f98b
OE
157
158 if (ignore_reg_reg_copies && REG_P (result.set_src))
159 {
160 reg = result.set_src;
161 continue;
162 }
163 if (ignore_reg_reg_copies && SUBREG_P (result.set_src)
164 && REG_P (SUBREG_REG (result.set_src)))
165 {
166 reg = SUBREG_REG (result.set_src);
167 continue;
168 }
169
b151091d 170 break;
355e9975
OE
171 }
172 }
173
da5b1ec1
OE
174 /* If the searched reg is found inside a (mem (post_inc:SI (reg))), set_of
175 will return NULL and set_rtx will be NULL.
176 In this case report a 'not found'. result.insn will always be non-null
177 at this point, so no need to check it. */
178 if (result.set_src != NULL && result.set_rtx == NULL)
179 result.set_src = NULL;
b151091d 180
355e9975
OE
181 return result;
182}
183
83e3f98b
OE
184/* Result value of sh_find_extending_set_of_reg. */
185struct sh_extending_set_of_reg : public set_of_reg
186{
187 /* The mode the set is extending from (QImode or HImode), or VOIDmode if
188 this is not a zero/sign extending set. */
189 machine_mode from_mode;
190
191 /* ZERO_EXTEND, SIGN_EXTEND or UNKNOWN. */
192 rtx_code ext_code;
193
194 sh_extending_set_of_reg (rtx_insn* i)
195 {
196 insn = i;
197 set_rtx = NULL;
198 set_src = NULL;
199 from_mode = VOIDmode;
200 ext_code = UNKNOWN;
201 }
202
203 sh_extending_set_of_reg (const set_of_reg& rhs)
204 {
205 *((set_of_reg*)this) = rhs;
206 from_mode = VOIDmode;
207 ext_code = UNKNOWN;
208 }
209
841dbf80
OE
210 /* Returns true if it's possible to use the source reg of the sign
211 or zero extending set directly, bypassing the extension. */
212 bool can_use_as_unextended_reg (void) const;
213
214 /* Returns the reg rtx of the sign or zero extending set source, that can
215 be safely used at the specified insn in SImode. */
216 rtx use_as_unextended_reg (rtx_insn* use_at_insn) const;
217
83e3f98b
OE
218 /* Returns the reg rtx of the sign or zero extending result, that can be
219 safely used at the specified insn in SImode. If the set source is an
220 implicitly sign extending mem load, the mem load is converted into an
221 explicitly sign extending mem load. */
222 rtx use_as_extended_reg (rtx_insn* use_at_insn) const;
223};
224
225extern sh_extending_set_of_reg sh_find_extending_set_of_reg (rtx reg,
226 rtx_insn* insn);
227
355e9975
OE
228extern bool sh_is_logical_t_store_expr (rtx op, rtx_insn* insn);
229extern rtx sh_try_omit_signzero_extend (rtx extended_op, rtx_insn* insn);
230extern bool sh_split_movrt_negc_to_movt_xor (rtx_insn* curr_insn,
231 rtx operands[]);
83e3f98b
OE
232extern void sh_split_tst_subregs (rtx_insn* curr_insn,
233 machine_mode subreg_mode, int subreg_offset,
234 rtx operands[]);
841dbf80
OE
235
236extern bool sh_is_nott_insn (const rtx_insn* i);
237extern rtx sh_movt_set_dest (const rtx_insn* i);
50c6dd20 238extern rtx sh_movt_set_dest (const_rtx i);
841dbf80 239extern rtx sh_movrt_set_dest (const rtx_insn* i);
50c6dd20 240extern rtx sh_movrt_set_dest (const_rtx i);
841dbf80
OE
241
242inline bool sh_is_movt_insn (const rtx_insn* i)
243{
244 return sh_movt_set_dest (i) != NULL;
245}
246
247inline bool sh_is_movrt_insn (const rtx_insn* i)
248{
249 return sh_movrt_set_dest (i) != NULL;
250}
251
252extern bool sh_insn_operands_modified_between_p (rtx_insn* operands_insn,
253 const rtx_insn* from,
254 const rtx_insn* to);
255
256extern bool sh_reg_dead_or_unused_after_insn (const rtx_insn* i, int regno);
83e3f98b 257extern void sh_remove_reg_dead_or_unused_notes (rtx_insn* i, int regno);
dac2637b 258extern rtx_insn* sh_check_add_incdec_notes (rtx_insn* i);
7dc5a9bb
OE
259extern rtx sh_remove_overlapping_post_inc (rtx dst, rtx src);
260extern rtx_insn* sh_peephole_emit_move_insn (rtx dst, rtx src);
841dbf80
OE
261
262extern bool sh_in_recog_treg_set_expr (void);
263extern bool sh_recog_treg_set_expr (rtx op, machine_mode mode);
264
265/* Result value of sh_split_treg_set_expr. Contains the first insn emitted
266 and the optional trailing nott insn. */
267class sh_treg_insns
268{
269public:
270 sh_treg_insns (void) : m_first_insn (NULL), m_trailing_nott_insn (NULL) { }
271 sh_treg_insns (rtx_insn* first_insn, rtx_insn* nott_insn)
272 : m_first_insn (first_insn),
273 m_trailing_nott_insn (nott_insn)
274 { }
275
276 bool was_treg_operand (void) const { return m_first_insn == NULL; }
277 bool has_trailing_nott (void) const { return m_trailing_nott_insn != NULL; }
278 rtx_insn* trailing_nott (void) const { return m_trailing_nott_insn; }
279 rtx_insn* first_insn (void) const { return m_first_insn; }
280
281 /* If there is a trailing nott, remove it from the emitted insns and
282 return true. Return false otherwise. */
283 bool
284 remove_trailing_nott (void)
285 {
286 if (!has_trailing_nott ())
287 return false;
288
289 remove_insn (trailing_nott ());
290 return true;
291 }
292
293private:
294 rtx_insn* m_first_insn;
295 rtx_insn* m_trailing_nott_insn;
296};
297
298extern sh_treg_insns sh_split_treg_set_expr (rtx x, rtx_insn* curr_insn);
299
e22daa4b
OE
300enum
301{
302 /* An effective conditional branch distance of zero bytes is impossible.
303 Hence we can use it to designate an unknown value. */
304 unknown_cbranch_distance = 0u,
305 infinite_cbranch_distance = ~0u
306};
307
308unsigned int
309sh_cbranch_distance (rtx_insn* cbranch_insn,
310 unsigned int max_dist = infinite_cbranch_distance);
311
318881c0
KG
312#endif /* RTX_CODE */
313
9597375a
OE
314extern void sh_cpu_cpp_builtins (cpp_reader* pfile);
315
cf277499 316extern const char *output_jump_label_table (void);
f031c344 317extern rtx get_t_reg_rtx (void);
cf277499 318extern void sh_expand_prologue (void);
726d4cb7 319extern void sh_expand_epilogue (bool);
cf277499
SB
320extern void sh_set_return_address (rtx, rtx);
321extern int initial_elimination_offset (int, int);
aaf701c5
OE
322extern bool sh_hard_regno_rename_ok (unsigned int, unsigned int);
323extern bool sh_cfun_interrupt_handler_p (void);
324extern bool sh_cfun_resbank_handler_p (void);
325extern bool sh_attr_renesas_p (const_tree);
326extern bool sh_cfun_attr_renesas_p (void);
ef4bddc2 327extern bool sh_small_register_classes_for_mode_p (machine_mode);
cf277499 328extern void sh_mark_label (rtx, int);
b32d5189 329extern bool check_use_sfunc_addr (rtx_insn *, rtx);
9f09b1f2
R
330
331#ifdef HARD_CONST
cf277499 332extern void fpscr_set_from_mem (int, HARD_REG_SET);
9f09b1f2 333#endif
8b97c5f8 334
cf277499
SB
335extern void sh_pr_interrupt (struct cpp_reader *);
336extern void sh_pr_trapa (struct cpp_reader *);
337extern void sh_pr_nosave_low_regs (struct cpp_reader *);
1e44e857
DJ
338
339struct function_symbol_result
340{
341 function_symbol_result (void) : sym (NULL), lab (NULL) { }
342 function_symbol_result (rtx s, rtx l) : sym (s), lab (l) { }
343
344 rtx sym;
345 rtx lab;
346};
347
348extern function_symbol_result function_symbol (rtx, const char *,
349 sh_function_kind);
350extern rtx sh_get_fdpic_reg_initial_val (void);
fada1961 351extern rtx sh_get_pr_initial_val (void);
8b97c5f8 352
50fe8924 353extern void sh_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree,
ef4bddc2 354 signed int, machine_mode);
63a9de54 355extern rtx sh_dwarf_register_span (rtx);
61f71b34 356
aaf701c5
OE
357extern bool sh_contains_memref_p (rtx);
358extern bool sh_loads_bankedreg_p (rtx);
561642fa 359extern int sh2a_get_function_vector_number (rtx);
aaf701c5 360extern bool sh2a_is_function_vector_call (rtx);
3217af3e 361extern void sh_fix_range (const char *);
fc1fcfa0
KK
362extern machine_mode sh_hard_regno_caller_save_mode (unsigned int, unsigned int,
363 machine_mode);
fcf8632e 364extern bool sh_can_use_simple_return_p (void);
1e44e857 365extern rtx sh_load_function_descriptor (rtx);
88657302 366#endif /* ! GCC_SH_PROTOS_H */