GCC Middle and Back End API Reference
expmed.c File Reference

Data Structures

struct  init_expmed_rtl

Enumerations

enum  mult_variant { basic_variant, negate_variant, add_variant }

Functions

static void store_fixed_bit_field (rtx, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, rtx)
static void store_split_bit_field (rtx, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, rtx)
static rtx extract_fixed_bit_field (enum machine_mode, rtx, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, rtx, int, bool)
static rtx mask_rtx (enum machine_mode, int, int, int)
static rtx lshift_value (enum machine_mode, rtx, int, int)
static rtx extract_split_bit_field (rtx, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, int)
static void do_cmp_and_jump (rtx, rtx, enum rtx_code, enum machine_mode, rtx)
static rtx expand_smod_pow2 (enum machine_mode, rtx, HOST_WIDE_INT)
static rtx expand_sdiv_pow2 (enum machine_mode, rtx, HOST_WIDE_INT)
static void init_expmed_one_conv (struct init_expmed_rtl *all, enum machine_mode to_mode, enum machine_mode from_mode, bool speed)
static void init_expmed_one_mode (struct init_expmed_rtl *all, enum machine_mode mode, int speed)
void init_expmed ()
rtx negate_rtx ()
static rtx narrow_bit_field_mem (rtx mem, enum machine_mode mode, unsigned HOST_WIDE_INT bitsize, unsigned HOST_WIDE_INT bitnum, unsigned HOST_WIDE_INT *new_bitnum)
static rtx adjust_bit_field_mem_for_reg (enum extraction_pattern pattern, rtx op0, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitnum, unsigned HOST_WIDE_INT bitregion_start, unsigned HOST_WIDE_INT bitregion_end, enum machine_mode fieldmode, unsigned HOST_WIDE_INT *new_bitnum)
static bool lowpart_bit_field_p (unsigned HOST_WIDE_INT bitnum, unsigned HOST_WIDE_INT bitsize, enum machine_mode struct_mode)
static bool simple_mem_bitfield_p (rtx op0, unsigned HOST_WIDE_INT bitsize, unsigned HOST_WIDE_INT bitnum, enum machine_mode mode)
static bool store_bit_field_using_insv (const extraction_insn *insv, rtx op0, unsigned HOST_WIDE_INT bitsize, unsigned HOST_WIDE_INT bitnum, rtx value)
static bool store_bit_field_1 (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, bool fallback_p)
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)
static rtx convert_extracted_bit_field (rtx x, enum machine_mode mode, enum machine_mode tmode, bool unsignedp)
static rtx extract_bit_field_using_extv (const extraction_insn *extv, rtx op0, unsigned HOST_WIDE_INT bitsize, unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target, enum machine_mode mode, enum machine_mode tmode)
static rtx extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, unsigned HOST_WIDE_INT bitnum, int unsignedp, bool packedp, rtx target, enum machine_mode mode, enum machine_mode tmode, bool fallback_p)
rtx extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, unsigned HOST_WIDE_INT bitnum, int unsignedp, bool packedp, rtx target, enum machine_mode mode, enum machine_mode tmode)
static rtx mask_rtx ()
static rtx lshift_value ()
rtx extract_low_bits ()
void expand_inc ()
void expand_dec ()
static rtx expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted, rtx amount, rtx target, int unsignedp)
rtx expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted, int amount, rtx target, int unsignedp)
rtx expand_variable_shift (enum tree_code code, enum machine_mode mode, rtx shifted, tree amount, rtx target, int unsignedp)
static void synth_mult (struct algorithm *, unsigned HOST_WIDE_INT, const struct mult_cost *, enum machine_mode mode)
static bool choose_mult_variant (enum machine_mode, HOST_WIDE_INT, struct algorithm *, enum mult_variant *, int)
static rtx expand_mult_const (enum machine_mode, rtx, HOST_WIDE_INT, rtx, const struct algorithm *, enum mult_variant)
static unsigned HOST_WIDE_INT invert_mod2n (unsigned HOST_WIDE_INT, int)
static rtx extract_high_half (enum machine_mode, rtx)
static rtx expmed_mult_highpart (enum machine_mode, rtx, rtx, rtx, int, int)
static rtx expmed_mult_highpart_optab (enum machine_mode, rtx, rtx, rtx, int, int)
rtx expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, int unsignedp)
int mult_by_coeff_cost ()
rtx expand_widening_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, int unsignedp, optab this_optab)
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)
static unsigned HOST_WIDE_INT invert_mod2n ()
rtx expand_mult_highpart_adjust (enum machine_mode mode, rtx adj_operand, rtx op0, rtx op1, rtx target, int unsignedp)
static rtx extract_high_half ()
static rtx expand_smod_pow2 ()
static rtx expand_sdiv_pow2 ()
rtx expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, rtx op0, rtx op1, rtx target, int unsignedp)
tree make_tree ()
rtx expand_and ()
static rtx emit_cstore (rtx target, enum insn_code icode, enum rtx_code code, enum machine_mode mode, enum machine_mode compare_mode, int unsignedp, rtx x, rtx y, int normalizep, enum machine_mode target_mode)
static rtx emit_store_flag_1 (rtx target, enum rtx_code code, rtx op0, rtx op1, enum machine_mode mode, int unsignedp, int normalizep, enum machine_mode target_mode)
rtx emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1, enum machine_mode mode, int unsignedp, int normalizep)
rtx emit_store_flag_force (rtx target, enum rtx_code code, rtx op0, rtx op1, enum machine_mode mode, int unsignedp, int normalizep)

Variables

struct target_expmed default_target_expmed
struct target_expmedthis_target_expmed = &default_target_expmed

Enumeration Type Documentation

Indicates the type of fixup needed after a constant multiplication.
   BASIC_VARIANT means no fixup is needed, NEGATE_VARIANT means that
   the result should be negated, and ADD_VARIANT means that the
   multiplicand should be added to the result.   
Enumerator:
basic_variant 
negate_variant 
add_variant 

Function Documentation

static rtx adjust_bit_field_mem_for_reg ( enum extraction_pattern  pattern,
rtx  op0,
HOST_WIDE_INT  bitsize,
HOST_WIDE_INT  bitnum,
unsigned HOST_WIDE_INT  bitregion_start,
unsigned HOST_WIDE_INT  bitregion_end,
enum machine_mode  fieldmode,
unsigned HOST_WIDE_INT new_bitnum 
)
static
The caller wants to perform insertion or extraction PATTERN on a
   bitfield of size BITSIZE at BITNUM bits into memory operand OP0.
   BITREGION_START and BITREGION_END are as for store_bit_field
   and FIELDMODE is the natural mode of the field.

   Search for a mode that is compatible with the memory access
   restrictions and (where applicable) with a register insertion or
   extraction.  Return the new memory on success, storing the adjusted
   bit position in *NEW_BITNUM.  Return null otherwise.   

References extraction_insn::field_mode, get_best_reg_extraction_insn(), narrow_bit_field_mem(), bit_field_mode_iterator::next_mode(), bit_field_mode_iterator::prefer_smaller_modes(), and word_mode.

Referenced by extract_bit_field_1(), and store_bit_field_1().

static bool choose_mult_variant ( enum machine_mode  mode,
HOST_WIDE_INT  val,
struct algorithm alg,
enum mult_variant variant,
int  mult_cost 
)
static
Find the cheapest way of multiplying a value of mode MODE by VAL.
   Try three variations:

       - a shift/add sequence based on VAL itself
       - a shift/add sequence based on -VAL, followed by a negation
       - a shift/add sequence based on VAL - 1, followed by an addition.

   Return true if the cheapest of these cost less than MULT_COST,
   describing the algorithm in *ALG and final fixup in *VARIANT.   

References add_cost(), add_variant, basic_variant, mult_cost::cost, algorithm::cost, HOST_BITS_PER_INT, mult_cost::latency, neg_cost(), negate_variant, optimize_insn_for_speed_p(), and synth_mult().

Referenced by expand_mult(), expand_widening_mult(), expmed_mult_highpart(), and mult_by_coeff_cost().

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.

   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.   

References ceil_log2(), double_int::div(), double_int::from_uhwi(), double_int::high, HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, double_int::low, pow(), double_int::set_bit(), and double_int::ult().

Referenced by expand_divmod(), expand_vector_divmod(), and vect_recog_divmod_pattern().

static rtx convert_extracted_bit_field ( rtx  x,
enum machine_mode  mode,
enum machine_mode  tmode,
bool  unsignedp 
)
static
A subroutine of extract_bit_field_1 that converts return value X
   to either MODE or TMODE.  MODE, TMODE and UNSIGNEDP are arguments
   to extract_bit_field.   

References convert_to_mode(), force_reg(), and mode_for_size().

Referenced by extract_bit_field_1(), and extract_bit_field_using_extv().

static void do_cmp_and_jump ( rtx  arg1,
rtx  arg2,
enum rtx_code  op,
enum machine_mode  mode,
rtx  label 
)
static
Perform possibly multi-word comparison and conditional jump to LABEL
   if ARG1 OP ARG2 true where ARG1 and ARG2 are of mode MODE.  This is
   now a thin wrapper around do_compare_rtx_and_jump.   

References do_compare_rtx_and_jump().

Referenced by expand_divmod(), expand_sdiv_pow2(), and expand_smod_pow2().

static rtx emit_cstore ( rtx  target,
enum insn_code  icode,
enum rtx_code  code,
enum machine_mode  mode,
enum machine_mode  compare_mode,
int  unsignedp,
rtx  x,
rtx  y,
int  normalizep,
enum machine_mode  target_mode 
)
static
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-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.   

References can_compare_p(), ccp_store_flag, convert_modes(), convert_move(), delete_insns_since(), emit_conditional_move(), emit_move_insn(), emit_store_flag(), emit_store_flag_1(), expand_binop(), expand_shift(), expand_unop(), get_last_insn(), last, optab_handler(), OPTAB_WIDEN, optimize_insn_for_speed_p(), reverse_condition(), reverse_condition_maybe_unordered(), rtx_cost(), rtx_equal_p(), split_comparison(), val_signbit_p(), and word_mode.

Referenced by convert_move(), emit_store_flag(), emit_store_flag_1(), emit_store_flag_force(), expand_divmod(), expand_sdiv_pow2(), expand_smod_pow2(), noce_emit_store_flag(), and noce_try_sign_mask().

static rtx emit_store_flag_1 ( rtx  target,
enum rtx_code  code,
rtx  op0,
rtx  op1,
enum machine_mode  mode,
int  unsignedp,
int  normalizep,
enum machine_mode  target_mode 
)
static
rtx emit_store_flag_force ( rtx  target,
enum rtx_code  code,
rtx  op0,
rtx  op1,
enum machine_mode  mode,
int  unsignedp,
int  normalizep 
)
rtx expand_and ( )
Compute the logical-and of OP0 and OP1, storing it in TARGET
   and returning TARGET.

   If TARGET is 0, a pseudo-register or constant is returned.   

References emit_move_insn(), expand_binop(), OPTAB_LIB_WIDEN, and simplify_binary_operation().

Referenced by emit_cstore(), expand_builtin_extract_return_addr(), expand_expr_real_1(), expand_mult_highpart_adjust(), optimize_bitfield_assignment_op(), and reduce_to_bit_field_precision().

void expand_dec ( )
Subtract DEC from TARGET.   

References emit_move_insn(), expand_binop(), OPTAB_LIB_WIDEN, and expand_operand::value.

Referenced by expand_divmod().

rtx expand_divmod ( int  rem_flag,
enum tree_code  code,
enum machine_mode  mode,
rtx  op0,
rtx  op1,
rtx  target,
int  unsignedp 
)
Emit the code to divide OP0 by OP1, putting the result in TARGET
   if that is convenient, and returning where the result is.
   You may request either the quotient or the remainder as the result;
   specify REM_FLAG nonzero to get the remainder.

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

   Cross-sum rules for even numbers can be derived by leaving as many bits
   to the right alone as the divisor has zeros to the right.
   E.g. if x is an unsigned 32 bit number:
   (x mod 12) == (((x & 1023) + ((x >> 8) & ~3)) * 0x15555558 >> 2 * 3) >> 28

References add_cost(), choose_multiplier(), convert_modes(), copy_to_mode_reg(), delete_insns_since(), do_cmp_and_jump(), emit_barrier(), emit_jump_insn(), emit_label(), emit_move_insn(), emit_store_flag(), emit_store_flag_force(), expand_abs(), expand_binop(), expand_dec(), expand_divmod(), expand_inc(), expand_mult(), expand_sdiv_pow2(), expand_shift(), expand_smod_pow2(), expand_twoval_binop(), expand_twoval_binop_libfunc(), expand_unop(), expmed_mult_highpart(), floor_log2(), force_operand(), force_reg(), gen_int_mode(), gen_label_rtx(), gen_reg_rtx(), get_last_insn(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, invert_mod2n(), last, mul_cost(), OPTAB_DIRECT, optab_handler(), OPTAB_LIB_WIDEN, optab_libfunc(), OPTAB_WIDEN, optimize_insn_for_speed_p(), plus_constant(), reg_mentioned_p(), sdiv_cost(), sdiv_pow2_cheap(), set_dst_reg_note(), shift_cost(), sign_expand_binop(), smod_pow2_cheap(), and udiv_cost().

Referenced by allocate_dynamic_stack_space(), expand_divmod(), expand_expr_real_2(), force_operand(), and round_push().

void expand_inc ( )
Add INC into TARGET.   

References emit_move_insn(), expand_binop(), OPTAB_LIB_WIDEN, and expand_operand::value.

Referenced by expand_divmod(), and expand_sdiv_pow2().

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.   

References choose_mult_variant(), dconst2, expand_binop(), expand_mult_const(), expand_shift(), expand_unop(), floor_log2(), force_reg(), gen_raw_REG(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, neg_cost(), OPTAB_LIB_WIDEN, optimize_insn_for_speed_p(), rtx_equal_p(), set_src_cost(), and shift.

Referenced by allocate_dynamic_stack_space(), builtin_memset_gen_str(), expand_divmod(), expand_expr_real_2(), force_operand(), and round_push().

static rtx expand_mult_const ( enum machine_mode  mode,
rtx  op0,
HOST_WIDE_INT  val,
rtx  target,
const struct algorithm alg,
enum mult_variant  variant 
)
static
A subroutine of expand_mult, used for constant multiplications.
   Multiply OP0 by VAL in mode MODE, storing the result in TARGET if
   convenient.  Use the shift/add sequence described by ALG and apply
   the final fixup specified by VARIANT.   

References add_variant, alg_add_factor, alg_add_t2_m, alg_add_t_m2, alg_m, alg_shift, alg_sub_factor, alg_sub_t2_m, alg_sub_t_m2, alg_zero, copy_to_mode_reg(), emit_move_insn(), expand_shift(), expand_unop(), force_operand(), force_reg(), get_last_insn(), HOST_WIDE_INT, log(), algorithm::log, negate_variant, algorithm::op, algorithm::ops, and set_dst_reg_note().

Referenced by expand_mult(), expand_widening_mult(), and expmed_mult_highpart().

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 expand_and(), expand_shift(), and force_operand().

Referenced by expand_expr_real_2(), and expmed_mult_highpart_optab().

static rtx expand_sdiv_pow2 ( enum  machine_mode,
rtx  ,
HOST_WIDE_INT   
)
static

Referenced by expand_divmod().

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

References add_cost(), expand_binop(), force_reg(), HOST_WIDE_INT, OPTAB_DIRECT, OPTAB_LIB_WIDEN, OPTAB_MUST_WIDEN, OPTAB_WIDEN, optimize_insn_for_speed_p(), shift_cost(), simplify_gen_binary(), simplify_gen_unary(), and subreg_lowpart_p().

Referenced by expand_shift(), and expand_variable_shift().

static rtx expand_smod_pow2 ( enum  machine_mode,
rtx  ,
HOST_WIDE_INT   
)
static

Referenced by expand_divmod().

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

References expand_normal(), and expand_shift_1().

Referenced by expand_expr_real_2().

rtx expand_widening_mult ( enum machine_mode  mode,
rtx  op0,
rtx  op1,
rtx  target,
int  unsignedp,
optab  this_optab 
)
Perform a widening 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).
   THIS_OPTAB is the optab we should use, it must be either umul_widen_optab
   or smul_widen_optab.

   We check specially for a constant integer as OP1, comparing the
   cost of a widening multiply against the cost of a sequence of shifts
   and adds.   

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

Referenced by expand_expr_real_2().

static rtx expmed_mult_highpart ( enum machine_mode  mode,
rtx  op0,
rtx  op1,
rtx  target,
int  unsignedp,
int  max_cost 
)
static
Emit code to multiply OP0 and OP1 (where OP1 is an integer constant),
   putting the high half of the result in TARGET if that is convenient,
   and return where the result is.  If the operation can not be performed,
   0 is returned.

   MODE is the mode of operation and result.

   UNSIGNEDP nonzero means unsigned multiply.

   MAX_COST is the total allowed cost for the expanded RTL.   

References add_cost(), choose_mult_variant(), convert_to_mode(), mult_cost::cost, algorithm::cost, expand_mult_const(), expmed_mult_highpart_optab(), extract_high_half(), force_operand(), HOST_WIDE_INT, optimize_insn_for_speed_p(), and shift_cost().

Referenced by expand_divmod().

static rtx expmed_mult_highpart_optab ( enum machine_mode  mode,
rtx  op0,
rtx  op1,
rtx  target,
int  unsignedp,
int  max_cost 
)
static
rtx extract_bit_field ( rtx  str_rtx,
unsigned HOST_WIDE_INT  bitsize,
unsigned HOST_WIDE_INT  bitnum,
int  unsignedp,
bool  packedp,
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.
   PACKEDP is nonzero if the field has the packed attribute.
   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.   

References extract_bit_field_1().

Referenced by copy_blkmode_from_reg(), copy_blkmode_to_reg(), emit_group_load_1(), expand_expr_real_1(), read_complex_part(), store_field(), and store_unaligned_arguments_into_pseudos().

static rtx extract_bit_field_1 ( rtx  str_rtx,
unsigned HOST_WIDE_INT  bitsize,
unsigned HOST_WIDE_INT  bitnum,
int  unsignedp,
bool  packedp,
rtx  target,
enum machine_mode  mode,
enum machine_mode  tmode,
bool  fallback_p 
)
static
static rtx extract_bit_field_using_extv ( const extraction_insn extv,
rtx  op0,
unsigned HOST_WIDE_INT  bitsize,
unsigned HOST_WIDE_INT  bitnum,
int  unsignedp,
rtx  target,
enum machine_mode  mode,
enum machine_mode  tmode 
)
static
Try to use an ext(z)v pattern to extract a field from OP0.
   Return the extracted value on success, otherwise return null.
   EXT_MODE is the mode of the extraction and the other arguments
   are as for extract_bit_field.   

References convert_extracted_bit_field(), create_fixed_operand(), create_integer_operand(), create_output_operand(), extraction_insn::field_mode, gen_lowpart_SUBREG(), gen_reg_rtx(), extraction_insn::icode, maybe_expand_insn(), narrow_bit_field_mem(), extraction_insn::struct_mode, and expand_operand::value.

Referenced by extract_bit_field_1().

static rtx extract_fixed_bit_field ( enum machine_mode  tmode,
rtx  op0,
unsigned HOST_WIDE_INT  bitsize,
unsigned HOST_WIDE_INT  bitnum,
rtx  target,
int  unsignedp,
bool  packedp 
)
static
Use shifts and boolean operations to extract a field of BITSIZE bits
   from bit BITNUM of OP0.

   UNSIGNEDP is nonzero for an unsigned bit field (don't sign-extend value).
   PACKEDP is true if the field has the packed attribute.

   If TARGET is nonzero, attempts to store the value there
   and return TARGET, but this is not guaranteed.
   If TARGET is not used, create a pseudo-reg of mode TMODE for the value.   

References convert_to_mode(), expand_binop(), expand_shift(), extract_split_bit_field(), force_reg(), get_best_mode(), HOST_WIDE_INT, inform(), input_location, mask_rtx(), OPTAB_LIB_WIDEN, warning_at(), and word_mode.

Referenced by extract_bit_field_1(), extract_split_bit_field(), and store_split_bit_field().

static rtx extract_high_half ( enum  machine_mode,
rtx   
)
static
static rtx extract_high_half ( )
static
Subroutine of expmed_mult_highpart.  Return the MODE high part of OP.   

References convert_modes(), expand_shift(), gen_highpart(), and word_mode.

rtx extract_low_bits ( )
Try to read the low bits of SRC as an rvalue of mode MODE, preserving
   the bit pattern.  SRC_MODE is the mode of SRC; if this is smaller than
   MODE, fill the upper bits with zeros.  Fail if the layout of either
   mode is unknown (as for CC modes) or if the extraction would involve
   unprofitable mode punning.  Return the value on success, otherwise
   return null.

   This is different from gen_lowpart* in these respects:

     - the returned value must always be considered an rvalue

     - when MODE is wider than SRC_MODE, the extraction involves
       a zero extension

     - when MODE is smaller than SRC_MODE, the extraction involves
       a truncation (and is thus subject to TRULY_NOOP_TRUNCATION).

   In other words, this routine performs a computation, whereas the
   gen_lowpart* routines are conceptually lvalue or rvalue subreg
   operations.   

References convert_modes(), force_reg(), gen_lowpart_common(), gen_rtx_SUBREG(), int_mode_for_mode(), simplify_subreg(), subreg_lowpart_offset(), and validate_subreg().

Referenced by find_shift_sequence(), and get_stored_val().

static rtx extract_split_bit_field ( rtx  op0,
unsigned HOST_WIDE_INT  bitsize,
unsigned HOST_WIDE_INT  bitpos,
int  unsignedp 
)
static
Extract a bit field that is split across two words
   and return an RTX for the result.

   OP0 is the REG, SUBREG or MEM rtx for the first of the two words.
   BITSIZE is the field width; BITPOS, position of its first bit, in the word.
   UNSIGNEDP is 1 if should zero-extend the contents; else sign-extend.   

References expand_binop(), expand_shift(), extract_fixed_bit_field(), first, HOST_WIDE_INT, offset, operand_subword_force(), OPTAB_LIB_WIDEN, and word_mode.

Referenced by extract_bit_field_1(), and extract_fixed_bit_field().

static void init_expmed_one_conv ( struct init_expmed_rtl all,
enum machine_mode  to_mode,
enum machine_mode  from_mode,
bool  speed 
)
static
static unsigned HOST_WIDE_INT invert_mod2n ( unsigned  HOST_WIDE_INT,
int   
)
static

Referenced by expand_divmod().

static unsigned HOST_WIDE_INT invert_mod2n ( )
static
Compute the inverse of X mod 2**n, i.e., find Y such that X * Y is
   congruent to 1 (mod 2**N).   

References HOST_BITS_PER_WIDE_INT, and HOST_WIDE_INT.

static bool lowpart_bit_field_p ( unsigned HOST_WIDE_INT  bitnum,
unsigned HOST_WIDE_INT  bitsize,
enum machine_mode  struct_mode 
)
static
Return true if a bitfield of size BITSIZE at bit number BITNUM within
   a structure of mode STRUCT_MODE represents a lowpart subreg.   The subreg
   offset is then BITNUM / BITS_PER_UNIT.   

Referenced by extract_bit_field_1(), and store_bit_field_1().

static rtx lshift_value ( enum  machine_mode,
rtx  ,
int  ,
int   
)
static

Referenced by store_fixed_bit_field().

static rtx lshift_value ( )
static
Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value
   VALUE truncated to BITSIZE bits and then shifted left BITPOS bits.   

References double_int::from_uhwi(), immed_double_int_const(), double_int::llshift(), and double_int::zext().

tree make_tree ( )
Return a tree node with data type TYPE, describing the value of X.
   Usually this is an VAR_DECL, if there is no obvious better choice.
   X may be an expression, however we only support those expressions
   generated by loop.c.   

References build_int_cst_wide(), build_real(), convert_memory_address_addr_space(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, signed_type_for(), type(), lang_hooks_for_types::type_for_mode, lang_hooks::types, and unsigned_type_for().

Referenced by assign_parm_setup_reg(), emit_block_move_via_libcall(), expand_asm_operands(), expand_builtin_cexpi(), expand_call(), expand_sjlj_dispatch_table(), force_const_mem(), initialize_argument_information(), set_storage_via_libcall(), store_constructor(), and store_expr().

static rtx mask_rtx ( enum  machine_mode,
int  ,
int  ,
int   
)
static
static rtx mask_rtx ( )
static
Return a constant integer (CONST_INT or CONST_DOUBLE) mask value
   of mode MODE with BITSIZE ones followed by BITPOS zeros, or the
   complement of that if COMPLEMENT.  The mask is truncated if
   necessary to the width of mode MODE.  The mask is zero-extended if
   BITSIZE+BITPOS is too small for MODE.   

References immed_double_int_const(), double_int::llshift(), and double_int::mask().

int mult_by_coeff_cost ( )
Return a cost estimate for multiplying a register by the given
   COEFFicient in the given MODE and SPEED.   

References choose_mult_variant(), mult_cost::cost, algorithm::cost, gen_raw_REG(), and set_src_cost().

Referenced by analyze_increments(), difference_cost(), force_expr_to_var_cost(), get_address_cost(), get_computation_cost_at(), most_expensive_mult_to_index(), and stmt_cost().

static rtx narrow_bit_field_mem ( rtx  mem,
enum machine_mode  mode,
unsigned HOST_WIDE_INT  bitsize,
unsigned HOST_WIDE_INT  bitnum,
unsigned HOST_WIDE_INT new_bitnum 
)
static
Adjust bitfield memory MEM so that it points to the first unit of mode
   MODE that contains a bitfield of size BITSIZE at bit position BITNUM.
   If MODE is BLKmode, return a reference to every byte in the bitfield.
   Set *NEW_BITNUM to the bit position of the field within the new memory.   

References HOST_WIDE_INT, and offset.

Referenced by adjust_bit_field_mem_for_reg(), extract_bit_field_using_extv(), store_bit_field_using_insv(), and store_fixed_bit_field().

rtx negate_rtx ( )
Return an rtx representing minus the value of X.
   MODE is the intended mode of the result,
   useful if X is a CONST_INT.   

References expand_unop(), and simplify_unary_operation().

Referenced by expand_binop(), expand_builtin_apply(), expand_expr_real_2(), fill_slots_from_thread(), force_operand(), and push_block().

static bool simple_mem_bitfield_p ( rtx  op0,
unsigned HOST_WIDE_INT  bitsize,
unsigned HOST_WIDE_INT  bitnum,
enum machine_mode  mode 
)
static
Return true if OP is a memory and if a bitfield of size BITSIZE at
   bit number BITNUM can be treated as a simple value of mode MODE.   

Referenced by extract_bit_field_1(), and store_bit_field_1().

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.   

References get_best_mode(), HOST_WIDE_INT, offset, and store_bit_field_1().

Referenced by copy_blkmode_from_reg(), copy_blkmode_to_reg(), emit_group_store(), expand_assignment(), noce_emit_move_insn(), store_expr(), store_field(), store_unaligned_arguments_into_pseudos(), and write_complex_part().

static bool store_bit_field_1 ( 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,
bool  fallback_p 
)
static
static bool store_bit_field_using_insv ( const extraction_insn insv,
rtx  op0,
unsigned HOST_WIDE_INT  bitsize,
unsigned HOST_WIDE_INT  bitnum,
rtx  value 
)
static
static void store_fixed_bit_field ( rtx  op0,
unsigned HOST_WIDE_INT  bitsize,
unsigned HOST_WIDE_INT  bitnum,
unsigned HOST_WIDE_INT  bitregion_start,
unsigned HOST_WIDE_INT  bitregion_end,
rtx  value 
)
static
Use shifts and boolean operations to store VALUE into a bit field of
   width BITSIZE in OP0, starting at bit BITNUM.   

References convert_to_mode(), copy_rtx(), emit_move_insn(), expand_binop(), expand_shift(), force_reg(), get_best_mode(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT, lshift_value(), mask_rtx(), narrow_bit_field_mem(), OPTAB_LIB_WIDEN, store_split_bit_field(), and word_mode.

Referenced by store_bit_field_1(), and store_split_bit_field().

static void store_split_bit_field ( rtx  op0,
unsigned HOST_WIDE_INT  bitsize,
unsigned HOST_WIDE_INT  bitpos,
unsigned HOST_WIDE_INT  bitregion_start,
unsigned HOST_WIDE_INT  bitregion_end,
rtx  value 
)
static
Store a bit field that is split across multiple accessible memory objects.

   OP0 is the REG, SUBREG or MEM rtx for the first of the objects.
   BITSIZE is the field width; BITPOS the position of its first bit
   (within the word).
   VALUE is the value to store.

   This does not yet handle fields wider than BITS_PER_WORD.   

References extract_fixed_bit_field(), force_reg(), gen_lowpart_common(), HOST_WIDE_INT, offset, operand_subword_force(), store_fixed_bit_field(), and word_mode.

Referenced by store_bit_field_1(), and store_fixed_bit_field().

static void synth_mult ( struct algorithm alg_out,
unsigned HOST_WIDE_INT  t,
const struct mult_cost cost_limit,
enum machine_mode  mode 
)
static
Compute and return the best algorithm for multiplying by T.
   The algorithm must cost less than cost_limit
   If retval.cost >= COST_LIMIT, no algorithm was found and all
   other field of the returned struct are undefined.
   MODE is the machine mode of the multiplication.   

References add_cost(), alg_hash_entry::alg, alg_add_factor, alg_add_t2_m, alg_add_t_m2, alg_hash_entry_ptr(), alg_impossible, alg_m, alg_shift, alg_sub_factor, alg_sub_t2_m, alg_sub_t_m2, alg_unknown, alg_zero, mult_cost::cost, algorithm::cost, alg_hash_entry::cost, exact_log2(), floor_log2(), HOST_WIDE_INT, mult_cost::latency, algorithm::log, memcpy(), alg_hash_entry::mode, algorithm::op, algorithm::ops, optimize_insn_for_speed_p(), shift_cost(), shiftadd_cost(), shiftsub0_cost(), shiftsub1_cost(), alg_hash_entry::speed, alg_hash_entry::t, and zero_cost().

Referenced by choose_mult_variant().


Variable Documentation

struct target_expmed default_target_expmed
@verbatim Medium-level subroutines: convert bit-field store and extract

and shifts, multiplies and divides to rtl instructions. 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/.

struct target_expmed* this_target_expmed = &default_target_expmed