1/* Definitions for code generation pass of GNU compiler.
2   Copyright (C) 1987-2015 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3.  If not see
18<http://www.gnu.org/licenses/>.  */
19
20#ifndef GCC_EXPR_H
21#define GCC_EXPR_H
22
23/* This is the 4th arg to `expand_expr'.
24   EXPAND_STACK_PARM means we are possibly expanding a call param onto
25   the stack.
26   EXPAND_SUM means it is ok to return a PLUS rtx or MULT rtx.
27   EXPAND_INITIALIZER is similar but also record any labels on forced_labels.
28   EXPAND_CONST_ADDRESS means it is ok to return a MEM whose address
29    is a constant that is not a legitimate address.
30   EXPAND_WRITE means we are only going to write to the resulting rtx.
31   EXPAND_MEMORY means we are interested in a memory result, even if
32    the memory is constant and we could have propagated a constant value,
33    or the memory is unaligned on a STRICT_ALIGNMENT target.  */
34enum expand_modifier {EXPAND_NORMAL = 0, EXPAND_STACK_PARM, EXPAND_SUM,
35		      EXPAND_CONST_ADDRESS, EXPAND_INITIALIZER, EXPAND_WRITE,
36		      EXPAND_MEMORY};
37
38/* Prevent the compiler from deferring stack pops.  See
39   inhibit_defer_pop for more information.  */
40#define NO_DEFER_POP (inhibit_defer_pop += 1)
41
42/* Allow the compiler to defer stack pops.  See inhibit_defer_pop for
43   more information.  */
44#define OK_DEFER_POP (inhibit_defer_pop -= 1)
45
46/* This structure is used to pass around information about exploded
47   unary, binary and trinary expressions between expand_expr_real_1 and
48   friends.  */
49typedef struct separate_ops
50{
51  enum tree_code code;
52  location_t location;
53  tree type;
54  tree op0, op1, op2;
55} *sepops;
56
57/* This is run during target initialization to set up which modes can be
58   used directly in memory and to initialize the block move optab.  */
59extern void init_expr_target (void);
60
61/* This is run at the start of compiling a function.  */
62extern void init_expr (void);
63
64/* Emit some rtl insns to move data between rtx's, converting machine modes.
65   Both modes must be floating or both fixed.  */
66extern void convert_move (rtx, rtx, int);
67
68/* Convert an rtx to specified machine mode and return the result.  */
69extern rtx convert_to_mode (machine_mode, rtx, int);
70
71/* Convert an rtx to MODE from OLDMODE and return the result.  */
72extern rtx convert_modes (machine_mode, machine_mode, rtx, int);
73
74/* Emit code to move a block Y to a block X.  */
75
76enum block_op_methods
77{
78  BLOCK_OP_NORMAL,
79  BLOCK_OP_NO_LIBCALL,
80  BLOCK_OP_CALL_PARM,
81  /* Like BLOCK_OP_NORMAL, but the libcall can be tail call optimized.  */
82  BLOCK_OP_TAILCALL
83};
84
85extern GTY(()) tree block_clear_fn;
86extern void init_block_move_fn (const char *);
87extern void init_block_clear_fn (const char *);
88
89extern rtx emit_block_move (rtx, rtx, rtx, enum block_op_methods);
90extern rtx emit_block_move_via_libcall (rtx, rtx, rtx, bool);
91extern rtx emit_block_move_hints (rtx, rtx, rtx, enum block_op_methods,
92			          unsigned int, HOST_WIDE_INT,
93				  unsigned HOST_WIDE_INT,
94				  unsigned HOST_WIDE_INT,
95				  unsigned HOST_WIDE_INT);
96extern bool emit_storent_insn (rtx to, rtx from);
97
98/* Copy all or part of a value X into registers starting at REGNO.
99   The number of registers to be filled is NREGS.  */
100extern void move_block_to_reg (int, rtx, int, machine_mode);
101
102/* Copy all or part of a BLKmode value X out of registers starting at REGNO.
103   The number of registers to be filled is NREGS.  */
104extern void move_block_from_reg (int, rtx, int);
105
106/* Generate a non-consecutive group of registers represented by a PARALLEL.  */
107extern rtx gen_group_rtx (rtx);
108
109/* Load a BLKmode value into non-consecutive registers represented by a
110   PARALLEL.  */
111extern void emit_group_load (rtx, rtx, tree, int);
112
113/* Similarly, but load into new temporaries.  */
114extern rtx emit_group_load_into_temps (rtx, rtx, tree, int);
115
116/* Move a non-consecutive group of registers represented by a PARALLEL into
117   a non-consecutive group of registers represented by a PARALLEL.  */
118extern void emit_group_move (rtx, rtx);
119
120/* Move a group of registers represented by a PARALLEL into pseudos.  */
121extern rtx emit_group_move_into_temps (rtx);
122
123/* Store a BLKmode value from non-consecutive registers represented by a
124   PARALLEL.  */
125extern void emit_group_store (rtx, rtx, tree, int);
126
127extern rtx maybe_emit_group_store (rtx, tree);
128
129/* Copy BLKmode object from a set of registers.  */
130extern void copy_blkmode_from_reg (rtx, rtx, tree);
131
132/* Mark REG as holding a parameter for the next CALL_INSN.
133   Mode is TYPE_MODE of the non-promoted parameter, or VOIDmode.  */
134extern void use_reg_mode (rtx *, rtx, machine_mode);
135extern void clobber_reg_mode (rtx *, rtx, machine_mode);
136
137extern rtx copy_blkmode_to_reg (machine_mode, tree);
138
139/* Mark REG as holding a parameter for the next CALL_INSN.  */
140static inline void
141use_reg (rtx *fusage, rtx reg)
142{
143  use_reg_mode (fusage, reg, VOIDmode);
144}
145
146/* Mark REG as clobbered by the call with FUSAGE as CALL_INSN_FUNCTION_USAGE.  */
147static inline void
148clobber_reg (rtx *fusage, rtx reg)
149{
150  clobber_reg_mode (fusage, reg, VOIDmode);
151}
152
153/* Mark NREGS consecutive regs, starting at REGNO, as holding parameters
154   for the next CALL_INSN.  */
155extern void use_regs (rtx *, int, int);
156
157/* Mark a PARALLEL as holding a parameter for the next CALL_INSN.  */
158extern void use_group_regs (rtx *, rtx);
159
160/* Write zeros through the storage of OBJECT.
161   If OBJECT has BLKmode, SIZE is its length in bytes.  */
162extern rtx clear_storage (rtx, rtx, enum block_op_methods);
163extern rtx clear_storage_hints (rtx, rtx, enum block_op_methods,
164			        unsigned int, HOST_WIDE_INT,
165				unsigned HOST_WIDE_INT,
166				unsigned HOST_WIDE_INT,
167				unsigned HOST_WIDE_INT);
168/* The same, but always output an library call.  */
169rtx set_storage_via_libcall (rtx, rtx, rtx, bool);
170
171/* Expand a setmem pattern; return true if successful.  */
172extern bool set_storage_via_setmem (rtx, rtx, rtx, unsigned int,
173				    unsigned int, HOST_WIDE_INT,
174				    unsigned HOST_WIDE_INT,
175				    unsigned HOST_WIDE_INT,
176				    unsigned HOST_WIDE_INT);
177
178extern unsigned HOST_WIDE_INT move_by_pieces_ninsns (unsigned HOST_WIDE_INT,
179						     unsigned int,
180						     unsigned int);
181
182/* Return nonzero if it is desirable to store LEN bytes generated by
183   CONSTFUN with several move instructions by store_by_pieces
184   function.  CONSTFUNDATA is a pointer which will be passed as argument
185   in every CONSTFUN call.
186   ALIGN is maximum alignment we can assume.
187   MEMSETP is true if this is a real memset/bzero, not a copy
188   of a const string.  */
189extern int can_store_by_pieces (unsigned HOST_WIDE_INT,
190				rtx (*) (void *, HOST_WIDE_INT,
191					 machine_mode),
192				void *, unsigned int, bool);
193
194/* Generate several move instructions to store LEN bytes generated by
195   CONSTFUN to block TO.  (A MEM rtx with BLKmode).  CONSTFUNDATA is a
196   pointer which will be passed as argument in every CONSTFUN call.
197   ALIGN is maximum alignment we can assume.
198   MEMSETP is true if this is a real memset/bzero, not a copy.
199   Returns TO + LEN.  */
200extern rtx store_by_pieces (rtx, unsigned HOST_WIDE_INT,
201			    rtx (*) (void *, HOST_WIDE_INT, machine_mode),
202			    void *, unsigned int, bool, int);
203
204/* Emit insns to set X from Y.  */
205extern rtx_insn *emit_move_insn (rtx, rtx);
206extern rtx gen_move_insn (rtx, rtx);
207
208/* Emit insns to set X from Y, with no frills.  */
209extern rtx_insn *emit_move_insn_1 (rtx, rtx);
210
211extern rtx_insn *emit_move_complex_push (machine_mode, rtx, rtx);
212extern rtx_insn *emit_move_complex_parts (rtx, rtx);
213extern void write_complex_part (rtx, rtx, bool);
214extern rtx emit_move_resolve_push (machine_mode, rtx);
215
216/* Push a block of length SIZE (perhaps variable)
217   and return an rtx to address the beginning of the block.  */
218extern rtx push_block (rtx, int, int);
219
220/* Generate code to push something onto the stack, given its mode and type.  */
221extern void emit_push_insn (rtx, machine_mode, tree, rtx, unsigned int,
222			    int, rtx, int, rtx, rtx, int, rtx);
223
224/* Expand an assignment that stores the value of FROM into TO.  */
225extern void expand_assignment (tree, tree, bool);
226
227/* Generate code for computing expression EXP,
228   and storing the value into TARGET.
229   If SUGGEST_REG is nonzero, copy the value through a register
230   and return that register, if that is possible.  */
231extern rtx store_expr_with_bounds (tree, rtx, int, bool, tree);
232extern rtx store_expr (tree, rtx, int, bool);
233
234/* Given an rtx that may include add and multiply operations,
235   generate them as insns and return a pseudo-reg containing the value.
236   Useful after calling expand_expr with 1 as sum_ok.  */
237extern rtx force_operand (rtx, rtx);
238
239/* Work horses for expand_expr.  */
240extern rtx expand_expr_real (tree, rtx, machine_mode,
241			     enum expand_modifier, rtx *, bool);
242extern rtx expand_expr_real_1 (tree, rtx, machine_mode,
243			       enum expand_modifier, rtx *, bool);
244extern rtx expand_expr_real_2 (sepops, rtx, machine_mode,
245			       enum expand_modifier);
246
247/* Generate code for computing expression EXP.
248   An rtx for the computed value is returned.  The value is never null.
249   In the case of a void EXP, const0_rtx is returned.  */
250static inline rtx
251expand_expr (tree exp, rtx target, machine_mode mode,
252	     enum expand_modifier modifier)
253{
254  return expand_expr_real (exp, target, mode, modifier, NULL, false);
255}
256
257static inline rtx
258expand_normal (tree exp)
259{
260  return expand_expr_real (exp, NULL_RTX, VOIDmode, EXPAND_NORMAL, NULL, false);
261}
262
263
264/* Return the tree node and offset if a given argument corresponds to
265   a string constant.  */
266extern tree string_constant (tree, tree *);
267
268/* Two different ways of generating switch statements.  */
269extern int try_casesi (tree, tree, tree, tree, rtx, rtx, rtx, int);
270extern int try_tablejump (tree, tree, tree, tree, rtx, rtx, int);
271
272extern int safe_from_p (const_rtx, tree, int);
273
274/* Get the personality libfunc for a function decl.  */
275rtx get_personality_function (tree);
276
277/* Determine whether the LEN bytes can be moved by using several move
278   instructions.  Return nonzero if a call to move_by_pieces should
279   succeed.  */
280extern int can_move_by_pieces (unsigned HOST_WIDE_INT, unsigned int);
281
282extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree);
283bool array_at_struct_end_p (tree);
284
285/* Return a tree of sizetype representing the size, in bytes, of the element
286   of EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
287extern tree array_ref_element_size (tree);
288
289extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *,
290				      HOST_WIDE_INT *, bool *);
291
292/* Return a tree representing the offset, in bytes, of the field referenced
293   by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */
294extern tree component_ref_field_offset (tree);
295
296extern void expand_operands (tree, tree, rtx, rtx*, rtx*,
297			     enum expand_modifier);
298
299/* rtl.h and tree.h were included.  */
300/* Return an rtx for the size in bytes of the value of an expr.  */
301extern rtx expr_size (tree);
302
303#endif /* GCC_EXPR_H */
304