]> 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
7b23765d 1/* Definitions of target machine for GNU compiler for Renesas / SuperH SH.
f1717362 2 Copyright (C) 1993-2016 Free Software Foundation, Inc.
b7dbbdb2 3 Contributed by Steve Chamberlain (sac@cygnus.com).
4 Improved by Jim Wilson (wilson@cygnus.com).
5
187b36cf 6This file is part of GCC.
b7dbbdb2 7
187b36cf 8GCC is free software; you can redistribute it and/or modify
b7dbbdb2 9it under the terms of the GNU General Public License as published by
038d1e19 10the Free Software Foundation; either version 3, or (at your option)
b7dbbdb2 11any later version.
12
187b36cf 13GCC is distributed in the hope that it will be useful,
b7dbbdb2 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
038d1e19 19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
b7dbbdb2 21
1fcd08b1 22#ifndef GCC_SH_PROTOS_H
23#define GCC_SH_PROTOS_H
24
59312820 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
7928e854 38/* Atomic model. */
39struct sh_atomic_model
40{
41 enum enum_type
42 {
43 none = 0,
44 soft_gusa,
45 hard_llcs,
46 soft_tcb,
47 soft_imask,
48
49 num_models
50 };
51
52 /* If strict is set, disallow mixing of different models, as it would
53 happen on SH4A. */
54 bool strict;
55 enum_type type;
cfaba078 56
57 /* Name string as it was specified on the command line. */
58 const char* name;
59
60 /* Name string as it is used in C/C++ defines. */
61 const char* cdef_name;
62
63 /* GBR offset variable for TCB model. */
7928e854 64 int tcb_gbr_offset;
65};
66
67extern const sh_atomic_model& selected_atomic_model (void);
68
69/* Shortcuts to check the currently selected atomic model. */
70#define TARGET_ATOMIC_ANY \
6cf92cc1 71 (selected_atomic_model ().type != sh_atomic_model::none)
7928e854 72
73#define TARGET_ATOMIC_STRICT \
6cf92cc1 74 (selected_atomic_model ().strict)
7928e854 75
76#define TARGET_ATOMIC_SOFT_GUSA \
6cf92cc1 77 (selected_atomic_model ().type == sh_atomic_model::soft_gusa)
7928e854 78
79#define TARGET_ATOMIC_HARD_LLCS \
6cf92cc1 80 (selected_atomic_model ().type == sh_atomic_model::hard_llcs)
7928e854 81
82#define TARGET_ATOMIC_SOFT_TCB \
6cf92cc1 83 (selected_atomic_model ().type == sh_atomic_model::soft_tcb)
7928e854 84
85#define TARGET_ATOMIC_SOFT_TCB_GBR_OFFSET_RTX \
86 GEN_INT (selected_atomic_model ().tcb_gbr_offset)
87
88#define TARGET_ATOMIC_SOFT_IMASK \
6cf92cc1 89 (selected_atomic_model ().type == sh_atomic_model::soft_imask)
7928e854 90
b7dbbdb2 91#ifdef RTX_CODE
9435e831 92extern rtx sh_fsca_sf2int (void);
9435e831 93extern rtx sh_fsca_int2sf (void);
b7dbbdb2 94
95/* Declare functions defined in sh.c and used in templates. */
2dd4467f 96extern bool sh_lra_p (void);
b7dbbdb2 97
d3ffa7b4 98extern const char *output_branch (int, rtx_insn *, rtx *);
b82334f7 99extern const char *output_ieee_ccmpeq (rtx_insn *, rtx *);
100extern const char *output_branchy_insn (enum rtx_code, const char *,
101 rtx_insn *, rtx *);
3754d046 102extern const char *output_movedouble (rtx, rtx[], machine_mode);
103extern const char *output_movepcrel (rtx, rtx[], machine_mode);
b82334f7 104extern const char *output_far_jump (rtx_insn *, rtx);
b7dbbdb2 105
d3ffa7b4 106extern rtx sfunc_uses_reg (rtx_insn *);
91a55c11 107extern int barrier_align (rtx_insn *);
ed3e6e5d 108extern int sh_loop_align (rtx_insn *);
a3b1178e 109extern bool fp_zero_operand (rtx);
110extern bool fp_one_operand (rtx);
3754d046 111extern bool sh_legitimate_index_p (machine_mode, rtx, bool, bool);
112extern bool sh_legitimize_reload_address (rtx *, machine_mode, int, int);
113extern rtx legitimize_pic_address (rtx, machine_mode, rtx);
a3b1178e 114extern bool nonpic_symbol_mentioned_p (rtx);
04f04b72 115extern void output_pic_addr_const (FILE *, rtx);
a3b1178e 116extern bool expand_block_move (rtx *);
3754d046 117extern void prepare_move_operands (rtx[], machine_mode mode);
ccd57e8a 118extern bool sh_expand_cmpstr (rtx *);
b421555d 119extern bool sh_expand_cmpnstr (rtx *);
c2daae6e 120extern bool sh_expand_strlen (rtx *);
1878fb5b 121extern void sh_expand_setmem (rtx *);
3754d046 122extern enum rtx_code prepare_cbranch_operands (rtx *, machine_mode mode,
5be30882 123 enum rtx_code comparison);
124extern void expand_cbranchsi4 (rtx *operands, enum rtx_code comparison, int);
125extern bool expand_cbranchdi4 (rtx *operands, enum rtx_code comparison);
74f4459c 126extern void sh_emit_scc_to_t (enum rtx_code, rtx, rtx);
3754d046 127extern rtx sh_emit_cheap_store_flag (machine_mode, enum rtx_code, rtx, rtx);
128extern void sh_emit_compare_and_branch (rtx *, machine_mode);
129extern void sh_emit_compare_and_set (rtx *, machine_mode);
55c71520 130extern bool sh_ashlsi_clobbers_t_reg_p (rtx);
8cec7a6e 131extern bool sh_lshrsi_clobbers_t_reg_p (rtx);
04f04b72 132extern void gen_shifty_op (int, rtx *);
133extern void gen_shifty_hi_op (int, rtx *);
a3b1178e 134extern bool expand_ashiftrt (rtx *);
135extern bool sh_dynamicalize_shift_p (rtx);
04f04b72 136extern int shl_and_kind (rtx, rtx, int *);
137extern int shl_and_length (rtx);
138extern int shl_and_scr_length (rtx);
a3b1178e 139extern bool gen_shl_and (rtx, rtx, rtx, rtx);
04f04b72 140extern int shl_sext_kind (rtx, rtx, int *);
141extern int shl_sext_length (rtx);
a3b1178e 142extern bool gen_shl_sext (rtx, rtx, rtx, rtx);
04f04b72 143extern rtx gen_datalabel_ref (rtx);
144extern int regs_used (rtx, int);
91a55c11 145extern void fixup_addr_diff_vecs (rtx_insn *);
04f04b72 146extern int get_dest_uid (rtx, int);
b82334f7 147extern void final_prescan_insn (rtx_insn *, rtx *, int);
3754d046 148extern enum tls_model tls_symbolic_operand (rtx, machine_mode);
149extern bool system_reg_operand (rtx, machine_mode);
91a55c11 150extern bool reg_unused_after (rtx, rtx_insn *);
b82334f7 151extern int sh_insn_length_adjustment (rtx_insn *);
04f04b72 152extern void sh_expand_unop_v2sf (enum rtx_code, rtx, rtx);
153extern void sh_expand_binop_v2sf (enum rtx_code, rtx, rtx, rtx);
9db04979 154extern bool sh_expand_t_scc (rtx *);
3754d046 155extern rtx sh_gen_truncate (machine_mode, rtx, int);
156extern bool sh_vector_mode_supported_p (machine_mode);
c8378feb 157extern bool sh_cfun_trap_exit_p (void);
1c733bf7 158extern rtx sh_find_equiv_gbr_addr (rtx_insn* cur_insn, rtx mem);
21910658 159extern int sh_eval_treg_value (rtx op);
9db63610 160extern HOST_WIDE_INT sh_disp_addr_displacement (rtx mem_op);
161extern int sh_max_mov_insn_displacement (machine_mode mode, bool consider_sh2a);
90e650e5 162extern bool sh_movsf_ie_ra_split_p (rtx, rtx, rtx);
ec0e49e4 163extern void sh_expand_sym_label2reg (rtx, rtx, rtx, bool);
99af687a 164
165/* Result value of sh_find_set_of_reg. */
166struct set_of_reg
167{
168 /* The insn where sh_find_set_of_reg stopped looking.
169 Can be NULL_RTX if the end of the insn list was reached. */
33f075ea 170 rtx_insn* insn;
99af687a 171
172 /* The set rtx of the specified reg if found, NULL_RTX otherwise. */
173 const_rtx set_rtx;
174
175 /* The set source rtx of the specified reg if found, NULL_RTX otherwise.
176 Usually, this is the most interesting return value. */
177 rtx set_src;
178};
179
33f075ea 180/* Given a reg rtx and a start insn, try to find the insn that sets the
181 specified reg by using the specified insn stepping function, such as
182 'prev_nonnote_insn_bb'. When the insn is found, try to extract the rtx
183 of the reg set. */
184template <typename F> inline set_of_reg
394e78ee 185sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc,
186 bool ignore_reg_reg_copies = false)
33f075ea 187{
188 set_of_reg result;
189 result.insn = insn;
190 result.set_rtx = NULL_RTX;
191 result.set_src = NULL_RTX;
192
193 if (!REG_P (reg) || insn == NULL_RTX)
194 return result;
195
9971a66b 196 for (rtx_insn* i = stepfunc (insn); i != NULL_RTX; i = stepfunc (i))
33f075ea 197 {
9971a66b 198 if (BARRIER_P (i))
4a03e703 199 break;
9971a66b 200 if (!INSN_P (i) || DEBUG_INSN_P (i))
201 continue;
202 if (reg_set_p (reg, i))
33f075ea 203 {
9971a66b 204 if (CALL_P (i))
205 break;
206
207 result.insn = i;
208 result.set_rtx = set_of (reg, i);
33f075ea 209
210 if (result.set_rtx == NULL_RTX || GET_CODE (result.set_rtx) != SET)
4a03e703 211 break;
33f075ea 212
213 result.set_src = XEXP (result.set_rtx, 1);
394e78ee 214
215 if (ignore_reg_reg_copies && REG_P (result.set_src))
216 {
217 reg = result.set_src;
218 continue;
219 }
220 if (ignore_reg_reg_copies && SUBREG_P (result.set_src)
221 && REG_P (SUBREG_REG (result.set_src)))
222 {
223 reg = SUBREG_REG (result.set_src);
224 continue;
225 }
226
4a03e703 227 break;
33f075ea 228 }
229 }
230
4a03e703 231 if (result.set_src != NULL)
232 gcc_assert (result.insn != NULL && result.set_rtx != NULL);
233
33f075ea 234 return result;
235}
236
394e78ee 237/* Result value of sh_find_extending_set_of_reg. */
238struct sh_extending_set_of_reg : public set_of_reg
239{
240 /* The mode the set is extending from (QImode or HImode), or VOIDmode if
241 this is not a zero/sign extending set. */
242 machine_mode from_mode;
243
244 /* ZERO_EXTEND, SIGN_EXTEND or UNKNOWN. */
245 rtx_code ext_code;
246
247 sh_extending_set_of_reg (rtx_insn* i)
248 {
249 insn = i;
250 set_rtx = NULL;
251 set_src = NULL;
252 from_mode = VOIDmode;
253 ext_code = UNKNOWN;
254 }
255
256 sh_extending_set_of_reg (const set_of_reg& rhs)
257 {
258 *((set_of_reg*)this) = rhs;
259 from_mode = VOIDmode;
260 ext_code = UNKNOWN;
261 }
262
6c97af1b 263 /* Returns true if it's possible to use the source reg of the sign
264 or zero extending set directly, bypassing the extension. */
265 bool can_use_as_unextended_reg (void) const;
266
267 /* Returns the reg rtx of the sign or zero extending set source, that can
268 be safely used at the specified insn in SImode. */
269 rtx use_as_unextended_reg (rtx_insn* use_at_insn) const;
270
394e78ee 271 /* Returns the reg rtx of the sign or zero extending result, that can be
272 safely used at the specified insn in SImode. If the set source is an
273 implicitly sign extending mem load, the mem load is converted into an
274 explicitly sign extending mem load. */
275 rtx use_as_extended_reg (rtx_insn* use_at_insn) const;
276};
277
278extern sh_extending_set_of_reg sh_find_extending_set_of_reg (rtx reg,
279 rtx_insn* insn);
280
33f075ea 281extern bool sh_is_logical_t_store_expr (rtx op, rtx_insn* insn);
282extern rtx sh_try_omit_signzero_extend (rtx extended_op, rtx_insn* insn);
283extern bool sh_split_movrt_negc_to_movt_xor (rtx_insn* curr_insn,
284 rtx operands[]);
394e78ee 285extern void sh_split_tst_subregs (rtx_insn* curr_insn,
286 machine_mode subreg_mode, int subreg_offset,
287 rtx operands[]);
6c97af1b 288
289extern bool sh_is_nott_insn (const rtx_insn* i);
290extern rtx sh_movt_set_dest (const rtx_insn* i);
291extern rtx sh_movrt_set_dest (const rtx_insn* i);
292
293inline bool sh_is_movt_insn (const rtx_insn* i)
294{
295 return sh_movt_set_dest (i) != NULL;
296}
297
298inline bool sh_is_movrt_insn (const rtx_insn* i)
299{
300 return sh_movrt_set_dest (i) != NULL;
301}
302
303extern bool sh_insn_operands_modified_between_p (rtx_insn* operands_insn,
304 const rtx_insn* from,
305 const rtx_insn* to);
306
307extern bool sh_reg_dead_or_unused_after_insn (const rtx_insn* i, int regno);
394e78ee 308extern void sh_remove_reg_dead_or_unused_notes (rtx_insn* i, int regno);
e13062e7 309extern rtx_insn* sh_check_add_incdec_notes (rtx_insn* i);
0394e184 310extern rtx sh_remove_overlapping_post_inc (rtx dst, rtx src);
311extern rtx_insn* sh_peephole_emit_move_insn (rtx dst, rtx src);
6c97af1b 312
313extern bool sh_in_recog_treg_set_expr (void);
314extern bool sh_recog_treg_set_expr (rtx op, machine_mode mode);
315
316/* Result value of sh_split_treg_set_expr. Contains the first insn emitted
317 and the optional trailing nott insn. */
318class sh_treg_insns
319{
320public:
321 sh_treg_insns (void) : m_first_insn (NULL), m_trailing_nott_insn (NULL) { }
322 sh_treg_insns (rtx_insn* first_insn, rtx_insn* nott_insn)
323 : m_first_insn (first_insn),
324 m_trailing_nott_insn (nott_insn)
325 { }
326
327 bool was_treg_operand (void) const { return m_first_insn == NULL; }
328 bool has_trailing_nott (void) const { return m_trailing_nott_insn != NULL; }
329 rtx_insn* trailing_nott (void) const { return m_trailing_nott_insn; }
330 rtx_insn* first_insn (void) const { return m_first_insn; }
331
332 /* If there is a trailing nott, remove it from the emitted insns and
333 return true. Return false otherwise. */
334 bool
335 remove_trailing_nott (void)
336 {
337 if (!has_trailing_nott ())
338 return false;
339
340 remove_insn (trailing_nott ());
341 return true;
342 }
343
344private:
345 rtx_insn* m_first_insn;
346 rtx_insn* m_trailing_nott_insn;
347};
348
349extern sh_treg_insns sh_split_treg_set_expr (rtx x, rtx_insn* curr_insn);
350
b7dbbdb2 351#endif /* RTX_CODE */
352
cfaba078 353extern void sh_cpu_cpp_builtins (cpp_reader* pfile);
354
04f04b72 355extern const char *output_jump_label_table (void);
a6be7821 356extern rtx get_t_reg_rtx (void);
04f04b72 357extern int sh_media_register_for_return (void);
358extern void sh_expand_prologue (void);
66209063 359extern void sh_expand_epilogue (bool);
04f04b72 360extern void sh_set_return_address (rtx, rtx);
361extern int initial_elimination_offset (int, int);
a3b1178e 362extern bool sh_hard_regno_rename_ok (unsigned int, unsigned int);
363extern bool sh_cfun_interrupt_handler_p (void);
364extern bool sh_cfun_resbank_handler_p (void);
365extern bool sh_attr_renesas_p (const_tree);
366extern bool sh_cfun_attr_renesas_p (void);
22aae821 367extern bool sh_cannot_change_mode_class
3754d046 368 (machine_mode, machine_mode, enum reg_class);
369extern bool sh_small_register_classes_for_mode_p (machine_mode);
04f04b72 370extern void sh_mark_label (rtx, int);
91a55c11 371extern bool check_use_sfunc_addr (rtx_insn *, rtx);
18862b5a 372
373#ifdef HARD_CONST
04f04b72 374extern void fpscr_set_from_mem (int, HARD_REG_SET);
18862b5a 375#endif
1fcd08b1 376
04f04b72 377extern void sh_pr_interrupt (struct cpp_reader *);
378extern void sh_pr_trapa (struct cpp_reader *);
379extern void sh_pr_nosave_low_regs (struct cpp_reader *);
bcc58dc6 380
381struct function_symbol_result
382{
383 function_symbol_result (void) : sym (NULL), lab (NULL) { }
384 function_symbol_result (rtx s, rtx l) : sym (s), lab (l) { }
385
386 rtx sym;
387 rtx lab;
388};
389
390extern function_symbol_result function_symbol (rtx, const char *,
391 sh_function_kind);
392extern rtx sh_get_fdpic_reg_initial_val (void);
41fafa66 393extern rtx sh_get_pr_initial_val (void);
1fcd08b1 394
6c049e03 395extern void sh_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree,
3754d046 396 signed int, machine_mode);
e1190e3a 397extern rtx sh_dwarf_register_span (rtx);
45550790 398
727d658b 399extern int shmedia_cleanup_truncate (rtx);
59312820 400
a3b1178e 401extern bool sh_contains_memref_p (rtx);
402extern bool sh_loads_bankedreg_p (rtx);
59312820 403extern rtx shmedia_prepare_call_address (rtx fnaddr, int is_sibcall);
5241f4ad 404extern int sh2a_get_function_vector_number (rtx);
a3b1178e 405extern bool sh2a_is_function_vector_call (rtx);
d47be40b 406extern void sh_fix_range (const char *);
3754d046 407extern bool sh_hard_regno_mode_ok (unsigned int, machine_mode);
ea68d4ba 408extern machine_mode sh_hard_regno_caller_save_mode (unsigned int, unsigned int,
409 machine_mode);
9579a4b9 410extern bool sh_can_use_simple_return_p (void);
bcc58dc6 411extern rtx sh_load_function_descriptor (rtx);
2a281353 412#endif /* ! GCC_SH_PROTOS_H */