118334Speter/* Definitions for code generation pass of GNU compiler.
290075Sobrien   Copyright (C) 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3169689Skan   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
4169689Skan   Free Software Foundation, Inc.
518334Speter
690075SobrienThis file is part of GCC.
718334Speter
890075SobrienGCC is free software; you can redistribute it and/or modify it under
990075Sobrienthe terms of the GNU General Public License as published by the Free
1090075SobrienSoftware Foundation; either version 2, or (at your option) any later
1190075Sobrienversion.
1218334Speter
1390075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1490075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1590075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1690075Sobrienfor more details.
1718334Speter
1818334SpeterYou should have received a copy of the GNU General Public License
1990075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
20169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21169689Skan02110-1301, USA.  */
2218334Speter
23169689Skan#ifndef GCC_EXPR_H
24169689Skan#define GCC_EXPR_H
25169689Skan
26169689Skan/* For inhibit_defer_pop */
27169689Skan#include "function.h"
28169689Skan/* For XEXP, GEN_INT, rtx_code */
29169689Skan#include "rtl.h"
30169689Skan/* For optimize_size */
31169689Skan#include "flags.h"
32169689Skan/* For host_integerp, tree_low_cst, fold_convert, size_binop, ssize_int,
33169689Skan   TREE_CODE, TYPE_SIZE, int_size_in_bytes,    */
34169689Skan#include "tree.h"
35169689Skan/* For GET_MODE_BITSIZE, word_mode */
36169689Skan#include "machmode.h"
37169689Skan
3818334Speter/* The default branch cost is 1.  */
3918334Speter#ifndef BRANCH_COST
4018334Speter#define BRANCH_COST 1
4118334Speter#endif
4218334Speter
4318334Speter/* This is the 4th arg to `expand_expr'.
44117395Skan   EXPAND_STACK_PARM means we are possibly expanding a call param onto
45169689Skan   the stack.
4618334Speter   EXPAND_SUM means it is ok to return a PLUS rtx or MULT rtx.
4718334Speter   EXPAND_INITIALIZER is similar but also record any labels on forced_labels.
4818334Speter   EXPAND_CONST_ADDRESS means it is ok to return a MEM whose address
4950397Sobrien    is a constant that is not a legitimate address.
50117395Skan   EXPAND_WRITE means we are only going to write to the resulting rtx.
51117395Skan   EXPAND_MEMORY means we are interested in a memory result, even if
52117395Skan    the memory is constant and we could have propagated a constant value.  */
53169689Skanenum expand_modifier {EXPAND_NORMAL = 0, EXPAND_STACK_PARM, EXPAND_SUM,
54117395Skan		      EXPAND_CONST_ADDRESS, EXPAND_INITIALIZER, EXPAND_WRITE,
55117395Skan		      EXPAND_MEMORY};
5618334Speter
5752284Sobrien/* Prevent the compiler from deferring stack pops.  See
5852284Sobrien   inhibit_defer_pop for more information.  */
5952284Sobrien#define NO_DEFER_POP (inhibit_defer_pop += 1)
6052284Sobrien
6152284Sobrien/* Allow the compiler to defer stack pops.  See inhibit_defer_pop for
6252284Sobrien   more information.  */
6352284Sobrien#define OK_DEFER_POP (inhibit_defer_pop -= 1)
6418334Speter
65132718Skan/* If a memory-to-memory move would take MOVE_RATIO or more simple
66169689Skan   move-instruction sequences, we will do a movmem or libcall instead.  */
67132718Skan
68132718Skan#ifndef MOVE_RATIO
69169689Skan#if defined (HAVE_movmemqi) || defined (HAVE_movmemhi) || defined (HAVE_movmemsi) || defined (HAVE_movmemdi) || defined (HAVE_movmemti)
70132718Skan#define MOVE_RATIO 2
71132718Skan#else
72132718Skan/* If we are optimizing for space (-Os), cut down the default move ratio.  */
73132718Skan#define MOVE_RATIO (optimize_size ? 3 : 15)
74132718Skan#endif
75132718Skan#endif
76132718Skan
77132718Skan/* If a clear memory operation would take CLEAR_RATIO or more simple
78169689Skan   move-instruction sequences, we will do a setmem or libcall instead.  */
79132718Skan
80132718Skan#ifndef CLEAR_RATIO
81169689Skan#if defined (HAVE_setmemqi) || defined (HAVE_setmemhi) || defined (HAVE_setmemsi) || defined (HAVE_setmemdi) || defined (HAVE_setmemti)
82132718Skan#define CLEAR_RATIO 2
83132718Skan#else
84132718Skan/* If we are optimizing for space, cut down the default clear ratio.  */
85132718Skan#define CLEAR_RATIO (optimize_size ? 3 : 15)
86132718Skan#endif
87132718Skan#endif
88132718Skan
89132718Skanenum direction {none, upward, downward};
90132718Skan
9118334Speter/* Structure to record the size of a sequence of arguments
9290075Sobrien   as the sum of a tree-expression and a constant.  This structure is
9390075Sobrien   also used to store offsets from the stack, which might be negative,
9490075Sobrien   so the variable part must be ssizetype, not sizetype.  */
9518334Speter
9618334Speterstruct args_size
9718334Speter{
9850397Sobrien  HOST_WIDE_INT constant;
9918334Speter  tree var;
10018334Speter};
10118334Speter
102132718Skan/* Package up various arg related fields of struct args for
103132718Skan   locate_and_pad_parm.  */
104132718Skanstruct locate_and_pad_arg_data
105132718Skan{
106132718Skan  /* Size of this argument on the stack, rounded up for any padding it
107132718Skan     gets.  If REG_PARM_STACK_SPACE is defined, then register parms are
108132718Skan     counted here, otherwise they aren't.  */
109132718Skan  struct args_size size;
110132718Skan  /* Offset of this argument from beginning of stack-args.  */
111132718Skan  struct args_size offset;
112132718Skan  /* Offset to the start of the stack slot.  Different from OFFSET
113132718Skan     if this arg pads downward.  */
114132718Skan  struct args_size slot_offset;
115132718Skan  /* The amount that the stack pointer needs to be adjusted to
116132718Skan     force alignment for the next argument.  */
117132718Skan  struct args_size alignment_pad;
118132718Skan  /* Which way we should pad this arg.  */
119132718Skan  enum direction where_pad;
120169689Skan  /* slot_offset is at least this aligned.  */
121169689Skan  unsigned int boundary;
122132718Skan};
123132718Skan
12418334Speter/* Add the value of the tree INC to the `struct args_size' TO.  */
12518334Speter
126169689Skan#define ADD_PARM_SIZE(TO, INC)					\
127169689Skando {								\
128169689Skan  tree inc = (INC);						\
129169689Skan  if (host_integerp (inc, 0))					\
130169689Skan    (TO).constant += tree_low_cst (inc, 0);			\
131169689Skan  else if ((TO).var == 0)					\
132169689Skan    (TO).var = fold_convert (ssizetype, inc);			\
133169689Skan  else								\
134169689Skan    (TO).var = size_binop (PLUS_EXPR, (TO).var,			\
135169689Skan			   fold_convert (ssizetype, inc));	\
13696263Sobrien} while (0)
13718334Speter
138169689Skan#define SUB_PARM_SIZE(TO, DEC)					\
139169689Skando {								\
140169689Skan  tree dec = (DEC);						\
141169689Skan  if (host_integerp (dec, 0))					\
142169689Skan    (TO).constant -= tree_low_cst (dec, 0);			\
143169689Skan  else if ((TO).var == 0)					\
144169689Skan    (TO).var = size_binop (MINUS_EXPR, ssize_int (0),		\
145169689Skan			   fold_convert (ssizetype, dec));	\
146169689Skan  else								\
147169689Skan    (TO).var = size_binop (MINUS_EXPR, (TO).var,		\
148169689Skan			   fold_convert (ssizetype, dec));	\
14996263Sobrien} while (0)
15018334Speter
15190075Sobrien/* Convert the implicit sum in a `struct args_size' into a tree
15290075Sobrien   of type ssizetype.  */
15390075Sobrien#define ARGS_SIZE_TREE(SIZE)					\
15490075Sobrien((SIZE).var == 0 ? ssize_int ((SIZE).constant)			\
155169689Skan : size_binop (PLUS_EXPR, fold_convert (ssizetype, (SIZE).var),	\
15696263Sobrien	       ssize_int ((SIZE).constant)))
15790075Sobrien
15818334Speter/* Convert the implicit sum in a `struct args_size' into an rtx.  */
15990075Sobrien#define ARGS_SIZE_RTX(SIZE)					\
16090075Sobrien((SIZE).var == 0 ? GEN_INT ((SIZE).constant)			\
161169689Skan : expand_normal (ARGS_SIZE_TREE (SIZE)))
16218334Speter
16318334Speter/* Supply a default definition for FUNCTION_ARG_PADDING:
16418334Speter   usually pad upward, but pad short args downward on
16518334Speter   big-endian machines.  */
16618334Speter
167132718Skan#define DEFAULT_FUNCTION_ARG_PADDING(MODE, TYPE)			\
16818334Speter  (! BYTES_BIG_ENDIAN							\
16918334Speter   ? upward								\
17018334Speter   : (((MODE) == BLKmode						\
17118334Speter       ? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST		\
17218334Speter	  && int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT)) \
17318334Speter       : GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY)			\
17418334Speter      ? downward : upward))
175132718Skan
176132718Skan#ifndef FUNCTION_ARG_PADDING
177132718Skan#define FUNCTION_ARG_PADDING(MODE, TYPE)	\
178132718Skan  DEFAULT_FUNCTION_ARG_PADDING ((MODE), (TYPE))
17918334Speter#endif
18018334Speter
18118334Speter/* Supply a default definition for FUNCTION_ARG_BOUNDARY.  Normally, we let
18218334Speter   FUNCTION_ARG_PADDING, which also pads the length, handle any needed
18318334Speter   alignment.  */
184117395Skan
18518334Speter#ifndef FUNCTION_ARG_BOUNDARY
18618334Speter#define FUNCTION_ARG_BOUNDARY(MODE, TYPE)	PARM_BOUNDARY
18718334Speter#endif
18818334Speter
18950397Sobrien/* Supply a default definition of STACK_SAVEAREA_MODE for emit_stack_save.
19050397Sobrien   Normally move_insn, so Pmode stack pointer.  */
19150397Sobrien
19250397Sobrien#ifndef STACK_SAVEAREA_MODE
19350397Sobrien#define STACK_SAVEAREA_MODE(LEVEL) Pmode
19450397Sobrien#endif
19550397Sobrien
19650397Sobrien/* Supply a default definition of STACK_SIZE_MODE for
19750397Sobrien   allocate_dynamic_stack_space.  Normally PLUS/MINUS, so word_mode.  */
19850397Sobrien
19950397Sobrien#ifndef STACK_SIZE_MODE
20050397Sobrien#define STACK_SIZE_MODE word_mode
20150397Sobrien#endif
20250397Sobrien
20350397Sobrien/* Provide default values for the macros controlling stack checking.  */
20450397Sobrien
20550397Sobrien#ifndef STACK_CHECK_BUILTIN
20650397Sobrien#define STACK_CHECK_BUILTIN 0
20750397Sobrien#endif
20850397Sobrien
20950397Sobrien/* The default interval is one page.  */
21050397Sobrien#ifndef STACK_CHECK_PROBE_INTERVAL
21150397Sobrien#define STACK_CHECK_PROBE_INTERVAL 4096
21250397Sobrien#endif
21350397Sobrien
21450397Sobrien/* The default is to do a store into the stack.  */
21550397Sobrien#ifndef STACK_CHECK_PROBE_LOAD
21650397Sobrien#define STACK_CHECK_PROBE_LOAD 0
21750397Sobrien#endif
21850397Sobrien
21950397Sobrien/* This value is arbitrary, but should be sufficient for most machines.  */
22050397Sobrien#ifndef STACK_CHECK_PROTECT
22150397Sobrien#define STACK_CHECK_PROTECT (75 * UNITS_PER_WORD)
22250397Sobrien#endif
22350397Sobrien
22450397Sobrien/* Make the maximum frame size be the largest we can and still only need
22550397Sobrien   one probe per function.  */
22650397Sobrien#ifndef STACK_CHECK_MAX_FRAME_SIZE
22750397Sobrien#define STACK_CHECK_MAX_FRAME_SIZE \
22850397Sobrien  (STACK_CHECK_PROBE_INTERVAL - UNITS_PER_WORD)
22950397Sobrien#endif
23050397Sobrien
23150397Sobrien/* This is arbitrary, but should be large enough everywhere.  */
23250397Sobrien#ifndef STACK_CHECK_FIXED_FRAME_SIZE
23350397Sobrien#define STACK_CHECK_FIXED_FRAME_SIZE (4 * UNITS_PER_WORD)
23450397Sobrien#endif
23550397Sobrien
23650397Sobrien/* Provide a reasonable default for the maximum size of an object to
23750397Sobrien   allocate in the fixed frame.  We may need to be able to make this
23850397Sobrien   controllable by the user at some point.  */
23950397Sobrien#ifndef STACK_CHECK_MAX_VAR_SIZE
24050397Sobrien#define STACK_CHECK_MAX_VAR_SIZE (STACK_CHECK_MAX_FRAME_SIZE / 100)
24150397Sobrien#endif
24218334Speter
24390075Sobrien/* Functions from optabs.c, commonly used, and without need for the optabs
24490075Sobrien   tables:  */
24518334Speter
24690075Sobrien/* Passed to expand_simple_binop and expand_binop to say which options
24790075Sobrien   to try to use if the requested operation can't be open-coded on the
24890075Sobrien   requisite mode.  Either OPTAB_LIB or OPTAB_LIB_WIDEN says try using
24990075Sobrien   a library call.  Either OPTAB_WIDEN or OPTAB_LIB_WIDEN says try
25090075Sobrien   using a wider mode.  OPTAB_MUST_WIDEN says try widening and don't
25190075Sobrien   try anything else.  */
25218334Speter
25318334Speterenum optab_methods
25418334Speter{
25518334Speter  OPTAB_DIRECT,
25618334Speter  OPTAB_LIB,
25718334Speter  OPTAB_WIDEN,
25818334Speter  OPTAB_LIB_WIDEN,
25918334Speter  OPTAB_MUST_WIDEN
26018334Speter};
26118334Speter
26290075Sobrien/* Generate code for a simple binary or unary operation.  "Simple" in
26390075Sobrien   this case means "can be unambiguously described by a (mode, code)
26490075Sobrien   pair and mapped to a single optab."  */
265132718Skanextern rtx expand_simple_binop (enum machine_mode, enum rtx_code, rtx,
266132718Skan				rtx, rtx, int, enum optab_methods);
267132718Skanextern rtx expand_simple_unop (enum machine_mode, enum rtx_code, rtx, rtx,
268132718Skan			       int);
26918334Speter
27090075Sobrien/* Report whether the machine description contains an insn which can
27190075Sobrien   perform the operation described by CODE and MODE.  */
272132718Skanextern int have_insn_for (enum rtx_code, enum machine_mode);
27318334Speter
27490075Sobrien/* Emit code to make a call to a constant function or a library call.  */
275132718Skanextern void emit_libcall_block (rtx, rtx, rtx, rtx);
27618334Speter
27790075Sobrien/* Create but don't emit one rtl instruction to perform certain operations.
27890075Sobrien   Modes must match; operands must meet the operation's predicates.
279169689Skan   Likewise for subtraction and for just copying.  */
280132718Skanextern rtx gen_add2_insn (rtx, rtx);
281132718Skanextern rtx gen_add3_insn (rtx, rtx, rtx);
282132718Skanextern rtx gen_sub2_insn (rtx, rtx);
283132718Skanextern rtx gen_sub3_insn (rtx, rtx, rtx);
284132718Skanextern rtx gen_move_insn (rtx, rtx);
285132718Skanextern int have_add2_insn (rtx, rtx);
286132718Skanextern int have_sub2_insn (rtx, rtx);
28718334Speter
288117395Skan/* Emit a pair of rtl insns to compare two rtx's and to jump
28952284Sobrien   to a label if the comparison is true.  */
290132718Skanextern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx,
291132718Skan				     enum machine_mode, int, rtx);
29252284Sobrien
29318334Speter/* Generate code to indirectly jump to a location given in the rtx LOC.  */
294132718Skanextern void emit_indirect_jump (rtx);
29518334Speter
296169689Skan/* Generate a conditional trap instruction.  */
297169689Skanextern rtx gen_cond_trap (enum rtx_code, rtx, rtx, rtx);
298169689Skan
299169689Skan#include "insn-config.h"
300169689Skan
30118334Speter#ifdef HAVE_conditional_move
30218334Speter/* Emit a conditional move operation.  */
303132718Skanrtx emit_conditional_move (rtx, enum rtx_code, rtx, rtx, enum machine_mode,
304132718Skan			   rtx, rtx, enum machine_mode, int);
30518334Speter
306117395Skan/* Return nonzero if the conditional move is supported.  */
307132718Skanint can_conditionally_move_p (enum machine_mode mode);
30850397Sobrien
30918334Speter#endif
310132718Skanrtx emit_conditional_add (rtx, enum rtx_code, rtx, rtx, enum machine_mode,
311132718Skan			  rtx, rtx, enum machine_mode, int);
31218334Speter
313169689Skanrtx expand_val_compare_and_swap (rtx, rtx, rtx, rtx);
314169689Skanrtx expand_bool_compare_and_swap (rtx, rtx, rtx, rtx);
315169689Skanrtx expand_sync_operation (rtx, rtx, enum rtx_code);
316169689Skanrtx expand_sync_fetch_operation (rtx, rtx, enum rtx_code, bool, rtx);
317169689Skanrtx expand_sync_lock_test_and_set (rtx, rtx, rtx);
31818334Speter
31918334Speter/* Functions from expmed.c:  */
32018334Speter
32118334Speter/* Arguments MODE, RTX: return an rtx for the negation of that value.
32218334Speter   May emit insns.  */
323132718Skanextern rtx negate_rtx (enum machine_mode, rtx);
32418334Speter
32518334Speter/* Expand a logical AND operation.  */
326132718Skanextern rtx expand_and (enum machine_mode, rtx, rtx, rtx);
32718334Speter
32818334Speter/* Emit a store-flag operation.  */
329132718Skanextern rtx emit_store_flag (rtx, enum rtx_code, rtx, rtx, enum machine_mode,
330132718Skan			    int, int);
33118334Speter
33250397Sobrien/* Like emit_store_flag, but always succeeds.  */
333132718Skanextern rtx emit_store_flag_force (rtx, enum rtx_code, rtx, rtx,
334132718Skan				  enum machine_mode, int, int);
33518334Speter
33690075Sobrien/* Functions from builtins.c:  */
337132718Skanextern rtx expand_builtin (tree, rtx, rtx, enum machine_mode, int);
338132718Skanextern tree std_build_builtin_va_list (void);
339132718Skanextern void std_expand_builtin_va_start (tree, rtx);
340132718Skanextern rtx default_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
341132718Skanextern void expand_builtin_setjmp_setup (rtx, rtx);
342132718Skanextern void expand_builtin_setjmp_receiver (rtx);
343132718Skanextern rtx expand_builtin_saveregs (void);
344132718Skanextern void expand_builtin_trap (void);
34590075Sobrien
34618334Speter/* Functions from expr.c:  */
34718334Speter
34818334Speter/* This is run once per compilation to set up which modes can be used
34918334Speter   directly in memory and to initialize the block move optab.  */
350132718Skanextern void init_expr_once (void);
35118334Speter
35218334Speter/* This is run at the start of compiling a function.  */
353132718Skanextern void init_expr (void);
35418334Speter
35518334Speter/* Emit some rtl insns to move data between rtx's, converting machine modes.
35618334Speter   Both modes must be floating or both fixed.  */
357132718Skanextern void convert_move (rtx, rtx, int);
35818334Speter
35918334Speter/* Convert an rtx to specified machine mode and return the result.  */
360132718Skanextern rtx convert_to_mode (enum machine_mode, rtx, int);
36118334Speter
36218334Speter/* Convert an rtx to MODE from OLDMODE and return the result.  */
363132718Skanextern rtx convert_modes (enum machine_mode, enum machine_mode, rtx, int);
36418334Speter
36518334Speter/* Emit code to move a block Y to a block X.  */
36618334Speter
367117395Skanenum block_op_methods
368117395Skan{
369117395Skan  BLOCK_OP_NORMAL,
370117395Skan  BLOCK_OP_NO_LIBCALL,
371169689Skan  BLOCK_OP_CALL_PARM,
372169689Skan  /* Like BLOCK_OP_NORMAL, but the libcall can be tail call optimized.  */
373169689Skan  BLOCK_OP_TAILCALL
374117395Skan};
375117395Skan
376132718Skanextern void init_block_move_fn (const char *);
377132718Skanextern void init_block_clear_fn (const char *);
378117395Skan
379132718Skanextern rtx emit_block_move (rtx, rtx, rtx, enum block_op_methods);
380132718Skan
38118334Speter/* Copy all or part of a value X into registers starting at REGNO.
38218334Speter   The number of registers to be filled is NREGS.  */
383132718Skanextern void move_block_to_reg (int, rtx, int, enum machine_mode);
38418334Speter
38518334Speter/* Copy all or part of a BLKmode value X out of registers starting at REGNO.
38618334Speter   The number of registers to be filled is NREGS.  */
387132718Skanextern void move_block_from_reg (int, rtx, int);
38818334Speter
389117395Skan/* Generate a non-consecutive group of registers represented by a PARALLEL.  */
390132718Skanextern rtx gen_group_rtx (rtx);
391117395Skan
39250397Sobrien/* Load a BLKmode value into non-consecutive registers represented by a
39350397Sobrien   PARALLEL.  */
394132718Skanextern void emit_group_load (rtx, rtx, tree, int);
39590075Sobrien
396169689Skan/* Similarly, but load into new temporaries.  */
397169689Skanextern rtx emit_group_load_into_temps (rtx, rtx, tree, int);
398169689Skan
399117395Skan/* Move a non-consecutive group of registers represented by a PARALLEL into
400117395Skan   a non-consecutive group of registers represented by a PARALLEL.  */
401132718Skanextern void emit_group_move (rtx, rtx);
402117395Skan
403169689Skan/* Move a group of registers represented by a PARALLEL into pseudos.  */
404169689Skanextern rtx emit_group_move_into_temps (rtx);
405169689Skan
40650397Sobrien/* Store a BLKmode value from non-consecutive registers represented by a
40750397Sobrien   PARALLEL.  */
408132718Skanextern void emit_group_store (rtx, rtx, tree, int);
40950397Sobrien
41090075Sobrien/* Copy BLKmode object from a set of registers.  */
411132718Skanextern rtx copy_blkmode_from_reg (rtx, rtx, tree);
41252284Sobrien
41318334Speter/* Mark REG as holding a parameter for the next CALL_INSN.  */
414132718Skanextern void use_reg (rtx *, rtx);
41590075Sobrien
41618334Speter/* Mark NREGS consecutive regs, starting at REGNO, as holding parameters
41718334Speter   for the next CALL_INSN.  */
418132718Skanextern void use_regs (rtx *, int, int);
41990075Sobrien
42050397Sobrien/* Mark a PARALLEL as holding a parameter for the next CALL_INSN.  */
421132718Skanextern void use_group_regs (rtx *, rtx);
42218334Speter
42318334Speter/* Write zeros through the storage of OBJECT.
42490075Sobrien   If OBJECT has BLKmode, SIZE is its length in bytes.  */
425169689Skanextern rtx clear_storage (rtx, rtx, enum block_op_methods);
42618334Speter
427169689Skan/* Expand a setmem pattern; return true if successful.  */
428169689Skanextern bool set_storage_via_setmem (rtx, rtx, rtx, unsigned int);
429169689Skan
430132718Skan/* Determine whether the LEN bytes can be moved by using several move
431132718Skan   instructions.  Return nonzero if a call to move_by_pieces should
432132718Skan   succeed.  */
433132718Skanextern int can_move_by_pieces (unsigned HOST_WIDE_INT, unsigned int);
434132718Skan
435117395Skan/* Return nonzero if it is desirable to store LEN bytes generated by
43690075Sobrien   CONSTFUN with several move instructions by store_by_pieces
43790075Sobrien   function.  CONSTFUNDATA is a pointer which will be passed as argument
43890075Sobrien   in every CONSTFUN call.
43990075Sobrien   ALIGN is maximum alignment we can assume.  */
440132718Skanextern int can_store_by_pieces (unsigned HOST_WIDE_INT,
441132718Skan				rtx (*) (void *, HOST_WIDE_INT,
442132718Skan					 enum machine_mode),
443132718Skan				void *, unsigned int);
44490075Sobrien
44590075Sobrien/* Generate several move instructions to store LEN bytes generated by
44690075Sobrien   CONSTFUN to block TO.  (A MEM rtx with BLKmode).  CONSTFUNDATA is a
44790075Sobrien   pointer which will be passed as argument in every CONSTFUN call.
448132718Skan   ALIGN is maximum alignment we can assume.
449132718Skan   Returns TO + LEN.  */
450132718Skanextern rtx store_by_pieces (rtx, unsigned HOST_WIDE_INT,
451132718Skan			    rtx (*) (void *, HOST_WIDE_INT, enum machine_mode),
452132718Skan			    void *, unsigned int, int);
45390075Sobrien
45418334Speter/* Emit insns to set X from Y.  */
455132718Skanextern rtx emit_move_insn (rtx, rtx);
45618334Speter
45718334Speter/* Emit insns to set X from Y, with no frills.  */
458132718Skanextern rtx emit_move_insn_1 (rtx, rtx);
45918334Speter
46018334Speter/* Push a block of length SIZE (perhaps variable)
46118334Speter   and return an rtx to address the beginning of the block.  */
462132718Skanextern rtx push_block (rtx, int, int);
46318334Speter
46418334Speter/* Generate code to push something onto the stack, given its mode and type.  */
465132718Skanextern void emit_push_insn (rtx, enum machine_mode, tree, rtx, unsigned int,
466132718Skan			    int, rtx, int, rtx, rtx, int, rtx);
46718334Speter
46890075Sobrien/* Expand an assignment that stores the value of FROM into TO.  */
469169689Skanextern void expand_assignment (tree, tree);
47018334Speter
47118334Speter/* Generate code for computing expression EXP,
47218334Speter   and storing the value into TARGET.
47318334Speter   If SUGGEST_REG is nonzero, copy the value through a register
47418334Speter   and return that register, if that is possible.  */
475132718Skanextern rtx store_expr (tree, rtx, int);
47618334Speter
47718334Speter/* Given an rtx that may include add and multiply operations,
47818334Speter   generate them as insns and return a pseudo-reg containing the value.
47918334Speter   Useful after calling expand_expr with 1 as sum_ok.  */
480132718Skanextern rtx force_operand (rtx, rtx);
48118334Speter
482169689Skan/* Work horse for expand_expr.  */
483169689Skanextern rtx expand_expr_real (tree, rtx, enum machine_mode,
484169689Skan			     enum expand_modifier, rtx *);
48550397Sobrien
48618334Speter/* Generate code for computing expression EXP.
48718334Speter   An rtx for the computed value is returned.  The value is never null.
48818334Speter   In the case of a void EXP, const0_rtx is returned.  */
489169689Skanstatic inline rtx
490169689Skanexpand_expr (tree exp, rtx target, enum machine_mode mode,
491169689Skan	     enum expand_modifier modifier)
492169689Skan{
493169689Skan  return expand_expr_real (exp, target, mode, modifier, NULL);
494169689Skan}
49518334Speter
496169689Skanstatic inline rtx
497169689Skanexpand_normal (tree exp)
498169689Skan{
499169689Skan  return expand_expr_real (exp, NULL_RTX, VOIDmode, EXPAND_NORMAL, NULL);
500169689Skan}
501169689Skan
502169689Skanextern void expand_var (tree);
503169689Skan
50418334Speter/* At the start of a function, record that we have no previously-pushed
50518334Speter   arguments waiting to be popped.  */
506132718Skanextern void init_pending_stack_adjust (void);
50718334Speter
508146895Skan/* Discard any pending stack adjustment.  */
509146895Skanextern void discard_pending_stack_adjust (void);
510146895Skan
51118334Speter/* When exiting from function, if safe, clear out any pending stack adjust
51218334Speter   so the adjustment won't get done.  */
513132718Skanextern void clear_pending_stack_adjust (void);
51418334Speter
51518334Speter/* Pop any previously-pushed arguments that have not been popped yet.  */
516132718Skanextern void do_pending_stack_adjust (void);
51718334Speter
51890075Sobrien/* Return the tree node and offset if a given argument corresponds to
51990075Sobrien   a string constant.  */
520132718Skanextern tree string_constant (tree, tree *);
52190075Sobrien
52218334Speter/* Generate code to evaluate EXP and jump to LABEL if the value is zero.  */
523132718Skanextern void jumpifnot (tree, rtx);
52418334Speter
52518334Speter/* Generate code to evaluate EXP and jump to LABEL if the value is nonzero.  */
526132718Skanextern void jumpif (tree, rtx);
52718334Speter
52818334Speter/* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
52918334Speter   the result is zero, or IF_TRUE_LABEL if the result is one.  */
530132718Skanextern void do_jump (tree, rtx, rtx);
53118334Speter
53218334Speter/* Generate rtl to compare two rtx's, will call emit_cmp_insn.  */
533132718Skanextern rtx compare_from_rtx (rtx, rtx, enum rtx_code, int, enum machine_mode,
534132718Skan			     rtx);
535132718Skanextern void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int,
536132718Skan				     enum machine_mode, rtx, rtx, rtx);
53718334Speter
53890075Sobrien/* Two different ways of generating switch statements.  */
539132718Skanextern int try_casesi (tree, tree, tree, tree, rtx, rtx);
540132718Skanextern int try_tablejump (tree, tree, tree, tree, rtx, rtx);
54190075Sobrien
54290075Sobrien/* Smallest number of adjacent cases before we use a jump table.
54390075Sobrien   XXX Should be a target hook.  */
544132718Skanextern unsigned int case_values_threshold (void);
54590075Sobrien
546169689Skan/* Functions from alias.c */
547169689Skan#include "alias.h"
548169689Skan
54918334Speter
55018334Speter/* rtl.h and tree.h were included.  */
55118334Speter/* Return an rtx for the size in bytes of the value of an expr.  */
552132718Skanextern rtx expr_size (tree);
55318334Speter
554102780Skan/* Return a wide integer for the size in bytes of the value of EXP, or -1
555102780Skan   if the size can vary or is larger than an integer.  */
556132718Skanextern HOST_WIDE_INT int_expr_size (tree);
557102780Skan
55818334Speter/* Return an rtx that refers to the value returned by a function
55918334Speter   in its original home.  This becomes invalid if any more code is emitted.  */
560169689Skanextern rtx hard_function_value (tree, tree, tree, int);
56118334Speter
562169689Skanextern rtx prepare_call_address (rtx, rtx, rtx *, int, int);
56318334Speter
564169689Skanextern bool shift_return_value (enum machine_mode, bool, rtx);
565169689Skan
566132718Skanextern rtx expand_call (tree, rtx, int);
56718334Speter
568169689Skanextern void fixup_tail_calls (void);
569169689Skan
570132718Skan#ifdef TREE_CODE
571132718Skanextern rtx expand_shift (enum tree_code, enum machine_mode, rtx, tree, rtx,
572132718Skan			 int);
573132718Skanextern rtx expand_divmod (int, enum tree_code, enum machine_mode, rtx, rtx,
574132718Skan			  rtx, int);
575132718Skan#endif
57690075Sobrien
577132718Skanextern void locate_and_pad_parm (enum machine_mode, tree, int, int, tree,
578132718Skan				 struct args_size *,
579132718Skan				 struct locate_and_pad_arg_data *);
580132718Skan
58118334Speter/* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary.  */
582132718Skanextern rtx label_rtx (tree);
58318334Speter
584132718Skan/* As label_rtx, but additionally the label is placed on the forced label
585132718Skan   list of its containing function (i.e. it is treated as reachable even
586132718Skan   if how is not obvious).  */
587132718Skanextern rtx force_label_rtx (tree);
588132718Skan
58918334Speter/* Indicate how an input argument register was promoted.  */
590132718Skanextern rtx promoted_input_arg (unsigned int, enum machine_mode *, int *);
59118334Speter
59218334Speter/* Return an rtx like arg but sans any constant terms.
59318334Speter   Returns the original rtx if it has no constant terms.
59418334Speter   The constant terms are added and stored via a second arg.  */
595132718Skanextern rtx eliminate_constant_term (rtx, rtx *);
59618334Speter
59718334Speter/* Convert arg to a valid memory address for specified machine mode,
59818334Speter   by emitting insns to perform arithmetic if nec.  */
599132718Skanextern rtx memory_address (enum machine_mode, rtx);
60018334Speter
601169689Skan/* Like `memory_address' but pretend `flag_force_addr' is 0.  */
602132718Skanextern rtx memory_address_noforce (enum machine_mode, rtx);
60318334Speter
60418334Speter/* Return a memory reference like MEMREF, but with its mode changed
60518334Speter   to MODE and its address changed to ADDR.
60618334Speter   (VOIDmode means don't change the mode.
60718334Speter   NULL for ADDR means don't change the address.)  */
608132718Skanextern rtx change_address (rtx, enum machine_mode, rtx);
60918334Speter
61090075Sobrien/* Return a memory reference like MEMREF, but with its mode changed
61190075Sobrien   to MODE and its address offset by OFFSET bytes.  */
61290075Sobrien#define adjust_address(MEMREF, MODE, OFFSET) \
61390075Sobrien  adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1)
61490075Sobrien
61590075Sobrien/* Likewise, but the reference is not required to be valid.  */
61690075Sobrien#define adjust_address_nv(MEMREF, MODE, OFFSET) \
61790075Sobrien  adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1)
61890075Sobrien
61990075Sobrien/* Return a memory reference like MEMREF, but with its mode changed
62090075Sobrien   to MODE and its address changed to ADDR, which is assumed to be
62190075Sobrien   increased by OFFSET bytes from MEMREF.  */
62290075Sobrien#define adjust_automodify_address(MEMREF, MODE, ADDR, OFFSET) \
62390075Sobrien  adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 1)
62490075Sobrien
62590075Sobrien/* Likewise, but the reference is not required to be valid.  */
62690075Sobrien#define adjust_automodify_address_nv(MEMREF, MODE, ADDR, OFFSET) \
62790075Sobrien  adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 0)
62890075Sobrien
629132718Skanextern rtx adjust_address_1 (rtx, enum machine_mode, HOST_WIDE_INT, int, int);
630132718Skanextern rtx adjust_automodify_address_1 (rtx, enum machine_mode, rtx,
631132718Skan					HOST_WIDE_INT, int);
63290075Sobrien
63390075Sobrien/* Return a memory reference like MEMREF, but whose address is changed by
63490075Sobrien   adding OFFSET, an RTX, to it.  POW2 is the highest power of two factor
63590075Sobrien   known to be in OFFSET (possibly 1).  */
636132718Skanextern rtx offset_address (rtx, rtx, unsigned HOST_WIDE_INT);
63790075Sobrien
638169689Skan/* Definitions from emit-rtl.c */
639169689Skan#include "emit-rtl.h"
64090075Sobrien
64190075Sobrien/* Return a memory reference like MEMREF, but with its mode widened to
64290075Sobrien   MODE and adjusted by OFFSET.  */
643132718Skanextern rtx widen_memory_access (rtx, enum machine_mode, HOST_WIDE_INT);
64490075Sobrien
64518334Speter/* Return a memory reference like MEMREF, but which is known to have a
64618334Speter   valid address.  */
647132718Skanextern rtx validize_mem (rtx);
64818334Speter
649169689Skanextern rtx use_anchored_address (rtx);
65018334Speter
65190075Sobrien/* Given REF, a MEM, and T, either the type of X or the expression
65290075Sobrien   corresponding to REF, set the memory attributes.  OBJECTP is nonzero
65390075Sobrien   if we are making a new object of this type.  */
654132718Skanextern void set_mem_attributes (rtx, tree, int);
655110611Skan
656110611Skan/* Similar, except that BITPOS has not yet been applied to REF, so if
657110611Skan   we alter MEM_OFFSET according to T then we should subtract BITPOS
658110611Skan   expecting that it'll be added back in later.  */
659132718Skanextern void set_mem_attributes_minus_bitpos (rtx, tree, int, HOST_WIDE_INT);
66090075Sobrien
66118334Speter/* Assemble the static constant template for function entry trampolines.  */
662132718Skanextern rtx assemble_trampoline_template (void);
66318334Speter
66418334Speter/* Copy given rtx to a new temp reg and return that.  */
665132718Skanextern rtx copy_to_reg (rtx);
66618334Speter
66718334Speter/* Like copy_to_reg but always make the reg Pmode.  */
668132718Skanextern rtx copy_addr_to_reg (rtx);
66918334Speter
67018334Speter/* Like copy_to_reg but always make the reg the specified mode MODE.  */
671132718Skanextern rtx copy_to_mode_reg (enum machine_mode, rtx);
67218334Speter
67318334Speter/* Copy given rtx to given temp reg and return that.  */
674132718Skanextern rtx copy_to_suggested_reg (rtx, rtx, enum machine_mode);
67518334Speter
67618334Speter/* Copy a value to a register if it isn't already a register.
67718334Speter   Args are mode (in case value is a constant) and the value.  */
678132718Skanextern rtx force_reg (enum machine_mode, rtx);
67918334Speter
68018334Speter/* Return given rtx, copied into a new temp reg if it was in memory.  */
681132718Skanextern rtx force_not_mem (rtx);
68218334Speter
68318334Speter/* Return mode and signedness to use when object is promoted.  */
684132718Skanextern enum machine_mode promote_mode (tree, enum machine_mode, int *, int);
68518334Speter
68618334Speter/* Remove some bytes from the stack.  An rtx says how many.  */
687132718Skanextern void adjust_stack (rtx);
68818334Speter
68918334Speter/* Add some bytes to the stack.  An rtx says how many.  */
690132718Skanextern void anti_adjust_stack (rtx);
69118334Speter
69218334Speter/* This enum is used for the following two functions.  */
69318334Speterenum save_level {SAVE_BLOCK, SAVE_FUNCTION, SAVE_NONLOCAL};
69418334Speter
69518334Speter/* Save the stack pointer at the specified level.  */
696132718Skanextern void emit_stack_save (enum save_level, rtx *, rtx);
69718334Speter
69818334Speter/* Restore the stack pointer from a save area of the specified level.  */
699132718Skanextern void emit_stack_restore (enum save_level, rtx, rtx);
70018334Speter
701169689Skan/* Invoke emit_stack_save for the nonlocal_goto_save_area.  */
702169689Skanextern void update_nonlocal_goto_save_area (void);
703169689Skan
70418334Speter/* Allocate some space on the stack dynamically and return its address.  An rtx
70518334Speter   says how many bytes.  */
706132718Skanextern rtx allocate_dynamic_stack_space (rtx, rtx, int);
70718334Speter
708117395Skan/* Probe a range of stack addresses from FIRST to FIRST+SIZE, inclusive.
70950397Sobrien   FIRST is a constant and size is a Pmode RTX.  These are offsets from the
71050397Sobrien   current stack pointer.  STACK_GROWS_DOWNWARD says whether to add or
71150397Sobrien   subtract from the stack.  If SIZE is constant, this is done
71250397Sobrien   with a fixed number of probes.  Otherwise, we must make a loop.  */
713132718Skanextern void probe_stack_range (HOST_WIDE_INT, rtx);
71418334Speter
71518334Speter/* Return an rtx that refers to the value returned by a library call
71618334Speter   in its original home.  This becomes invalid if any more code is emitted.  */
717132718Skanextern rtx hard_libcall_value (enum machine_mode);
71818334Speter
71990075Sobrien/* Return the mode desired by operand N of a particular bitfield
72090075Sobrien   insert/extract insn, or MAX_MACHINE_MODE if no such insn is
72190075Sobrien   available.  */
72218334Speter
72390075Sobrienenum extraction_pattern { EP_insv, EP_extv, EP_extzv };
72490075Sobrienextern enum machine_mode
725132718Skanmode_for_extraction (enum extraction_pattern, int);
72618334Speter
727132718Skanextern rtx store_bit_field (rtx, unsigned HOST_WIDE_INT,
728169689Skan			    unsigned HOST_WIDE_INT, enum machine_mode, rtx);
729132718Skanextern rtx extract_bit_field (rtx, unsigned HOST_WIDE_INT,
730132718Skan			      unsigned HOST_WIDE_INT, int, rtx,
731169689Skan			      enum machine_mode, enum machine_mode);
732132718Skanextern rtx expand_mult (enum machine_mode, rtx, rtx, rtx, int);
733132718Skanextern rtx expand_mult_highpart_adjust (enum machine_mode, rtx, rtx, rtx, rtx, int);
73490075Sobrien
735132718Skanextern rtx assemble_static_space (unsigned HOST_WIDE_INT);
736132718Skanextern int safe_from_p (rtx, tree, int);
73790075Sobrien
73890075Sobrien/* Call this once to initialize the contents of the optabs
73990075Sobrien   appropriately for the current target machine.  */
740132718Skanextern void init_optabs (void);
741132718Skanextern void init_all_optabs (void);
74250397Sobrien
74390075Sobrien/* Call this to initialize an optab function entry.  */
744132718Skanextern rtx init_one_libfunc (const char *);
74590075Sobrien
746132718Skanextern int vector_mode_valid_p (enum machine_mode);
747132718Skan
748169689Skan#endif /* GCC_EXPR_H */
749