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