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