home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 7
/
FreshFishVol7.bin
/
bbs
/
gnu
/
gcc-2.3.3-src.lha
/
GNU
/
src
/
amiga
/
gcc-2.3.3
/
expr.h
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-06
|
23KB
|
685 lines
/* Definitions for code generation pass of GNU compiler.
Copyright (C) 1987, 1991 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef __STDC__
#ifndef const
#define const
#endif
#endif
/* The default branch cost is 1. */
#ifndef BRANCH_COST
#define BRANCH_COST 1
#endif
/* The default is that we do not promote the mode of an object. */
#ifndef PROMOTE_MODE
#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE)
#endif
/* Macros to access the slots of a QUEUED rtx.
Here rather than in rtl.h because only the expansion pass
should ever encounter a QUEUED. */
/* The variable for which an increment is queued. */
#define QUEUED_VAR(P) XEXP (P, 0)
/* If the increment has been emitted, this is the insn
that does the increment. It is zero before the increment is emitted. */
#define QUEUED_INSN(P) XEXP (P, 1)
/* If a pre-increment copy has been generated, this is the copy
(it is a temporary reg). Zero if no copy made yet. */
#define QUEUED_COPY(P) XEXP (P, 2)
/* This is the body to use for the insn to do the increment.
It is used to emit the increment. */
#define QUEUED_BODY(P) XEXP (P, 3)
/* Next QUEUED in the queue. */
#define QUEUED_NEXT(P) XEXP (P, 4)
/* This is the 4th arg to `expand_expr'.
EXPAND_SUM means it is ok to return a PLUS rtx or MULT rtx.
EXPAND_INITIALIZER is similar but also record any labels on forced_labels.
EXPAND_CONST_ADDRESS means it is ok to return a MEM whose address
is a constant that is not a legitimate address. */
enum expand_modifier {EXPAND_NORMAL, EXPAND_SUM,
EXPAND_CONST_ADDRESS, EXPAND_INITIALIZER};
/* List of labels that must never be deleted. */
extern rtx forced_labels;
/* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.
So we can mark them all live at the end of the function, if stupid. */
extern rtx save_expr_regs;
extern int current_function_calls_alloca;
extern int current_function_outgoing_args_size;
/* This is the offset from the arg pointer to the place where the first
anonymous arg can be found, if there is one. */
extern rtx current_function_arg_offset_rtx;
/* This is nonzero if the current function uses the constant pool. */
extern int current_function_uses_const_pool;
/* This is nonzero if the current function uses pic_offset_table_rtx. */
extern int current_function_uses_pic_offset_table;
/* The arg pointer hard register, or the pseudo into which it was copied. */
extern rtx current_function_internal_arg_pointer;
/* Nonzero means stack pops must not be deferred, and deferred stack
pops must not be output. It is nonzero inside a function call,
inside a conditional expression, inside a statement expression,
and in other cases as well. */
extern int inhibit_defer_pop;
/* Number of function calls seen so far in current function. */
extern int function_call_count;
/* RTX for stack slot that holds the current handler for nonlocal gotos.
Zero when function does not have nonlocal labels. */
extern rtx nonlocal_goto_handler_slot;
/* RTX for stack slot that holds the stack pointer value to restore
for a nonlocal goto.
Zero when function does not have nonlocal labels. */
extern rtx nonlocal_goto_stack_level;
/* List (chain of TREE_LIST) of LABEL_DECLs for all nonlocal labels
(labels to which there can be nonlocal gotos from nested functions)
in this function. */
#ifdef TREE_CODE /* Don't lose if tree.h not included. */
extern tree nonlocal_labels;
#endif
#define NO_DEFER_POP (inhibit_defer_pop += 1)
#define OK_DEFER_POP (inhibit_defer_pop -= 1)
/* Number of units that we should eventually pop off the stack.
These are the arguments to function calls that have already returned. */
extern int pending_stack_adjust;
/* A list of all cleanups which belong to the arguments of
function calls being expanded by expand_call. */
#ifdef TREE_CODE /* Don't lose if tree.h not included. */
extern tree cleanups_this_call;
#endif
#ifdef TREE_CODE /* Don't lose if tree.h not included. */
/* Structure to record the size of a sequence of arguments
as the sum of a tree-expression and a constant. */
struct args_size
{
int constant;
tree var;
};
#endif
/* Add the value of the tree INC to the `struct args_size' TO. */
#define ADD_PARM_SIZE(TO, INC) \
{ tree inc = (INC); \
if (TREE_CODE (inc) == INTEGER_CST) \
(TO).constant += TREE_INT_CST_LOW (inc); \
else if ((TO).var == 0) \
(TO).var = inc; \
else \
(TO).var = size_binop (PLUS_EXPR, (TO).var, inc); }
#define SUB_PARM_SIZE(TO, DEC) \
{ tree dec = (DEC); \
if (TREE_CODE (dec) == INTEGER_CST) \
(TO).constant -= TREE_INT_CST_LOW (dec); \
else if ((TO).var == 0) \
(TO).var = size_binop (MINUS_EXPR, integer_zero_node, dec); \
else \
(TO).var = size_binop (MINUS_EXPR, (TO).var, dec); }
/* Convert the implicit sum in a `struct args_size' into an rtx. */
#define ARGS_SIZE_RTX(SIZE) \
((SIZE).var == 0 ? GEN_INT ((SIZE).constant) \
: expand_expr (size_binop (PLUS_EXPR, (SIZE).var, \
size_int ((SIZE).constant)), \
NULL_RTX, VOIDmode, 0))
/* Convert the implicit sum in a `struct args_size' into a tree. */
#define ARGS_SIZE_TREE(SIZE) \
((SIZE).var == 0 ? size_int ((SIZE).constant) \
: size_binop (PLUS_EXPR, (SIZE).var, size_int ((SIZE).constant)))
/* Supply a default definition for FUNCTION_ARG_PADDING:
usually pad upward, but pad short args downward on
big-endian machines. */
enum direction {none, upward, downward}; /* Value has this type. */
#ifndef FUNCTION_ARG_PADDING
#if BYTES_BIG_ENDIAN
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
(((MODE) == BLKmode \
? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
&& int_size_in_bytes (TYPE) < PARM_BOUNDARY / BITS_PER_UNIT) \
: GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY) \
? downward : upward)
#else
#define FUNCTION_ARG_PADDING(MODE, TYPE) upward
#endif
#endif
/* Supply a default definition for FUNCTION_ARG_BOUNDARY. Normally, we let
FUNCTION_ARG_PADDING, which also pads the length, handle any needed
alignment. */
#ifndef FUNCTION_ARG_BOUNDARY
#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) PARM_BOUNDARY
#endif
/* Nonzero if we do not know how to pass TYPE solely in registers.
We cannot do so in the following cases:
- if the type has variable size
- if the type is marked as addressable (it is required to be constructed
into the stack)
- if the padding and mode of the type is such that a copy into a register
would put it into the wrong part of the register
- when STRICT_ALIGNMENT and the type is BLKmode and is is not
aligned to a boundary corresponding to what can be loaded into a
register. */
#define MUST_PASS_IN_STACK_BAD_ALIGN(MODE,TYPE) \
(STRICT_ALIGNMENT && MODE == BLKmode \
&& TYPE_ALIGN (TYPE) < (BIGGEST_ALIGNMENT < BITS_PER_WORD \
? BIGGEST_ALIGNMENT : BITS_PER_WORD))
/* Which padding can't be supported depends on the byte endianness. */
/* A value in a register is implicitly padded at the most significant end.
On a big-endian machine, that is the lower end in memory.
So a value padded in memory at the upper end can't go in a register.
For a little-endian machine, the reverse is true. */
#if BYTES_BIG_ENDIAN
#define MUST_PASS_IN_STACK_BAD_PADDING upward
#else
#define MUST_PASS_IN_STACK_BAD_PADDING downward
#endif
#define MUST_PASS_IN_STACK(MODE,TYPE) \
((TYPE) != 0 \
&& (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \