GCC Middle and Back End API Reference
expr.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  args_size
struct  locate_and_pad_arg_data
struct  separate_ops

Typedefs

typedef struct separate_opssepops

Enumerations

enum  expand_modifier {
  EXPAND_NORMAL = 0, EXPAND_STACK_PARM, EXPAND_SUM, EXPAND_CONST_ADDRESS,
  EXPAND_INITIALIZER, EXPAND_WRITE, EXPAND_MEMORY
}
enum  direction { none, upward, downward }
enum  optab_methods {
  OPTAB_DIRECT, OPTAB_LIB, OPTAB_WIDEN, OPTAB_LIB_WIDEN,
  OPTAB_MUST_WIDEN
}
enum  block_op_methods { BLOCK_OP_NORMAL, BLOCK_OP_NO_LIBCALL, BLOCK_OP_CALL_PARM, BLOCK_OP_TAILCALL }
enum  save_level { SAVE_BLOCK, SAVE_FUNCTION, SAVE_NONLOCAL }

Functions

rtx expand_simple_binop (enum machine_mode, enum rtx_code, rtx, rtx, rtx, int, enum optab_methods)
rtx expand_simple_unop (enum machine_mode, enum rtx_code, rtx, rtx, int)
int have_insn_for (enum rtx_code, enum machine_mode)
void emit_libcall_block (rtx, rtx, rtx, rtx)
rtx gen_add2_insn (rtx, rtx)
rtx gen_add3_insn (rtx, rtx, rtx)
rtx gen_sub2_insn (rtx, rtx)
rtx gen_sub3_insn (rtx, rtx, rtx)
rtx gen_move_insn (rtx, rtx)
int have_add2_insn (rtx, rtx)
int have_sub2_insn (rtx, rtx)
void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx, enum machine_mode, int, rtx, int prob=-1)
void emit_indirect_jump (rtx)
rtx gen_cond_trap (enum rtx_code, rtx, rtx, rtx)
rtx emit_conditional_move (rtx, enum rtx_code, rtx, rtx, enum machine_mode, rtx, rtx, enum machine_mode, int)
int can_conditionally_move_p (enum machine_mode mode)
rtx emit_conditional_add (rtx, enum rtx_code, rtx, rtx, enum machine_mode, rtx, rtx, enum machine_mode, int)
rtx expand_sync_operation (rtx, rtx, enum rtx_code)
rtx expand_sync_fetch_operation (rtx, rtx, enum rtx_code, bool, rtx)
rtx expand_sync_lock_test_and_set (rtx, rtx, rtx)
rtx expand_atomic_exchange (rtx, rtx, rtx, enum memmodel)
rtx expand_atomic_load (rtx, rtx, enum memmodel)
rtx expand_atomic_store (rtx, rtx, enum memmodel, bool)
rtx expand_atomic_fetch_op (rtx, rtx, rtx, enum rtx_code, enum memmodel, bool)
rtx expand_atomic_test_and_set (rtx, rtx, enum memmodel)
rtx expand_atomic_clear (rtx, enum memmodel)
void expand_atomic_thread_fence (enum memmodel)
void expand_atomic_signal_fence (enum memmodel)
rtx negate_rtx (enum machine_mode, rtx)
rtx expand_and (enum machine_mode, rtx, rtx, rtx)
rtx emit_store_flag (rtx, enum rtx_code, rtx, rtx, enum machine_mode, int, int)
rtx emit_store_flag_force (rtx, enum rtx_code, rtx, rtx, enum machine_mode, int, int)
unsigned HOST_WIDE_INT choose_multiplier (unsigned HOST_WIDE_INT, int, int, unsigned HOST_WIDE_INT *, int *, int *)
rtx expand_builtin (tree, rtx, rtx, enum machine_mode, int)
tree std_build_builtin_va_list (void)
tree std_fn_abi_va_list (tree)
tree std_canonical_va_list_type (tree)
void std_expand_builtin_va_start (tree, rtx)
rtx default_expand_builtin (tree, rtx, rtx, enum machine_mode, int)
void expand_builtin_setjmp_setup (rtx, rtx)
void expand_builtin_setjmp_receiver (rtx)
rtx expand_builtin_saveregs (void)
void expand_builtin_trap (void)
rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode)
void init_expr_target (void)
void init_expr (void)
void convert_move (rtx, rtx, int)
rtx convert_to_mode (enum machine_mode, rtx, int)
rtx convert_modes (enum machine_mode, enum machine_mode, rtx, int)
void init_block_move_fn (const char *)
void init_block_clear_fn (const char *)
rtx emit_block_move (rtx, rtx, rtx, enum block_op_methods)
rtx emit_block_move_via_libcall (rtx, rtx, rtx, bool)
rtx emit_block_move_hints (rtx, rtx, rtx, enum block_op_methods, unsigned int, HOST_WIDE_INT)
bool emit_storent_insn (rtx to, rtx from)
void move_block_to_reg (int, rtx, int, enum machine_mode)
void move_block_from_reg (int, rtx, int)
rtx gen_group_rtx (rtx)
void emit_group_load (rtx, rtx, tree, int)
rtx emit_group_load_into_temps (rtx, rtx, tree, int)
void emit_group_move (rtx, rtx)
rtx emit_group_move_into_temps (rtx)
void emit_group_store (rtx, rtx, tree, int)
rtx maybe_emit_group_store (rtx, tree)
void copy_blkmode_from_reg (rtx, rtx, tree)
void use_reg_mode (rtx *, rtx, enum machine_mode)
rtx copy_blkmode_to_reg (enum machine_mode, tree)
static void use_reg ()
void use_regs (rtx *, int, int)
void use_group_regs (rtx *, rtx)
rtx clear_storage (rtx, rtx, enum block_op_methods)
rtx clear_storage_hints (rtx, rtx, enum block_op_methods, unsigned int, HOST_WIDE_INT)
rtx set_storage_via_libcall (rtx, rtx, rtx, bool)
bool set_storage_via_setmem (rtx, rtx, rtx, unsigned int, unsigned int, HOST_WIDE_INT)
unsigned HOST_WIDE_INT move_by_pieces_ninsns (unsigned HOST_WIDE_INT, unsigned int, unsigned int)
int can_store_by_pieces (unsigned HOST_WIDE_INT, rtx(*)(void *, HOST_WIDE_INT, enum machine_mode), void *, unsigned int, bool)
rtx store_by_pieces (rtx, unsigned HOST_WIDE_INT, rtx(*)(void *, HOST_WIDE_INT, enum machine_mode), void *, unsigned int, bool, int)
rtx emit_move_insn (rtx, rtx)
rtx emit_move_insn_1 (rtx, rtx)
rtx emit_move_complex_push (enum machine_mode, rtx, rtx)
rtx emit_move_complex_parts (rtx, rtx)
rtx push_block (rtx, int, int)
void emit_push_insn (rtx, enum machine_mode, tree, rtx, unsigned int, int, rtx, int, rtx, rtx, int, rtx)
void expand_assignment (tree, tree, bool)
rtx store_expr (tree, rtx, int, bool)
rtx force_operand (rtx, rtx)
rtx expand_expr_real (tree, rtx, enum machine_mode, enum expand_modifier, rtx *)
rtx expand_expr_real_1 (tree, rtx, enum machine_mode, enum expand_modifier, rtx *)
rtx expand_expr_real_2 (sepops, rtx, enum machine_mode, enum expand_modifier)
static rtx expand_expr (tree exp, rtx target, enum machine_mode mode, enum expand_modifier modifier)
static rtx expand_normal ()
void init_pending_stack_adjust (void)
void discard_pending_stack_adjust (void)
void clear_pending_stack_adjust (void)
void do_pending_stack_adjust (void)
tree string_constant (tree, tree *)
void jumpifnot (tree, rtx, int)
void jumpifnot_1 (enum tree_code, tree, tree, rtx, int)
void jumpif (tree, rtx, int)
void jumpif_1 (enum tree_code, tree, tree, rtx, int)
void do_jump (tree, rtx, rtx, int)
void do_jump_1 (enum tree_code, tree, tree, rtx, rtx, int)
void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int, enum machine_mode, rtx, rtx, rtx, int)
int try_casesi (tree, tree, tree, tree, rtx, rtx, rtx, int)
int try_tablejump (tree, tree, tree, tree, rtx, rtx, int)
rtx expr_size (tree)
HOST_WIDE_INT int_expr_size (tree)
rtx hard_function_value (const_tree, const_tree, const_tree, int)
rtx prepare_call_address (tree, rtx, rtx, rtx *, int, int)
bool shift_return_value (enum machine_mode, bool, rtx)
rtx expand_call (tree, rtx, int)
void fixup_tail_calls (void)
rtx expand_variable_shift (enum tree_code, enum machine_mode, rtx, tree, rtx, int)
rtx expand_shift (enum tree_code, enum machine_mode, rtx, int, rtx, int)
rtx expand_divmod (int, enum tree_code, enum machine_mode, rtx, rtx, rtx, int)
void locate_and_pad_parm (enum machine_mode, tree, int, int, tree, struct args_size *, struct locate_and_pad_arg_data *)
rtx label_rtx (tree)
rtx force_label_rtx (tree)
rtx eliminate_constant_term (rtx, rtx *)
rtx memory_address_addr_space (enum machine_mode, rtx, addr_space_t)
rtx change_address (rtx, enum machine_mode, rtx)
rtx adjust_address_1 (rtx, enum machine_mode, HOST_WIDE_INT, int, int, int, HOST_WIDE_INT)
rtx adjust_automodify_address_1 (rtx, enum machine_mode, rtx, HOST_WIDE_INT, int)
rtx offset_address (rtx, rtx, unsigned HOST_WIDE_INT)
rtx widen_memory_access (rtx, enum machine_mode, HOST_WIDE_INT)
rtx validize_mem (rtx)
rtx use_anchored_address (rtx)
void set_mem_attributes (rtx, tree, int)
void set_mem_attributes_minus_bitpos (rtx, tree, int, HOST_WIDE_INT)
int get_mem_align_offset (rtx, unsigned int)
rtx assemble_trampoline_template (void)
rtx copy_to_reg (rtx)
rtx copy_addr_to_reg (rtx)
rtx copy_to_mode_reg (enum machine_mode, rtx)
rtx copy_to_suggested_reg (rtx, rtx, enum machine_mode)
rtx force_reg (enum machine_mode, rtx)
rtx force_not_mem (rtx)
enum machine_mode promote_function_mode (const_tree, enum machine_mode, int *, const_tree, int)
enum machine_mode promote_mode (const_tree, enum machine_mode, int *)
enum machine_mode promote_decl_mode (const_tree, int *)
void adjust_stack (rtx)
void anti_adjust_stack (rtx)
void anti_adjust_stack_and_probe (rtx, bool)
void emit_stack_save (enum save_level, rtx *)
void emit_stack_restore (enum save_level, rtx)
void update_nonlocal_goto_save_area (void)
rtx allocate_dynamic_stack_space (rtx, unsigned, unsigned, bool)
void emit_stack_probe (rtx)
void probe_stack_range (HOST_WIDE_INT, rtx)
rtx hard_libcall_value (enum machine_mode, rtx)
void store_bit_field (rtx, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, enum machine_mode, rtx)
rtx extract_bit_field (rtx, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, int, rtx, enum machine_mode, enum machine_mode)
rtx extract_low_bits (enum machine_mode, enum machine_mode, rtx)
rtx expand_mult (enum machine_mode, rtx, rtx, rtx, int)
rtx expand_mult_highpart_adjust (enum machine_mode, rtx, rtx, rtx, rtx, int)
rtx assemble_static_space (unsigned HOST_WIDE_INT)
int safe_from_p (const_rtx, tree, int)
bool split_comparison (enum rtx_code, enum machine_mode, enum rtx_code *, enum rtx_code *)
void init_optabs (void)
void init_all_optabs (struct target_optabs *)
rtx init_one_libfunc (const char *)
rtx set_user_assembler_libfunc (const char *, const char *)
tree build_libfunc_function (const char *)
rtx get_personality_function (tree)
void expand_case (gimple)
void expand_sjlj_dispatch_table (rtx, vec< tree >)

Variables

tree block_clear_fn

Typedef Documentation

typedef struct separate_ops * sepops
   This structure is used to pass around information about exploded
   unary, binary and trinary expressions between expand_expr_real_1 and
   friends.  

Enumeration Type Documentation

   Emit code to move a block Y to a block X.  
Enumerator:
BLOCK_OP_NORMAL 
BLOCK_OP_NO_LIBCALL 
BLOCK_OP_CALL_PARM 
BLOCK_OP_TAILCALL 
     Like BLOCK_OP_NORMAL, but the libcall can be tail call optimized.  
enum direction
Enumerator:
none 
upward 
downward 
   For inhibit_defer_pop 
   For XEXP, GEN_INT, rtx_code 
   For optimize_size 
   For host_integerp, tree_low_cst, fold_convert, size_binop, ssize_int,
   TREE_CODE, TYPE_SIZE, int_size_in_bytes,    
   For GET_MODE_BITSIZE, word_mode 
   This is the 4th arg to `expand_expr'.
   EXPAND_STACK_PARM means we are possibly expanding a call param onto
   the stack.
   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.
   EXPAND_WRITE means we are only going to write to the resulting rtx.
   EXPAND_MEMORY means we are interested in a memory result, even if
    the memory is constant and we could have propagated a constant value.  
Enumerator:
EXPAND_NORMAL 
EXPAND_STACK_PARM 
EXPAND_SUM 
EXPAND_CONST_ADDRESS 
EXPAND_INITIALIZER 
EXPAND_WRITE 
EXPAND_MEMORY 
   Functions from optabs.c, commonly used, and without need for the optabs
   tables:  
   Passed to expand_simple_binop and expand_binop to say which options
   to try to use if the requested operation can't be open-coded on the
   requisite mode.  Either OPTAB_LIB or OPTAB_LIB_WIDEN says try using
   a library call.  Either OPTAB_WIDEN or OPTAB_LIB_WIDEN says try
   using a wider mode.  OPTAB_MUST_WIDEN says try widening and don't
   try anything else.  
Enumerator:
OPTAB_DIRECT 
OPTAB_LIB 
OPTAB_WIDEN 
OPTAB_LIB_WIDEN 
OPTAB_MUST_WIDEN 
enum save_level
   This enum is used for the following two functions.  
Enumerator:
SAVE_BLOCK 
SAVE_FUNCTION 
SAVE_NONLOCAL 

Function Documentation

rtx adjust_address_1 ( rtx  memref,
enum machine_mode  mode,
HOST_WIDE_INT  offset,
int  validate,
int  adjust_address,
int  adjust_object,
HOST_WIDE_INT  size 
)
   Return a memory reference like MEMREF, but with its mode changed
   to MODE and its address offset by OFFSET bytes.  If VALIDATE is
   nonzero, the memory address is forced to be valid.
   If ADJUST_ADDRESS is zero, OFFSET is only used to update MEM_ATTRS
   and the caller is responsible for adjusting MEMREF base register.
   If ADJUST_OBJECT is zero, the underlying object associated with the
   memory reference is left unchanged and the caller is responsible for
   dealing with it.  Otherwise, if the new memory reference is outside
   the underlying object, even partially, then the object is dropped.
   SIZE, if nonzero, is the size of an access in cases where MODE
   has no inherent size.  
     VOIDmode means no mode change for change_address_1.  
     Take the size of non-BLKmode accesses from the mode.  
     If there are no changes, just return the original memory reference.  
     ??? Prefer to create garbage instead of creating shared rtl.
     This may happen even if offset is nonzero -- consider
     (plus (plus reg reg) const_int) -- so do this always.  
     Convert a possibly large offset to a signed value within the
     range of the target address space.  
         If MEMREF is a LO_SUM and the offset is within the alignment of the
         object, we can merge it into the LO_SUM.  
         If MEMREF is a ZERO_EXTEND from pointer_mode and the offset is valid
         in that mode, we merge it into the ZERO_EXTEND.  We take advantage of
         the fact that pointers are not allowed to overflow.  
     If the address is a REG, change_address_1 rightfully returns memref,
     but this would destroy memref's MEM_ATTRS.  
     Conservatively drop the object if we don't know where we start from.  
     Compute the new values of the memory attributes due to this adjustment.
     We add the offsets and update the alignment.  
         Drop the object if the new left end is not within its bounds.  
     Compute the new alignment by taking the MIN of the alignment and the
     lowest-order set bit in OFFSET, but don't change the alignment if OFFSET
     if zero.  
         Drop the object if the new right end is not within its bounds.  
         ??? The store_by_pieces machinery generates negative sizes,
         so don't assert for that here.  
rtx adjust_automodify_address_1 ( rtx  memref,
enum machine_mode  mode,
rtx  addr,
HOST_WIDE_INT  offset,
int  validate 
)
   Return a memory reference like MEMREF, but with its mode changed
   to MODE and its address changed to ADDR, which is assumed to be
   MEMREF offset by OFFSET bytes.  If VALIDATE is
   nonzero, the memory address is forced to be valid.  
void adjust_stack ( rtx  )
   Remove some bytes from the stack.  An rtx says how many.  
rtx allocate_dynamic_stack_space ( rtx  size,
unsigned  size_align,
unsigned  required_align,
bool  cannot_accumulate 
)
   Allocate some space on the stack dynamically and return its address.  
   Return an rtx representing the address of an area of memory dynamically
   pushed on the stack.

   Any required stack pointer alignment is preserved.

   SIZE is an rtx representing the size of the area.

   SIZE_ALIGN is the alignment (in bits) that we know SIZE has.  This
   parameter may be zero.  If so, a proper value will be extracted 
   from SIZE if it is constant, otherwise BITS_PER_UNIT will be assumed.

   REQUIRED_ALIGN is the alignment (in bits) required for the region
   of memory.

   If CANNOT_ACCUMULATE is set to TRUE, the caller guarantees that the
   stack space allocated by the generated code cannot be added with itself
   in the course of the execution of the function.  It is always safe to
   pass FALSE here and the following criterion is sufficient in order to
   pass TRUE: every path in the CFG that starts at the allocation point and
   loops to it executes the associated deallocation code.  
     If we're asking for zero bytes, it doesn't matter what we point
     to since we can't dereference it.  But return a reasonable
     address anyway.  
     Otherwise, show we're calling alloca or equivalent.  
     If stack usage info is requested, look into the size we are passed.
     We need to do so this early to avoid the obfuscation that may be
     introduced later by the various alignment operations.  
             Look into the last emitted insn and see if we can deduce
             something for the register.  
         If the size is not constant, we can't say anything.  
     Ensure the size is in the proper mode.  
     Adjust SIZE_ALIGN, if needed.  
         Watch out for overflow truncating to "unsigned".  
     We can't attempt to minimize alignment necessary, because we don't
     know the final value of preferred_stack_boundary yet while executing
     this code.  
     We will need to ensure that the address we return is aligned to
     REQUIRED_ALIGN.  If STACK_DYNAMIC_OFFSET is defined, we don't
     always know its final value at this point in the compilation (it
     might depend on the size of the outgoing parameter lists, for
     example), so we must align the value to be returned in that case.
     (Note that STACK_DYNAMIC_OFFSET will have a default nonzero value if
     STACK_POINTER_OFFSET or ACCUMULATE_OUTGOING_ARGS are defined).
     We must also do an alignment operation on the returned value if
     the stack pointer alignment is less strict than REQUIRED_ALIGN.

     If we have to align, we must leave space in SIZE for the hole
     that might result from the alignment operation.  
     ??? STACK_POINTER_OFFSET is always defined now.  
     Round the size to a multiple of the required stack alignment.
     Since the stack if presumed to be rounded before this allocation,
     this will maintain the required alignment.

     If the stack grows downward, we could save an insn by subtracting
     SIZE from the stack pointer and then aligning the stack pointer.
     The problem with this is that the stack pointer may be unaligned
     between the execution of the subtraction and alignment insns and
     some machines do not allow this.  Even on those that do, some
     signal handlers malfunction if a signal should occur between those
     insns.  Since this is an extremely rare event, we have no reliable
     way of knowing which systems have this problem.  So we avoid even
     momentarily mis-aligning the stack.  
     The size is supposed to be fully adjusted at this point so record it
     if stack usage info is requested.  
         ??? This is gross but the only safe stance in the absence
         of stack usage oriented flow analysis.  
     If we are splitting the stack, we need to ask the backend whether
     there is enough room on the current stack.  If there isn't, or if
     the backend doesn't know how to tell is, then we need to call a
     function to allocate memory in some other way.  This memory will
     be released when we release the current stack segment.  The
     effect is that stack allocation becomes less efficient, but at
     least it doesn't cause a stack overflow.  
             This instruction will branch to AVAILABLE_LABEL if there
             are SIZE bytes available on the stack.  
         The __morestack_allocate_stack_space function will allocate
         memory using malloc.  If the alignment of the memory returned
         by malloc does not meet REQUIRED_ALIGN, we increase SIZE to
         make sure we allocate enough space.  
    We ought to be called always on the toplevel and stack ought to be aligned
    properly.  
     If needed, check that we have the required amount of stack.  Take into
     account what has already been checked.  
     Don't let anti_adjust_stack emit notes.  
     Perform the required allocation from the stack.  Some systems do
     this differently than simply incrementing/decrementing from the
     stack pointer, such as acquiring the space by calling malloc().  
         We don't have to check against the predicate for operand 0 since
         TARGET is known to be a pseudo of the proper mode, which must
         be valid for the operand.  
         Check stack bounds if necessary.  
         Even if size is constant, don't modify stack_pointer_delta.
         The constant size alloca should preserve
         crtl->preferred_stack_boundary alignment.  
     Finish up the split stack handling.  
         CEIL_DIV_EXPR needs to worry about the addition overflowing,
         but we know it can't.  So add ourselves and then do
         TRUNC_DIV_EXPR.  
     Now that we've committed to a return value, mark its alignment.  
     Record the new stack level for nonlocal gotos.  

Referenced by initialize_argument_information().

void anti_adjust_stack ( rtx  )
   Add some bytes to the stack.  An rtx says how many.  
void anti_adjust_stack_and_probe ( rtx  ,
bool   
)
   Add some bytes to the stack while probing it.  An rtx says how many. 
rtx assemble_static_space ( unsigned  HOST_WIDE_INT)

Referenced by set_cfun().

rtx assemble_trampoline_template ( void  )
   Assemble the static constant template for function entry trampolines.  
     By default, put trampoline templates in read-only data section.  
     Write the assembler code to define one.  
     Record the rtl to refer to it.  
tree build_libfunc_function ( const char *  )
   Build a decl for a libfunc named NAME. 
rtx builtin_strncpy_read_str ( void *  data,
HOST_WIDE_INT  offset,
enum machine_mode  mode 
)
   Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
   bytes from constant string DATA + OFFSET and return it as target
   constant.  
int can_conditionally_move_p ( enum machine_mode  mode)
   Return nonzero if the conditional move is supported.  

Referenced by convert_tree_comp_to_rtx().

int can_store_by_pieces ( unsigned HOST_WIDE_INT  len,
rtx(*)(void *, HOST_WIDE_INT, enum machine_mode)  constfun,
void *  constfundata,
unsigned int  align,
bool  memsetp 
)
   Return nonzero if it is desirable to store LEN bytes generated by
   CONSTFUN with several move instructions by store_by_pieces
   function.  CONSTFUNDATA is a pointer which will be passed as argument
   in every CONSTFUN call.
   ALIGN is maximum alignment we can assume.
   MEMSETP is true if this is a real memset/bzero, not a copy
   of a const string.  
   Determine whether the LEN bytes generated by CONSTFUN can be
   stored to memory using several move instructions.  CONSTFUNDATA is
   a pointer which will be passed as argument in every CONSTFUN call.
   ALIGN is maximum alignment we can assume.  MEMSETP is true if this is
   a memset operation and false if it's a copy of a constant string.
   Return nonzero if a call to store_by_pieces should succeed.  
     cst is set but not used if LEGITIMATE_CONSTANT doesn't use it.  
     We would first store what we can in the largest integer mode, then go to
     successively smaller modes.  
         The code above should have handled everything.  
rtx change_address ( rtx  ,
enum  machine_mode,
rtx   
)
   Return a memory reference like MEMREF, but with its mode changed
   to MODE and its address changed to ADDR.
   (VOIDmode means don't change the mode.
   NULL for ADDR means don't change the address.)  
unsigned HOST_WIDE_INT choose_multiplier ( unsigned HOST_WIDE_INT  d,
int  n,
int  precision,
unsigned HOST_WIDE_INT multiplier_ptr,
int *  post_shift_ptr,
int *  lgup_ptr 
)
   Choose a minimal N + 1 bit approximation to 1/D that can be used to
   replace division by D, and put the least significant N bits of the result
   in *MULTIPLIER_PTR and return the most significant bit.  
   Choose a minimal N + 1 bit approximation to 1/D that can be used to
   replace division by D, and put the least significant N bits of the result
   in *MULTIPLIER_PTR and return the most significant bit.

   The width of operations is N (should be <= HOST_BITS_PER_WIDE_INT), the
   needed precision is in PRECISION (should be <= N).

   PRECISION should be as small as possible so this function can choose
   multiplier more freely.

   The rounded-up logarithm of D is placed in *lgup_ptr.  A shift count that
   is to be used for a final right shift is placed in *POST_SHIFT_PTR.

   Using this function, x/D will be equal to (x * m) >> (*POST_SHIFT_PTR),
   where m is the full HOST_BITS_PER_WIDE_INT + 1 bit multiplier.  
     lgup = ceil(log2(divisor)); 
     We could handle this with some effort, but this case is much
     better handled directly with a scc insn, so rely on caller using
     that.  
     mlow = 2^(N + lgup)/d 
     mhigh = (2^(N + lgup) + 2^(N + lgup - precision))/d 
     Assert that mlow < mhigh.  
     If precision == N, then mlow, mhigh exceed 2^N
     (but they do not exceed 2^(N+1)).  
     Reduce to lowest terms.  
void clear_pending_stack_adjust ( void  )
   When exiting from function, if safe, clear out any pending stack adjust
   so the adjustment won't get done.  
   When exiting from function, if safe, clear out any pending stack adjust
   so the adjustment won't get done.

   Note, if the current function calls alloca, then it must have a
   frame pointer regardless of the value of flag_omit_frame_pointer.  
rtx clear_storage ( rtx  ,
rtx  ,
enum  block_op_methods 
)
   Write zeros through the storage of OBJECT.
   If OBJECT has BLKmode, SIZE is its length in bytes.  
rtx clear_storage_hints ( rtx  object,
rtx  size,
enum block_op_methods  method,
unsigned int  expected_align,
HOST_WIDE_INT  expected_size 
)
   Write zeros through the storage of OBJECT.  If OBJECT has BLKmode, SIZE is
   its length in bytes.  
     If OBJECT is not BLKmode and SIZE is the same size as its mode,
     just move a zero.  Otherwise, do this a piece at a time.  

References byte_mode, create_convert_operand_from(), create_convert_operand_to(), create_fixed_operand(), create_integer_operand(), insn_data, and maybe_expand_insn().

rtx convert_modes ( enum  machine_mode,
enum  machine_mode,
rtx  ,
int   
)
   Convert an rtx to MODE from OLDMODE and return the result.  
void convert_move ( rtx  ,
rtx  ,
int   
)
   Emit some rtl insns to move data between rtx's, converting machine modes.
   Both modes must be floating or both fixed.  
rtx convert_to_mode ( enum  machine_mode,
rtx  ,
int   
)
   Convert an rtx to specified machine mode and return the result.  
rtx copy_addr_to_reg ( rtx  )
   Like copy_to_reg but always make the reg Pmode.  
void copy_blkmode_from_reg ( rtx  ,
rtx  ,
tree   
)
   Copy BLKmode object from a set of registers.  
rtx copy_blkmode_to_reg ( enum  machine_mode,
tree   
)
rtx copy_to_mode_reg ( enum  machine_mode,
rtx   
)
   Like copy_to_reg but always make the reg the specified mode MODE.  
rtx copy_to_reg ( rtx  )
   Copy given rtx to a new temp reg and return that.  
rtx copy_to_suggested_reg ( rtx  ,
rtx  ,
enum  machine_mode 
)
   Copy given rtx to given temp reg and return that.  
rtx default_expand_builtin ( tree  exp,
rtx  target,
rtx  subtarget,
enum machine_mode  mode,
int  ignore 
)
   Default target-specific builtin expander that does nothing.  

References validate_arg().

void discard_pending_stack_adjust ( void  )
   Discard any pending stack adjustment.  
   Discard any pending stack adjustment.  This avoid relying on the
   RTL optimizers to remove useless adjustments when we know the
   stack pointer value is dead.  

References function::calls_alloca, cfun, and discard_pending_stack_adjust().

Referenced by discard_pending_stack_adjust().

void do_compare_rtx_and_jump ( rtx  op0,
rtx  op1,
enum rtx_code  code,
int  unsignedp,
enum machine_mode  mode,
rtx  size,
rtx  if_false_label,
rtx  if_true_label,
int  prob 
)
   Like do_compare_and_jump but expects the values to compare as two rtx's.
   The decision as to signed or unsigned comparison must be made by the caller.

   If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
   compared.  
     Reverse the comparison if that is safe and we want to jump if it is
     false.  Also convert to the reverse comparison if the target can
     implement it.  
         Canonicalize to UNORDERED for the libcall.  
     If one operand is constant, make it the second one.  Only do this
     if the other operand is not constant as well.  
                  Never split ORDERED and UNORDERED.
                  These must be implemented.  
                  Split a floating-point comparison if
                  we can jump on other conditions...  
                      ... or if there is no libcall for it.  
             If there are no NaNs, the first comparison should always fall
             through.  
                     If we only jump if true, just bypass the second jump.  

References emit_jump().

Referenced by do_jump_by_parts_zero_rtx(), and expand_return().

void do_jump ( tree  ,
rtx  ,
rtx  ,
int   
)
   Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
   the result is zero, or IF_TRUE_LABEL if the result is one.  
void do_jump_1 ( enum tree_code  code,
tree  op0,
tree  op1,
rtx  if_false_label,
rtx  if_true_label,
int  prob 
)
   Subroutine of do_jump, dealing with exploded comparisons of the type
   OP0 CODE OP1 .  IF_FALSE_LABEL and IF_TRUE_LABEL like in do_jump.
   PROB is probability of jump to if_true_label, or -1 if unknown.  
           Spread the probability that the expression is false evenly between
           the two conditions. So the first condition is false half the total
           probability of being false. The second condition is false the other
           half of the total probability of being false, so its jump has a false
           probability of half the total, relative to the probability we
           reached it (i.e. the first condition was true).  
               Get the probability that each jump below is true.  
           Spread the probability evenly between the two conditions. So
           the first condition has half the total probability of being true.
           The second condition has the other half of the total probability,
           so its jump has a probability of half the total, relative to
           the probability we reached it (i.e. the first condition was false).  
void do_pending_stack_adjust ( void  )
   Pop any previously-pushed arguments that have not been popped yet.  

Referenced by build_libfunc_function(), dump_case_nodes(), emit_jump(), expand_computed_goto(), expand_float(), and have_sub2_insn().

rtx eliminate_constant_term ( rtx  ,
rtx  
)
   Return an rtx like arg but sans any constant terms.
   Returns the original rtx if it has no constant terms.
   The constant terms are added and stored via a second arg.  
rtx emit_block_move ( rtx  ,
rtx  ,
rtx  ,
enum  block_op_methods 
)
rtx emit_block_move_hints ( rtx  x,
rtx  y,
rtx  size,
enum block_op_methods  method,
unsigned int  expected_align,
HOST_WIDE_INT  expected_size 
)
   Emit code to move a block Y to a block X.  This may be done with
   string-move instructions, with multiple scalar move instructions,
   or with a library call.

   Both X and Y must be MEM rtx's (perhaps inside VOLATILE) with mode BLKmode.
   SIZE is an rtx that says how long they are.
   ALIGN is the maximum alignment we can assume they have.
   METHOD describes what kind of copy this is, and what mechanisms may be used.

   Return the address of the new block, if memcpy is called and returns it,
   0 otherwise.  
         Make inhibit_defer_pop nonzero around the library call
         to force it to pop the arguments right away.  
     Make sure we've got BLKmode addresses; store_one_arg can decide that
     block copy is more efficient for other large modes, e.g. DCmode.  
     Set MEM_SIZE as appropriate for this block copy.  The main place this
     can be incorrect is coming from __builtin_memcpy.  
         Since x and y are passed to a libcall, mark the corresponding
         tree EXPR as addressable.  
rtx emit_block_move_via_libcall ( rtx  ,
rtx  ,
rtx  ,
bool   
)
void emit_cmp_and_jump_insns ( rtx  x,
rtx  y,
enum rtx_code  comparison,
rtx  size,
enum machine_mode  mode,
int  unsignedp,
rtx  label,
int  prob 
)
   Emit a pair of rtl insns to compare two rtx's and to jump
   to a label if the comparison is true.  
   Generate code to compare X with Y so that the condition codes are
   set and to jump to LABEL if the condition is true.  If X is a
   constant and Y is not a constant, then the comparison is swapped to
   ensure that the comparison RTL has the canonical form.

   UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
   need to be widened.  UNSIGNEDP is also used to select the proper
   branch condition code.

   If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.

   MODE is the mode of the inputs (in case they are const_int).

   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
   It will be potentially converted into an unsigned variant based on
   UNSIGNEDP to select a proper jump instruction.
   
   PROB is the probability of jumping to LABEL.  
     Swap operands and condition to ensure canonical RTL.  
     If OP0 is still a constant, then both X and Y must be constants
     or the opposite comparison is not supported.  Force X into a register
     to create canonical RTL.  

Referenced by expand_float(), have_sub2_insn(), and node_has_low_bound().

rtx emit_conditional_add ( rtx  target,
enum rtx_code  code,
rtx  op0,
rtx  op1,
enum machine_mode  cmode,
rtx  op2,
rtx  op3,
enum machine_mode  mode,
int  unsignedp 
)
   Emit a conditional addition instruction if the machine supports one for that
   condition and machine mode.

   OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
   the mode to use should they be constants.  If it is VOIDmode, they cannot
   both be constants.

   OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
   should be stored there.  MODE is the mode to use should they be constants.
   If it is VOIDmode, they cannot both be constants.

   The result is either TARGET (perhaps modified) or NULL_RTX if the operation
   is not supported.  
     If one operand is constant, make it the second one.  Only do this
     if the other operand is not constant as well.  
     get_condition will prefer to generate LT and GT even if the old
     comparison was against zero, so undo that canonicalization here since
     comparisons against zero are cheaper.  
     We can get const0_rtx or const_true_rtx in some circumstances.  Just
     return NULL and let the caller figure out how best to deal with this
     situation.  
rtx emit_conditional_move ( rtx  target,
enum rtx_code  code,
rtx  op0,
rtx  op1,
enum machine_mode  cmode,
rtx  op2,
rtx  op3,
enum machine_mode  mode,
int  unsignedp 
)
   Emit a conditional move operation.  
   Emit a conditional move instruction if the machine supports one for that
   condition and machine mode.

   OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
   the mode to use should they be constants.  If it is VOIDmode, they cannot
   both be constants.

   OP2 should be stored in TARGET if the comparison is true, otherwise OP3
   should be stored there.  MODE is the mode to use should they be constants.
   If it is VOIDmode, they cannot both be constants.

   The result is either TARGET (perhaps modified) or NULL_RTX if the operation
   is not supported.  
     If one operand is constant, make it the second one.  Only do this
     if the other operand is not constant as well.  
     get_condition will prefer to generate LT and GT even if the old
     comparison was against zero, so undo that canonicalization here since
     comparisons against zero are cheaper.  
     We can get const0_rtx or const_true_rtx in some circumstances.  Just
     return NULL and let the caller figure out how best to deal with this
     situation.  
void emit_group_load ( rtx  ,
rtx  ,
tree  ,
int   
)
   Load a BLKmode value into non-consecutive registers represented by a
   PARALLEL.  
rtx emit_group_load_into_temps ( rtx  ,
rtx  ,
tree  ,
int   
)
   Similarly, but load into new temporaries.  
void emit_group_move ( rtx  ,
rtx   
)
   Move a non-consecutive group of registers represented by a PARALLEL into
   a non-consecutive group of registers represented by a PARALLEL.  
rtx emit_group_move_into_temps ( rtx  )
   Move a group of registers represented by a PARALLEL into pseudos.  
void emit_group_store ( rtx  ,
rtx  ,
tree  ,
int   
)
   Store a BLKmode value from non-consecutive registers represented by a
   PARALLEL.  
void emit_indirect_jump ( rtx  )
   Generate code to indirectly jump to a location given in the rtx LOC.  

Referenced by emit_jump().

void emit_libcall_block ( rtx  ,
rtx  ,
rtx  ,
rtx   
)
   Emit code to make a call to a constant function or a library call.  
rtx emit_move_complex_parts ( rtx  ,
rtx   
)
rtx emit_move_complex_push ( enum  machine_mode,
rtx  ,
rtx   
)
rtx emit_move_insn ( rtx  ,
rtx   
)
   Emit insns to set X from Y.  
rtx emit_move_insn_1 ( rtx  ,
rtx   
)
   Emit insns to set X from Y, with no frills.  
void emit_push_insn ( rtx  x,
enum machine_mode  mode,
tree  type,
rtx  size,
unsigned int  align,
int  partial,
rtx  reg,
int  extra,
rtx  args_addr,
rtx  args_so_far,
int  reg_parm_stack_space,
rtx  alignment_pad 
)
   Generate code to push something onto the stack, given its mode and type.  
   Generate code to push X onto the stack, assuming it has mode MODE and
   type TYPE.
   MODE is redundant except when X is a CONST_INT (since they don't
   carry mode info).
   SIZE is an rtx for the size of data to be copied (in bytes),
   needed only if X is BLKmode.

   ALIGN (in bits) is maximum alignment we can assume.

   If PARTIAL and REG are both nonzero, then copy that many of the first
   bytes of X into registers starting with REG, and push the rest of X.
   The amount of space pushed is decreased by PARTIAL bytes.
   REG must be a hard register in this case.
   If REG is zero but PARTIAL is not, take any all others actions for an
   argument partially in registers, but do not actually load any
   registers.

   EXTRA is the amount in bytes of extra space to leave next to this arg.
   This is ignored if an argument block has already been allocated.

   On a machine that lacks real push insns, ARGS_ADDR is the address of
   the bottom of the argument block for this call.  We use indexing off there
   to store the arg.  On machines with push insns, ARGS_ADDR is 0 when a
   argument block has not been preallocated.

   ARGS_SO_FAR is the size of args previously pushed for this call.

   REG_PARM_STACK_SPACE is nonzero if functions require stack space
   for arguments passed in registers.  If nonzero, it will be the number
   of bytes required.  
     Decide where to pad the argument: `downward' for below,
     `upward' for above, or `none' for don't pad it.
     Default is below for small data on big-endian machines; else above.  
     Invert direction if stack is post-decrement.
     FIXME: why?  
         Copy a block into the stack, entirely or partially.  
             A value is to be stored in an insufficiently aligned
             stack slot; copy via a suitably aligned slot if
             necessary.  
         USED is now the # of bytes we need not copy to the stack
         because registers will take care of them.  
         If the partial register-part of the arg counts in its stack size,
         skip the part of stack space corresponding to the registers.
         Otherwise, start copying to the beginning of the stack space,
         by setting SKIP to 0.  
         Do it with several push insns if that doesn't take lots of insns
         and if there is no difficulty with push insns that skip bytes
         on the stack for alignment purposes.  
             Here we avoid the case of a structure whose weak alignment
             forces many pushes of a small amount of data,
             and such small pushes do rounding that causes trouble.  
             Push padding now if padding above and stack grows down,
             or if padding below and stack grows up.
             But if space already allocated, this has already been done.  
             Otherwise make space on the stack and copy the data
             to the address of that space.  
             Deduct words put into registers from the size we must copy.  
             Get the address of the stack space.
             In this case, we do not deal with EXTRA separately.
             A single stack adjust will do.  
                 If the source is referenced relative to the stack pointer,
                 copy it to another register to stabilize it.  We do not need
                 to do this if we know that we won't be changing sp.  
             We do *not* set_mem_attributes here, because incoming arguments
             may overlap with sibling call outgoing arguments and we cannot
             allow reordering of reads from function arguments with stores
             to outgoing arguments of sibling calls.  We do, however, want
             to record the alignment of the stack slot.  
             ALIGN may well be better aligned than TYPE, e.g. due to
             PARM_BOUNDARY.  Assume the caller isn't lying.  
         Scalar partly in registers.  
         # bytes of start of argument
         that we must make space for but need not store.  
         Push padding now if padding above and stack grows down,
         or if padding below and stack grows up.
         But if space already allocated, this has already been done.  
         If we make space by pushing it, we might as well push
         the real data.  Otherwise, we can leave OFFSET nonzero
         and leave the space uninitialized.  
         Now NOT_STACK gets the number of words that we don't need to
         allocate on the stack.  Convert OFFSET to words too.  
         If the partial register-part of the arg counts in its stack size,
         skip the part of stack space corresponding to the registers.
         Otherwise, start copying to the beginning of the stack space,
         by setting SKIP to 0.  
         If X is a hard register in a non-integer mode, copy it into a pseudo;
         SUBREGs of such registers are not allowed.  
         Loop over all the words allocated on the stack for this arg.  
         We can do it by words, because any scalar bigger than a word
         has a size a multiple of a word.  
         Push padding now if padding above and stack grows down,
         or if padding below and stack grows up.
         But if space already allocated, this has already been done.  
             We do *not* set_mem_attributes here, because incoming arguments
             may overlap with sibling call outgoing arguments and we cannot
             allow reordering of reads from function arguments with stores
             to outgoing arguments of sibling calls.  We do, however, want
             to record the alignment of the stack slot.  
             ALIGN may well be better aligned than TYPE, e.g. due to
             PARM_BOUNDARY.  Assume the caller isn't lying.  
     If part should go in registers, copy that part
     into the appropriate registers.  Do this now, at the end,
     since mem-to-mem copies above may do function calls.  
         Handle calls that pass values in multiple non-contiguous locations.
         The Irix 6 ABI has examples of this.  

References emit_group_load(), and move_block_to_reg().

void emit_stack_probe ( rtx  )
   Emit one stack probe at ADDRESS, an address within the stack.  
void emit_stack_restore ( enum  save_level,
rtx   
)
   Restore the stack pointer from a save area of the specified level.  
void emit_stack_save ( enum  save_level,
rtx  
)
   Save the stack pointer at the specified level.  
rtx emit_store_flag ( rtx  target,
enum rtx_code  code,
rtx  op0,
rtx  op1,
enum machine_mode  mode,
int  unsignedp,
int  normalizep 
)
   Emit a store-flag operation.  
   Emit a store-flags instruction for comparison CODE on OP0 and OP1
   and storing in TARGET.  Normally return TARGET.
   Return 0 if that cannot be done.

   MODE is the mode to use for OP0 and OP1 should they be CONST_INTs.  If
   it is VOIDmode, they cannot both be CONST_INT.

   UNSIGNEDP is for the case where we have to widen the operands
   to perform the operation.  It says to use zero-extension.

   NORMALIZEP is 1 if we should convert the result to be either zero
   or one.  Normalize is -1 if we should convert the result to be
   either zero or -1.  If NORMALIZEP is zero, the result will be left
   "raw" out of the scc insn.  
     If we reached here, we can't do this with a scc insn, however there
     are some comparisons that can be done in other ways.  Don't do any
     of these cases if branches are very cheap.  
     See what we need to return.  We can only return a 1, -1, or the
     sign bit.  
     If optimizing, use different pseudo registers for each insn, instead
     of reusing the same pseudo.  This leads to better CSE, but slows
     down the compiler, since there are more pseudos 
     For floating-point comparisons, try the reverse comparison or try
     changing the "orderedness" of the comparison.  
             For the reverse comparison, use either an addition or a XOR.  
         Cannot split ORDERED and UNORDERED, only try the above trick.   
         If there are no NaNs, the first comparison should always fall through.
         Effectively change the comparison to the other one.  
         Try using a setcc instruction for ORDERED/UNORDERED, followed by a
         conditional move.  
     The remaining tricks only apply to integer comparisons.  
     If this is an equality comparison of integers, we can try to exclusive-or
     (or subtract) the two operands and use a recursive call to try the
     comparison with zero.  Don't do any of these cases if branches are
     very cheap.  
     For integer comparisons, try the reverse comparison.  However, for
     small X and if we'd have anyway to extend, implementing "X != 0"
     as "-(int)X >> 31" is still cheaper than inverting "(int)X == 0".  
         Again, for the reverse comparison, use either an addition or a XOR.  
     Some other cases we can do are EQ, NE, LE, and GT comparisons with
     the constant zero.  Reject all other comparisons at this point.  Only
     do LE and GT if branches are expensive since they are expensive on
     2-operand machines.  
     Try to put the result of the comparison in the sign bit.  Assume we can't
     do the necessary operation below.  
     To see if A <= 0, compute (A | (A - 1)).  A <= 0 iff that result has
     the sign bit set.  
         This is destructive, so SUBTARGET can't be OP0.  
     To see if A > 0, compute (((signed) A) << BITS) - A, where BITS is the
     number of bits in the mode of OP0, minus one.  
         For EQ or NE, one way to do the comparison is to apply an operation
         that converts the operand into a positive number if it is nonzero
         or zero if it was originally zero.  Then, for EQ, we subtract 1 and
         for NE we negate.  This puts the result in the sign bit.  Then we
         normalize with a shift, if needed.

         Two operations that can do the above actions are ABS and FFS, so try
         them.  If that doesn't work, and MODE is smaller than a full word,
         we can use zero-extension to the wider mode (an unsigned conversion)
         as the operation.  
         Note that ABS doesn't yield a positive number for INT_MIN, but
         that is compensated by the subsequent overflow when subtracting
         one / negating.  
         If we couldn't do it that way, for NE we can "or" the two's complement
         of the value with itself.  For EQ, we take the one's complement of
         that "or", which is an extra insn, so we only handle EQ if branches
         are expensive.  

Referenced by expand_mult_highpart_adjust().

rtx emit_store_flag_force ( rtx  target,
enum rtx_code  code,
rtx  op0,
rtx  op1,
enum machine_mode  mode,
int  unsignedp,
int  normalizep 
)
   Like emit_store_flag, but always succeeds.  
     First see if emit_store_flag can do the job.  
     If this failed, we have to do this with set/compare/jump/set code.
     For foo != 0, if foo is in OP0, just replace it with 1 if nonzero.  
     Jump in the right direction if the target cannot implement CODE
     but can jump on its reverse condition.  
         Canonicalize to UNORDERED for the libcall.  
bool emit_storent_insn ( rtx  to,
rtx  from 
)
rtx expand_and ( enum  machine_mode,
rtx  ,
rtx  ,
rtx   
)
   Expand a logical AND operation.  
void expand_assignment ( tree  ,
tree  ,
bool   
)
   Expand an assignment that stores the value of FROM into TO.  
rtx expand_atomic_clear ( rtx  ,
enum  memmodel 
)
rtx expand_atomic_exchange ( rtx  ,
rtx  ,
rtx  ,
enum  memmodel 
)
rtx expand_atomic_fetch_op ( rtx  target,
rtx  mem,
rtx  val,
enum rtx_code  code,
enum memmodel  model,
bool  after 
)
   This function expands an atomic fetch_OP or OP_fetch operation:
   TARGET is an option place to stick the return value.  const0_rtx indicates
   the result is unused. 
   atomically fetch MEM, perform the operation with VAL and return it to MEM.
   CODE is the operation being performed (OP)
   MEMMODEL is the memory model variant to use.
   AFTER is true to return the result of the operation (OP_fetch).
   AFTER is false to return the value before the operation (fetch_OP).  
     Add/sub can be implemented by doing the reverse operation with -(val).  
             PLUS worked so emit the insns and return.  
         PLUS did not work, so throw away the negation code and continue.  
     Try the __sync libcalls only if we can't do compare-and-swap inline.  
         We need the original code for any further attempts.  
     If nothing else has succeeded, default to a compare and swap loop.  
         If the result is used, get a register for it.  
             If fetch_before, copy the value now.  
         For after, copy the value now.  

References insn_data.

rtx expand_atomic_load ( rtx  ,
rtx  ,
enum  memmodel 
)
void expand_atomic_signal_fence ( enum  memmodel)
rtx expand_atomic_store ( rtx  ,
rtx  ,
enum  memmodel,
bool   
)
rtx expand_atomic_test_and_set ( rtx  ,
rtx  ,
enum  memmodel 
)
void expand_atomic_thread_fence ( enum  memmodel)
rtx expand_builtin ( tree  exp,
rtx  target,
rtx  subtarget,
enum machine_mode  mode,
int  ignore 
)
   Functions from builtins.c:  
   Expand an expression EXP that calls a built-in function,
   with result going to TARGET if that's convenient
   (and in mode MODE if that's convenient).
   SUBTARGET may be used as the target for computing one of EXP's operands.
   IGNORE is nonzero if the value is to be ignored.  
     When not optimizing, generate calls to library functions for a certain
     set of builtins.  
     The built-in function expanders test for target == const0_rtx
     to determine whether the function's result will be ignored.  
     If the result of a pure or const built-in function is ignored, and
     none of its arguments are volatile, we can avoid expanding the
     built-in call and just evaluate the arguments for side-effects.  
         Just do a normal library call if we were unable to fold
         the values.  
         Treat these like sqrt only if unsafe math optimizations are allowed,
         because of possible accuracy problems.  
         __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
         FUNCTION with a copy of the parameters described by
         ARGUMENTS, and ARGSIZE.  It returns a block of memory
         allocated on the stack into which is stored all the registers
         that might possibly be used for returning the result of a
         function.  ARGUMENTS is the value returned by
         __builtin_apply_args.  ARGSIZE is the number of bytes of
         arguments that must be copied.  ??? How should this value be
         computed?  We'll also need a safe worst case value for varargs
         functions.  
         __builtin_return (RESULT) causes the function to return the
         value described by RESULT.  RESULT is address of the block of
         memory returned by __builtin_apply.  
         All valid uses of __builtin_va_arg_pack () are removed during
         inlining.  
         All valid uses of __builtin_va_arg_pack_len () are removed during
         inlining.  
         Return the address of the first anonymous stack arg.  
       Returns the address of the area where the structure is returned.
       0 otherwise.  
         If the allocation stems from the declaration of a variable-sized
         object, it cannot accumulate.  
         This should have been lowered to the builtins below.  
         __builtin_setjmp_setup is passed a pointer to an array of five words
          and the receiver label.  
             This is copied from the handling of non-local gotos.  
             ??? Do not let expand_label treat us as such since we would
             not want to be both on the list of non-local labels and on
             the list of forced labels.  
          __builtin_setjmp_dispatcher is passed the dispatcher label.  
             Remove the dispatcher label from the list of non-local labels
             since the receiver labels have been added to it above.  
          __builtin_setjmp_receiver is passed the receiver label.  
         __builtin_longjmp is passed a pointer to an array of five words.
         It's similar to the C library longjmp function but works with
         __builtin_setjmp above.  
         This updates the setjmp buffer that is its argument with the value
         of the current stack pointer.  
         Various hooks for the DWARF 2 __throw routine.  
           If this is turned into an external library call, the weak parameter
           must be dropped to match the expected parameter list.  
           Skip the boolean weak parameter.  
         We allow user CHKP builtins if Pointer Bounds
         Checker is off.  
         FALLTHROUGH 
         Software implementation of pointers checker is NYI.
         Target support is required.  
     The switch statement above can drop through to cause the function
     to be called normally.  
rtx expand_builtin_saveregs ( void  )
   Expand a call to __builtin_saveregs, generating the result in TARGET,
   if that's convenient.  
     Don't do __builtin_saveregs more than once in a function.
     Save the result of the first call and reuse it.  
     When this function is called, it means that registers must be
     saved on entry to this function.  So we migrate the call to the
     first insn of this function.  
     Do whatever the machine needs done in this case.  
     Put the insns after the NOTE that starts the function.  If this
     is inside a start_sequence, make the outer-level insn chain current, so
     the code is placed at the start of the function.  
void expand_builtin_setjmp_receiver ( rtx  )
void expand_builtin_setjmp_setup ( rtx  ,
rtx   
)
void expand_builtin_trap ( void  )
         For trap insns when not accumulating outgoing args force
         REG_ARGS_SIZE note to prevent crossjumping of calls with
         different args sizes.  
rtx expand_call ( tree  ,
rtx  ,
int   
)
void expand_case ( gimple  )
   In stmt.c 
   Expand a GIMPLE_SWITCH statement.  
rtx expand_divmod ( int  rem_flag,
enum tree_code  code,
enum machine_mode  mode,
rtx  op0,
rtx  op1,
rtx  target,
int  unsignedp 
)
   Emit the code to divide OP0 by OP1, putting the result in TARGET
   if that is convenient, and returning where the result is.
   You may request either the quotient or the remainder as the result;
   specify REM_FLAG nonzero to get the remainder.

   CODE is the expression code for which kind of division this is;
   it controls how rounding is done.  MODE is the machine mode to use.
   UNSIGNEDP nonzero means do unsigned division.  
   ??? For CEIL_MOD_EXPR, can compute incorrect remainder with ANDI
   and then correct it by or'ing in missing high bits
   if result of ANDI is nonzero.
   For ROUND_MOD_EXPR, can use ANDI and then sign-extend the result.
   This could optimize to a bfexts instruction.
   But C doesn't use these operations, so their optimizations are
   left for later.  
   ??? For modulo, we don't actually need the highpart of the first product,
   the low part will do nicely.  And for small divisors, the second multiply
   can also be a low-part only multiply or even be completely left out.
   E.g. to calculate the remainder of a division by 3 with a 32 bit
   multiply, multiply with 0x55555556 and extract the upper two bits;
   the result is exact for inputs up to 0x1fffffff.
   The input range can be reduced by using cross-sum rules.
   For odd divisors >= 3, the following table gives right shift counts
   so that if a number is shifted by an integer multiple of the given
   amount, the remainder stays the same:
   2, 4, 3, 6, 10, 12, 4, 8, 18, 6, 11, 20, 18, 0, 5, 10, 12, 0, 12, 20,
   14, 12, 23, 21, 8, 0, 20, 18, 0, 0, 6, 12, 0, 22, 0, 18, 20, 30, 0, 0,
   0, 8, 0, 11, 12, 10, 36, 0, 30, 0, 0, 12, 0, 0, 0, 0, 44, 12, 24, 0,
   20, 0, 7, 14, 0, 18, 36, 0, 0, 46, 60, 0, 42, 0, 15, 24, 20, 0, 0, 33,
   0, 20, 0, 0, 18, 0, 60, 0, 0, 0, 0, 0, 40, 18, 0, 0, 12

   Cross-sum rules for even numbers can be derived by leaving as many bits
   to the right alone as the divisor has zeros to the right.
   E.g. if x is an unsigned 32 bit number:
   (x mod 12) == (((x & 1023) + ((x >> 8) & ~3)) * 0x15555558 >> 2 * 3) >> 28
     We shouldn't be called with OP1 == const1_rtx, but some of the
     code below will malfunction if we are, so check here and handle
     the special case if so.  
       When dividing by -1, we could get an overflow.
     negv_optab can handle overflows.  
         Don't use the function value register as a target
         since we have to read it as well as write it,
         and function-inlining gets confused by this.  
             Don't clobber an operand while doing a multi-step calculation.  
     Get the mode in which to perform this computation.  Normally it will
     be MODE, but sometimes we can't do the desired operation in MODE.
     If so, pick a wider mode in which we can do the operation.  Convert
     to that mode at the start to avoid repeated conversions.

     First see what operations we need.  These depend on the expression
     we are evaluating.  (We assume that divxx3 insns exist under the
     same conditions that modxx3 insns and that these insns don't normally
     fail.  If these assumptions are not correct, we may generate less
     efficient code in some cases.)

     Then see if we find a mode in which we can open-code that operation
     (either a division, modulus, or shift).  Finally, check for the smallest
     mode for which we can do the operation with a library call.  
     We might want to refine this now that we have division-by-constant
     optimization.  Since expmed_mult_highpart tries so many variants, it is
     not straightforward to generalize this.  Maybe we should make an array
     of possible modes in init_expmed?  Save this for GCC 2.7.  
     If we still couldn't find a mode, use MODE, but expand_binop will
     probably die.  
     It should be possible to restrict the precision to GET_MODE_BITSIZE
     (mode), and thereby get better code when OP1 is a constant.  Do that
     later.  It will require going over all usages of SIZE below.  
     Only deduct something for a REM if the last divide done was
     for a different constant.   Then set the constant of the last
     divide.  
     Now convert to the best mode to use.  
         convert_modes may have placed op1 into a register, so we
         must recompute the following.  
     If one of the operands is a volatile MEM, copy it into a register.  
     If we need the remainder or if OP1 is constant, we need to
     put OP0 in a register in case it has any queued subexpressions.  
     Promote floor rounding to trunc rounding for unsigned operations.  
                           Most significant bit of divisor is set; emit an scc
                           insn.  
                           Find a suitable multiplier and right shift count
                           instead of multiplying with D.  
                           If the suggested multiplier is more than SIZE bits,
                           we can do better for even divisors, using an
                           initial right shift.  
                   Since d might be INT_MIN, we have to cast to
                   unsigned HOST_WIDE_INT before negating to avoid
                   undefined signed overflow.  
                   n rem d = n rem -d 
                       This case is not handled correctly below.  
                            We assume that cheap metric is true if the
                            optab has an expander for this mode.  
                       We have computed OP0 / abs(OP1).  If OP1 is negative,
                       negate the quotient.  
         We will come here only for signed operations.  
                   We could just as easily deal with negative constants here,
                   but it does not seem worth the trouble for GCC 2.6.  
           Try using an instruction that produces both the quotient and
           remainder, using truncation.  We can easily compensate the quotient
           or remainder to get floor rounding, once we have the remainder.
           Notice that we compute also the final remainder value here,
           and return the result right away.  
               This could be computed with a branch-less sequence.
               Save that for later.  
           No luck with division elimination or divmod.  Have to do it
           by conditionally adjusting op0 *and* the result.  
               Try using an instruction that produces both the quotient and
               remainder, using truncation.  We can easily compensate the
               quotient or remainder to get ceiling rounding, once we have the
               remainder.  Notice that we compute also the final remainder
               value here, and return the result right away.  
                   This could be computed with a branch-less sequence.
                   Save that for later.  
               No luck with division elimination or divmod.  Have to do it
               by conditionally adjusting op0 *and* the result.  
                   This is extremely similar to the code for the unsigned case
                   above.  For 2.7 we should merge these variants, but for
                   2.6.1 I don't want to touch the code for unsigned since that
                   get used in C.  The signed case will only be used by other
                   languages (Ada).  
               Try using an instruction that produces both the quotient and
               remainder, using truncation.  We can easily compensate the
               quotient or remainder to get ceiling rounding, once we have the
               remainder.  Notice that we compute also the final remainder
               value here, and return the result right away.  
                   This could be computed with a branch-less sequence.
                   Save that for later.  
               No luck with division elimination or divmod.  Have to do it
               by conditionally adjusting op0 *and* the result.  
             Try to produce the remainder without producing the quotient.
             If we seem to have a divmod pattern that does not require widening,
             don't try widening here.  We should really have a WIDEN argument
             to expand_twoval_binop, since what we'd really like to do here is
             1) try a mod insn in compute_mode
             2) try a divmod insn in compute_mode
             3) try a div insn in compute_mode and multiply-subtract to get
                remainder
             4) try the same things with widening allowed.  
                 No luck there.  Can we do remainder and divide at once
                 without a library call?  
         Produce the quotient.  Try a quotient insn, but not a library call.
         If we have a divmod in this mode, use it in preference to widening
         the div (for this test we assume it will not fail). Note that optab2
         is set to the one of the two optabs that the call below will use.  
             No luck there.  Try a quotient-and-remainder insn,
             keeping the quotient alone.  
                   Still no luck.  If we are not computing the remainder,
                   use a library call for the quotient.  
             No divide instruction either.  Use library for remainder.  
             No remainder function.  Try a quotient-and-remainder
             function, keeping the remainder.  
             We divided.  Now finish doing X - Y * (X / Y).  
static rtx expand_expr ( tree  exp,
rtx  target,
enum machine_mode  mode,
enum expand_modifier  modifier 
)
inlinestatic
rtx expand_expr_real ( tree  exp,
rtx  target,
enum machine_mode  tmode,
enum expand_modifier  modifier,
rtx alt_rtl 
)
   Work horses for expand_expr.  
   expand_expr: generate code for computing expression EXP.
   An rtx for the computed value is returned.  The value is never null.
   In the case of a void EXP, const0_rtx is returned.

   The value may be stored in TARGET if TARGET is nonzero.
   TARGET is just a suggestion; callers must assume that
   the rtx returned may not be the same as TARGET.

   If TARGET is CONST0_RTX, it means that the value will be ignored.

   If TMODE is not VOIDmode, it suggests generating the
   result in mode TMODE.  But this is done only when convenient.
   Otherwise, TMODE is ignored and the value generated in its natural mode.
   TMODE is just a suggestion; callers must assume that
   the rtx returned may not have mode TMODE.

   Note that TARGET may have neither TMODE nor MODE.  In that case, it
   probably will not be used.

   If MODIFIER is EXPAND_SUM then when EXP is an addition
   we can return an rtx of the form (MULT (REG ...) (CONST_INT ...))
   or a nest of (PLUS ...) and (MINUS ...) where the terms are
   products as above, or REG or MEM, or constant.
   Ordinarily in such cases we would output mul or add instructions
   and then return a pseudo reg containing the sum.

   EXPAND_INITIALIZER is much like EXPAND_SUM except that
   it also marks a label as absolutely required (it can't be dead).
   It also makes a ZERO_EXTEND or SIGN_EXTEND instead of emitting extend insns.
   This is used for outputting expressions used in initializers.

   EXPAND_CONST_ADDRESS says that it is okay to return a MEM
   with a constant address even if that address is not normally legitimate.
   EXPAND_INITIALIZER and EXPAND_SUM also have this effect.

   EXPAND_STACK_PARM is used when expanding to a TARGET on the stack for
   a call parameter.  Such targets require special care as we haven't yet
   marked TARGET so that it's safe from being trashed by libcalls.  We
   don't want to use TARGET for anything but the final result;
   Intermediate values must go elsewhere.   Additionally, calls to
   emit_block_move will be flagged with BLOCK_OP_CALL_PARM.

   If EXP is a VAR_DECL whose DECL_RTL was a MEM with an invalid
   address, and ALT_RTL is non-NULL, then *ALT_RTL is set to the
   DECL_RTL of the VAR_DECL.  *ALT_RTL is also set if EXP is a
   COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on
   recursively.  
     Handle ERROR_MARK before anybody tries to access its type.  
rtx expand_expr_real_1 ( tree  ,
rtx  ,
enum  machine_mode,
enum  expand_modifier,
rtx  
)
     An operation in what may be a bit-field type needs the
     result to be reduced to the precision of the bit-field type,
     which is narrower than that of the type's mode.  
     If we are going to ignore this result, we need only do something
     if there is a side-effect somewhere in the expression.  If there
     is, short-circuit the most common cases here.  Note that we must
     not call expand_expr with anything but const0_rtx in case this
     is an initial expansion of a size that contains a PLACEHOLDER_EXPR.  
         Ensure we reference a volatile object even if value is ignored, but
         don't do this if all we are doing is taking its address.  
     Use subtarget as the target for operand 0 of a binary operation.  
         ??? ivopts calls expander, without any preparation from
         out-of-ssa.  So fake instructions as if this was an access to the
         base variable.  This unnecessarily allocates a pseudo, see how we can
         reuse it, if partition base vars have it set already.  
         For EXPAND_INITIALIZER try harder to get something simpler.  
         If a static var's type was incomplete when the decl was written,
         but the type is complete now, lay out the decl now.  
         ... fall through ...  
         Record writes to register variables.  
         Ensure variable marked as used even if it doesn't go through
         a parser.  If it hasn't be used yet, write out an external
         definition.  
         Show we haven't gotten RTL for this yet.  
         Variables inherited from containing functions should have
         been lowered by this point.  
                     ??? C++ creates functions that are not TREE_STATIC.  
         This is the case of an array whose size is to be determined
         from its initializer, while the initializer is still being parsed.
         ??? We aren't parsing while expanding anymore.  
         If DECL_RTL is memory, we are in the normal case and the
         address is not valid, get the address into a register.  
         If we got something, return it.  But first, set the alignment
         if the address is a register.  
         If the mode of DECL_RTL does not match that of the decl,
         there are two cases: we are dealing with a BLKmode value
         that is returned in a register, or we are dealing with
         a promoted value.  In the latter case, return a SUBREG
         of the wanted mode, but mark it so that we know that it
         was already extended.  
             Get the signedness to be used for this variable.  Ensure we get
             the same mode we got when the variable was declared.  
         If optimized, generate immediate CONST_DOUBLE
         which will be turned into memory by reload if necessary.

         We used to force a register so that loop.c could see it.  But
         this does not allow gen_* patterns to perform optimizations with
         the constants.  It also produces two insns in cases like "x = 1.0;".
         On most machines, floating-point constants are not permitted in
         many insns, so we'd end up copying it to a register in any case.

         Now, we do the copying in expand_binop, if appropriate.  
         Handle evaluating a complex constant in a CONCAT target.  
             Move the real and imaginary parts separately.  
         ... fall through ...  
         temp contains a constant address.
         On RISC machines where a constant address isn't valid,
         make some insns to get that address into a register.  
               We can indeed still hit this case, typically via builtin
               expanders calling save_expr immediately before expanding
               something.  Assume this means that we only have to deal
               with non-BLKmode values.  
         If we don't need the result, just ensure we evaluate any
         subexpressions.  
               If the target does not have special handling for unaligned
               loads of mode then it can use regular moves for them.  
               We've already validated the memory, and we're creating a
               new pseudo destination.  The predicates really can't fail,
               nor can the generator.  
           Handle expansion of non-aliased memory with non-BLKmode.  That
           might end up in a register.  
                   We've already validated the memory, and we're creating a
                   new pseudo destination.  The predicates really can't fail,
                   nor can the generator.  
           Fold an expression like: "foo"[2].
           This is not done in fold so it won't happen inside &.
           Don't fold if this is for wide characters since it's too
           difficult to do correctly and this is a very rare case.  
           If this is a constant index into a constant array,
           just get the value from the array.  Handle both the cases when
           we have an explicit constructor and when our operand is a variable
           that was declared const.  
                             If VALUE is a CONSTRUCTOR, this
                             optimization is only useful if
                             this doesn't store the CONSTRUCTOR
                             into memory.  If it does, it is more
                             efficient to just load the data from
                             the array directly.  
                   Optimize the special case of a zero lower bound.

                   We convert the lower bound to sizetype to avoid problems
                   with constant folding.  E.g. suppose the lower bound is
                   1 and its mode is QI.  Without the conversion
                      (ARRAY + (INDEX - (unsigned char)1))
                   becomes
                      (ARRAY + (-(unsigned char)1) + INDEX)
                   which becomes
                      (ARRAY + 255 + INDEX).  Oops!  
         If the operand is a CONSTRUCTOR, we can just extract the
         appropriate field if it is present.  
                   We can normally use the value of the field in the
                   CONSTRUCTOR.  However, if this is a bitfield in
                   an integral mode that we can fit in a HOST_WIDE_INT,
                   we must mask only the number of bits in the bitfield,
                   since this is done implicitly by the constructor.  If
                   the bitfield does not meet either of those conditions,
                   we can't do this optimization.  
           If we got back the original object, something is wrong.  Perhaps
           we are evaluating an expression too early.  In any event, don't
           infinitely recurse.  
           If TEM's type is a union of variable size, pass TARGET to the inner
           computation, since it will need a temporary and TARGET is known
           to have to do.  This occurs in unchecked conversion in Ada.  
           If the bitfield is volatile, we want to access it in the
           field's mode, not the computed mode.
           If a MEM has VOIDmode (external with incomplete type),
           use BLKmode for it instead.  
           If we have either an offset, a BLKmode result, or a reference
           outside the underlying object, we must force it to memory.
           Such a case can occur in Ada if we have unchecked conversion
           of an expression from a scalar type to an aggregate type or
           for an ARRAY_RANGE_REF whose type is BLKmode, or if we were
           passed a partially uninitialized object or a view-conversion
           to a larger size.  
           Handle CONCAT first.  
                 Otherwise force into memory.  
           If this is a constant, put it in a register if it is a legitimate
           constant and we don't need a memory reference.  
           Otherwise, if this is a constant, try to force it to the constant
           pool.  Note that back-ends, e.g. MIPS, may refuse to do so if it
           is a legitimate constant.  
           Otherwise, if this is a constant or the object is not in memory
           and need be, put it there.  
                   A constant address in OP0 can have VOIDmode, we must
                   not try to call force_reg in that case.  
           If OFFSET is making OP0 more aligned than BIGGEST_ALIGNMENT,
           record its alignment as BIGGEST_ALIGNMENT.  
           Don't forget about volatility even if this is a bitfield.  
           In cases where an aligned union has an unaligned object
           as a field, we might be extracting a BLKmode value from
           an integer-mode (e.g., SImode) object.  Handle this case
           by doing the extract into an object as wide as the field
           (which we know to be the width of a basic mode), then
           storing into memory, and changing the mode to BLKmode.  
               If the field is volatile, we always want an aligned
               access.  Do this in following two situations:
               1. the access is not already naturally
               aligned, otherwise "normal" (non-bitfield) volatile fields
               become non-addressable.
               2. the bitsize is narrower than the access size. Need
               to extract bitfields from the access.  
               If the field isn't aligned enough to fetch as a memref,
               fetch it as a bit field.  
               If the type and the field are a constant size and the
               size of the type isn't the same size as the bitfield,
               we must use bitfield operations.  
                   In this case, BITPOS must start at a byte boundary and
                   TARGET, if specified, must be a MEM.  
               If the result is a record type and BITSIZE is narrower than
               the mode of OP0, an integral mode, and this is a big endian
               machine, we must put the field into the high-order bits.  
               If the result type is BLKmode, store the data into a temporary
               of the appropriate type, but with the mode corresponding to the
               mode for the data we have (op0's mode).  It's tempting to make
               this a constant type, since we know it's only being stored once,
               but that can cause problems if we are taking the address of this
               COMPONENT_REF because the MEM of any reference via that address
               will have flags corresponding to the type, which will not
               necessarily be constant.  
           If the result is BLKmode, use that to access the object
           now as well.  
           Get a reference to just this component.  
           If op0 is a temporary because of forcing to memory, pass only the
           type to set_mem_attributes so that the original expression is never
           marked as ADDRESSABLE through MEM_EXPR of the temporary.  
         All valid uses of __builtin_va_arg_pack () are removed during
         inlining.  
           Check for a built-in function.  
         If we are converting to BLKmode, try to avoid an intermediate
         temporary by fetching an inner memory reference.  
           ??? We should work harder and deal with non-zero offsets.  
               See the normal_inner_ref case for the rationale.  
                   Get a reference to just this component.  
         If the input and output modes are both the same, we are done.  
         If neither mode is BLKmode, and both modes are the same size
         then we can use gen_lowpart.  
         If both types are integral, convert from one mode to the other.  
         As a last resort, spill op0 to memory, and reload it in a
         different mode.  
             If the operand is not a MEM, force it into memory.  Since we
             are going to be changing the mode of the MEM, don't call
             force_const_mem for constants because we don't allow pool
             constants to change mode.  
         At this point, OP0 is in the correct mode.  If the output type is
         such that the operand is known to be aligned, indicate that it is.
         Otherwise, we need only be concerned about alignment for non-BLKmode
         results.  
                 ??? Copying the MEM without substantially changing it might
                 run afoul of the code handling volatile memory references in
                 store_expr, which assumes that TARGET is returned unmodified
                 if it has been used.  
                      If the target does have special handling for unaligned
                      loads of mode then use them.  
                 We've already validated the memory, and we're creating a
                 new pseudo destination.  The predicates really can't
                 fail.  
                 Nor can the insn generator.  
           Check for |= or &= of a bitfield of size one into another bitfield
           of size 1.  In this case, (unless we need the result of the
           assignment) we can do this more efficiently with a
           test followed by an assignment, if necessary.

           ??? At this point, we can't get a BIT_FIELD_REF here.  But if
           things change so we do, this code should be enhanced to
           support it.  
         Expanded in cfgexpand.c.  
         Lowered by tree-eh.c.  
         Lowered by gimplify.c.  
         Function descriptors are not valid except for as
         initialization constants, and should not be expanded.  
         WITH_SIZE_EXPR expands to its first argument.  The caller should
         have pulled out the size to use in whatever context it needed.  

References array_ref_low_bound(), compare_tree_int(), expand_constructor(), expand_expr(), fold(), fold_convert_loc(), gen_int_mode(), integer_zerop(), size_diffop_loc(), tree_int_cst_equal(), and expand_operand::value.

rtx expand_expr_real_2 ( sepops  ,
rtx  ,
enum  machine_mode,
enum  expand_modifier 
)
     We should be called only on simple (binary or unary) expressions,
     exactly those that are valid in gimple expressions that aren't
     GIMPLE_SINGLE_RHS (or invalid).  
     We should be called only if we need the result.  
     An operation in what may be a bit-field type needs the
     result to be reduced to the precision of the bit-field type,
     which is narrower than that of the type's mode.  
     Use subtarget as the target for operand 0 of a binary operation.  
             If both input and output are BLKmode, this conversion isn't doing
             anything except possibly changing memory attribute.  
               Store data into beginning of memory target.  
                 Store this field into a union of the proper type.  
             Return the entire union.  
             If the signedness of the conversion differs and OP0 is
             a promoted SUBREG, clear that indication since we now
             have to do the proper extension.  
         If OP0 is a constant, just convert it into the proper mode.  
           Conversions between pointers to the same address space should
           have been implemented via CONVERT_EXPR / NOP_EXPR.  
           Ask target code to handle conversion between pointers
           to overlapping address spaces.  
           For disjoint address spaces, converting anything but
           a null pointer invokes undefined behaviour.  We simply
           always return a null pointer here.  
         Even though the sizetype mode and the pointer's mode can be different
         expand is able to handle this correctly and get the correct result out
         of the PLUS_EXPR code.  
         Make sure to sign-extend the sizetype offset in a POINTER_PLUS_EXPR
         if sizetype precision is smaller than pointer precision.  
         If sizetype precision is larger than pointer precision, truncate the
         offset to have matching modes.  
         If we are adding a constant, a VAR_DECL that is sp, fp, or ap, and
         something else, make sure we add the register to the constant and
         then to the other thing.  This case can occur during strength
         reduction and doing it this way will produce better code if the
         frame pointer or argument pointer is eliminated.

         fold-const.c will ensure that the constant is always in the inner
         PLUS_EXPR, so the only case we need to do anything about is if
         sp, ap, or fp is our second argument, in which case we must swap
         the innermost first argument and our second argument.  
         If the result is to be ptr_mode and we are adding an integer to
         something, we might be forming a constant.  So try to use
         plus_constant.  If it produces a sum and we can't accept it,
         use force_operand.  This allows P = &ARR[const] to generate
         efficient code on machines where a SYMBOL_REF is not a valid
         address.

         If this is an EXPAND_SUM call, always return the sum.  
                 Use immed_double_const to ensure that the constant is
                 truncated according to the mode of OP1, then sign extended
                 to a HOST_WIDE_INT.  Using the constant directly can result
                 in non-canonical RTL in a 64x32 cross compile.  
                     Return a PLUS if modifier says it's OK.  
                 Use immed_double_const to ensure that the constant is
                 truncated according to the mode of OP1, then sign extended
                 to a HOST_WIDE_INT.  Using the constant directly can result
                 in non-canonical RTL in a 64x32 cross compile.  
         Use TER to expand pointer addition of a negated value
         as pointer subtraction.  
         No sense saving up arithmetic to be done
         if it's all in the wrong mode to form part of an address.
         And force_operand won't know whether to sign-extend or
         zero-extend.  
         For initializers, we are allowed to return a MINUS of two
         symbolic constants.  Here we handle all cases when both operands
         are constant.  
         Handle difference of two symbolic constants,
         for the sake of an initializer.  
             If the last operand is a CONST_INT, use plus_constant of
             the negated constant.  Else make the MINUS.  
         No sense saving up arithmetic to be done
         if it's all in the wrong mode to form part of an address.
         And force_operand won't know whether to sign-extend or
         zero-extend.  
         Convert A - const to A + (-const).  
         If first operand is constant, swap them.
         Thus the following special case checks need only
         check the second operand.  
         First, check if we have a multiplication of one signed and one
         unsigned operand.  
                 op0 and op1 might still be constant, despite the above
                 != INTEGER_CST check.  Handle it.  
         Check for a multiplication with matching signedness.  
                     op0 and op1 might still be constant, despite the above
                     != INTEGER_CST check.  Handle it.  
                     op0 and op1 might still be constant, despite the above
                     != INTEGER_CST check.  Handle it.  
           If there is no insn for FMA, emit it as __builtin_fma{,f,l}
           call.  
         If this is a fixed-point operation, then we cannot use the code
         below because "expand_mult" doesn't support sat/no-sat fixed-point
         multiplications.   
         If first operand is constant, swap them.
         Thus the following special case checks need only
         check the second operand.  
         Attempt to return something suitable for generating an
         indexed address, for machines that support that.  
         If this is a fixed-point operation, then we cannot use the code
         below because "expand_divmod" doesn't support sat/no-sat fixed-point
         divisions.   
         Possible optimization: compute the dividend with EXPAND_SUM
         then if the divisor is constant can optimize the case
         where some terms of the dividend have coeffs divisible by it.  
         expand_float can't figure out what to do if FROM has VOIDmode.
         So give it the correct mode.  With -O, cse will optimize this.  
         ABS_EXPR is not valid for complex arguments.  
         Unsigned abs is simply the operand.  Testing here means we don't
         risk generating incorrect code below.  
         First try to do it with a special MIN or MAX instruction.
         If that does not win, use a conditional jump to select the proper
         value.  
         At this point, a MEM target is no longer useful; we will get better
         code without it.  
         If op1 was placed in target, swap op0 and op1.  
         We generate better code and avoid problems with op1 mentioning
         target by forcing op1 into a pseudo if it isn't a constant.  
           Canonicalize to comparisons against 0.  
               Converting (a >= 1 ? a : 1) into (a > 0 ? a : 1)
               or (a != 0 ? a : 1) for unsigned.
               For MIN we are safe converting (a <= 1 ? a : 1)
               into (a <= 0 ? a : 1)  
               Converting (a >= -1 ? a : -1) into (a >= 0 ? a : -1)
               and (a <= -1 ? a : -1) into (a < 0 ? a : -1) 
           Use a conditional move if possible.  
               ??? Same problem as in expmed.c: emit_conditional_move
               forces a stack adjustment via compare_from_rtx, and we
               lose the stack adjustment if the sequence we are about
               to create is discarded.  
               Try to emit the conditional move.  
               If we could do the conditional move, emit the sequence,
               and return.  
               Otherwise discard the sequence and fall back to code with
               branches.  
         In case we have to reduce the result to bitfield precision
         for unsigned bitfield expand this as XOR with a proper constant
         instead.  
         ??? Can optimize bitwise operations with one arg constant.
         Can optimize (a bitwise1 n) bitwise2 (a bitwise3 b)
         and (a bitwise1 b) bitwise2 b (etc)
         but that is probably not worth while.  
         fall through 
         If this is a fixed-point operation, then we cannot use the code
         below because "expand_shift" doesn't support sat/no-sat fixed-point
         shifts.   
         Could determine the answer when only additive constants differ.  Also,
         the addition of one can be handled by changing the condition.  
         Use a compare and a jump for BLKmode comparisons, or for function
         type comparisons is HAVE_canonicalize_funcptr_for_compare.  
              Make sure we don't have a hard reg (such as function's return
              value) live across basic blocks, if not optimizing.  
         Get the rtx code of the operands.  
           If target overlaps with op1, then either we need to force
           op1 into a pseudo (if target also overlaps with op0),
           or write the complex parts in reverse order.  
                   Move the imaginary (op1) and real (op0) parts to their
                   location.  
         Move the real (op0) and imaginary (op1) parts to their location.  
           The signedness is determined from input operand.  
         Careful here: if the target doesn't support integral vector modes,
         a constant selection vector could wind up smooshed into a normal
         integral constant.  
         A COND_EXPR with its type being VOID_TYPE represents a
         conditional jump and is handled in
         expand_gimple_cond_expr.  
         Note that COND_EXPRs whose type is a structure or union
         are required to be constructed to contain assignments of
         a temporary variable, so that we can evaluate them here
         for side effect only.  If type is void, we must do likewise.  
         If we are not to produce a result, we have no target.  Otherwise,
         if a target was specified use it; it will not be used as an
         intermediate target unless it is safe.  If no target, use a
         temporary.  
     Here to do an ordinary binary operator.  
     Bitwise operations do not need bitfield reduction as we expect their
     operands being properly truncated.  
rtx expand_mult ( enum machine_mode  mode,
rtx  op0,
rtx  op1,
rtx  target,
int  unsignedp 
)
   Perform a multiplication and return an rtx for the result.
   MODE is mode of value; OP0 and OP1 are what to multiply (rtx's);
   TARGET is a suggestion for where to store the result (an rtx).

   We check specially for a constant integer as OP1.
   If you want this check for OP0 as well, then before calling
   you should swap the two operands if OP0 would be constant.  
     For vectors, there are several simplifications that can be made if
     all elements of the vector constant are identical.  
         These are the operations that are potentially turned into
         a sequence of shifts and additions.  
         synth_mult does an `unsigned int' multiply.  As long as the mode is
         less than or equal in size to `unsigned int' this doesn't matter.
         If the mode is larger than `unsigned int', then synth_mult works
         only if the constant value exactly fits in an `unsigned int' without
         any truncation.  This means that multiplying by negative values does
         not work; results are off by 2^32 on a 32 bit machine.  
             If we are multiplying in DImode, it may still be a win
             to try to work with shifts and adds.  
         We used to test optimize here, on the grounds that it's better to
         produce a smaller program when -O is not used.  But this causes
         such a terrible slowdown sometimes that it seems better to always
         use synth_mult.  
         Special case powers of two.  
         Attempt to handle multiplication of DImode values by negative
         coefficients, by performing the multiplication by a positive
         multiplier and then inverting the result.  
             Its safe to use -coeff even for INT_MIN, as the
             result is interpreted as an unsigned coefficient.
             Exclude cost of op0 from max_cost to match the cost
             calculation of the synth_mult.  
             Special case powers of two.  
         Exclude cost of op0 from max_cost to match the cost
         calculation of the synth_mult.  
     Expand x*2.0 as x+x.  
     This used to use umul_optab if unsigned, but for non-widening multiply
     there is no difference between signed and unsigned.  

References choose_mult_variant(), convert_modes(), convert_to_mode(), expand_binop(), expand_mult_const(), expand_shift(), floor_log2(), mul_widen_cost(), OPTAB_LIB_WIDEN, and optimize_insn_for_speed_p().

rtx expand_mult_highpart_adjust ( enum machine_mode  mode,
rtx  adj_operand,
rtx  op0,
rtx  op1,
rtx  target,
int  unsignedp 
)
   Emit code to adjust ADJ_OPERAND after multiplication of wrong signedness
   flavor of OP0 and OP1.  ADJ_OPERAND is already the high half of the
   product OP0 x OP1.  If UNSIGNEDP is nonzero, adjust the signed product
   to become unsigned, if UNSIGNEDP is zero, adjust the unsigned product to
   become signed.

   The result is put in TARGET if that is convenient.

   MODE is the mode of operation.  

References emit_store_flag(), floor_log2(), force_reg(), gen_reg_rtx(), HOST_WIDE_INT, optimize_insn_for_speed_p(), and shift.

Referenced by expand_widening_mult().

rtx expand_shift ( enum tree_code  code,
enum machine_mode  mode,
rtx  shifted,
int  amount,
rtx  target,
int  unsignedp 
)
   Output a shift instruction for expression code CODE,
   with SHIFTED being the rtx for the value to shift,
   and AMOUNT the amount to shift by.
   Store the result in the rtx TARGET, if that is convenient.
   If UNSIGNEDP is nonzero, do a logical shift; otherwise, arithmetic.
   Return the rtx for where the value is.  

References alg_add_t_m2, alg_shift, and alg_sub_t_m2.

Referenced by expand_mult(), and mem_overlaps_already_clobbered_arg_p().

rtx expand_simple_binop ( enum machine_mode  mode,
enum rtx_code  code,
rtx  op0,
rtx  op1,
rtx  target,
int  unsignedp,
enum optab_methods  methods 
)
   Generate code for a simple binary or unary operation.  "Simple" in
   this case means "can be unambiguously described by a (mode, code)
   pair and mapped to a single optab."  
   Wrapper around expand_binop which takes an rtx code to specify
   the operation to perform, not an optab pointer.  All other
   arguments are the same.  

Referenced by expand_builtin_sync_operation(), expand_mem_thread_fence(), noce_try_addcc(), noce_try_store_flag_constants(), and split_edge_and_insert().

rtx expand_simple_unop ( enum machine_mode  mode,
enum rtx_code  code,
rtx  op0,
rtx  target,
int  unsignedp 
)
   Wrapper around expand_unop which takes an rtx code to specify
   the operation to perform, not an optab pointer.  All other
   arguments are the same.  

Referenced by expand_atomic_load(), expand_builtin_sync_operation(), and expand_mem_thread_fence().

void expand_sjlj_dispatch_table ( rtx  dispatch_index,
vec< tree dispatch_table 
)
   Like expand_case but special-case for SJLJ exception dispatching.  
   Expand the dispatch to a short decrement chain if there are few cases
   to dispatch to.  Likewise if neither casesi nor tablejump is available,
   or if flag_jump_tables is set.  Otherwise, expand as a casesi or a
   tablejump.  The index mode is always the mode of integer_type_node.
   Trap if no case matches the index.

   DISPATCH_INDEX is the index expression to switch on.  It should be a
   memory or register operand.
   
   DISPATCH_TABLE is a set of case labels.  The set should be sorted in
   ascending order, be contiguous, starting with value 0, and contain only
   single-valued case labels.  
     Expand as a decrement-chain if there are 5 or fewer dispatch
     labels.  This covers more than 98% of the cases in libjava,
     and seems to be a reasonable compromise between the "old way"
     of expanding as a decision tree or dispatch table vs. the "new
     way" with decrement chain or dispatch table.  
         Expand the dispatch as a decrement chain:

         "switch(index) {case 0: do_0; case 1: do_1; ...; case N: do_N;}"

         ==>

         if (index == 0) do_0; else index--;
         if (index == 0) do_1; else index--;
         ...
         if (index == 0) do_N; else index--;

         This is more efficient than a dispatch table on most machines.
         The last "index--" is redundant but the code is trivially dead
         and will be cleaned up by later passes.  
         Similar to expand_case, but much simpler.  
     Dispatching something not handled?  Trap!  
rtx expand_sync_fetch_operation ( rtx  ,
rtx  ,
enum  rtx_code,
bool  ,
rtx   
)
rtx expand_sync_lock_test_and_set ( rtx  ,
rtx  ,
rtx   
)
rtx expand_sync_operation ( rtx  ,
rtx  ,
enum  rtx_code 
)
rtx expand_variable_shift ( enum tree_code  code,
enum machine_mode  mode,
rtx  shifted,
tree  amount,
rtx  target,
int  unsignedp 
)
   Output a shift instruction for expression code CODE,
   with SHIFTED being the rtx for the value to shift,
   and AMOUNT the tree for the amount to shift by.
   Store the result in the rtx TARGET, if that is convenient.
   If UNSIGNEDP is nonzero, do a logical shift; otherwise, arithmetic.
   Return the rtx for where the value is.  
rtx expr_size ( tree  )
   Functions from alias.c 
   rtl.h and tree.h were included.  
   Return an rtx for the size in bytes of the value of an expr.  
rtx extract_bit_field ( rtx  str_rtx,
unsigned HOST_WIDE_INT  bitsize,
unsigned HOST_WIDE_INT  bitnum,
int  unsignedp,
rtx  target,
enum machine_mode  mode,
enum machine_mode  tmode 
)
   Generate code to extract a byte-field from STR_RTX
   containing BITSIZE bits, starting at BITNUM,
   and put it in TARGET if possible (if TARGET is nonzero).
   Regardless of TARGET, we return the rtx for where the value is placed.

   STR_RTX is the structure containing the byte (a REG or MEM).
   UNSIGNEDP is nonzero if this is an unsigned bit field.
   MODE is the natural mode of the field value once extracted.
   TMODE is the mode the caller would like the value to have;
   but the value may be returned with type MODE instead.

   If a TARGET is specified and we can store in it at no extra cost,
   we do so, and return TARGET.
   Otherwise, we return a REG of mode TMODE or MODE, with TMODE preferred
   if they are equally easy.  

Referenced by emit_group_load_1(), and restore_fixed_argument_area().

rtx extract_low_bits ( enum  machine_mode,
enum  machine_mode,
rtx   
)
void fixup_tail_calls ( void  )
   A sibling call sequence invalidates any REG_EQUIV notes made for
   this function's incoming arguments.

   At the start of RTL generation we know the only REG_EQUIV notes
   in the rtl chain are those for incoming arguments, so we can look
   for REG_EQUIV notes between the start of the function and the
   NOTE_INSN_FUNCTION_BEG.

   This is (slight) overkill.  We could keep track of the highest
   argument we clobber and be more selective in removing notes, but it
   does not seem to be worth the effort.  
         There are never REG_EQUIV notes for the incoming arguments
         after the NOTE_INSN_FUNCTION_BEG note, so stop if we see it.  
rtx force_label_rtx ( tree  )
   As label_rtx, but additionally the label is placed on the forced label
   list of its containing function (i.e. it is treated as reachable even
   if how is not obvious).  
rtx force_not_mem ( rtx  )
   Return given rtx, copied into a new temp reg if it was in memory.  
rtx force_operand ( rtx  ,
rtx   
)
   Given an rtx that may include add and multiply operations,
   generate them as insns and return a pseudo-reg containing the value.
   Useful after calling expand_expr with 1 as sum_ok.  
rtx force_reg ( enum  machine_mode,
rtx   
)
   Copy a value to a register if it isn't already a register.
   Args are mode (in case value is a constant) and the value.  
rtx gen_add2_insn ( rtx  ,
rtx   
)
   Create but don't emit one rtl instruction to perform certain operations.
   Modes must match; operands must meet the operation's predicates.
   Likewise for subtraction and for just copying.  

Referenced by do_output_reload(), and get_def_for_expr().

rtx gen_add3_insn ( rtx  ,
rtx  ,
rtx   
)
rtx gen_cond_trap ( enum  rtx_code,
rtx  ,
rtx  ,
rtx   
)
   Generate a conditional trap instruction.  

Referenced by cond_exec_find_if_block().

rtx gen_group_rtx ( rtx  )
   Generate a non-consecutive group of registers represented by a PARALLEL.  
rtx gen_sub2_insn ( rtx  ,
rtx   
)
rtx gen_sub3_insn ( rtx  ,
rtx  ,
rtx   
)
int get_mem_align_offset ( rtx  ,
unsigned  int 
)
   Return OFFSET if XEXP (MEM, 0) - OFFSET is known to be ALIGN
   bits aligned for 0 <= OFFSET < ALIGN / BITS_PER_UNIT, or
   -1 if not known.  
rtx get_personality_function ( tree  )
   Get the personality libfunc for a function decl.  
rtx hard_function_value ( const_tree  valtype,
const_tree  func,
const_tree  fntype,
int  outgoing 
)
   Return an rtx that refers to the value returned by a function
   in its original home.  This becomes invalid if any more code is emitted.  
   Return an rtx representing the register or memory location
   in which a scalar value of data type VALTYPE
   was returned by a function call to function FUNC.
   FUNC is a FUNCTION_DECL, FNTYPE a FUNCTION_TYPE node if the precise
   function is known, otherwise 0.
   OUTGOING is 1 if on a machine with register windows this function
   should return the register in which the function will put its result
   and 0 otherwise.  
         int_size_in_bytes can return -1.  We don't need a check here
         since the value of bytes will then be large enough that no
         mode will match anyway.  
             Have we found a large enough mode?  
         No suitable mode found.  

Referenced by get_next_funcdef_no().

rtx hard_libcall_value ( enum  machine_mode,
rtx   
)
   Return an rtx that refers to the value returned by a library call
   in its original home.  This becomes invalid if any more code is emitted.  
int have_add2_insn ( rtx  ,
rtx   
)
int have_insn_for ( enum  rtx_code,
enum  machine_mode 
)
   Report whether the machine description contains an insn which can
   perform the operation described by CODE and MODE.  

Referenced by default_shift_truncation_mask(), dump_case_nodes(), and make_extraction().

int have_sub2_insn ( rtx  ,
rtx   
)
void init_all_optabs ( struct target_optabs )
void init_block_clear_fn ( const char *  )
void init_block_move_fn ( const char *  )
void init_expr ( void  )
   This is run at the start of compiling a function.  

Referenced by blocks_nreverse(), and vect_can_advance_ivs_p().

void init_expr_target ( void  )
   Functions from expr.c:  
   This is run during target initialization to set up which modes can be
   used directly in memory and to initialize the block move optab.  
   This is run to set up which modes can be used
   directly in memory and to initialize the block move optab.  It is run
   at the beginning of compilation and when the target is reinitialized.  
     Try indexing by frame ptr and try by stack ptr.
     It is known that on the Convex the stack ptr isn't a valid index.
     With luck, one or the other is valid on any machine.  
     A scratch register we can modify in-place below to avoid
     useless RTL allocations.  
         See if there is some register that can be used in this mode and
         directly loaded or stored from memory.  
rtx init_one_libfunc ( const char *  )
   Call this to initialize an optab function entry.  

Referenced by gen_fp_to_int_conv_libfunc().

void init_optabs ( void  )
   Call this once to initialize the contents of the optabs
   appropriately for the current target machine.  
   Call this to initialize the contents of the optabs
   appropriately for the current target machine.  
     Fill in the optabs with the insns we support.  
     The ffs function operates on `int'.  Fall back on it if we do not
     have a libgcc2 function for that width.  
     Explicitly initialize the bswap libfuncs since we need them to be
     valid for things other than word_mode.  
     Use cabs for double complex abs, since systems generally have cabs.
     Don't define any libcall for float complex, so that cabs will be used.  
     For function entry/exit instrumentation.  
     Allow the target to add more libcalls or rename some, etc.  

References direct_optab_handler(), mode_for_vector(), optab_handler(), and targetm.

void init_pending_stack_adjust ( void  )
   At the start of a function, record that we have no previously-pushed
   arguments waiting to be popped.  
HOST_WIDE_INT int_expr_size ( tree  )
   Return a wide integer for the size in bytes of the value of EXP, or -1
   if the size can vary or is larger than an integer.  
void jumpif ( tree  ,
rtx  ,
int   
)
   Generate code to evaluate EXP and jump to LABEL if the value is nonzero.  
void jumpif_1 ( enum  tree_code,
tree  ,
tree  ,
rtx  ,
int   
)
void jumpifnot ( tree  ,
rtx  ,
int   
)
   Generate code to evaluate EXP and jump to LABEL if the value is zero.  
void jumpifnot_1 ( enum  tree_code,
tree  ,
tree  ,
rtx  ,
int   
)
rtx label_rtx ( tree  )
   Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary.  

Referenced by expand_computed_goto(), and node_has_low_bound().

void locate_and_pad_parm ( enum machine_mode  passed_mode,
tree  type,
int  in_regs,
int  partial,
tree  fndecl,
struct args_size initial_offset_ptr,
struct locate_and_pad_arg_data locate 
)
   Compute the size and offset from the start of the stacked arguments for a
   parm passed in mode PASSED_MODE and with type TYPE.

   INITIAL_OFFSET_PTR points to the current offset into the stacked
   arguments.

   The starting offset and size for this parm are returned in
   LOCATE->OFFSET and LOCATE->SIZE, respectively.  When IN_REGS is
   nonzero, the offset is that of stack slot, which is returned in
   LOCATE->SLOT_OFFSET.  LOCATE->ALIGNMENT_PAD is the amount of
   padding required from the initial offset ptr to the stack slot.

   IN_REGS is nonzero if the argument will be passed in registers.  It will
   never be set if REG_PARM_STACK_SPACE is not defined.

   FNDECL is the function in which the argument was defined.

   There are two types of rounding that are done.  The first, controlled by
   TARGET_FUNCTION_ARG_BOUNDARY, forces the offset from the start of the
   argument list to be aligned to the specific boundary (in bits).  This
   rounding affects the initial and starting offsets, but not the argument
   size.

   The second, controlled by FUNCTION_ARG_PADDING and PARM_BOUNDARY,
   optionally rounds the size of the parm to PARM_BOUNDARY.  The
   initial offset is not affected by this rounding, while the size always
   is and the starting offset may be.  
    LOCATE->OFFSET will be negative for ARGS_GROW_DOWNWARD case;
    INITIAL_OFFSET_PTR is positive because locate_and_pad_parm's
    callers pass in the total size of args so far as
    INITIAL_OFFSET_PTR.  LOCATE->SIZE is always positive.  
     If we have found a stack parm before we reach the end of the
     area reserved for registers, skip that area.  
     Alignment can't exceed MAX_SUPPORTED_STACK_ALIGNMENT.  
         stack_alignment_estimated can't change after stack has been
         realigned.  
                 If stack is realigned and stack alignment value
                 hasn't been finalized, it is OK not to increase
                 stack_alignment_estimated.  The bigger alignment
                 requirement is recorded in stack_alignment_needed
                 below.  
     Remember if the outgoing parameter requires extra alignment on the
     calling function side.  
     Pad_below needs the pre-rounded size to know how much to pad
     below.  
     Pad_below needs the pre-rounded size to know how much to pad below
     so this must be done before rounding up.  

References current_function_decl, regno_clobbered_at_setjmp(), and warning().

Referenced by initialize_argument_information(), and split_complex_types().

rtx maybe_emit_group_store ( rtx  ,
tree   
)
rtx memory_address_addr_space ( enum  machine_mode,
rtx  ,
addr_space_t   
)
   Convert arg to a valid memory address for specified machine mode that points
   to a specific named address space, by emitting insns to perform arithmetic
   if necessary.  
void move_block_from_reg ( int  ,
rtx  ,
int   
)
   Copy all or part of a BLKmode value X out of registers starting at REGNO.
   The number of registers to be filled is NREGS.  
void move_block_to_reg ( int  ,
rtx  ,
int  ,
enum  machine_mode 
)
   Copy all or part of a value X into registers starting at REGNO.
   The number of registers to be filled is NREGS.  
unsigned HOST_WIDE_INT move_by_pieces_ninsns ( unsigned HOST_WIDE_INT  l,
unsigned int  align,
unsigned int  max_size 
)
   Return number of insns required to move L bytes by pieces.
   ALIGN (in bits) is maximum alignment we can assume.  
rtx negate_rtx ( enum  machine_mode,
rtx   
)
   Functions from expmed.c:  
   Arguments MODE, RTX: return an rtx for the negation of that value.
   May emit insns.  
rtx offset_address ( rtx  ,
rtx  ,
unsigned  HOST_WIDE_INT 
)
   Return a memory reference like MEMREF, but whose address is changed by
   adding OFFSET, an RTX, to it.  POW2 is the highest power of two factor
   known to be in OFFSET (possibly 1).  
rtx prepare_call_address ( tree  fndecl,
rtx  funexp,
rtx  static_chain_value,
rtx call_fusage,
int  reg_parm_seen,
int  sibcallp 
)
   Force FUNEXP into a form suitable for the address of a CALL,
   and return that as an rtx.  Also load the static chain register
   if FNDECL is a nested function.

   CALL_FUSAGE points to a variable holding the prospective
   CALL_INSN_FUNCTION_USAGE information.  
     Make a valid memory address and copy constants through pseudo-regs,
     but not for a constant address if -fno-function-cse.  
       If we are using registers for parameters, force the
       function address into a register now.  

References targetm.

void probe_stack_range ( HOST_WIDE_INT  ,
rtx   
)
   Probe a range of stack addresses from FIRST to FIRST+SIZE, inclusive.
   FIRST is a constant and size is a Pmode RTX.  These are offsets from
   the current stack pointer.  STACK_GROWS_DOWNWARD says whether to add
   or subtract them from the stack pointer.  
enum machine_mode promote_decl_mode ( const_tree  ,
int *   
)
   Return mode and signedness to use when object is promoted.  
enum machine_mode promote_function_mode ( const_tree  type,
enum machine_mode  mode,
int *  punsignedp,
const_tree  funtype,
int  for_return 
)
   Return mode and signedness to use when an argument or result in the
   given mode is promoted.  
   Return the mode to use to pass or return a scalar of TYPE and MODE.
   PUNSIGNEDP points to the signedness of the type and may be adjusted
   to show what signedness to use on extension operations.

   FOR_RETURN is nonzero if the caller is promoting the return value
   of FNDECL, else it is for promoting args.  
     Called without a type node for a libcall.  

References targetm.

Referenced by assign_parm_remove_parallels(), initialize_argument_information(), promote_mode(), and resolve_operand_name_1().

enum machine_mode promote_mode ( const_tree  type,
enum machine_mode  mode,
int *  punsignedp 
)
   Return mode and signedness to use when an object in the given mode
   is promoted.  
   Return the mode to use to store a scalar of TYPE and MODE.
   PUNSIGNEDP points to the signedness of the type and may be adjusted
   to show what signedness to use on extension operations.  
     For libcalls this is invoked without TYPE from the backends
     TARGET_PROMOTE_FUNCTION_MODE hooks.  Don't do anything in that
     case.  
     FIXME: this is the same logic that was there until GCC 4.4, but we
     probably want to test POINTERS_EXTEND_UNSIGNED even if PROMOTE_MODE
     is not defined.  The affected targets are M32C, S390, SPARC.  

References current_function_decl, promote_function_mode(), and promote_mode().

Referenced by compute_argument_block_size(), convert_tree_comp_to_rtx(), default_promote_function_mode(), default_promote_function_mode_always_promote(), and promote_mode().

rtx push_block ( rtx  ,
int  ,
int   
)
   Push a block of length SIZE (perhaps variable)
   and return an rtx to address the beginning of the block.  
int safe_from_p ( const_rtx  ,
tree  ,
int   
)
void set_mem_attributes ( rtx  ,
tree  ,
int   
)
   Given REF, a MEM, and T, either the type of X or the expression
   corresponding to REF, set the memory attributes.  OBJECTP is nonzero
   if we are making a new object of this type.  
void set_mem_attributes_minus_bitpos ( rtx  ref,
tree  t,
int  objectp,
HOST_WIDE_INT  bitpos 
)
   Similar, except that BITPOS has not yet been applied to REF, so if
   we alter MEM_OFFSET according to T then we should subtract BITPOS
   expecting that it'll be added back in later.  
   Given REF (a MEM) and T, either the type of X or the expression
   corresponding to REF, set the memory attributes.  OBJECTP is nonzero
   if we are making a new object of this type.  BITPOS is nonzero if
   there is an offset outstanding on T that will be applied later.  
     It can happen that type_for_mode was given a mode for which there
     is no language-level type.  In which case it returns NULL, which
     we can see here.  
     If we have already set DECL_RTL = ref, get_alias_set will get the
     wrong answer, as it assumes that DECL_RTL already has the right alias
     info.  Callers should not set DECL_RTL until after the call to
     set_mem_attributes.  
     Get the alias set from the expression or type (perhaps using a
     front-end routine) and use it.  
     Default values from pre-existing memory attributes if present.  
         ??? Can this ever happen?  Calling this routine on a MEM that
         already carries memory attributes should probably be invalid.  
     Otherwise, default values from the mode of the MEM reference.  
         Respect mode size.  
         ??? Is this really necessary?  We probably should always get
         the size from the type below.  
         Respect mode alignment for STRICT_ALIGNMENT targets if T is a type;
         if T is an object, always compute the object alignment below.  
         ??? If T is a type, respecting mode alignment may *also* be wrong
         e.g. if the type carries an alignment attribute.  Should we be
         able to simply always use TYPE_ALIGN?  
     We can set the alignment from the type if we are making an object,
     this is an INDIRECT_REF, or if TYPE_ALIGN_OK.  
     If the size is known, we can set that.  
     The address-space is that of the type.  
     If T is not a type, we may be able to deduce some more information about
     the expression.  
         Now remove any conversions: they don't change what the underlying
         object is.  Likewise for SAVE_EXPR.  
         Note whether this expression can trap.  
             Mark static const strings readonly as well.  
             Address-space information is on the base object.  
         If this expression uses it's parent's alias set, mark it such
         that we won't change it.  
         If this is a decl, set the attributes of the MEM from it.  
         ???  If we end up with a constant here do record a MEM_EXPR.  
         If this is a field reference, record it.  
         If this is an array reference, look for an outer field reference.  
             We can't modify t, because we use it at the end of the
             function.  
                 We assume all arrays have sizes that are a multiple of a byte.
                 First subtract the lower bound, if any, in the type of the
                 index, then convert to sizetype and multiply by the size of
                 the array element.  
             Else do not record a MEM_EXPR.  
         If this is an indirect reference, record it.  
         Compute the alignment.  
     If we modified OFFSET based on T, then subtract the outstanding
     bit position offset.  Similarly, increase the size of the accessed
     object to contain the negative offset.  
     Now set the attributes we computed above.  
rtx set_storage_via_libcall ( rtx  ,
rtx  ,
rtx  ,
bool   
)
   The same, but always output an library call.  
bool set_storage_via_setmem ( rtx  object,
rtx  size,
rtx  val,
unsigned int  align,
unsigned int  expected_align,
HOST_WIDE_INT  expected_size 
)
   Expand a setmem pattern; return true if successful.  
     Try the most limited insn first, because there's no point
     including more than one in the machine description unless
     the more limited one has some advantage.  
             We don't need MODE to be narrower than
             BITS_PER_HOST_WIDE_INT here because if SIZE is less than
             the mode mask, as it is returned by the macro, it will
             definitely be less than the actual mode mask.  
             The check above guarantees that this size conversion is valid.  

References copy_replacements(), gen_rtx_MEM(), push_operand(), reload_in_progress, simplify_gen_subreg(), and simplify_subreg().

rtx set_user_assembler_libfunc ( const char *  ,
const char *   
)
bool shift_return_value ( enum  machine_mode,
bool  ,
rtx   
)
bool split_comparison ( enum rtx_code  code,
enum machine_mode  mode,
enum rtx_code code1,
enum rtx_code code2 
)
   Split a comparison into two others, the second of which has the other
   "orderedness".  The first is always ORDERED or UNORDERED if MODE
   does not honor NaNs (which means that it can be skipped in that case;
   see do_compare_rtx_and_jump).

   The two conditions are written in *CODE1 and *CODE2.  Return true if
   the conditions must be ANDed, false if they must be ORed.  
         Do not turn a trapping comparison into a non-trapping one.  

Referenced by emit_cstore().

tree std_build_builtin_va_list ( void  )
   The "standard" definition of va_list is void*.  
tree std_canonical_va_list_type ( tree  )
void std_expand_builtin_va_start ( tree  ,
rtx   
)
tree std_fn_abi_va_list ( tree  )
void store_bit_field ( rtx  str_rtx,
unsigned HOST_WIDE_INT  bitsize,
unsigned HOST_WIDE_INT  bitnum,
unsigned HOST_WIDE_INT  bitregion_start,
unsigned HOST_WIDE_INT  bitregion_end,
enum machine_mode  fieldmode,
rtx  value 
)
   Generate code to store value from rtx VALUE
   into a bit-field within structure STR_RTX
   containing BITSIZE bits starting at bit BITNUM.

   BITREGION_START is bitpos of the first bitfield in this region.
   BITREGION_END is the bitpos of the ending bitfield in this region.
   These two fields are 0, if the C++ memory model does not apply,
   or we are not interested in keeping track of bitfield regions.

   FIELDMODE is the machine-mode of the FIELD_DECL node for this field.  
     Under the C++0x memory model, we must not touch bits outside the
     bit region.  Adjust the address to start at the beginning of the
     bit region.  

References get_best_mode(), HOST_WIDE_INT, and word_mode.

Referenced by noce_emit_store_flag(), and restore_fixed_argument_area().

rtx store_by_pieces ( rtx  to,
unsigned HOST_WIDE_INT  len,
rtx(*)(void *, HOST_WIDE_INT, enum machine_mode)  constfun,
void *  constfundata,
unsigned int  align,
bool  memsetp,
int  endp 
)
   Generate several move instructions to store LEN bytes generated by
   CONSTFUN to block TO.  (A MEM rtx with BLKmode).  CONSTFUNDATA is a
   pointer which will be passed as argument in every CONSTFUN call.
   ALIGN is maximum alignment we can assume.
   MEMSETP is true if this is a real memset/bzero, not a copy.
   Returns TO + LEN.  
   Generate several move instructions to store LEN bytes generated by
   CONSTFUN to block TO.  (A MEM rtx with BLKmode).  CONSTFUNDATA is a
   pointer which will be passed as argument in every CONSTFUN call.
   ALIGN is maximum alignment we can assume.  MEMSETP is true if this is
   a memset operation and false if it's a copy of a constant string.
   If ENDP is 0 return to, if ENDP is 1 return memory at the end ala
   mempcpy, and if ENDP is 2 return memory the end minus one byte ala
   stpcpy.  
rtx store_expr ( tree  ,
rtx  ,
int  ,
bool   
)
   Generate code for computing expression EXP,
   and storing the value into TARGET.
   If SUGGEST_REG is nonzero, copy the value through a register
   and return that register, if that is possible.  
tree string_constant ( tree  ,
tree  
)
   Return the tree node and offset if a given argument corresponds to
   a string constant.  
int try_casesi ( tree  index_type,
tree  index_expr,
tree  minval,
tree  range,
rtx  table_label,
rtx  default_label,
rtx  fallback_label,
int  default_probability 
)
   Two different ways of generating switch statements.  
   Attempt to generate a casesi instruction.  Returns 1 if successful,
   0 otherwise (i.e. if there is no casesi instruction).

   DEFAULT_PROBABILITY is the probability of jumping to the default
   label.  
     Convert the index to SImode.  
         We must handle the endpoints in the original mode.  
         Now we can safely truncate.  
int try_tablejump ( tree  ,
tree  ,
tree  ,
tree  ,
rtx  ,
rtx  ,
int   
)
void update_nonlocal_goto_save_area ( void  )
   Invoke emit_stack_save for the nonlocal_goto_save_area.  
   Invoke emit_stack_save on the nonlocal_goto_save_area for the current
   function.  This function should be called whenever we allocate or
   deallocate dynamic stack space.  
     The nonlocal_goto_save_area object is an array of N pointers.  The
     first one is used for the frame pointer save; the rest are sized by
     STACK_SAVEAREA_MODE.  Create a reference to array index 1, the first
     of the stack save area slots.  
rtx use_anchored_address ( rtx  )
void use_group_regs ( rtx ,
rtx   
)
   Mark a PARALLEL as holding a parameter for the next CALL_INSN.  
static void use_reg ( )
inlinestatic
   Mark REG as holding a parameter for the next CALL_INSN.  
void use_reg_mode ( rtx ,
rtx  ,
enum  machine_mode 
)
   Mark REG as holding a parameter for the next CALL_INSN.
   Mode is TYPE_MODE of the non-promoted parameter, or VOIDmode.  
void use_regs ( rtx ,
int  ,
int   
)
   Mark NREGS consecutive regs, starting at REGNO, as holding parameters
   for the next CALL_INSN.  
rtx validize_mem ( rtx  )
   Return a memory reference like MEMREF, but which is known to have a
   valid address.  
rtx widen_memory_access ( rtx  ,
enum  machine_mode,
HOST_WIDE_INT   
)
   Definitions from emit-rtl.c 
   Return a memory reference like MEMREF, but with its mode widened to
   MODE and adjusted by OFFSET.  

Variable Documentation

tree block_clear_fn
   A subroutine of set_storage_via_libcall.  Create the tree node
   for the function we use for block clears.