Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/sh/sh-protos.h @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
rev | line source |
---|---|
0 | 1 /* Definitions of target machine for GNU compiler for Renesas / SuperH SH. |
145 | 2 Copyright (C) 1993-2020 Free Software Foundation, Inc. |
0 | 3 Contributed by Steve Chamberlain (sac@cygnus.com). |
4 Improved by Jim Wilson (wilson@cygnus.com). | |
5 | |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify | |
9 it under the terms of the GNU General Public License as published by | |
10 the Free Software Foundation; either version 3, or (at your option) | |
11 any later version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 GNU General Public License for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. */ | |
21 | |
22 #ifndef GCC_SH_PROTOS_H | |
23 #define GCC_SH_PROTOS_H | |
24 | |
25 enum 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 | |
38 #ifdef RTX_CODE | |
39 extern rtx sh_fsca_sf2int (void); | |
40 extern rtx sh_fsca_int2sf (void); | |
41 | |
42 /* Declare functions defined in sh.c and used in templates. */ | |
111 | 43 extern bool sh_lra_p (void); |
0 | 44 |
111 | 45 extern const char *output_branch (int, rtx_insn *, rtx *); |
46 extern const char *output_ieee_ccmpeq (rtx_insn *, rtx *); | |
47 extern const char *output_branchy_insn (enum rtx_code, const char *, | |
48 rtx_insn *, rtx *); | |
49 extern const char *output_movedouble (rtx, rtx[], machine_mode); | |
50 extern const char *output_movepcrel (rtx, rtx[], machine_mode); | |
51 extern const char *output_far_jump (rtx_insn *, rtx); | |
0 | 52 |
111 | 53 extern rtx sfunc_uses_reg (rtx_insn *); |
54 extern int barrier_align (rtx_insn *); | |
55 extern int sh_loop_align (rtx_insn *); | |
56 extern bool fp_zero_operand (rtx); | |
57 extern bool fp_one_operand (rtx); | |
58 extern bool sh_legitimate_index_p (machine_mode, rtx, bool, bool); | |
59 extern bool sh_legitimize_reload_address (rtx *, machine_mode, int, int); | |
60 extern rtx legitimize_pic_address (rtx, machine_mode, rtx); | |
61 extern bool nonpic_symbol_mentioned_p (rtx); | |
0 | 62 extern void output_pic_addr_const (FILE *, rtx); |
111 | 63 extern bool expand_block_move (rtx *); |
64 extern void prepare_move_operands (rtx[], machine_mode mode); | |
65 extern bool sh_expand_cmpstr (rtx *); | |
66 extern bool sh_expand_cmpnstr (rtx *); | |
67 extern bool sh_expand_strlen (rtx *); | |
68 extern void sh_expand_setmem (rtx *); | |
69 extern enum rtx_code prepare_cbranch_operands (rtx *, machine_mode mode, | |
0 | 70 enum rtx_code comparison); |
111 | 71 extern void expand_cbranchsi4 (rtx *operands, enum rtx_code comparison); |
0 | 72 extern bool expand_cbranchdi4 (rtx *operands, enum rtx_code comparison); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
73 extern void sh_emit_scc_to_t (enum rtx_code, rtx, rtx); |
111 | 74 extern void sh_emit_compare_and_branch (rtx *, machine_mode); |
75 extern void sh_emit_compare_and_set (rtx *, machine_mode); | |
76 extern bool sh_ashlsi_clobbers_t_reg_p (rtx); | |
77 extern bool sh_lshrsi_clobbers_t_reg_p (rtx); | |
0 | 78 extern void gen_shifty_op (int, rtx *); |
79 extern void gen_shifty_hi_op (int, rtx *); | |
111 | 80 extern bool expand_ashiftrt (rtx *); |
81 extern bool sh_dynamicalize_shift_p (rtx); | |
0 | 82 extern int shl_and_kind (rtx, rtx, int *); |
83 extern int shl_and_length (rtx); | |
84 extern int shl_and_scr_length (rtx); | |
111 | 85 extern bool gen_shl_and (rtx, rtx, rtx, rtx); |
0 | 86 extern int shl_sext_kind (rtx, rtx, int *); |
87 extern int shl_sext_length (rtx); | |
111 | 88 extern bool gen_shl_sext (rtx, rtx, rtx, rtx); |
0 | 89 extern int regs_used (rtx, int); |
111 | 90 extern void fixup_addr_diff_vecs (rtx_insn *); |
131 | 91 extern int get_dest_uid (rtx_insn *, int); |
111 | 92 extern void final_prescan_insn (rtx_insn *, rtx *, int); |
93 extern enum tls_model tls_symbolic_operand (rtx, machine_mode); | |
94 extern bool system_reg_operand (rtx, machine_mode); | |
95 extern bool reg_unused_after (rtx, rtx_insn *); | |
96 extern int sh_insn_length_adjustment (rtx_insn *); | |
97 extern bool sh_expand_t_scc (rtx *); | |
98 extern rtx sh_gen_truncate (machine_mode, rtx, int); | |
99 extern bool sh_vector_mode_supported_p (machine_mode); | |
100 extern bool sh_cfun_trap_exit_p (void); | |
101 extern rtx sh_find_equiv_gbr_addr (rtx_insn* cur_insn, rtx mem); | |
102 extern int sh_eval_treg_value (rtx op); | |
103 extern HOST_WIDE_INT sh_disp_addr_displacement (rtx mem_op); | |
104 extern int sh_max_mov_insn_displacement (machine_mode mode, bool consider_sh2a); | |
105 extern bool sh_movsf_ie_ra_split_p (rtx, rtx, rtx); | |
106 extern void sh_expand_sym_label2reg (rtx, rtx, rtx, bool); | |
107 | |
108 /* Result value of sh_find_set_of_reg. */ | |
109 struct 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. */ | |
113 rtx_insn* insn; | |
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 | |
131 | 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. */ | |
111 | 127 template <typename F> inline set_of_reg |
128 sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc, | |
129 bool ignore_reg_reg_copies = false) | |
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 | |
139 for (rtx_insn* i = stepfunc (insn); i != NULL_RTX; i = stepfunc (i)) | |
140 { | |
141 if (BARRIER_P (i)) | |
142 break; | |
143 if (!INSN_P (i) || DEBUG_INSN_P (i)) | |
144 continue; | |
145 if (reg_set_p (reg, i)) | |
146 { | |
147 if (CALL_P (i)) | |
148 break; | |
149 | |
150 result.insn = i; | |
151 result.set_rtx = set_of (reg, i); | |
152 | |
153 if (result.set_rtx == NULL_RTX || GET_CODE (result.set_rtx) != SET) | |
154 break; | |
155 | |
156 result.set_src = XEXP (result.set_rtx, 1); | |
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 | |
170 break; | |
171 } | |
172 } | |
173 | |
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; | |
180 | |
181 return result; | |
182 } | |
183 | |
184 /* Result value of sh_find_extending_set_of_reg. */ | |
185 struct 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 | |
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 | |
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 | |
225 extern sh_extending_set_of_reg sh_find_extending_set_of_reg (rtx reg, | |
226 rtx_insn* insn); | |
227 | |
228 extern bool sh_is_logical_t_store_expr (rtx op, rtx_insn* insn); | |
229 extern rtx sh_try_omit_signzero_extend (rtx extended_op, rtx_insn* insn); | |
230 extern bool sh_split_movrt_negc_to_movt_xor (rtx_insn* curr_insn, | |
231 rtx operands[]); | |
232 extern void sh_split_tst_subregs (rtx_insn* curr_insn, | |
233 machine_mode subreg_mode, int subreg_offset, | |
234 rtx operands[]); | |
235 | |
236 extern bool sh_is_nott_insn (const rtx_insn* i); | |
237 extern rtx sh_movt_set_dest (const rtx_insn* i); | |
238 extern rtx sh_movt_set_dest (const_rtx i); | |
239 extern rtx sh_movrt_set_dest (const rtx_insn* i); | |
240 extern rtx sh_movrt_set_dest (const_rtx i); | |
241 | |
242 inline bool sh_is_movt_insn (const rtx_insn* i) | |
243 { | |
244 return sh_movt_set_dest (i) != NULL; | |
245 } | |
246 | |
247 inline bool sh_is_movrt_insn (const rtx_insn* i) | |
248 { | |
249 return sh_movrt_set_dest (i) != NULL; | |
250 } | |
251 | |
252 extern bool sh_insn_operands_modified_between_p (rtx_insn* operands_insn, | |
253 const rtx_insn* from, | |
254 const rtx_insn* to); | |
255 | |
256 extern bool sh_reg_dead_or_unused_after_insn (const rtx_insn* i, int regno); | |
257 extern void sh_remove_reg_dead_or_unused_notes (rtx_insn* i, int regno); | |
258 extern rtx_insn* sh_check_add_incdec_notes (rtx_insn* i); | |
259 extern rtx sh_remove_overlapping_post_inc (rtx dst, rtx src); | |
260 extern rtx_insn* sh_peephole_emit_move_insn (rtx dst, rtx src); | |
261 | |
262 extern bool sh_in_recog_treg_set_expr (void); | |
263 extern 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. */ | |
267 class sh_treg_insns | |
268 { | |
269 public: | |
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 | |
293 private: | |
294 rtx_insn* m_first_insn; | |
295 rtx_insn* m_trailing_nott_insn; | |
296 }; | |
297 | |
298 extern sh_treg_insns sh_split_treg_set_expr (rtx x, rtx_insn* curr_insn); | |
299 | |
300 enum | |
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 | |
308 unsigned int | |
309 sh_cbranch_distance (rtx_insn* cbranch_insn, | |
310 unsigned int max_dist = infinite_cbranch_distance); | |
311 | |
0 | 312 #endif /* RTX_CODE */ |
313 | |
111 | 314 extern void sh_cpu_cpp_builtins (cpp_reader* pfile); |
315 | |
0 | 316 extern const char *output_jump_label_table (void); |
111 | 317 extern rtx get_t_reg_rtx (void); |
0 | 318 extern void sh_expand_prologue (void); |
319 extern void sh_expand_epilogue (bool); | |
320 extern void sh_set_return_address (rtx, rtx); | |
321 extern int initial_elimination_offset (int, int); | |
111 | 322 extern bool sh_hard_regno_rename_ok (unsigned int, unsigned int); |
323 extern bool sh_cfun_interrupt_handler_p (void); | |
324 extern bool sh_cfun_resbank_handler_p (void); | |
325 extern bool sh_attr_renesas_p (const_tree); | |
326 extern bool sh_cfun_attr_renesas_p (void); | |
327 extern bool sh_small_register_classes_for_mode_p (machine_mode); | |
0 | 328 extern void sh_mark_label (rtx, int); |
111 | 329 extern bool check_use_sfunc_addr (rtx_insn *, rtx); |
0 | 330 |
331 #ifdef HARD_CONST | |
332 extern void fpscr_set_from_mem (int, HARD_REG_SET); | |
333 #endif | |
334 | |
335 extern void sh_pr_interrupt (struct cpp_reader *); | |
336 extern void sh_pr_trapa (struct cpp_reader *); | |
337 extern void sh_pr_nosave_low_regs (struct cpp_reader *); | |
111 | 338 |
339 struct 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 | |
348 extern function_symbol_result function_symbol (rtx, const char *, | |
349 sh_function_kind); | |
350 extern rtx sh_get_fdpic_reg_initial_val (void); | |
0 | 351 extern rtx sh_get_pr_initial_val (void); |
352 | |
111 | 353 extern void sh_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, |
354 signed int, machine_mode); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
355 extern rtx sh_dwarf_register_span (rtx); |
0 | 356 |
111 | 357 extern bool sh_contains_memref_p (rtx); |
358 extern bool sh_loads_bankedreg_p (rtx); | |
0 | 359 extern int sh2a_get_function_vector_number (rtx); |
111 | 360 extern bool sh2a_is_function_vector_call (rtx); |
0 | 361 extern void sh_fix_range (const char *); |
111 | 362 extern machine_mode sh_hard_regno_caller_save_mode (unsigned int, unsigned int, |
363 machine_mode); | |
364 extern bool sh_can_use_simple_return_p (void); | |
365 extern rtx sh_load_function_descriptor (rtx); | |
0 | 366 #endif /* ! GCC_SH_PROTOS_H */ |