expr.h revision 102780
154359Sroberto/* Definitions for code generation pass of GNU compiler.
282498Sroberto   Copyright (C) 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
354359Sroberto   1999, 2000 Free Software Foundation, Inc.
454359Sroberto
554359SrobertoThis file is part of GCC.
654359Sroberto
754359SrobertoGCC is free software; you can redistribute it and/or modify it under
854359Srobertothe terms of the GNU General Public License as published by the Free
954359SrobertoSoftware Foundation; either version 2, or (at your option) any later
1054359Srobertoversion.
1154359Sroberto
1254359SrobertoGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1354359SrobertoWARRANTY; without even the implied warranty of MERCHANTABILITY or
1454359SrobertoFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1554359Srobertofor more details.
1654359Sroberto
1754359SrobertoYou should have received a copy of the GNU General Public License
1854359Srobertoalong with GCC; see the file COPYING.  If not, write to the Free
19182007SrobertoSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
2054359Sroberto02111-1307, USA.  */
2182498Sroberto
2282498Sroberto/* The default branch cost is 1.  */
2354359Sroberto#ifndef BRANCH_COST
2482498Sroberto#define BRANCH_COST 1
2554359Sroberto#endif
2682498Sroberto
2782498Sroberto/* Macros to access the slots of a QUEUED rtx.
2854359Sroberto   Here rather than in rtl.h because only the expansion pass
2982498Sroberto   should ever encounter a QUEUED.  */
3082498Sroberto
3182498Sroberto/* The variable for which an increment is queued.  */
3282498Sroberto#define QUEUED_VAR(P) XEXP (P, 0)
3382498Sroberto/* If the increment has been emitted, this is the insn
3482498Sroberto   that does the increment.  It is zero before the increment is emitted.
3582498Sroberto   If more than one insn is emitted, this is the first insn.  */
3682498Sroberto#define QUEUED_INSN(P) XEXP (P, 1)
3782498Sroberto/* If a pre-increment copy has been generated, this is the copy
3882498Sroberto   (it is a temporary reg).  Zero if no copy made yet.  */
3982498Sroberto#define QUEUED_COPY(P) XEXP (P, 2)
4082498Sroberto/* This is the body to use for the insn to do the increment.
4182498Sroberto   It is used to emit the increment.  */
4282498Sroberto#define QUEUED_BODY(P) XEXP (P, 3)
4382498Sroberto/* Next QUEUED in the queue.  */
4482498Sroberto#define QUEUED_NEXT(P) XEXP (P, 4)
45182007Sroberto
46182007Sroberto/* This is the 4th arg to `expand_expr'.
4754359Sroberto   EXPAND_SUM means it is ok to return a PLUS rtx or MULT rtx.
4882498Sroberto   EXPAND_INITIALIZER is similar but also record any labels on forced_labels.
4982498Sroberto   EXPAND_CONST_ADDRESS means it is ok to return a MEM whose address
5082498Sroberto    is a constant that is not a legitimate address.
5154359Sroberto   EXPAND_WRITE means we are only going to write to the resulting rtx.  */
5282498Srobertoenum expand_modifier {EXPAND_NORMAL, EXPAND_SUM, EXPAND_CONST_ADDRESS,
5382498Sroberto			EXPAND_INITIALIZER, EXPAND_WRITE};
5482498Sroberto
55182007Sroberto/* Prevent the compiler from deferring stack pops.  See
56182007Sroberto   inhibit_defer_pop for more information.  */
5782498Sroberto#define NO_DEFER_POP (inhibit_defer_pop += 1)
58182007Sroberto
5982498Sroberto/* Allow the compiler to defer stack pops.  See inhibit_defer_pop for
6082498Sroberto   more information.  */
61182007Sroberto#define OK_DEFER_POP (inhibit_defer_pop -= 1)
6282498Sroberto
6382498Sroberto#ifdef TREE_CODE /* Don't lose if tree.h not included.  */
6454359Sroberto/* Structure to record the size of a sequence of arguments
6582498Sroberto   as the sum of a tree-expression and a constant.  This structure is
6654359Sroberto   also used to store offsets from the stack, which might be negative,
6754359Sroberto   so the variable part must be ssizetype, not sizetype.  */
6854359Sroberto
6982498Srobertostruct args_size
7054359Sroberto{
7182498Sroberto  HOST_WIDE_INT constant;
7282498Sroberto  tree var;
7354359Sroberto};
7454359Sroberto#endif
75182007Sroberto
7682498Sroberto/* Add the value of the tree INC to the `struct args_size' TO.  */
7754359Sroberto
78182007Sroberto#define ADD_PARM_SIZE(TO, INC)				\
79182007Srobertodo {							\
80182007Sroberto  tree inc = (INC);					\
8154359Sroberto  if (host_integerp (inc, 0))				\
8282498Sroberto    (TO).constant += tree_low_cst (inc, 0);		\
8354359Sroberto  else if ((TO).var == 0)				\
8454359Sroberto    (TO).var = convert (ssizetype, inc);		\
8554359Sroberto  else							\
8654359Sroberto    (TO).var = size_binop (PLUS_EXPR, (TO).var,		\
8754359Sroberto			   convert (ssizetype, inc));	\
8854359Sroberto} while (0)
8954359Sroberto
9054359Sroberto#define SUB_PARM_SIZE(TO, DEC)				\
9154359Srobertodo {							\
92285612Sdelphij  tree dec = (DEC);					\
93285612Sdelphij  if (host_integerp (dec, 0))				\
94285612Sdelphij    (TO).constant -= tree_low_cst (dec, 0);		\
95285612Sdelphij  else if ((TO).var == 0)				\
9654359Sroberto    (TO).var = size_binop (MINUS_EXPR, ssize_int (0),	\
9754359Sroberto			   convert (ssizetype, dec));	\
9854359Sroberto  else							\
9954359Sroberto    (TO).var = size_binop (MINUS_EXPR, (TO).var,	\
10054359Sroberto			   convert (ssizetype, dec));	\
10154359Sroberto} while (0)
10254359Sroberto
10354359Sroberto/* Convert the implicit sum in a `struct args_size' into a tree
10482498Sroberto   of type ssizetype.  */
10582498Sroberto#define ARGS_SIZE_TREE(SIZE)					\
10682498Sroberto((SIZE).var == 0 ? ssize_int ((SIZE).constant)			\
10782498Sroberto : size_binop (PLUS_EXPR, convert (ssizetype, (SIZE).var),	\
10854359Sroberto	       ssize_int ((SIZE).constant)))
10954359Sroberto
11054359Sroberto/* Convert the implicit sum in a `struct args_size' into an rtx.  */
11154359Sroberto#define ARGS_SIZE_RTX(SIZE)					\
11254359Sroberto((SIZE).var == 0 ? GEN_INT ((SIZE).constant)			\
11354359Sroberto : expand_expr (ARGS_SIZE_TREE (SIZE), NULL_RTX, VOIDmode, 0))
11454359Sroberto
11554359Sroberto/* Supply a default definition for FUNCTION_ARG_PADDING:
11654359Sroberto   usually pad upward, but pad short args downward on
11754359Sroberto   big-endian machines.  */
11854359Sroberto
11954359Srobertoenum direction {none, upward, downward};  /* Value has this type.  */
12054359Sroberto
12154359Sroberto#ifndef FUNCTION_ARG_PADDING
12282498Sroberto#define FUNCTION_ARG_PADDING(MODE, TYPE)				\
12354359Sroberto  (! BYTES_BIG_ENDIAN							\
12482498Sroberto   ? upward								\
12554359Sroberto   : (((MODE) == BLKmode						\
12654359Sroberto       ? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST		\
12754359Sroberto	  && int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT)) \
128285612Sdelphij       : GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY)			\
129285612Sdelphij      ? downward : upward))
130285612Sdelphij#endif
13154359Sroberto
13254359Sroberto/* Supply a default definition for FUNCTION_ARG_BOUNDARY.  Normally, we let
13354359Sroberto   FUNCTION_ARG_PADDING, which also pads the length, handle any needed
13454359Sroberto   alignment.  */
13554359Sroberto
136285612Sdelphij#ifndef FUNCTION_ARG_BOUNDARY
137285612Sdelphij#define FUNCTION_ARG_BOUNDARY(MODE, TYPE)	PARM_BOUNDARY
13854359Sroberto#endif
13954359Sroberto
140285612Sdelphij/* Provide a default value for STRICT_ARGUMENT_NAMING.  */
14154359Sroberto#ifndef STRICT_ARGUMENT_NAMING
14254359Sroberto#define STRICT_ARGUMENT_NAMING 0
14354359Sroberto#endif
144285612Sdelphij
145285612Sdelphij/* Provide a default value for PRETEND_OUTGOING_VARARGS_NAMED.  */
14654359Sroberto#ifdef SETUP_INCOMING_VARARGS
14754359Sroberto#ifndef PRETEND_OUTGOING_VARARGS_NAMED
14854359Sroberto#define PRETEND_OUTGOING_VARARGS_NAMED 1
149285612Sdelphij#endif
15054359Sroberto#else
15154359Sroberto/* It is an error to define PRETEND_OUTGOING_VARARGS_NAMED without
15254359Sroberto   defining SETUP_INCOMING_VARARGS.  */
15354359Sroberto#define PRETEND_OUTGOING_VARARGS_NAMED 0
15454359Sroberto#endif
15554359Sroberto
15654359Sroberto/* Nonzero if we do not know how to pass TYPE solely in registers.
15754359Sroberto   We cannot do so in the following cases:
15854359Sroberto
15954359Sroberto   - if the type has variable size
16054359Sroberto   - if the type is marked as addressable (it is required to be constructed
16154359Sroberto     into the stack)
16254359Sroberto   - if the padding and mode of the type is such that a copy into a register
16354359Sroberto     would put it into the wrong part of the register.
16454359Sroberto
16554359Sroberto   Which padding can't be supported depends on the byte endianness.
16654359Sroberto
16754359Sroberto   A value in a register is implicitly padded at the most significant end.
16854359Sroberto   On a big-endian machine, that is the lower end in memory.
16954359Sroberto   So a value padded in memory at the upper end can't go in a register.
17054359Sroberto   For a little-endian machine, the reverse is true.  */
17154359Sroberto
17254359Sroberto#ifndef MUST_PASS_IN_STACK
17354359Sroberto#define MUST_PASS_IN_STACK(MODE,TYPE)			\
174285612Sdelphij  ((TYPE) != 0						\
175285612Sdelphij   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST	\
176285612Sdelphij       || TREE_ADDRESSABLE (TYPE)			\
177285612Sdelphij       || ((MODE) == BLKmode 				\
178285612Sdelphij	   && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
17954359Sroberto		 && 0 == (int_size_in_bytes (TYPE)	\
18054359Sroberto			  % (PARM_BOUNDARY / BITS_PER_UNIT))) \
18154359Sroberto	   && (FUNCTION_ARG_PADDING (MODE, TYPE)	\
18254359Sroberto	       == (BYTES_BIG_ENDIAN ? upward : downward)))))
18354359Sroberto#endif
18454359Sroberto
18554359Sroberto/* Nonzero if type TYPE should be returned in memory.
18654359Sroberto   Most machines can use the following default definition.  */
18754359Sroberto
18854359Sroberto#ifndef RETURN_IN_MEMORY
18954359Sroberto#define RETURN_IN_MEMORY(TYPE) (TYPE_MODE (TYPE) == BLKmode)
19054359Sroberto#endif
19154359Sroberto
19254359Sroberto/* Supply a default definition of STACK_SAVEAREA_MODE for emit_stack_save.
19354359Sroberto   Normally move_insn, so Pmode stack pointer.  */
194285612Sdelphij
195285612Sdelphij#ifndef STACK_SAVEAREA_MODE
196285612Sdelphij#define STACK_SAVEAREA_MODE(LEVEL) Pmode
197285612Sdelphij#endif
198285612Sdelphij
199285612Sdelphij/* Supply a default definition of STACK_SIZE_MODE for
200285612Sdelphij   allocate_dynamic_stack_space.  Normally PLUS/MINUS, so word_mode.  */
20182498Sroberto
20254359Sroberto#ifndef STACK_SIZE_MODE
20354359Sroberto#define STACK_SIZE_MODE word_mode
20454359Sroberto#endif
20554359Sroberto
206285612Sdelphij/* Provide default values for the macros controlling stack checking.  */
20754359Sroberto
208285612Sdelphij#ifndef STACK_CHECK_BUILTIN
20954359Sroberto#define STACK_CHECK_BUILTIN 0
21054359Sroberto#endif
21154359Sroberto
21254359Sroberto/* The default interval is one page.  */
21382498Sroberto#ifndef STACK_CHECK_PROBE_INTERVAL
21454359Sroberto#define STACK_CHECK_PROBE_INTERVAL 4096
21554359Sroberto#endif
21654359Sroberto
21754359Sroberto/* The default is to do a store into the stack.  */
21854359Sroberto#ifndef STACK_CHECK_PROBE_LOAD
21954359Sroberto#define STACK_CHECK_PROBE_LOAD 0
22054359Sroberto#endif
22154359Sroberto
22254359Sroberto/* This value is arbitrary, but should be sufficient for most machines.  */
22354359Sroberto#ifndef STACK_CHECK_PROTECT
22454359Sroberto#define STACK_CHECK_PROTECT (75 * UNITS_PER_WORD)
22554359Sroberto#endif
22654359Sroberto
22754359Sroberto/* Make the maximum frame size be the largest we can and still only need
22854359Sroberto   one probe per function.  */
22954359Sroberto#ifndef STACK_CHECK_MAX_FRAME_SIZE
23054359Sroberto#define STACK_CHECK_MAX_FRAME_SIZE \
23154359Sroberto  (STACK_CHECK_PROBE_INTERVAL - UNITS_PER_WORD)
23254359Sroberto#endif
23354359Sroberto
23454359Sroberto/* This is arbitrary, but should be large enough everywhere.  */
23582498Sroberto#ifndef STACK_CHECK_FIXED_FRAME_SIZE
23682498Sroberto#define STACK_CHECK_FIXED_FRAME_SIZE (4 * UNITS_PER_WORD)
23754359Sroberto#endif
238182007Sroberto
23982498Sroberto/* Provide a reasonable default for the maximum size of an object to
24082498Sroberto   allocate in the fixed frame.  We may need to be able to make this
241182007Sroberto   controllable by the user at some point.  */
24282498Sroberto#ifndef STACK_CHECK_MAX_VAR_SIZE
243182007Sroberto#define STACK_CHECK_MAX_VAR_SIZE (STACK_CHECK_MAX_FRAME_SIZE / 100)
244182007Sroberto#endif
245182007Sroberto
246182007Sroberto/* Functions from optabs.c, commonly used, and without need for the optabs
247182007Sroberto   tables:  */
24882498Sroberto
249182007Sroberto/* Passed to expand_simple_binop and expand_binop to say which options
250182007Sroberto   to try to use if the requested operation can't be open-coded on the
251182007Sroberto   requisite mode.  Either OPTAB_LIB or OPTAB_LIB_WIDEN says try using
252182007Sroberto   a library call.  Either OPTAB_WIDEN or OPTAB_LIB_WIDEN says try
253182007Sroberto   using a wider mode.  OPTAB_MUST_WIDEN says try widening and don't
254182007Sroberto   try anything else.  */
255182007Sroberto
256182007Srobertoenum optab_methods
257182007Sroberto{
258182007Sroberto  OPTAB_DIRECT,
259182007Sroberto  OPTAB_LIB,
260182007Sroberto  OPTAB_WIDEN,
261182007Sroberto  OPTAB_LIB_WIDEN,
262182007Sroberto  OPTAB_MUST_WIDEN
263182007Sroberto};
264182007Sroberto
265182007Sroberto/* Generate code for a simple binary or unary operation.  "Simple" in
266182007Sroberto   this case means "can be unambiguously described by a (mode, code)
267182007Sroberto   pair and mapped to a single optab."  */
268182007Srobertoextern rtx expand_simple_binop PARAMS ((enum machine_mode, enum rtx_code, rtx,
269182007Sroberto					rtx, rtx, int, enum optab_methods));
270182007Srobertoextern rtx expand_simple_unop PARAMS ((enum machine_mode, enum rtx_code,
271182007Sroberto				       rtx, rtx, int));
272182007Sroberto
273182007Sroberto/* Report whether the machine description contains an insn which can
274182007Sroberto   perform the operation described by CODE and MODE.  */
275182007Srobertoextern int have_insn_for PARAMS ((enum rtx_code, enum machine_mode));
276182007Sroberto
277182007Sroberto/* Emit code to make a call to a constant function or a library call.  */
278182007Srobertoextern void emit_libcall_block PARAMS ((rtx, rtx, rtx, rtx));
279182007Sroberto
280182007Sroberto/* Create but don't emit one rtl instruction to perform certain operations.
281182007Sroberto   Modes must match; operands must meet the operation's predicates.
282182007Sroberto   Likewise for subtraction and for just copying.
283182007Sroberto   These do not call protect_from_queue; caller must do so.  */
284182007Srobertoextern rtx gen_add2_insn PARAMS ((rtx, rtx));
285182007Srobertoextern rtx gen_add3_insn PARAMS ((rtx, rtx, rtx));
286182007Srobertoextern rtx gen_sub2_insn PARAMS ((rtx, rtx));
287182007Srobertoextern rtx gen_sub3_insn PARAMS ((rtx, rtx, rtx));
288182007Srobertoextern rtx gen_move_insn PARAMS ((rtx, rtx));
289182007Srobertoextern int have_add2_insn PARAMS ((rtx, rtx));
290182007Srobertoextern int have_sub2_insn PARAMS ((rtx, rtx));
291182007Sroberto
292182007Sroberto/* Emit a pair of rtl insns to compare two rtx's and to jump
293182007Sroberto   to a label if the comparison is true.  */
294182007Srobertoextern void emit_cmp_and_jump_insns PARAMS ((rtx, rtx, enum rtx_code, rtx,
295182007Sroberto					     enum machine_mode, int, rtx));
296182007Sroberto
297182007Sroberto/* Generate code to indirectly jump to a location given in the rtx LOC.  */
298182007Srobertoextern void emit_indirect_jump PARAMS ((rtx));
299182007Sroberto
300182007Sroberto#ifdef HAVE_conditional_move
301182007Sroberto/* Emit a conditional move operation.  */
302182007Srobertortx emit_conditional_move PARAMS ((rtx, enum rtx_code, rtx, rtx,
303182007Sroberto				   enum machine_mode, rtx, rtx,
304182007Sroberto				   enum machine_mode, int));
305182007Sroberto
306182007Sroberto/* Return non-zero if the conditional move is supported.  */
307182007Srobertoint can_conditionally_move_p PARAMS ((enum machine_mode mode));
308182007Sroberto
309182007Sroberto#endif
310182007Sroberto
311182007Sroberto
312182007Sroberto/* Functions from expmed.c:  */
313182007Sroberto
314182007Sroberto/* Arguments MODE, RTX: return an rtx for the negation of that value.
315182007Sroberto   May emit insns.  */
316182007Srobertoextern rtx negate_rtx PARAMS ((enum machine_mode, rtx));
317182007Sroberto
318182007Sroberto/* Expand a logical AND operation.  */
319182007Srobertoextern rtx expand_and PARAMS ((enum machine_mode, rtx, rtx, rtx));
32082498Sroberto
321182007Sroberto/* Emit a store-flag operation.  */
322182007Srobertoextern rtx emit_store_flag PARAMS ((rtx, enum rtx_code, rtx, rtx,
323182007Sroberto				    enum machine_mode, int, int));
324182007Sroberto
325182007Sroberto/* Like emit_store_flag, but always succeeds.  */
326182007Srobertoextern rtx emit_store_flag_force PARAMS ((rtx, enum rtx_code, rtx, rtx,
327182007Sroberto					  enum machine_mode, int, int));
328182007Sroberto
329182007Sroberto/* Functions from loop.c:  */
330182007Sroberto
331182007Sroberto/* Given an insn and condition, return a canonical description of
332182007Sroberto   the test being made.  */
333182007Srobertoextern rtx canonicalize_condition PARAMS ((rtx, rtx, int, rtx *, rtx));
334182007Sroberto
335182007Sroberto/* Given a JUMP_INSN, return a canonical description of the test
336182007Sroberto   being made.  */
337182007Srobertoextern rtx get_condition PARAMS ((rtx, rtx *));
338182007Sroberto
339182007Sroberto/* Generate a conditional trap instruction.  */
340182007Srobertoextern rtx gen_cond_trap PARAMS ((enum rtx_code, rtx, rtx, rtx));
341182007Sroberto
342182007Sroberto/* Functions from builtins.c:  */
343182007Srobertoextern rtx expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
344182007Srobertoextern void std_expand_builtin_va_start PARAMS ((int, tree, rtx));
345182007Srobertoextern rtx std_expand_builtin_va_arg PARAMS ((tree, tree));
346182007Srobertoextern rtx expand_builtin_va_arg PARAMS ((tree, tree));
347182007Srobertoextern void default_init_builtins PARAMS ((void));
348182007Srobertoextern rtx default_expand_builtin PARAMS ((tree, rtx, rtx,
349182007Sroberto					   enum machine_mode, int));
350182007Srobertoextern void expand_builtin_setjmp_setup PARAMS ((rtx, rtx));
351182007Srobertoextern void expand_builtin_setjmp_receiver PARAMS ((rtx));
352182007Srobertoextern void expand_builtin_longjmp PARAMS ((rtx, rtx));
353182007Srobertoextern rtx expand_builtin_saveregs PARAMS ((void));
354182007Srobertoextern void expand_builtin_trap PARAMS ((void));
355182007Srobertoextern HOST_WIDE_INT get_varargs_alias_set PARAMS ((void));
356182007Srobertoextern HOST_WIDE_INT get_frame_alias_set PARAMS ((void));
357182007Srobertoextern void record_base_value		PARAMS ((unsigned int, rtx, int));
358182007Srobertoextern void record_alias_subset         PARAMS ((HOST_WIDE_INT,
359182007Sroberto						 HOST_WIDE_INT));
360182007Srobertoextern HOST_WIDE_INT new_alias_set		PARAMS ((void));
361182007Srobertoextern int can_address_p		PARAMS ((tree));
362182007Sroberto
363182007Sroberto/* Functions from expr.c:  */
364182007Sroberto
365182007Sroberto/* This is run once per compilation to set up which modes can be used
366182007Sroberto   directly in memory and to initialize the block move optab.  */
367182007Srobertoextern void init_expr_once PARAMS ((void));
368182007Sroberto
36982498Sroberto/* This is run at the start of compiling a function.  */
370182007Srobertoextern void init_expr PARAMS ((void));
37182498Sroberto
372182007Sroberto/* This function is run once to initialize stor-layout.c.  */
37382498Sroberto
374182007Srobertoextern void init_stor_layout_once PARAMS ((void));
37554359Sroberto
376182007Sroberto/* This is run at the end of compiling a function.  */
377182007Srobertoextern void finish_expr_for_function PARAMS ((void));
378182007Sroberto
379182007Sroberto/* Use protect_from_queue to convert a QUEUED expression
380182007Sroberto   into something that you can put immediately into an instruction.  */
381182007Srobertoextern rtx protect_from_queue PARAMS ((rtx, int));
382182007Sroberto
383182007Sroberto/* Perform all the pending incrementations.  */
384182007Srobertoextern void emit_queue PARAMS ((void));
385182007Sroberto
386182007Sroberto/* Tell if something has a queued subexpression.  */
38782498Srobertoextern int queued_subexp_p PARAMS ((rtx));
388182007Sroberto
389182007Sroberto/* Emit some rtl insns to move data between rtx's, converting machine modes.
390182007Sroberto   Both modes must be floating or both fixed.  */
39182498Srobertoextern void convert_move PARAMS ((rtx, rtx, int));
392182007Sroberto
39382498Sroberto/* Convert an rtx to specified machine mode and return the result.  */
394182007Srobertoextern rtx convert_to_mode PARAMS ((enum machine_mode, rtx, int));
39582498Sroberto
39682498Sroberto/* Convert an rtx to MODE from OLDMODE and return the result.  */
39782498Srobertoextern rtx convert_modes PARAMS ((enum machine_mode, enum machine_mode,
39882498Sroberto				  rtx, int));
39982498Sroberto
40082498Sroberto/* Emit code to move a block Y to a block X.  */
40182498Srobertoextern rtx emit_block_move PARAMS ((rtx, rtx, rtx));
40282498Sroberto
40382498Sroberto/* Copy all or part of a value X into registers starting at REGNO.
40482498Sroberto   The number of registers to be filled is NREGS.  */
40582498Srobertoextern void move_block_to_reg PARAMS ((int, rtx, int, enum machine_mode));
40682498Sroberto
40782498Sroberto/* Copy all or part of a BLKmode value X out of registers starting at REGNO.
40882498Sroberto   The number of registers to be filled is NREGS.  */
40982498Srobertoextern void move_block_from_reg PARAMS ((int, rtx, int, int));
41082498Sroberto
41182498Sroberto/* Load a BLKmode value into non-consecutive registers represented by a
41282498Sroberto   PARALLEL.  */
41382498Srobertoextern void emit_group_load PARAMS ((rtx, rtx, int));
41482498Sroberto
41582498Sroberto/* Store a BLKmode value from non-consecutive registers represented by a
41682498Sroberto   PARALLEL.  */
41782498Srobertoextern void emit_group_store PARAMS ((rtx, rtx, int));
41882498Sroberto
41982498Sroberto#ifdef TREE_CODE
42082498Sroberto/* Copy BLKmode object from a set of registers.  */
42182498Srobertoextern rtx copy_blkmode_from_reg PARAMS ((rtx,rtx,tree));
422182007Sroberto#endif
423132451Sroberto
42482498Sroberto/* Mark REG as holding a parameter for the next CALL_INSN.  */
42582498Srobertoextern void use_reg PARAMS ((rtx *, rtx));
426132451Sroberto
427132451Sroberto/* Mark NREGS consecutive regs, starting at REGNO, as holding parameters
42882498Sroberto   for the next CALL_INSN.  */
42982498Srobertoextern void use_regs PARAMS ((rtx *, int, int));
43082498Sroberto
43182498Sroberto/* Mark a PARALLEL as holding a parameter for the next CALL_INSN.  */
43282498Srobertoextern void use_group_regs PARAMS ((rtx *, rtx));
43382498Sroberto
43482498Sroberto/* Write zeros through the storage of OBJECT.
43582498Sroberto   If OBJECT has BLKmode, SIZE is its length in bytes.  */
43682498Srobertoextern rtx clear_storage PARAMS ((rtx, rtx));
43782498Sroberto
43882498Sroberto/* Return non-zero if it is desirable to store LEN bytes generated by
43982498Sroberto   CONSTFUN with several move instructions by store_by_pieces
44054359Sroberto   function.  CONSTFUNDATA is a pointer which will be passed as argument
44182498Sroberto   in every CONSTFUN call.
44282498Sroberto   ALIGN is maximum alignment we can assume.  */
44382498Srobertoextern int can_store_by_pieces PARAMS ((unsigned HOST_WIDE_INT,
44482498Sroberto					rtx (*) (PTR, HOST_WIDE_INT,
44582498Sroberto						 enum machine_mode),
44654359Sroberto					PTR, unsigned int));
44754359Sroberto
44882498Sroberto/* Generate several move instructions to store LEN bytes generated by
44982498Sroberto   CONSTFUN to block TO.  (A MEM rtx with BLKmode).  CONSTFUNDATA is a
45082498Sroberto   pointer which will be passed as argument in every CONSTFUN call.
45182498Sroberto   ALIGN is maximum alignment we can assume.  */
45282498Srobertoextern void store_by_pieces PARAMS ((rtx, unsigned HOST_WIDE_INT,
45382498Sroberto				     rtx (*) (PTR, HOST_WIDE_INT,
45482498Sroberto					      enum machine_mode),
45582498Sroberto				     PTR, unsigned int));
45682498Sroberto
45782498Sroberto/* Emit insns to set X from Y.  */
45882498Srobertoextern rtx emit_move_insn PARAMS ((rtx, rtx));
45982498Sroberto
46082498Sroberto/* Emit insns to set X from Y, with no frills.  */
46182498Srobertoextern rtx emit_move_insn_1 PARAMS ((rtx, rtx));
46282498Sroberto
46382498Sroberto/* Push a block of length SIZE (perhaps variable)
46454359Sroberto   and return an rtx to address the beginning of the block.  */
46582498Srobertoextern rtx push_block PARAMS ((rtx, int, int));
46682498Sroberto
46782498Sroberto#ifdef TREE_CODE
46882498Sroberto/* Generate code to push something onto the stack, given its mode and type.  */
46982498Srobertoextern void emit_push_insn PARAMS ((rtx, enum machine_mode, tree, rtx,
47082498Sroberto				    unsigned int, int, rtx, int, rtx, rtx,
47182498Sroberto				    int, rtx));
47282498Sroberto
47382498Sroberto/* Expand an assignment that stores the value of FROM into TO.  */
47482498Srobertoextern rtx expand_assignment PARAMS ((tree, tree, int, int));
47582498Sroberto
47682498Sroberto/* Generate code for computing expression EXP,
47782498Sroberto   and storing the value into TARGET.
47882498Sroberto   If SUGGEST_REG is nonzero, copy the value through a register
47982498Sroberto   and return that register, if that is possible.  */
48082498Srobertoextern rtx store_expr PARAMS ((tree, rtx, int));
48182498Sroberto#endif
48282498Sroberto
48382498Sroberto/* Given an rtx that may include add and multiply operations,
48482498Sroberto   generate them as insns and return a pseudo-reg containing the value.
48582498Sroberto   Useful after calling expand_expr with 1 as sum_ok.  */
48682498Srobertoextern rtx force_operand PARAMS ((rtx, rtx));
48782498Sroberto
48882498Sroberto/* Return an object on the placeholder list that matches EXP, a
48982498Sroberto   PLACEHOLDER_EXPR.  An object "matches" if it is of the type of the
49082498Sroberto   PLACEHOLDER_EXPR or a pointer type to it.  For further information, see
49182498Sroberto   tree.def.  If no such object is found, abort.  If PLIST is nonzero, it is
49282498Sroberto   a location which initially points to a starting location in the
49382498Sroberto   placeholder list (zero means start of the list) and where a pointer into
49482498Sroberto   the placeholder list at which the object is found is placed.  */
49582498Srobertoextern tree find_placeholder PARAMS ((tree, tree *));
49682498Sroberto
49782498Sroberto/* Generate code for computing expression EXP.
49882498Sroberto   An rtx for the computed value is returned.  The value is never null.
49982498Sroberto   In the case of a void EXP, const0_rtx is returned.  */
50082498Srobertoextern rtx expand_expr PARAMS ((tree, rtx, enum machine_mode,
50182498Sroberto				enum expand_modifier));
50282498Sroberto
50382498Sroberto/* At the start of a function, record that we have no previously-pushed
50482498Sroberto   arguments waiting to be popped.  */
50582498Srobertoextern void init_pending_stack_adjust PARAMS ((void));
50682498Sroberto
50754359Sroberto/* When exiting from function, if safe, clear out any pending stack adjust
50882498Sroberto   so the adjustment won't get done.  */
50954359Srobertoextern void clear_pending_stack_adjust PARAMS ((void));
51054359Sroberto
51154359Sroberto/* Pop any previously-pushed arguments that have not been popped yet.  */
51254359Srobertoextern void do_pending_stack_adjust PARAMS ((void));
51382498Sroberto
51482498Sroberto#ifdef TREE_CODE
51582498Sroberto/* Return the tree node and offset if a given argument corresponds to
51682498Sroberto   a string constant.  */
51782498Srobertoextern tree string_constant PARAMS ((tree, tree *));
51882498Sroberto
51982498Sroberto/* Generate code to evaluate EXP and jump to LABEL if the value is zero.  */
52082498Srobertoextern void jumpifnot PARAMS ((tree, rtx));
52182498Sroberto
52254359Sroberto/* Generate code to evaluate EXP and jump to LABEL if the value is nonzero.  */
52354359Srobertoextern void jumpif PARAMS ((tree, rtx));
52454359Sroberto
52554359Sroberto/* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
52682498Sroberto   the result is zero, or IF_TRUE_LABEL if the result is one.  */
52754359Srobertoextern void do_jump PARAMS ((tree, rtx, rtx));
52882498Sroberto#endif
52982498Sroberto
53054359Sroberto/* Generate rtl to compare two rtx's, will call emit_cmp_insn.  */
53154359Srobertoextern rtx compare_from_rtx PARAMS ((rtx, rtx, enum rtx_code, int,
53254359Sroberto				     enum machine_mode, rtx));
53354359Srobertoextern void do_compare_rtx_and_jump PARAMS ((rtx, rtx, enum rtx_code, int,
53454359Sroberto					     enum machine_mode, rtx,
535182007Sroberto					     rtx, rtx));
53654359Sroberto
53754359Sroberto/* Two different ways of generating switch statements.  */
53854359Srobertoextern int try_casesi    PARAMS ((tree, tree, tree, tree, rtx, rtx));
53954359Srobertoextern int try_tablejump PARAMS ((tree, tree, tree, tree, rtx, rtx));
54054359Sroberto
54154359Sroberto/* Smallest number of adjacent cases before we use a jump table.
54282498Sroberto   XXX Should be a target hook.  */
54382498Srobertoextern unsigned int case_values_threshold PARAMS ((void));
54454359Sroberto
54582498Sroberto
54682498Sroberto#ifdef TREE_CODE
54782498Sroberto/* rtl.h and tree.h were included.  */
54882498Sroberto/* Return an rtx for the size in bytes of the value of an expr.  */
54982498Srobertoextern rtx expr_size PARAMS ((tree));
55082498Sroberto
55182498Sroberto/* Return a wide integer for the size in bytes of the value of EXP, or -1
55282498Sroberto   if the size can vary or is larger than an integer.  */
55354359Srobertoextern HOST_WIDE_INT int_expr_size PARAMS ((tree));
55482498Sroberto
55554359Srobertoextern rtx lookup_static_chain PARAMS ((tree));
55682498Sroberto
55782498Sroberto/* Convert a stack slot address ADDR valid in function FNDECL
55882498Sroberto   into an address valid in this function (using a static chain).  */
55982498Srobertoextern rtx fix_lexical_addr PARAMS ((rtx, tree));
560132451Sroberto
561132451Sroberto/* Return the address of the trampoline for entering nested fn FUNCTION.  */
562132451Srobertoextern rtx trampoline_address PARAMS ((tree));
56382498Sroberto
56454359Sroberto/* Return an rtx that refers to the value returned by a function
56554359Sroberto   in its original home.  This becomes invalid if any more code is emitted.  */
56654359Srobertoextern rtx hard_function_value PARAMS ((tree, tree, int));
56754359Sroberto
56854359Srobertoextern rtx prepare_call_address	PARAMS ((rtx, tree, rtx *, int, int));
569
570extern rtx expand_call PARAMS ((tree, rtx, int));
571
572extern rtx expand_shift PARAMS ((enum tree_code, enum machine_mode, rtx, tree,
573				 rtx, int));
574extern rtx expand_divmod PARAMS ((int, enum tree_code, enum machine_mode, rtx,
575				  rtx, rtx, int));
576extern void locate_and_pad_parm PARAMS ((enum machine_mode, tree, int, tree,
577					 struct args_size *,
578					 struct args_size *,
579					 struct args_size *,
580					 struct args_size *));
581extern rtx expand_inline_function PARAMS ((tree, tree, rtx, int, tree, rtx));
582
583/* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary.  */
584extern rtx label_rtx PARAMS ((tree));
585#endif
586
587/* Indicate how an input argument register was promoted.  */
588extern rtx promoted_input_arg PARAMS ((unsigned int, enum machine_mode *,
589				       int *));
590
591/* Return an rtx like arg but sans any constant terms.
592   Returns the original rtx if it has no constant terms.
593   The constant terms are added and stored via a second arg.  */
594extern rtx eliminate_constant_term PARAMS ((rtx, rtx *));
595
596/* Convert arg to a valid memory address for specified machine mode,
597   by emitting insns to perform arithmetic if nec.  */
598extern rtx memory_address PARAMS ((enum machine_mode, rtx));
599
600/* Like `memory_address' but pretent `flag_force_addr' is 0.  */
601extern rtx memory_address_noforce PARAMS ((enum machine_mode, rtx));
602
603/* Set the alias set of MEM to SET.  */
604extern void set_mem_alias_set PARAMS ((rtx, HOST_WIDE_INT));
605
606/* Set the alignment of MEM to ALIGN bits.  */
607extern void set_mem_align PARAMS ((rtx, unsigned int));
608
609/* Set the expr for MEM to EXPR.  */
610extern void set_mem_expr PARAMS ((rtx, tree));
611
612/* Set the offset for MEM to OFFSET.  */
613extern void set_mem_offset PARAMS ((rtx, rtx));
614
615/* Return a memory reference like MEMREF, but with its mode changed
616   to MODE and its address changed to ADDR.
617   (VOIDmode means don't change the mode.
618   NULL for ADDR means don't change the address.)  */
619extern rtx change_address PARAMS ((rtx, enum machine_mode, rtx));
620
621/* Return a memory reference like MEMREF, but with its mode changed
622   to MODE and its address offset by OFFSET bytes.  */
623#define adjust_address(MEMREF, MODE, OFFSET) \
624  adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1)
625
626/* Likewise, but the reference is not required to be valid.  */
627#define adjust_address_nv(MEMREF, MODE, OFFSET) \
628  adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1)
629
630/* Return a memory reference like MEMREF, but with its mode changed
631   to MODE and its address changed to ADDR, which is assumed to be
632   increased by OFFSET bytes from MEMREF.  */
633#define adjust_automodify_address(MEMREF, MODE, ADDR, OFFSET) \
634  adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 1)
635
636/* Likewise, but the reference is not required to be valid.  */
637#define adjust_automodify_address_nv(MEMREF, MODE, ADDR, OFFSET) \
638  adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 0)
639
640extern rtx adjust_address_1 PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT,
641				     int, int));
642extern rtx adjust_automodify_address_1 PARAMS ((rtx, enum machine_mode,
643						rtx, HOST_WIDE_INT, int));
644
645/* Return a memory reference like MEMREF, but whose address is changed by
646   adding OFFSET, an RTX, to it.  POW2 is the highest power of two factor
647   known to be in OFFSET (possibly 1).  */
648extern rtx offset_address PARAMS ((rtx, rtx, HOST_WIDE_INT));
649
650/* Return a memory reference like MEMREF, but with its address changed to
651   ADDR.  The caller is asserting that the actual piece of memory pointed
652   to is the same, just the form of the address is being changed, such as
653   by putting something into a register.  */
654extern rtx replace_equiv_address PARAMS ((rtx, rtx));
655
656/* Likewise, but the reference is not required to be valid.  */
657extern rtx replace_equiv_address_nv PARAMS ((rtx, rtx));
658
659/* Return a memory reference like MEMREF, but with its mode widened to
660   MODE and adjusted by OFFSET.  */
661extern rtx widen_memory_access PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT));
662
663/* Return a memory reference like MEMREF, but which is known to have a
664   valid address.  */
665extern rtx validize_mem PARAMS ((rtx));
666
667#ifdef TREE_CODE
668/* Given REF, either a MEM or a REG, and T, either the type of X or
669   the expression corresponding to REF, set RTX_UNCHANGING_P if
670   appropriate.  */
671extern void maybe_set_unchanging PARAMS ((rtx, tree));
672
673/* Given REF, a MEM, and T, either the type of X or the expression
674   corresponding to REF, set the memory attributes.  OBJECTP is nonzero
675   if we are making a new object of this type.  */
676extern void set_mem_attributes PARAMS ((rtx, tree, int));
677#endif
678
679/* Assemble the static constant template for function entry trampolines.  */
680extern rtx assemble_trampoline_template PARAMS ((void));
681
682/* Given rtx, return new rtx whose address won't be affected by
683   any side effects.  It has been copied to a new temporary reg.  */
684extern rtx stabilize PARAMS ((rtx));
685
686/* Given an rtx, copy all regs it refers to into new temps
687   and return a modified copy that refers to the new temps.  */
688extern rtx copy_all_regs PARAMS ((rtx));
689
690/* Copy given rtx to a new temp reg and return that.  */
691extern rtx copy_to_reg PARAMS ((rtx));
692
693/* Like copy_to_reg but always make the reg Pmode.  */
694extern rtx copy_addr_to_reg PARAMS ((rtx));
695
696/* Like copy_to_reg but always make the reg the specified mode MODE.  */
697extern rtx copy_to_mode_reg PARAMS ((enum machine_mode, rtx));
698
699/* Copy given rtx to given temp reg and return that.  */
700extern rtx copy_to_suggested_reg PARAMS ((rtx, rtx, enum machine_mode));
701
702/* Copy a value to a register if it isn't already a register.
703   Args are mode (in case value is a constant) and the value.  */
704extern rtx force_reg PARAMS ((enum machine_mode, rtx));
705
706/* Return given rtx, copied into a new temp reg if it was in memory.  */
707extern rtx force_not_mem PARAMS ((rtx));
708
709#ifdef TREE_CODE
710/* Return mode and signedness to use when object is promoted.  */
711extern enum machine_mode promote_mode PARAMS ((tree, enum machine_mode,
712					       int *, int));
713#endif
714
715/* Remove some bytes from the stack.  An rtx says how many.  */
716extern void adjust_stack PARAMS ((rtx));
717
718/* Add some bytes to the stack.  An rtx says how many.  */
719extern void anti_adjust_stack PARAMS ((rtx));
720
721/* This enum is used for the following two functions.  */
722enum save_level {SAVE_BLOCK, SAVE_FUNCTION, SAVE_NONLOCAL};
723
724/* Save the stack pointer at the specified level.  */
725extern void emit_stack_save PARAMS ((enum save_level, rtx *, rtx));
726
727/* Restore the stack pointer from a save area of the specified level.  */
728extern void emit_stack_restore PARAMS ((enum save_level, rtx, rtx));
729
730/* Allocate some space on the stack dynamically and return its address.  An rtx
731   says how many bytes.  */
732extern rtx allocate_dynamic_stack_space PARAMS ((rtx, rtx, int));
733
734/* Probe a range of stack addresses from FIRST to FIRST+SIZE, inclusive.
735   FIRST is a constant and size is a Pmode RTX.  These are offsets from the
736   current stack pointer.  STACK_GROWS_DOWNWARD says whether to add or
737   subtract from the stack.  If SIZE is constant, this is done
738   with a fixed number of probes.  Otherwise, we must make a loop.  */
739extern void probe_stack_range PARAMS ((HOST_WIDE_INT, rtx));
740
741/* Return an rtx that refers to the value returned by a library call
742   in its original home.  This becomes invalid if any more code is emitted.  */
743extern rtx hard_libcall_value PARAMS ((enum machine_mode));
744
745/* Given an rtx, return an rtx for a value rounded up to a multiple
746   of STACK_BOUNDARY / BITS_PER_UNIT.  */
747extern rtx round_push PARAMS ((rtx));
748
749/* Return the mode desired by operand N of a particular bitfield
750   insert/extract insn, or MAX_MACHINE_MODE if no such insn is
751   available.  */
752
753enum extraction_pattern { EP_insv, EP_extv, EP_extzv };
754extern enum machine_mode
755mode_for_extraction PARAMS ((enum extraction_pattern, int));
756
757extern rtx store_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
758				    unsigned HOST_WIDE_INT,
759				    enum machine_mode, rtx, HOST_WIDE_INT));
760extern rtx extract_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
761				      unsigned HOST_WIDE_INT, int, rtx,
762				      enum machine_mode, enum machine_mode,
763				      HOST_WIDE_INT));
764extern rtx expand_mult PARAMS ((enum machine_mode, rtx, rtx, rtx, int));
765extern rtx expand_mult_add PARAMS ((rtx, rtx, rtx, rtx,enum machine_mode, int));
766extern rtx expand_mult_highpart_adjust PARAMS ((enum machine_mode, rtx, rtx, rtx, rtx, int));
767
768extern rtx assemble_static_space PARAMS ((int));
769
770/* Hook called by expand_expr for language-specific tree codes.
771   It is up to the language front end to install a hook
772   if it has any such codes that expand_expr needs to know about.  */
773extern rtx (*lang_expand_expr) PARAMS ((union tree_node *, rtx,
774					enum machine_mode,
775					enum expand_modifier modifier));
776
777extern int safe_from_p PARAMS ((rtx, tree, int));
778
779/* Call this once to initialize the contents of the optabs
780   appropriately for the current target machine.  */
781extern void init_optabs				PARAMS ((void));
782extern void init_all_optabs			PARAMS ((void));
783
784/* Call this to initialize an optab function entry.  */
785extern rtx init_one_libfunc			PARAMS ((const char *));
786
787extern void do_jump_by_parts_equality_rtx	PARAMS ((rtx, rtx, rtx));
788extern void do_jump_by_parts_greater_rtx	PARAMS ((enum machine_mode,
789							 int, rtx, rtx, rtx,
790							 rtx));
791
792#ifdef TREE_CODE   /* Don't lose if tree.h not included.  */
793extern void mark_seen_cases			PARAMS ((tree, unsigned char *,
794							 HOST_WIDE_INT, int));
795#endif
796