1/* Definitions of target machine for GNU compiler, for IBM RS/6000.
2   Copyright (C) 2000-2022 Free Software Foundation, Inc.
3   Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
4
5   This file is part of GCC.
6
7   GCC is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published
9   by the Free Software Foundation; either version 3, or (at your
10   option) any later version.
11
12   GCC is distributed in the hope that it will be useful, but WITHOUT
13   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15   License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with GCC; see the file COPYING3.  If not see
19   <http://www.gnu.org/licenses/>.  */
20
21#ifndef GCC_RS6000_PROTOS_H
22#define GCC_RS6000_PROTOS_H
23
24/* Declare functions in rs6000.cc */
25
26#ifdef RTX_CODE
27
28#ifdef TREE_CODE
29extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, int, int, int,
30				  tree, machine_mode);
31#endif /* TREE_CODE */
32
33extern int easy_altivec_constant (rtx, machine_mode);
34extern bool xxspltib_constant_p (rtx, machine_mode, int *, int *);
35extern int vspltis_shifted (rtx);
36extern HOST_WIDE_INT const_vector_elt_as_int (rtx, unsigned int);
37extern bool macho_lo_sum_memory_operand (rtx, machine_mode);
38extern int num_insns_constant (rtx, machine_mode);
39extern int small_data_operand (rtx, machine_mode);
40extern bool mem_operand_gpr (rtx, machine_mode);
41extern bool mem_operand_ds_form (rtx, machine_mode);
42extern bool toc_relative_expr_p (const_rtx, bool, const_rtx *, const_rtx *);
43extern void validate_condition_mode (enum rtx_code, machine_mode);
44extern bool legitimate_constant_pool_address_p (const_rtx, machine_mode,
45						bool);
46extern bool legitimate_indirect_address_p (rtx, int);
47extern bool legitimate_indexed_address_p (rtx, int);
48extern bool avoiding_indexed_address_p (machine_mode);
49extern rtx rs6000_force_indexed_or_indirect_mem (rtx x);
50
51extern rtx rs6000_got_register (rtx);
52extern rtx find_addr_reg (rtx);
53extern rtx gen_easy_altivec_constant (rtx);
54extern const char *output_vec_const_move (rtx *);
55extern const char *rs6000_output_move_128bit (rtx *);
56extern bool rs6000_move_128bit_ok_p (rtx []);
57extern bool rs6000_split_128bit_ok_p (rtx []);
58extern void rs6000_expand_float128_convert (rtx, rtx, bool);
59extern void rs6000_expand_vector_init (rtx, rtx);
60extern void rs6000_expand_vector_set (rtx, rtx, rtx);
61extern void rs6000_expand_vector_extract (rtx, rtx, rtx);
62extern void rs6000_split_vec_extract_var (rtx, rtx, rtx, rtx, rtx);
63extern rtx rs6000_adjust_vec_address (rtx, rtx, rtx, rtx, machine_mode);
64extern void altivec_expand_vec_perm_le (rtx op[4]);
65extern void rs6000_expand_extract_even (rtx, rtx, rtx);
66extern void rs6000_expand_interleave (rtx, rtx, rtx, bool);
67extern void rs6000_scale_v2df (rtx, rtx, int);
68extern void rs6000_generate_float2_code (bool, rtx, rtx, rtx);
69extern void rs6000_generate_float2_double_code (rtx, rtx, rtx);
70extern void rs6000_generate_vsigned2_code (bool, rtx, rtx, rtx);
71extern int expand_block_clear (rtx[]);
72extern int expand_block_move (rtx[], bool);
73extern bool expand_block_compare (rtx[]);
74extern bool expand_strn_compare (rtx[], int);
75extern bool rs6000_is_valid_mask (rtx, int *, int *, machine_mode);
76extern bool rs6000_is_valid_rotate_dot_mask (rtx mask, machine_mode mode);
77extern bool rs6000_is_valid_and_mask (rtx, machine_mode);
78extern bool rs6000_is_valid_shift_mask (rtx, rtx, machine_mode);
79extern bool rs6000_is_valid_insert_mask (rtx, rtx, machine_mode);
80extern const char *rs6000_insn_for_and_mask (machine_mode, rtx *, bool);
81extern const char *rs6000_insn_for_shift_mask (machine_mode, rtx *, bool);
82extern const char *rs6000_insn_for_insert_mask (machine_mode, rtx *, bool);
83extern bool rs6000_is_valid_2insn_and (rtx, machine_mode);
84extern void rs6000_emit_2insn_and (machine_mode, rtx *, bool, int);
85extern int registers_ok_for_quad_peep (rtx, rtx);
86extern int mems_ok_for_quad_peep (rtx, rtx);
87extern bool gpr_or_gpr_p (rtx, rtx);
88extern bool direct_move_p (rtx, rtx);
89extern bool quad_address_p (rtx, machine_mode, bool);
90extern bool quad_load_store_p (rtx, rtx);
91extern bool fusion_gpr_load_p (rtx, rtx, rtx, rtx);
92extern void expand_fusion_gpr_load (rtx *);
93extern void emit_fusion_addis (rtx, rtx);
94extern const char *emit_fusion_gpr_load (rtx, rtx);
95extern enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx,
96							    enum reg_class);
97extern enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
98							    machine_mode,
99							    rtx);
100extern void rs6000_secondary_reload_inner (rtx, rtx, rtx, bool);
101extern void rs6000_secondary_reload_gpr (rtx, rtx, rtx, bool);
102
103
104extern int ccr_bit (rtx, int);
105extern void rs6000_output_function_entry (FILE *, const char *);
106extern void print_operand (FILE *, rtx, int);
107extern void print_operand_address (FILE *, rtx);
108extern const char *rs6000_call_template (rtx *, unsigned int);
109extern const char *rs6000_sibcall_template (rtx *, unsigned int);
110extern const char *rs6000_indirect_call_template (rtx *, unsigned int);
111extern const char *rs6000_indirect_sibcall_template (rtx *, unsigned int);
112extern const char *rs6000_pltseq_template (rtx *, int);
113extern enum rtx_code rs6000_reverse_condition (machine_mode,
114					       enum rtx_code);
115extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx);
116extern rtx rs6000_emit_fp_cror (rtx_code, machine_mode, rtx);
117extern void rs6000_emit_sCOND (machine_mode, rtx[]);
118extern void rs6000_emit_cbranch (machine_mode, rtx[]);
119extern char * output_cbranch (rtx, const char *, int, rtx_insn *);
120extern const char * output_probe_stack_range (rtx, rtx, rtx);
121extern void rs6000_emit_dot_insn (rtx dst, rtx src, int dot, rtx ccreg);
122extern bool rs6000_emit_set_const (rtx, rtx);
123extern bool rs6000_emit_cmove (rtx, rtx, rtx, rtx);
124extern bool rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
125extern int rs6000_emit_vector_cond_expr (rtx, rtx, rtx, rtx, rtx, rtx);
126extern void rs6000_emit_minmax (rtx, enum rtx_code, rtx, rtx);
127extern void rs6000_expand_atomic_compare_and_swap (rtx op[]);
128extern rtx swap_endian_selector_for_mode (machine_mode mode);
129
130extern void rs6000_expand_atomic_exchange (rtx op[]);
131extern void rs6000_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx);
132extern void rs6000_emit_swdiv (rtx, rtx, rtx, bool);
133extern void rs6000_emit_swsqrt (rtx, rtx, bool);
134extern void output_toc (FILE *, rtx, int, machine_mode);
135extern void rs6000_fatal_bad_address (rtx);
136extern rtx create_TOC_reference (rtx, rtx);
137extern void rs6000_split_multireg_move (rtx, rtx);
138extern void rs6000_emit_le_vsx_permute (rtx, rtx, machine_mode);
139extern void rs6000_emit_le_vsx_move (rtx, rtx, machine_mode);
140extern bool valid_sf_si_move (rtx, rtx, machine_mode);
141extern void rs6000_emit_move (rtx, rtx, machine_mode);
142extern bool rs6000_legitimate_offset_address_p (machine_mode, rtx,
143						bool, bool);
144extern rtx rs6000_find_base_term (rtx);
145extern rtx rs6000_return_addr (int, rtx);
146extern void rs6000_output_symbol_ref (FILE*, rtx);
147extern HOST_WIDE_INT rs6000_initial_elimination_offset (int, int);
148extern void rs6000_emit_popcount (rtx, rtx);
149extern void rs6000_emit_parity (rtx, rtx);
150
151extern rtx rs6000_machopic_legitimize_pic_address (rtx, machine_mode,
152						   rtx);
153extern rtx rs6000_allocate_stack_temp (machine_mode, bool, bool);
154extern align_flags rs6000_loop_align (rtx);
155extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool);
156extern bool rs6000_function_pcrel_p (struct function *);
157extern bool rs6000_pcrel_p (void);
158extern bool rs6000_fndecl_pcrel_p (const_tree);
159extern void rs6000_output_addr_vec_elt (FILE *, int);
160
161/* Different PowerPC instruction formats that are used by GCC.  There are
162   various other instruction formats used by the PowerPC hardware, but these
163   formats are not currently used by GCC.  */
164
165enum insn_form {
166  INSN_FORM_BAD,		/* Bad instruction format.  */
167  INSN_FORM_BASE_REG,		/* Base register only.  */
168  INSN_FORM_D,			/* Reg + 16-bit numeric offset.  */
169  INSN_FORM_DS,			/* Reg + offset, bottom 2 bits must be 0.  */
170  INSN_FORM_DQ,			/* Reg + offset, bottom 4 bits must be 0.  */
171  INSN_FORM_X,			/* Base register + index register.  */
172  INSN_FORM_UPDATE,		/* Address updates base register.  */
173  INSN_FORM_LO_SUM,		/* Reg + offset using symbol.  */
174  INSN_FORM_PREFIXED_NUMERIC,	/* Reg + 34 bit numeric offset.  */
175  INSN_FORM_PCREL_LOCAL,	/* PC-relative local symbol.  */
176  INSN_FORM_PCREL_EXTERNAL	/* PC-relative external symbol.  */
177};
178
179/* Instruction format for the non-prefixed version of a load or store.  This is
180   used to determine if a 16-bit offset is valid to be used with a non-prefixed
181   (traditional) instruction or if the bottom bits of the offset cannot be used
182   with a DS or DQ instruction format, and GCC has to use a prefixed
183   instruction for the load or store.  */
184
185enum non_prefixed_form {
186  NON_PREFIXED_DEFAULT,		/* Use the default.  */
187  NON_PREFIXED_D,		/* All 16-bits are valid.  */
188  NON_PREFIXED_DS,		/* Bottom 2 bits must be 0.  */
189  NON_PREFIXED_DQ,		/* Bottom 4 bits must be 0.  */
190  NON_PREFIXED_X		/* No offset memory form exists.  */
191};
192
193extern enum insn_form address_to_insn_form (rtx, machine_mode,
194					    enum non_prefixed_form);
195extern bool address_is_non_pfx_d_or_x (rtx addr, machine_mode mode,
196				       enum non_prefixed_form non_prefix_format);
197extern bool pcrel_opt_valid_mem_p (rtx, machine_mode, rtx);
198enum non_prefixed_form reg_to_non_prefixed (rtx reg, machine_mode mode);
199extern bool prefixed_load_p (rtx_insn *);
200extern bool prefixed_store_p (rtx_insn *);
201extern bool prefixed_paddi_p (rtx_insn *);
202extern void rs6000_asm_output_opcode (FILE *);
203extern void output_pcrel_opt_reloc (rtx);
204extern void rs6000_final_prescan_insn (rtx_insn *, rtx [], int);
205extern int rs6000_adjust_insn_length (rtx_insn *, int);
206
207/* Return true if the address can be used for a prefixed load, store, or add
208   immediate instructions that cannot be used with a non-prefixed instruction.
209   For example, using a numeric offset that is not valid for the non-prefixed
210   instruction or a PC-relative reference to a local symbol would return true,
211   but an address with an offset of 64 would not return true.
212
213   References to external PC-relative symbols aren't allowed, because GCC has
214   to load the address into a register and then issue a separate load or
215   store.  */
216
217static inline bool
218address_is_prefixed (rtx addr,
219		     machine_mode mode,
220		     enum non_prefixed_form non_prefixed)
221{
222  enum insn_form iform = address_to_insn_form (addr, mode, non_prefixed);
223  return (iform == INSN_FORM_PREFIXED_NUMERIC
224	  || iform == INSN_FORM_PCREL_LOCAL);
225}
226
227/* Functions and data structures relating to 128-bit constants that are
228   converted to byte, half-word, word, and double-word values.  All fields are
229   kept in big endian order.  We also convert scalar values to 128-bits if they
230   are going to be loaded into vector registers.  */
231#define VECTOR_128BIT_BITS		128
232#define VECTOR_128BIT_BYTES		(128 / 8)
233#define VECTOR_128BIT_HALF_WORDS	(128 / 16)
234#define VECTOR_128BIT_WORDS		(128 / 32)
235#define VECTOR_128BIT_DOUBLE_WORDS	(128 / 64)
236
237typedef struct {
238  /* Constant as various sized items.  */
239  unsigned HOST_WIDE_INT double_words[VECTOR_128BIT_DOUBLE_WORDS];
240  unsigned int words[VECTOR_128BIT_WORDS];
241  unsigned short half_words[VECTOR_128BIT_HALF_WORDS];
242  unsigned char bytes[VECTOR_128BIT_BYTES];
243
244  unsigned original_size;		/* Constant size before splat.  */
245  bool fp_constant_p;			/* Is the constant floating point?  */
246  bool all_double_words_same;		/* Are the double words all equal?  */
247  bool all_words_same;			/* Are the words all equal?  */
248  bool all_half_words_same;		/* Are the half words all equal?  */
249  bool all_bytes_same;			/* Are the bytes all equal?  */
250} vec_const_128bit_type;
251
252extern bool vec_const_128bit_to_bytes (rtx, machine_mode,
253				       vec_const_128bit_type *);
254extern unsigned constant_generates_lxvkq (vec_const_128bit_type *);
255extern unsigned constant_generates_xxspltiw (vec_const_128bit_type *);
256extern unsigned constant_generates_xxspltidp (vec_const_128bit_type *);
257#endif /* RTX_CODE */
258
259#ifdef TREE_CODE
260extern unsigned int rs6000_data_alignment (tree, unsigned int, enum data_align);
261extern unsigned int rs6000_special_adjust_field_align (tree, unsigned int);
262extern unsigned int rs6000_special_round_type_align (tree, unsigned int,
263						     unsigned int);
264extern unsigned int darwin_rs6000_special_round_type_align (tree, unsigned int,
265							    unsigned int);
266extern tree altivec_resolve_overloaded_builtin (location_t, tree, void *);
267extern rtx rs6000_libcall_value (machine_mode);
268extern rtx rs6000_va_arg (tree, tree);
269extern int function_ok_for_sibcall (tree);
270extern int rs6000_reg_parm_stack_space (tree, bool);
271extern void rs6000_asm_weaken_decl (FILE *, tree, const char *, const char *);
272extern void rs6000_xcoff_declare_function_name (FILE *, const char *, tree);
273extern void rs6000_xcoff_declare_object_name (FILE *, const char *, tree);
274extern void rs6000_xcoff_asm_output_aligned_decl_common (FILE *, tree,
275							 const char *,
276							 unsigned HOST_WIDE_INT,
277							 unsigned int);
278extern void rs6000_elf_declare_function_name (FILE *, const char *, tree);
279extern bool rs6000_elf_in_small_data_p (const_tree);
280
281#endif /* TREE_CODE */
282
283extern int direct_return (void);
284extern int first_reg_to_save (void);
285extern int first_fp_reg_to_save (void);
286extern void output_ascii (FILE *, const char *, int);
287extern void rs6000_gen_section_name (char **, const char *, const char *);
288extern void output_function_profiler (FILE *, int);
289extern void output_profile_hook  (int);
290extern int rs6000_trampoline_size (void);
291extern alias_set_type get_TOC_alias_set (void);
292extern void rs6000_emit_prologue (void);
293extern void rs6000_emit_load_toc_table (int);
294extern unsigned int rs6000_dbx_register_number (unsigned int, unsigned int);
295extern void rs6000_emit_epilogue (enum epilogue_type);
296extern void rs6000_expand_split_stack_prologue (void);
297extern void rs6000_split_stack_space_check (rtx, rtx);
298extern void rs6000_emit_eh_reg_restore (rtx, rtx);
299extern void rs6000_call_aix (rtx, rtx, rtx, rtx);
300extern void rs6000_sibcall_aix (rtx, rtx, rtx, rtx);
301extern void rs6000_call_sysv (rtx, rtx, rtx, rtx);
302extern void rs6000_sibcall_sysv (rtx, rtx, rtx, rtx);
303extern void rs6000_call_darwin (rtx, rtx, rtx, rtx);
304extern void rs6000_sibcall_darwin (rtx, rtx, rtx, rtx);
305extern void rs6000_aix_asm_output_dwarf_table_ref (char *);
306extern void get_ppc476_thunk_name (char name[32]);
307extern int rs6000_store_data_bypass_p (rtx_insn *, rtx_insn *);
308extern HOST_WIDE_INT rs6000_builtin_mask_calculate (void);
309extern void rs6000_asm_output_dwarf_pcrel (FILE *file, int size,
310					   const char *label);
311extern void rs6000_asm_output_dwarf_datarel (FILE *file, int size,
312					     const char *label);
313extern long rs6000_const_f32_to_i32 (rtx operand);
314
315/* Declare functions in rs6000-c.cc */
316
317extern void rs6000_pragma_longcall (struct cpp_reader *);
318extern void rs6000_cpu_cpp_builtins (struct cpp_reader *);
319#ifdef TREE_CODE
320extern bool rs6000_pragma_target_parse (tree, tree);
321#endif
322extern void rs6000_activate_target_options (tree new_tree);
323extern void rs6000_target_modify_macros (bool, HOST_WIDE_INT, HOST_WIDE_INT);
324extern void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT,
325						HOST_WIDE_INT);
326
327#ifdef NO_DOLLAR_IN_LABEL
328const char * rs6000_xcoff_strip_dollar (const char *);
329#endif
330
331extern unsigned char rs6000_class_max_nregs[][LIM_REG_CLASSES];
332extern unsigned char rs6000_hard_regno_nregs[][FIRST_PSEUDO_REGISTER];
333
334extern bool rs6000_linux_float_exceptions_rounding_supported_p (void);
335
336/* Pass management.  */
337namespace gcc { class context; }
338class rtl_opt_pass;
339
340extern rtl_opt_pass *make_pass_analyze_swaps (gcc::context *);
341extern rtl_opt_pass *make_pass_pcrel_opt (gcc::context *);
342extern bool rs6000_sum_of_two_registers_p (const_rtx expr);
343extern bool rs6000_quadword_masked_address_p (const_rtx exp);
344extern rtx rs6000_gen_lvx (enum machine_mode, rtx, rtx);
345extern rtx rs6000_gen_stvx (enum machine_mode, rtx, rtx);
346
347extern void rs6000_emit_xxspltidp_v2df (rtx, long value);
348extern gimple *currently_expanding_gimple_stmt;
349extern bool rs6000_opaque_type_invalid_use_p (gimple *);
350#endif  /* rs6000-protos.h */
351