GCC Middle and Back End API Reference
expr.h File Reference
#include "function.h"
#include "rtl.h"
#include "flags.h"
#include "tree-core.h"
#include "machmode.h"
#include "insn-config.h"
#include "alias.h"
#include "emit-rtl.h"
Include dependency graph for expr.h:
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

Macros

#define NO_DEFER_POP   (inhibit_defer_pop += 1)
#define OK_DEFER_POP   (inhibit_defer_pop -= 1)
#define ADD_PARM_SIZE(TO, INC)
#define SUB_PARM_SIZE(TO, DEC)
#define ARGS_SIZE_TREE(SIZE)
#define ARGS_SIZE_RTX(SIZE)
#define memory_address(MODE, RTX)   memory_address_addr_space ((MODE), (RTX), ADDR_SPACE_GENERIC)
#define adjust_address(MEMREF, MODE, OFFSET)   adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 0, 0)
#define adjust_address_nv(MEMREF, MODE, OFFSET)   adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1, 0, 0)
#define adjust_bitfield_address(MEMREF, MODE, OFFSET)   adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 1, 0)
#define adjust_bitfield_address_size(MEMREF, MODE, OFFSET, SIZE)   adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 1, SIZE)
#define adjust_bitfield_address_nv(MEMREF, MODE, OFFSET)   adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1, 1, 0)
#define adjust_automodify_address(MEMREF, MODE, ADDR, OFFSET)   adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 1)
#define adjust_automodify_address_nv(MEMREF, MODE, ADDR, OFFSET)   adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 0)

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_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)
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

Macro Definition Documentation

#define ADD_PARM_SIZE (   TO,
  INC 
)
Value:
do { \
tree inc = (INC); \
if (host_integerp (inc, 0)) \
(TO).constant += tree_low_cst (inc, 0); \
else if ((TO).var == 0) \
(TO).var = fold_convert (ssizetype, inc); \
else \
(TO).var = size_binop (PLUS_EXPR, (TO).var, \
fold_convert (ssizetype, inc)); \
} while (0)

Add the value of the tree INC to the `struct args_size' TO.

Referenced by initialize_argument_information().

#define adjust_address (   MEMREF,
  MODE,
  OFFSET 
)    adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 0, 0)

Return a memory reference like MEMREF, but with its mode changed to MODE and its address offset by OFFSET bytes.

Referenced by apply_args_size(), move_by_pieces_1(), set_storage_via_setmem(), and sjlj_assign_call_site_values().

#define adjust_address_nv (   MEMREF,
  MODE,
  OFFSET 
)    adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1, 0, 0)
#define adjust_automodify_address (   MEMREF,
  MODE,
  ADDR,
  OFFSET 
)    adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 1)

Return a memory reference like MEMREF, but with its mode changed to MODE and its address changed to ADDR, which is assumed to be increased by OFFSET bytes from MEMREF.

#define adjust_automodify_address_nv (   MEMREF,
  MODE,
  ADDR,
  OFFSET 
)    adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 0)

Likewise, but the reference is not required to be valid.

#define adjust_bitfield_address (   MEMREF,
  MODE,
  OFFSET 
)    adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 1, 0)

Return a memory reference like MEMREF, but with its mode changed to MODE and its address offset by OFFSET bytes. Assume that it's for a bitfield and conservatively drop the underlying object if we cannot be sure to stay within its bounds.

#define adjust_bitfield_address_nv (   MEMREF,
  MODE,
  OFFSET 
)    adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1, 1, 0)

Likewise, but the reference is not required to be valid.

#define adjust_bitfield_address_size (   MEMREF,
  MODE,
  OFFSET,
  SIZE 
)    adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 1, SIZE)

As for adjust_bitfield_address, but specify that the width of BLKmode accesses is SIZE bytes.

#define ARGS_SIZE_RTX (   SIZE)
Value:
((SIZE).var == 0 ? GEN_INT ((SIZE).constant) \

Convert the implicit sum in a `struct args_size' into an rtx.

#define ARGS_SIZE_TREE (   SIZE)
Value:
((SIZE).var == 0 ? ssize_int ((SIZE).constant) \
: size_binop (PLUS_EXPR, fold_convert (ssizetype, (SIZE).var), \
ssize_int ((SIZE).constant)))

Convert the implicit sum in a `struct args_size' into a tree of type ssizetype.

#define memory_address (   MODE,
  RTX 
)    memory_address_addr_space ((MODE), (RTX), ADDR_SPACE_GENERIC)

Like memory_address_addr_space, except assume the memory address points to the generic named address space.

Referenced by expand_builtin_prefetch(), and expand_builtin_return_addr().

#define NO_DEFER_POP   (inhibit_defer_pop += 1)

Prevent the compiler from deferring stack pops. See inhibit_defer_pop for more information.

Referenced by move_by_pieces_1().

#define OK_DEFER_POP   (inhibit_defer_pop -= 1)

Allow the compiler to defer stack pops. See inhibit_defer_pop for more information.

#define SUB_PARM_SIZE (   TO,
  DEC 
)
Value:
do { \
tree dec = (DEC); \
if (host_integerp (dec, 0)) \
(TO).constant -= tree_low_cst (dec, 0); \
else if ((TO).var == 0) \
(TO).var = size_binop (MINUS_EXPR, ssize_int (0), \
else \
(TO).var = size_binop (MINUS_EXPR, (TO).var, \
fold_convert (ssizetype, dec)); \
} while (0)

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 

Definitions for code generation pass of GNU compiler. Copyright (C) 1987-2013 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see http://www.gnu.org/licenses/. 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 &ndash; consider
 (plus (plus reg reg) const_int) &ndash; 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 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.   
     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().   
     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.   

References BITS_PER_UNIT, and PREFERRED_STACK_BOUNDARY.

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_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.   

References const0_rtx.

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(), gcc_assert, 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 NULL, NULL_TREE, and 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 cfun, discard_pending_stack_adjust(), and EXIT_IGNORE_STACK.

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 const0_rtx, CONST0_RTX, and 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(), 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.   
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.   
         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(), gcc_assert, GET_CODE, move_block_to_reg(), and REGNO.

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.   
 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  )
rtx expand_call ( tree  ,
rtx  ,
int   
)
void expand_case ( gimple  )

In stmt.c Expand a GIMPLE_SWITCH statement.

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(), CONSTRUCTOR_ELTS, expand_constructor(), expand_expr(), fold(), fold_convert_loc(), FOR_EACH_CONSTRUCTOR_ELT, gen_int_mode(), GET_MODE_CLASS, integer_zerop(), NULL_RTX, size_diffop_loc(), sizetype, TREE_CODE, tree_int_cst_equal(), TREE_INT_CST_LOW, TREE_SIDE_EFFECTS, TREE_STRING_LENGTH, TREE_STRING_POINTER, TREE_TYPE, TYPE_MODE, 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)  
     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(), CONST_INT_P, convert_modes(), convert_to_mode(), EXACT_POWER_OF_2_OR_ZERO_P, expand_binop(), expand_mult_const(), expand_shift(), floor_log2(), GET_MODE, HWI_COMPUTABLE_MODE_P, INTVAL, 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 const0_rtx, emit_store_flag(), floor_log2(), force_reg(), GEN_INT, gen_reg_rtx(), GET_MODE_BITSIZE, HOST_WIDE_INT, optimize_insn_for_speed_p(), and shift.

Referenced by expand_widening_mult().

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&ndash;;
     if (index == 0) do_1; else index&ndash;;
     ...
     if (index == 0) do_N; else index&ndash;;

     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 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().

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(), GET_MODE_INNER, GET_MODE_SIZE, GET_MODE_UNIT_SIZE, mode_for_vector(), NULL, optab_handler(), targetm, and VECTOR_MODE_P.

void init_pending_stack_adjust ( void  )

At the start of a function, record that we have no previously-pushed arguments waiting to be popped.

References pending_stack_adjust, and stack_pointer_delta.

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.

 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
 so this must be done before rounding up.   

References DECL_ARGUMENTS, DECL_CHAIN, DECL_RTL, REG_P, REGNO, 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, TREE_TYPE, and TYPE_ADDR_SPACE.

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 DECL_MODE, promote_function_mode(), promote_mode(), TREE_CODE, TREE_TYPE, and TYPE_UNSIGNED.

Referenced by compute_argument_block_size(), 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 adjust_address, adjust_address_nv, copy_replacements(), gen_rtx_MEM(), GET_MODE, MEM_COPY_ATTRIBUTES, MEM_P, push_operand(), reload_in_progress, simplify_gen_subreg(), simplify_subreg(), and XEXP.

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(), GET_MODE, GET_MODE_BITSIZE, HOST_WIDE_INT, MAX_FIXED_MODE_SIZE, MEM_ALIGN, MEM_VOLATILE_P, and word_mode.

Referenced by noce_emit_store_flag().

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.