comparison gcc/config/sh/sh-protos.h @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 /* Definitions of target machine for GNU compiler for Renesas / SuperH SH. 1 /* Definitions of target machine for GNU compiler for Renesas / SuperH SH.
2 Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2003, 2 Copyright (C) 1993-2017 Free Software Foundation, Inc.
3 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by Steve Chamberlain (sac@cygnus.com). 3 Contributed by Steve Chamberlain (sac@cygnus.com).
6 Improved by Jim Wilson (wilson@cygnus.com). 4 Improved by Jim Wilson (wilson@cygnus.com).
7 5
8 This file is part of GCC. 6 This file is part of GCC.
9 7
37 SFUNC_STATIC 35 SFUNC_STATIC
38 }; 36 };
39 37
40 #ifdef RTX_CODE 38 #ifdef RTX_CODE
41 extern rtx sh_fsca_sf2int (void); 39 extern rtx sh_fsca_sf2int (void);
42 extern rtx sh_fsca_df2int (void);
43 extern rtx sh_fsca_int2sf (void); 40 extern rtx sh_fsca_int2sf (void);
44 41
45 /* Declare functions defined in sh.c and used in templates. */ 42 /* Declare functions defined in sh.c and used in templates. */
46 43 extern bool sh_lra_p (void);
47 extern const char *output_branch (int, rtx, rtx *); 44
48 extern const char *output_ieee_ccmpeq (rtx, rtx *); 45 extern const char *output_branch (int, rtx_insn *, rtx *);
49 extern const char *output_branchy_insn (enum rtx_code, const char *, rtx, rtx *); 46 extern const char *output_ieee_ccmpeq (rtx_insn *, rtx *);
50 extern const char *output_movedouble (rtx, rtx[], enum machine_mode); 47 extern const char *output_branchy_insn (enum rtx_code, const char *,
51 extern const char *output_movepcrel (rtx, rtx[], enum machine_mode); 48 rtx_insn *, rtx *);
52 extern const char *output_far_jump (rtx, rtx); 49 extern const char *output_movedouble (rtx, rtx[], machine_mode);
53 50 extern const char *output_movepcrel (rtx, rtx[], machine_mode);
54 extern struct rtx_def *sfunc_uses_reg (rtx); 51 extern const char *output_far_jump (rtx_insn *, rtx);
55 extern int barrier_align (rtx); 52
56 extern int sh_loop_align (rtx); 53 extern rtx sfunc_uses_reg (rtx_insn *);
57 extern int fp_zero_operand (rtx); 54 extern int barrier_align (rtx_insn *);
58 extern int fp_one_operand (rtx); 55 extern int sh_loop_align (rtx_insn *);
59 extern int fp_int_operand (rtx); 56 extern bool fp_zero_operand (rtx);
60 extern rtx get_fpscr_rtx (void); 57 extern bool fp_one_operand (rtx);
61 extern bool sh_legitimate_index_p (enum machine_mode, rtx); 58 extern bool sh_legitimate_index_p (machine_mode, rtx, bool, bool);
62 extern bool sh_legitimize_reload_address (rtx *, enum machine_mode, int, int); 59 extern bool sh_legitimize_reload_address (rtx *, machine_mode, int, int);
63 extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx); 60 extern rtx legitimize_pic_address (rtx, machine_mode, rtx);
64 extern int nonpic_symbol_mentioned_p (rtx); 61 extern bool nonpic_symbol_mentioned_p (rtx);
65 extern void emit_sf_insn (rtx);
66 extern void emit_df_insn (rtx);
67 extern void output_pic_addr_const (FILE *, rtx); 62 extern void output_pic_addr_const (FILE *, rtx);
68 extern int expand_block_move (rtx *); 63 extern bool expand_block_move (rtx *);
69 extern int prepare_move_operands (rtx[], enum machine_mode mode); 64 extern void prepare_move_operands (rtx[], machine_mode mode);
70 extern enum rtx_code prepare_cbranch_operands (rtx *, enum 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,
71 enum rtx_code comparison); 70 enum rtx_code comparison);
72 extern void expand_cbranchsi4 (rtx *operands, enum rtx_code comparison, int); 71 extern void expand_cbranchsi4 (rtx *operands, enum rtx_code comparison);
73 extern bool expand_cbranchdi4 (rtx *operands, enum rtx_code comparison); 72 extern bool expand_cbranchdi4 (rtx *operands, enum rtx_code comparison);
74 extern void sh_emit_scc_to_t (enum rtx_code, rtx, rtx); 73 extern void sh_emit_scc_to_t (enum rtx_code, rtx, rtx);
75 extern rtx sh_emit_cheap_store_flag (enum machine_mode, enum rtx_code, rtx, rtx); 74 extern void sh_emit_compare_and_branch (rtx *, machine_mode);
76 extern void sh_emit_compare_and_branch (rtx *, enum machine_mode); 75 extern void sh_emit_compare_and_set (rtx *, machine_mode);
77 extern void sh_emit_compare_and_set (rtx *, enum machine_mode); 76 extern bool sh_ashlsi_clobbers_t_reg_p (rtx);
78 extern int shift_insns_rtx (rtx); 77 extern bool sh_lshrsi_clobbers_t_reg_p (rtx);
79 extern void gen_ashift (int, int, rtx);
80 extern void gen_ashift_hi (int, int, rtx);
81 extern void gen_shifty_op (int, rtx *); 78 extern void gen_shifty_op (int, rtx *);
82 extern void gen_shifty_hi_op (int, rtx *); 79 extern void gen_shifty_hi_op (int, rtx *);
83 extern int expand_ashiftrt (rtx *); 80 extern bool expand_ashiftrt (rtx *);
84 extern int sh_dynamicalize_shift_p (rtx); 81 extern bool sh_dynamicalize_shift_p (rtx);
85 extern int shl_and_kind (rtx, rtx, int *); 82 extern int shl_and_kind (rtx, rtx, int *);
86 extern int shl_and_length (rtx); 83 extern int shl_and_length (rtx);
87 extern int shl_and_scr_length (rtx); 84 extern int shl_and_scr_length (rtx);
88 extern int gen_shl_and (rtx, rtx, rtx, rtx); 85 extern bool gen_shl_and (rtx, rtx, rtx, rtx);
89 extern int shl_sext_kind (rtx, rtx, int *); 86 extern int shl_sext_kind (rtx, rtx, int *);
90 extern int shl_sext_length (rtx); 87 extern int shl_sext_length (rtx);
91 extern int gen_shl_sext (rtx, rtx, rtx, rtx); 88 extern bool gen_shl_sext (rtx, rtx, rtx, rtx);
92 extern rtx gen_datalabel_ref (rtx);
93 extern int regs_used (rtx, int); 89 extern int regs_used (rtx, int);
94 extern void fixup_addr_diff_vecs (rtx); 90 extern void fixup_addr_diff_vecs (rtx_insn *);
95 extern int get_dest_uid (rtx, int); 91 extern int get_dest_uid (rtx, int);
96 extern void final_prescan_insn (rtx, rtx *, int); 92 extern void final_prescan_insn (rtx_insn *, rtx *, int);
97 extern int symbol_ref_operand (rtx, enum machine_mode); 93 extern enum tls_model tls_symbolic_operand (rtx, machine_mode);
98 extern enum tls_model tls_symbolic_operand (rtx, enum machine_mode); 94 extern bool system_reg_operand (rtx, machine_mode);
99 extern int system_reg_operand (rtx, enum machine_mode); 95 extern bool reg_unused_after (rtx, rtx_insn *);
100 extern int general_movsrc_operand (rtx, enum machine_mode); 96 extern int sh_insn_length_adjustment (rtx_insn *);
101 extern int general_movdst_operand (rtx, enum machine_mode); 97 extern bool sh_expand_t_scc (rtx *);
102 extern int arith_reg_operand (rtx, enum machine_mode); 98 extern rtx sh_gen_truncate (machine_mode, rtx, int);
103 extern int fp_arith_reg_operand (rtx, enum machine_mode); 99 extern bool sh_vector_mode_supported_p (machine_mode);
104 extern int arith_operand (rtx, enum machine_mode); 100 extern bool sh_cfun_trap_exit_p (void);
105 extern int arith_reg_or_0_operand (rtx, enum machine_mode); 101 extern rtx sh_find_equiv_gbr_addr (rtx_insn* cur_insn, rtx mem);
106 extern int logical_operand (rtx, enum machine_mode); 102 extern int sh_eval_treg_value (rtx op);
107 extern int tertiary_reload_operand (rtx, enum machine_mode); 103 extern HOST_WIDE_INT sh_disp_addr_displacement (rtx mem_op);
108 extern int fpscr_operand (rtx, enum machine_mode); 104 extern int sh_max_mov_insn_displacement (machine_mode mode, bool consider_sh2a);
109 extern int fpul_operand (rtx, enum machine_mode); 105 extern bool sh_movsf_ie_ra_split_p (rtx, rtx, rtx);
110 extern int commutative_float_operator (rtx, enum machine_mode); 106 extern void sh_expand_sym_label2reg (rtx, rtx, rtx, bool);
111 extern int noncommutative_float_operator (rtx, enum machine_mode); 107
112 extern int reg_unused_after (rtx, rtx); 108 /* Result value of sh_find_set_of_reg. */
113 extern void expand_sf_unop (rtx (*)(rtx, rtx, rtx), rtx *); 109 struct set_of_reg
114 extern void expand_sf_binop (rtx (*)(rtx, rtx, rtx, rtx), rtx *); 110 {
115 extern void expand_df_unop (rtx (*)(rtx, rtx, rtx), rtx *); 111 /* The insn where sh_find_set_of_reg stopped looking.
116 extern void expand_df_binop (rtx (*)(rtx, rtx, rtx, rtx), rtx *); 112 Can be NULL_RTX if the end of the insn list was reached. */
117 extern void expand_fp_branch (rtx (*)(void), rtx (*)(void)); 113 rtx_insn* insn;
118 extern int sh_insn_length_adjustment (rtx); 114
119 extern int sh_can_redirect_branch (rtx, rtx); 115 /* The set rtx of the specified reg if found, NULL_RTX otherwise. */
120 extern void sh_expand_unop_v2sf (enum rtx_code, rtx, rtx); 116 const_rtx set_rtx;
121 extern void sh_expand_binop_v2sf (enum rtx_code, rtx, rtx, rtx); 117
122 extern int sh_expand_t_scc (rtx *); 118 /* The set source rtx of the specified reg if found, NULL_RTX otherwise.
123 extern rtx sh_gen_truncate (enum machine_mode, rtx, int); 119 Usually, this is the most interesting return value. */
124 extern bool sh_vector_mode_supported_p (enum machine_mode); 120 rtx set_src;
121 };
122
123 /* Given a reg rtx and a start insn, try to find the insn that sets the
124 specified reg by using the specified insn stepping function, such as
125 'prev_nonnote_insn_bb'. When the insn is found, try to extract the rtx
126 of the reg set. */
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
125 #endif /* RTX_CODE */ 312 #endif /* RTX_CODE */
126 313
314 extern void sh_cpu_cpp_builtins (cpp_reader* pfile);
315
127 extern const char *output_jump_label_table (void); 316 extern const char *output_jump_label_table (void);
128 extern int sh_handle_pragma (int (*)(void), void (*)(int), const char *); 317 extern rtx get_t_reg_rtx (void);
129 extern struct rtx_def *get_fpscr_rtx (void);
130 extern int sh_media_register_for_return (void);
131 extern void sh_expand_prologue (void); 318 extern void sh_expand_prologue (void);
132 extern void sh_expand_epilogue (bool); 319 extern void sh_expand_epilogue (bool);
133 extern int sh_need_epilogue (void);
134 extern void sh_set_return_address (rtx, rtx); 320 extern void sh_set_return_address (rtx, rtx);
135 extern int initial_elimination_offset (int, int); 321 extern int initial_elimination_offset (int, int);
136 extern int fldi_ok (void); 322 extern bool sh_hard_regno_rename_ok (unsigned int, unsigned int);
137 extern int sh_hard_regno_rename_ok (unsigned int, unsigned int); 323 extern bool sh_cfun_interrupt_handler_p (void);
138 extern int sh_cfun_interrupt_handler_p (void); 324 extern bool sh_cfun_resbank_handler_p (void);
139 extern int sh_cfun_resbank_handler_p (void); 325 extern bool sh_attr_renesas_p (const_tree);
140 extern int sh_attr_renesas_p (const_tree); 326 extern bool sh_cfun_attr_renesas_p (void);
141 extern int sh_cfun_attr_renesas_p (void); 327 extern bool sh_small_register_classes_for_mode_p (machine_mode);
142 extern bool sh_cannot_change_mode_class
143 (enum machine_mode, enum machine_mode, enum reg_class);
144 extern bool sh_small_register_classes_for_mode_p (enum machine_mode);
145 extern void sh_mark_label (rtx, int); 328 extern void sh_mark_label (rtx, int);
146 extern int check_use_sfunc_addr (rtx, rtx); 329 extern bool check_use_sfunc_addr (rtx_insn *, rtx);
147 330
148 #ifdef HARD_CONST 331 #ifdef HARD_CONST
149 extern void fpscr_set_from_mem (int, HARD_REG_SET); 332 extern void fpscr_set_from_mem (int, HARD_REG_SET);
150 #endif 333 #endif
151 334
152 extern void sh_pr_interrupt (struct cpp_reader *); 335 extern void sh_pr_interrupt (struct cpp_reader *);
153 extern void sh_pr_trapa (struct cpp_reader *); 336 extern void sh_pr_trapa (struct cpp_reader *);
154 extern void sh_pr_nosave_low_regs (struct cpp_reader *); 337 extern void sh_pr_nosave_low_regs (struct cpp_reader *);
155 extern rtx function_symbol (rtx, const char *, enum sh_function_kind); 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);
156 extern rtx sh_get_pr_initial_val (void); 351 extern rtx sh_get_pr_initial_val (void);
157 352
158 extern int sh_pass_in_reg_p (CUMULATIVE_ARGS *, enum machine_mode, tree); 353 extern void sh_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree,
159 extern void sh_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, signed int, enum machine_mode); 354 signed int, machine_mode);
160 extern rtx sh_dwarf_register_span (rtx); 355 extern rtx sh_dwarf_register_span (rtx);
161 356
162 extern rtx replace_n_hard_rtx (rtx, rtx *, int , int); 357 extern bool sh_contains_memref_p (rtx);
163 extern int shmedia_cleanup_truncate (rtx *, void *); 358 extern bool sh_loads_bankedreg_p (rtx);
164
165 extern int sh_contains_memref_p (rtx);
166 extern int sh_loads_bankedreg_p (rtx);
167 extern rtx shmedia_prepare_call_address (rtx fnaddr, int is_sibcall);
168 extern int sh2a_get_function_vector_number (rtx); 359 extern int sh2a_get_function_vector_number (rtx);
169 extern int sh2a_is_function_vector_call (rtx); 360 extern bool sh2a_is_function_vector_call (rtx);
170 extern void sh_fix_range (const char *); 361 extern void sh_fix_range (const char *);
171 extern bool sh_hard_regno_mode_ok (unsigned int, enum machine_mode); 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);
172 #endif /* ! GCC_SH_PROTOS_H */ 366 #endif /* ! GCC_SH_PROTOS_H */
173
174 #ifdef SYMBIAN
175 extern const char * sh_symbian_strip_name_encoding (const char *);
176 extern bool sh_symbian_is_dllexported_name (const char *);
177 #ifdef TREE_CODE
178 extern bool sh_symbian_is_dllexported (tree);
179 extern int sh_symbian_import_export_class (tree, int);
180 extern tree sh_symbian_handle_dll_attribute (tree *, tree, tree, int, bool *);
181 #ifdef RTX_CODE
182 extern void sh_symbian_encode_section_info (tree, rtx, int);
183 #endif
184 #endif
185 #endif /* SYMBIAN */
186