GCC Middle and Back End API Reference
|
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "predict.h"
#include "memmodel.h"
#include "tm_p.h"
#include "optabs.h"
#include "expmed.h"
#include "regs.h"
#include "emit-rtl.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "dojump.h"
#include "explow.h"
#include "expr.h"
#include "langhooks.h"
#include "tree-vector-builder.h"
#include "recog.h"
Data Structures | |
struct | init_expmed_rtl |
Macros | |
#define | EXACT_POWER_OF_2_OR_ZERO_P(x) |
Functions | |
static bool | store_integral_bit_field (rtx, opt_scalar_int_mode, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, poly_uint64, poly_uint64, machine_mode, rtx, bool, bool) |
static void | store_fixed_bit_field (rtx, opt_scalar_int_mode, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, poly_uint64, poly_uint64, rtx, scalar_int_mode, bool) |
static void | store_fixed_bit_field_1 (rtx, scalar_int_mode, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, rtx, scalar_int_mode, bool) |
static void | store_split_bit_field (rtx, opt_scalar_int_mode, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, poly_uint64, poly_uint64, rtx, scalar_int_mode, bool) |
static rtx | extract_integral_bit_field (rtx, opt_scalar_int_mode, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, int, rtx, machine_mode, machine_mode, bool, bool) |
static rtx | extract_fixed_bit_field (machine_mode, rtx, opt_scalar_int_mode, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, rtx, int, bool) |
static rtx | extract_fixed_bit_field_1 (machine_mode, rtx, scalar_int_mode, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, rtx, int, bool) |
static rtx | lshift_value (machine_mode, unsigned HOST_WIDE_INT, int) |
static rtx | extract_split_bit_field (rtx, opt_scalar_int_mode, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, int, bool) |
static void | do_cmp_and_jump (rtx, rtx, enum rtx_code, machine_mode, rtx_code_label *) |
static rtx | expand_smod_pow2 (scalar_int_mode, rtx, HOST_WIDE_INT) |
static rtx | expand_sdiv_pow2 (scalar_int_mode, rtx, HOST_WIDE_INT) |
static rtx | mask_rtx (scalar_int_mode mode, int bitpos, int bitsize, bool complement) |
static void | init_expmed_one_conv (struct init_expmed_rtl *all, scalar_int_mode to_mode, scalar_int_mode from_mode, bool speed) |
static void | init_expmed_one_mode (struct init_expmed_rtl *all, machine_mode mode, int speed) |
void | init_expmed (void) |
rtx | negate_rtx (machine_mode mode, rtx x) |
static void | check_reverse_storage_order_support (void) |
static void | check_reverse_float_storage_order_support (void) |
rtx | flip_storage_order (machine_mode mode, rtx x) |
static rtx | narrow_bit_field_mem (rtx mem, opt_scalar_int_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, poly_uint64 bitregion_start, poly_uint64 bitregion_end, machine_mode fieldmode, unsigned HOST_WIDE_INT *new_bitnum) |
static bool | lowpart_bit_field_p (poly_uint64 bitnum, poly_uint64 bitsize, machine_mode struct_mode) |
static bool | strict_volatile_bitfield_p (rtx op0, unsigned HOST_WIDE_INT bitsize, unsigned HOST_WIDE_INT bitnum, scalar_int_mode fieldmode, poly_uint64 bitregion_start, poly_uint64 bitregion_end) |
static bool | simple_mem_bitfield_p (rtx op0, poly_uint64 bitsize, poly_uint64 bitnum, machine_mode mode, poly_uint64 *bytenum) |
static bool | store_bit_field_using_insv (const extraction_insn *insv, rtx op0, opt_scalar_int_mode op0_mode, unsigned HOST_WIDE_INT bitsize, unsigned HOST_WIDE_INT bitnum, rtx value, scalar_int_mode value_mode) |
static bool | store_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum, poly_uint64 bitregion_start, poly_uint64 bitregion_end, machine_mode fieldmode, rtx value, bool reverse, bool fallback_p, bool undefined_p) |
void | store_bit_field (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum, poly_uint64 bitregion_start, poly_uint64 bitregion_end, machine_mode fieldmode, rtx value, bool reverse, bool undefined_p) |
static rtx | convert_extracted_bit_field (rtx x, machine_mode mode, machine_mode tmode, bool unsignedp) |
static rtx | extract_bit_field_using_extv (const extraction_insn *extv, rtx op0, opt_scalar_int_mode op0_mode, unsigned HOST_WIDE_INT bitsize, unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target, machine_mode mode, machine_mode tmode) |
static rtx | extract_bit_field_as_subreg (machine_mode mode, rtx op0, machine_mode op0_mode, poly_uint64 bitsize, poly_uint64 bitnum) |
static rtx | extract_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum, int unsignedp, rtx target, machine_mode mode, machine_mode tmode, bool reverse, bool fallback_p, rtx *alt_rtl) |
rtx | extract_bit_field (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum, int unsignedp, rtx target, machine_mode mode, machine_mode tmode, bool reverse, rtx *alt_rtl) |
rtx | extract_low_bits (machine_mode mode, machine_mode src_mode, rtx src) |
void | expand_inc (rtx target, rtx inc) |
void | expand_dec (rtx target, rtx dec) |
static rtx | expand_shift_1 (enum tree_code code, machine_mode mode, rtx shifted, rtx amount, rtx target, int unsignedp, bool may_fail=false) |
rtx | expand_shift (enum tree_code code, machine_mode mode, rtx shifted, poly_int64 amount, rtx target, int unsignedp) |
rtx | maybe_expand_shift (enum tree_code code, machine_mode mode, rtx shifted, int amount, rtx target, int unsignedp) |
rtx | expand_variable_shift (enum tree_code code, 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 *, machine_mode mode) |
static rtx | expand_mult_const (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 (scalar_int_mode, rtx) |
static rtx | expmed_mult_highpart (scalar_int_mode, rtx, rtx, rtx, int, int) |
bool | choose_mult_variant (machine_mode mode, HOST_WIDE_INT val, struct algorithm *alg, enum mult_variant *variant, int mult_cost) |
rtx | expand_mult (machine_mode mode, rtx op0, rtx op1, rtx target, int unsignedp, bool no_libcall) |
int | mult_by_coeff_cost (HOST_WIDE_INT coeff, machine_mode mode, bool speed) |
rtx | expand_widening_mult (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) |
rtx | expand_mult_highpart_adjust (scalar_int_mode mode, rtx adj_operand, rtx op0, rtx op1, rtx target, int unsignedp) |
rtx | expmed_mult_highpart_optab (scalar_int_mode mode, rtx op0, rtx op1, rtx target, int unsignedp, int max_cost) |
rtx | expand_divmod (int rem_flag, enum tree_code code, machine_mode mode, rtx op0, rtx op1, rtx target, int unsignedp, enum optab_methods methods) |
tree | make_tree (tree type, rtx x) |
rtx | expand_and (machine_mode mode, rtx op0, rtx op1, rtx target) |
rtx | emit_cstore (rtx target, enum insn_code icode, enum rtx_code code, machine_mode mode, machine_mode compare_mode, int unsignedp, rtx x, rtx y, int normalizep, machine_mode target_mode) |
static rtx | emit_store_flag_1 (rtx target, enum rtx_code code, rtx op0, rtx op1, machine_mode mode, int unsignedp, int normalizep, machine_mode target_mode) |
rtx | emit_store_flag_int (rtx target, rtx subtarget, enum rtx_code code, rtx op0, rtx op1, scalar_int_mode mode, int unsignedp, int normalizep, rtx trueval) |
rtx | emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1, machine_mode mode, int unsignedp, int normalizep) |
rtx | emit_store_flag_force (rtx target, enum rtx_code code, rtx op0, rtx op1, machine_mode mode, int unsignedp, int normalizep) |
rtx | expand_rotate_as_vec_perm (machine_mode mode, rtx dst, rtx x, rtx amt) |
static enum rtx_code | equivalent_cmp_code (enum rtx_code code) |
void | canonicalize_comparison (machine_mode mode, enum rtx_code *code, rtx *imm) |
Variables | |
struct target_expmed | default_target_expmed |
static int | reverse_storage_order_supported = -1 |
static int | reverse_float_storage_order_supported = -1 |
#define EXACT_POWER_OF_2_OR_ZERO_P | ( | x | ) |
Test whether a value is zero of a power of two.
Referenced by expand_divmod(), expand_mult(), and expand_widening_mult().
|
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(), GET_MODE_BITSIZE(), GET_MODE_SIZE(), MEM_ALIGN, MEM_VOLATILE_P, narrow_bit_field_mem(), bit_field_mode_iterator::next_mode(), NULL_RTX, bit_field_mode_iterator::prefer_smaller_modes(), and word_mode.
Referenced by extract_integral_bit_field(), and store_integral_bit_field().
Choose the more appropiate immediate in scalar integer comparisons. The purpose of this is to end up with an immediate which can be loaded into a register in fewer moves, if possible. For each integer comparison there exists an equivalent choice: i) a > b or a >= b + 1 ii) a <= b or a < b + 1 iii) a >= b or a > b - 1 iv) a < b or a <= b - 1 MODE is the mode of the first operand. CODE points to the comparison code. IMM points to the rtx containing the immediate. *IMM must satisfy CONST_SCALAR_INT_P on entry and continues to satisfy CONST_SCALAR_INT_P on exit.
References wi::add(), can_create_pseudo_p, equivalent_cmp_code(), gen_move_insn(), gen_rtx_REG(), immed_wide_int_const(), insn_cost(), LAST_VIRTUAL_REGISTER, expand_operand::mode, wi::OVF_NONE, SCALAR_INT_MODE_P, SIGNED, wi::sub(), UNSIGNED, and unsigned_condition_p().
Referenced by emit_store_flag_1(), and prepare_cmp_insn().
|
static |
Check whether reverse FP storage order is supported on the target.
References FLOAT_WORDS_BIG_ENDIAN, reverse_float_storage_order_supported, and sorry().
Referenced by flip_storage_order().
|
static |
Check whether reverse storage order is supported on the target.
References reverse_storage_order_supported, and sorry().
Referenced by flip_storage_order().
bool choose_mult_variant | ( | machine_mode | mode, |
HOST_WIDE_INT | val, | ||
struct algorithm * | alg, | ||
enum mult_variant * | variant, | ||
int | mult_cost ) |
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, CHEAPER_MULT_COST, algorithm::cost, mult_cost::cost, GET_MODE_UNIT_BITSIZE, GET_MODE_UNIT_PRECISION, HOST_BITS_PER_INT, HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, HOST_WIDE_INT_MIN, mult_cost::latency, MULT_COST_LESS, neg_cost(), negate_variant, optimize_insn_for_speed_p(), and synth_mult().
Referenced by expand_expr_real_2(), expand_mult(), expand_widening_mult(), expmed_mult_highpart(), mult_by_coeff_cost(), and vect_synth_mult_by_constant().
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 ) |
Choose a minimal N + 1 bit approximation to 2**K / D that can be used to replace division by D, put the least significant N bits of the result in *MULTIPLIER_PTR, the value K - N in *POST_SHIFT_PTR, and return the most significant bit. The width of operations is N (should be <= HOST_BITS_PER_WIDE_INT), the needed precision is PRECISION (should be <= N). PRECISION should be as small as possible so this function can choose the multiplier more freely. If PRECISION is <= N - 1, the most significant bit returned by the function will be zero. Using this function, x / D is equal to (x*m) / 2**N >> (*POST_SHIFT_PTR), where m is the full N + 1 bit multiplier.
References ceil_log2(), wi::extract_uhwi(), gcc_assert, HOST_BITS_PER_DOUBLE_INT, HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, wi::set_bit_in_zero(), generic_wide_int< storage >::to_uhwi(), wi::udiv_trunc(), and wi::uhwi().
Referenced by expand_divmod(), expand_vector_divmod(), and vect_recog_divmod_pattern().
|
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(), gen_lowpart, GET_MODE, int_mode_for_mode(), expand_operand::mode, opt_mode< T >::require(), and SCALAR_INT_MODE_P.
Referenced by extract_bit_field(), extract_bit_field_1(), extract_bit_field_using_extv(), and extract_integral_bit_field().
|
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(), expand_operand::mode, NULL, NULL_RTX, and profile_probability::uninitialized().
Referenced by expand_divmod(), expand_sdiv_pow2(), and expand_smod_pow2().
rtx emit_cstore | ( | rtx | target, |
enum insn_code | icode, | ||
enum rtx_code | code, | ||
machine_mode | mode, | ||
machine_mode | compare_mode, | ||
int | unsignedp, | ||
rtx | x, | ||
rtx | y, | ||
int | normalizep, | ||
machine_mode | target_mode ) |
Helper function for emit_store_flag.
References as_a(), const1_rtx, convert_move(), create_fixed_operand(), create_output_operand(), delete_insns_since(), expand_and(), expand_shift(), expand_unop(), gcc_assert, gen_reg_rtx(), get_last_insn(), GET_MODE_BITSIZE(), GET_MODE_PRECISION(), last, maybe_expand_insn(), expand_operand::mode, NULL_RTX, prepare_operand(), STORE_FLAG_VALUE, expand_operand::target, targetm, val_signbit_known_set_p(), expand_operand::value, and y.
Referenced by emit_store_flag_1(), and expand_ccmp_expr().
rtx emit_store_flag | ( | rtx | target, |
enum rtx_code | code, | ||
rtx | op0, | ||
rtx | op1, | ||
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, const0_rtx, CONSTANT_P, delete_insns_since(), emit_conditional_move(), emit_store_flag_1(), emit_store_flag_int(), expand_binop(), gcc_assert, GEN_INT, gen_int_mode(), get_last_insn(), GET_MODE, GET_MODE_CLASS, HONOR_NANS(), HONOR_SNANS(), INTVAL, is_int_mode(), last, expand_operand::mode, NULL_RTX, OPTAB_WIDEN, optimize_insn_for_speed_p(), reverse_condition_maybe_unordered(), rtx_cost(), split_comparison(), STORE_FLAG_VALUE, expand_operand::target, and val_signbit_p().
Referenced by emit_store_flag_1(), emit_store_flag_force(), emit_store_flag_int(), expand_divmod(), expand_POPCOUNT(), expand_sdiv_pow2(), expand_smod_pow2(), noce_emit_store_flag(), and noce_try_sign_mask().
|
static |
A subroutine of emit_store_flag only including "tricks" that do not need a recursive call. These are kept separate to avoid infinite loops.
References as_a(), BITS_PER_WORD, canonicalize_comparison(), const0_rtx, const1_rtx, CONST_SCALAR_INT_P, constm1_rtx, convert_modes(), convert_move(), do_pending_stack_adjust(), emit_cstore(), emit_store_flag(), expand_binop(), expand_shift(), expand_unop(), FOR_EACH_WIDER_MODE_FROM, force_highpart_subreg(), force_subreg(), gen_reg_rtx(), GET_MODE, GET_MODE_BITSIZE(), GET_MODE_CLASS, GET_MODE_SIZE(), is_int_mode(), MEM_P, MEM_VOLATILE_P, expand_operand::mode, NULL_RTX, OPTAB_DIRECT, optab_handler(), STORE_FLAG_VALUE, swap_commutative_operands_p(), swap_condition(), expand_operand::target, unsigned_condition(), val_signbit_known_set_p(), val_signbit_p(), and word_mode.
Referenced by emit_store_flag(), and emit_store_flag_int().
rtx emit_store_flag_force | ( | rtx | target, |
enum rtx_code | code, | ||
rtx | op0, | ||
rtx | op1, | ||
machine_mode | mode, | ||
int | unsignedp, | ||
int | normalizep ) |
Like emit_store_flag, but always succeeds.
References can_compare_p(), ccp_jump, const0_rtx, const1_rtx, do_compare_rtx_and_jump(), emit_label(), emit_move_insn(), emit_store_flag(), FLOAT_MODE_P, GEN_INT, gen_label_rtx(), gen_reg_rtx(), GET_MODE, GET_MODE_CLASS, HONOR_NANS(), HONOR_SNANS(), expand_operand::mode, NULL, NULL_RTX, reg_mentioned_p(), REG_P, reverse_condition(), reverse_condition_maybe_unordered(), swap_commutative_operands_p(), swap_condition(), expand_operand::target, profile_probability::uninitialized(), and word_mode.
Referenced by convert_mode_scalar(), do_store_flag(), expand_atomic_compare_and_swap(), expand_atomic_test_and_set(), expand_binop(), expand_builtin_issignaling(), expand_divmod(), and expand_ifn_atomic_op_fetch_cmp_0().
rtx emit_store_flag_int | ( | rtx | target, |
rtx | subtarget, | ||
enum rtx_code | code, | ||
rtx | op0, | ||
rtx | op1, | ||
scalar_int_mode | mode, | ||
int | unsignedp, | ||
int | normalizep, | ||
rtx | trueval ) |
Subroutine of emit_store_flag that handles cases in which the operands are scalar integers. SUBTARGET is the target to use for temporary operations and TRUEVAL is the value to store when the condition is true. All other arguments are as for emit_store_flag.
References can_compare_p(), ccp_store_flag, const0_rtx, const1_rtx, convert_modes(), convert_move(), delete_insns_since(), emit_move_insn(), emit_store_flag(), emit_store_flag_1(), expand_binop(), expand_unop(), GEN_INT, gen_int_mode(), get_last_insn(), GET_MODE, GET_MODE_BITSIZE(), GET_MODE_SIZE(), INTVAL, last, maybe_expand_shift(), expand_operand::mode, optab_handler(), OPTAB_WIDEN, optimize_insn_for_speed_p(), reverse_condition(), rtx_cost(), rtx_equal_p(), STORE_FLAG_VALUE, expand_operand::target, and word_mode.
Referenced by emit_store_flag().
Helper function for canonicalize_cmp_for_target. Swap between inclusive and exclusive ranges in order to create an equivalent comparison. See canonicalize_cmp_for_target for the possible cases.
Referenced by canonicalize_comparison().
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(), GET_MODE, OPTAB_LIB_WIDEN, and simplify_binary_operation().
Referenced by emit_cstore(), expand_builtin_extract_return_addr(), expand_expr_real_2(), expand_mult_highpart_adjust(), optimize_bitfield_assignment_op(), and reduce_to_bit_field_precision().
Subtract DEC from TARGET.
References emit_move_insn(), expand_binop(), GET_MODE, OPTAB_LIB_WIDEN, expand_operand::target, and expand_operand::value.
Referenced by expand_divmod().
rtx expand_divmod | ( | int | rem_flag, |
enum tree_code | code, | ||
machine_mode | mode, | ||
rtx | op0, | ||
rtx | op1, | ||
rtx | target, | ||
int | unsignedp, | ||
enum optab_methods | methods ) |
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(), as_a(), BITS_PER_WORD, choose_multiplier(), const0_rtx, const1_rtx, CONST_INT_P, constm1_rtx, convert_modes(), copy_to_mode_reg(), ctz_or_zero(), delete_insns_since(), do_cmp_and_jump(), emit_barrier(), emit_jump_insn(), emit_label(), emit_move_insn(), emit_store_flag(), emit_store_flag_force(), EXACT_POWER_OF_2_OR_ZERO_P, 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(), FOR_EACH_MODE_FROM, force_operand(), force_reg(), gcc_assert, gcc_unreachable, gen_int_mode(), gen_label_rtx(), gen_lowpart, gen_reg_rtx(), get_last_insn(), GET_MODE, GET_MODE_BITSIZE(), GET_MODE_CLASS, HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, HOST_WIDE_INT_M1U, HOST_WIDE_INT_MIN, HWI_COMPUTABLE_MODE_P(), INTVAL, invert_mod2n(), last, MEM_P, MEM_VOLATILE_P, mul_cost(), wi::neg(), NULL_RTX, OPTAB_DIRECT, optab_handler(), OPTAB_LIB, OPTAB_LIB_WIDEN, optab_libfunc(), OPTAB_WIDEN, optimize_insn_for_speed_p(), plus_constant(), wi::popcount(), REG_FUNCTION_VALUE_P, reg_mentioned_p(), REG_P, sdiv_cost(), sdiv_pow2_cheap(), set_dst_reg_note(), shift_cost(), sign_expand_binop(), smod_pow2_cheap(), targetm, generic_wide_int< storage >::to_uhwi(), and udiv_cost().
Referenced by align_dynamic_address(), expand_divmod(), expand_doubleword_divmod(), expand_doubleword_mod(), expand_expr_divmod(), force_operand(), and round_push().
Add INC into TARGET.
References emit_move_insn(), expand_binop(), GET_MODE, OPTAB_LIB_WIDEN, expand_operand::target, and expand_operand::value.
Referenced by expand_divmod(), and expand_sdiv_pow2().
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(), CONST0_RTX, CONST1_RTX, CONST_DOUBLE_AS_FLOAT_P, CONST_DOUBLE_AS_INT_P, CONST_DOUBLE_REAL_VALUE, CONST_INT_P, CONST_WIDE_INT_P, CONSTANT_P, CONSTM1_RTX, dconst2, wi::exact_log2(), EXACT_POWER_OF_2_OR_ZERO_P, expand_binop(), expand_mult_const(), expand_shift(), expand_unop(), floor_log2(), force_reg(), gcc_assert, gen_raw_REG(), GET_MODE, GET_MODE_CLASS, GET_MODE_UNIT_BITSIZE, HOST_BITS_PER_WIDE_INT, INTEGRAL_MODE_P, INTVAL, LAST_VIRTUAL_REGISTER, neg_cost(), NULL_RTX, optab_handler(), OPTAB_LIB_WIDEN, OPTAB_WIDEN, optimize_insn_for_speed_p(), real_equal(), SCALAR_INT_MODE_P, set_src_cost(), shift, and unwrap_const_vec_duplicate().
Referenced by align_dynamic_address(), builtin_memset_gen_str(), can_widen_mult_without_libcall(), expand_divmod(), expand_expr_real_2(), force_operand(), index_part_to_reg(), and round_push().
|
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, as_a(), CONST0_RTX, copy_to_mode_reg(), emit_move_insn(), expand_shift(), expand_unop(), force_operand(), force_reg(), gcc_assert, gcc_unreachable, gen_lowpart, GET_CODE, get_last_insn(), GET_MODE, GET_MODE_INNER, GET_MODE_MASK, GET_MODE_PRECISION(), HOST_WIDE_INT_1U, immed_wide_int_const(), algorithm::log, log(), negate_variant, NULL_RTX, algorithm::op, algorithm::ops, paradoxical_subreg_p(), SCALAR_INT_MODE_P, set_dst_reg_note(), SUBREG_REG, and wi::uhwi().
Referenced by expand_mult(), expand_widening_mult(), and expmed_mult_highpart().
rtx expand_mult_highpart_adjust | ( | scalar_int_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(), force_operand(), GET_MODE_BITSIZE(), and NULL_RTX.
Referenced by expand_expr_real_2(), and expmed_mult_highpart_optab().
Expand a vector (left) rotate of MODE of X by an immediate AMT as a vector permute operation. Emit code to put the result in DST if successfull and return it. Otherwise return NULL. This is intended to implement vector rotates by byte amounts using vector permutes when the target does not offer native vector rotate operations.
References CONST_INT_P, emit_move_insn(), expand_vec_perm_const(), GET_MODE_INNER, GET_MODE_SIZE(), i, INTVAL, lowpart_subreg(), expand_operand::mode, int_vector_builder< T >::new_vector(), NULL_RTX, qimode_for_vec_perm(), and unwrap_const_vec_duplicate().
|
static |
Expand signed division of OP0 by a power of two D in mode MODE. This routine is only called for positive values of D.
References BITS_PER_WORD, const0_rtx, copy_to_mode_reg(), COSTS_N_INSNS, do_cmp_and_jump(), emit_conditional_move(), emit_insn(), emit_label(), emit_store_flag(), end_sequence(), expand_binop(), expand_inc(), expand_shift(), floor_log2(), force_reg(), gen_int_mode(), gen_label_rtx(), gen_reg_rtx(), get_insns(), GET_MODE_BITSIZE(), NULL_RTX, OPTAB_LIB_WIDEN, optimize_insn_for_speed_p(), shift_cost(), and start_sequence().
Referenced by expand_divmod().
rtx expand_shift | ( | enum tree_code | code, |
machine_mode | mode, | ||
rtx | shifted, | ||
poly_int64 | amount, | ||
rtx | target, | ||
int | unsignedp ) |
Output a shift instruction for expression code CODE, with SHIFTED being the rtx for the value to shift, and AMOUNT the amount to shift by. Store the result in the rtx TARGET, if that is convenient. If UNSIGNEDP is nonzero, do a logical shift; otherwise, arithmetic. Return the rtx for where the value is.
References expand_shift_1(), gen_int_shift_amount(), expand_operand::mode, and expand_operand::target.
Referenced by assign_parm_setup_block(), convert_mode_scalar(), emit_cstore(), emit_group_load_1(), emit_group_store(), emit_library_call_value_1(), emit_store_flag_1(), expand_abs_nojump(), expand_arith_overflow_result_store(), expand_builtin_issignaling(), expand_builtin_signbit(), expand_divmod(), expand_expr_real_1(), expand_float(), expand_mul_overflow(), expand_mult(), expand_mult_const(), expand_mult_highpart_adjust(), expand_one_cmpl_abs_nojump(), expand_sdiv_pow2(), expand_ubsan_result_store(), expand_unop(), expand_widening_mult(), extract_fixed_bit_field_1(), extract_high_half(), extract_integral_bit_field(), extract_split_bit_field(), load_register_parameters(), optimize_bitfield_assignment_op(), reduce_to_bit_field_precision(), resolve_shift_zext(), store_field(), store_fixed_bit_field_1(), and widen_bswap().
|
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. If that cannot be done, abort the compilation unless MAY_FAIL is true, in which case 0 is returned.
References add_cost(), const0_rtx, CONST_INT_P, expand_binop(), expand_shift_1(), expand_unop(), force_reg(), gcc_assert, gen_int_mode(), gen_int_shift_amount(), GET_CODE, GET_MODE, GET_MODE_BITSIZE(), GET_MODE_INNER, GET_MODE_PRECISION(), GET_MODE_SIZE(), i, INTVAL, MAX_BITS_PER_WORD, MAX_COST, expand_operand::mode, NULL_RTX, OPTAB_DIRECT, optab_handler(), OPTAB_LIB_WIDEN, OPTAB_MUST_WIDEN, OPTAB_WIDEN, optimize_insn_for_speed_p(), reverse_rotate_by_imm_p(), SCALAR_INT_MODE_P, shift_cost(), SHIFT_COUNT_TRUNCATED, simplify_gen_binary(), simplify_gen_unary(), subreg_lowpart_p(), SUBREG_REG, expand_operand::target, and VECTOR_MODE_P.
Referenced by expand_shift(), expand_shift_1(), expand_variable_shift(), and maybe_expand_shift().
|
static |
Expand signed modulus of OP0 by a power of two D in mode MODE.
References const0_rtx, const1_rtx, COSTS_N_INSNS, do_cmp_and_jump(), emit_label(), emit_move_insn(), emit_store_flag(), expand_binop(), floor_log2(), force_reg(), gen_int_mode(), gen_int_shift_amount(), gen_label_rtx(), gen_reg_rtx(), GET_MODE_BITSIZE(), GET_MODE_PRECISION(), HOST_WIDE_INT_1, immed_wide_int_const(), wi::mask(), NULL_RTX, optab_handler(), OPTAB_LIB_WIDEN, optimize_insn_for_speed_p(), wi::set_bit(), set_src_cost(), and shift.
Referenced by expand_divmod().
rtx expand_variable_shift | ( | enum tree_code | code, |
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(), expand_shift_1(), expand_operand::mode, and expand_operand::target.
Referenced by expand_expr_real_2().
rtx expand_widening_mult | ( | 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(), CONST0_RTX, 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().
Referenced by expand_expr_real_2().
|
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 cannot 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(), BITS_PER_WORD, choose_mult_variant(), convert_to_mode(), algorithm::cost, mult_cost::cost, expand_mult_const(), expmed_mult_highpart_optab(), extract_high_half(), force_operand(), gcc_assert, gen_int_mode(), GET_MODE_BITSIZE(), GET_MODE_MASK, GET_MODE_WIDER_MODE(), HWI_COMPUTABLE_MODE_P(), INTVAL, optimize_insn_for_speed_p(), and shift_cost().
Referenced by expand_divmod().
rtx expmed_mult_highpart_optab | ( | scalar_int_mode | mode, |
rtx | op0, | ||
rtx | op1, | ||
rtx | target, | ||
int | unsignedp, | ||
int | max_cost ) |
Like expmed_mult_highpart, but only consider using multiplication optab.
References add_cost(), BITS_PER_WORD, convert_modes(), convert_optab_handler(), emit_insn(), end_sequence(), expand_binop(), expand_mult_highpart_adjust(), extract_high_half(), get_insns(), GET_MODE_BITSIZE(), GET_MODE_WIDER_MODE(), insns, mul_cost(), mul_highpart_cost(), mul_widen_cost(), NULL_RTX, OPTAB_DIRECT, optab_handler(), OPTAB_WIDEN, optimize_insn_for_speed_p(), shift_cost(), and start_sequence().
Referenced by expand_mult_highpart(), and expmed_mult_highpart().
rtx extract_bit_field | ( | rtx | str_rtx, |
poly_uint64 | bitsize, | ||
poly_uint64 | bitnum, | ||
int | unsignedp, | ||
rtx | target, | ||
machine_mode | mode, | ||
machine_mode | tmode, | ||
bool | reverse, | ||
rtx * | alt_rtl ) |
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 REVERSE is true, the extraction is to be done in reverse order. 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. If the result can be stored at TARGET, and ALT_RTL is non-NULL, then *ALT_RTL is set to TARGET (before legitimziation).
References adjust_bitfield_address, convert_extracted_bit_field(), copy_to_reg(), extract_bit_field_1(), flip_storage_order(), gcc_assert, GET_MODE, GET_MODE_BITSIZE(), is_a(), poly_int< N, C >::is_constant(), expand_operand::mode, narrow_bit_field_mem(), strict_volatile_bitfield_p(), and expand_operand::target.
Referenced by assign_parm_setup_reg(), copy_blkmode_from_reg(), copy_blkmode_to_reg(), emit_group_load_1(), expand_expr_real_1(), expand_misaligned_mem_ref(), expand_single_bit_test(), load_register_parameters(), read_complex_part(), store_field(), store_integral_bit_field(), and store_unaligned_arguments_into_pseudos().
|
static |
A subroutine of extract_bit_field, with the same arguments. If UNSIGNEDP is -1, the result need not be sign or zero extended. If FALLBACK_P is true, fall back to extract_fixed_bit_field if we can find no other means of implementing the operation. if FALLBACK_P is false, return NULL instead.
References adjust_bitfield_address, adjust_bitfield_address_size, assign_stack_temp(), bits_to_bytes_round_down, bits_to_bytes_round_up, convert_extracted_bit_field(), convert_optab_handler(), create_input_operand(), create_integer_operand(), create_output_operand(), opt_mode< T >::else_blk(), emit_move_insn(), opt_mode< T >::exists(), extract_bit_field_as_subreg(), extract_integral_bit_field(), flip_storage_order(), FOR_EACH_MODE_FROM, force_reg(), gcc_assert, gen_lowpart, gen_reg_rtx(), GET_CODE, GET_MODE, GET_MODE_BITSIZE(), GET_MODE_CLASS, GET_MODE_INNER, GET_MODE_PRECISION(), GET_MODE_SIZE(), GET_MODE_UNIT_BITSIZE, GET_MODE_UNIT_PRECISION, GET_MODE_UNIT_SIZE, insn_data, int_mode_for_mode(), poly_int< N, C >::is_constant(), known_eq, known_ge, maybe_expand_insn(), maybe_gt, MEM_P, MEM_SIZE, expand_operand::mode, mode_for_size(), new_mode(), num_trailing_bits, REG_P, related_vector_mode(), SCALAR_INT_MODE_P, simple_mem_bitfield_p(), SUBREG_BYTE, SUBREG_REG, expand_operand::target, targetm, poly_int< N, C >::to_constant(), expand_operand::value, and VECTOR_MODE_P.
Referenced by extract_bit_field(), and extract_integral_bit_field().
|
static |
See whether it would be valid to extract the part of OP0 with mode OP0_MODE described by BITNUM and BITSIZE into a value of mode MODE using a subreg operation. Return the subreg if so, otherwise return null.
References force_subreg(), GET_MODE_BITSIZE(), known_eq, lowpart_bit_field_p(), expand_operand::mode, NULL_RTX, and TRULY_NOOP_TRUNCATION_MODES_P.
Referenced by extract_bit_field_1().
|
static |
Try to use an ext(z)v pattern to extract a field from OP0. Return the extracted value on success, otherwise return null. EXTV describes the extraction instruction to use. If OP0_MODE is defined, it is the mode of OP0, otherwise OP0 is a BLKmode MEM. 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_if_possible(), gen_lowpart_SUBREG(), gen_reg_rtx(), GET_CODE, GET_MODE, GET_MODE_BITSIZE(), extraction_insn::icode, maybe_expand_insn(), MEM_P, expand_operand::mode, narrow_bit_field_mem(), NULL_RTX, partial_subreg_p(), REG_P, opt_mode< T >::require(), extraction_insn::struct_mode, expand_operand::target, TRULY_NOOP_TRUNCATION_MODES_P, and expand_operand::value.
Referenced by extract_integral_bit_field().
|
static |
Use shifts and boolean operations to extract a field of BITSIZE bits from bit BITNUM of OP0. If OP0_MODE is defined, it is the mode of OP0, otherwise OP0 is a BLKmode MEM. UNSIGNEDP is nonzero for an unsigned bit field (don't sign-extend value). If REVERSE is true, the extraction is to be done in reverse order. 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 BITS_PER_WORD, extract_fixed_bit_field_1(), extract_split_bit_field(), get_best_mode(), MEM_ALIGN, MEM_P, MEM_VOLATILE_P, expand_operand::mode, narrow_bit_field_mem(), opt_mode< T >::require(), and expand_operand::target.
Referenced by extract_integral_bit_field(), extract_split_bit_field(), and store_split_bit_field().
|
static |
Helper function for extract_fixed_bit_field, extracts the bit field always using MODE, which is the mode of OP0. If UNSIGNEDP is -1, the result need not be sign or zero extended. The other arguments are as for extract_fixed_bit_field.
References as_a(), convert_to_mode(), expand_binop(), expand_shift(), flip_storage_order(), FOR_EACH_MODE_IN_CLASS, force_reg(), GET_MODE_BITSIZE(), mask_rtx(), expand_operand::mode, new_mode(), OPTAB_LIB_WIDEN, REG_P, opt_mode< T >::require(), and expand_operand::target.
Referenced by extract_fixed_bit_field().
|
static |
Subroutine of expmed_mult_highpart. Return the MODE high part of OP.
References convert_modes(), expand_shift(), gen_highpart(), GET_MODE_BITSIZE(), GET_MODE_WIDER_MODE(), algorithm::op, and word_mode.
Referenced by expmed_mult_highpart(), and expmed_mult_highpart_optab().
|
static |
Subroutine of extract_bit_field_1, with the same arguments, except that BITSIZE and BITNUM are constant. Handle cases specific to integral modes. If OP0_MODE is defined, it is the mode of OP0, otherwise OP0 is a BLKmode MEM.
References adjust_bit_field_mem_for_reg(), BITS_PER_WORD, COMPLEX_MODE_P, const0_rtx, convert_extracted_bit_field(), copy_to_reg(), delete_insns_since(), emit_clobber(), emit_move_insn(), EP_extv, EP_extzv, expand_shift(), extract_bit_field_1(), extract_bit_field_using_extv(), extract_fixed_bit_field(), extract_split_bit_field(), flip_storage_order(), force_subreg(), gcc_assert, gen_reg_rtx(), get_best_mem_extraction_insn(), get_best_reg_extraction_insn(), get_last_insn(), GET_MODE, GET_MODE_BITSIZE(), GET_MODE_SIZE(), HARD_REGISTER_P, i, int_mode_for_mode(), last, MAX, MEM_P, MIN, expand_operand::mode, NULL, NULL_RTX, operand_subword(), reg_mentioned_p(), REG_P, opt_mode< T >::require(), expand_operand::target, poly_int< N, C >::to_constant(), valid_multiword_target_p(), and word_mode.
Referenced by extract_bit_field_1().
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 TARGET_TRULY_NOOP_TRUNCATION). In other words, this routine performs a computation, whereas the gen_lowpart* routines are conceptually lvalue or rvalue subreg operations.
References CONSTANT_P, convert_modes(), force_reg(), gen_lowpart, gen_lowpart_common(), gen_rtx_SUBREG(), GET_MODE, GET_MODE_BITSIZE(), GET_MODE_CLASS, int_mode_for_mode(), known_eq, expand_operand::mode, NULL_RTX, simplify_subreg(), subreg_lowpart_offset(), targetm, and validate_subreg().
Referenced by find_shift_sequence(), and get_stored_val().
|
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. If OP0_MODE is defined, it is the mode of OP0, otherwise OP0 is a BLKmode MEM. If REVERSE is true, the extraction is to be done in reverse order.
References BITS_PER_WORD, expand_binop(), expand_shift(), extract_fixed_bit_field(), GET_CODE, MEM_ALIGN, MIN, NULL_RTX, offset, operand_subword_force(), OPTAB_LIB_WIDEN, REG_P, opt_mode< T >::require(), SUBREG_P, and word_mode.
Referenced by extract_fixed_bit_field(), and extract_integral_bit_field().
Return an rtx representing value of X with reverse storage order. MODE is the intended mode of the result, useful if X is a CONST_INT.
References check_reverse_float_storage_order_support(), check_reverse_storage_order_support(), COMPLEX_MODE_P, expand_unop(), flip_storage_order(), FLOAT_MODE_P, gen_lowpart, GET_MODE_INNER, GET_MODE_NAME, GET_MODE_PRECISION(), int_mode_for_size(), is_a(), alg_hash_entry::mode, NULL_RTX, read_complex_part(), reverse_float_storage_order_supported, reverse_storage_order_supported, simplify_unary_operation(), sorry(), targetm, and UNLIKELY.
Referenced by assemble_real(), expand_assignment(), expand_expr_real_1(), extract_bit_field(), extract_bit_field_1(), extract_fixed_bit_field_1(), extract_integral_bit_field(), flip_storage_order(), optimize_bitfield_assignment_op(), output_constant(), store_bit_field(), store_bit_field_1(), store_expr(), store_field(), and store_fixed_bit_field_1().
void init_expmed | ( | void | ) |
In expmed.cc
References alg_hash_entry_ptr(), alg_hash_used_p(), init_expmed_rtl::cint, const0_rtx, crtl, default_rtl_profile(), GEN_INT, gen_raw_REG(), ggc_free(), HOST_WIDE_INT_1, init_expmed_one_mode(), LAST_VIRTUAL_REGISTER, MAX_BITS_PER_WORD, init_expmed_rtl::mult, init_expmed_rtl::neg, NUM_ALG_HASH_ENTRIES, init_expmed_rtl::plus, init_expmed_rtl::pow2, init_expmed_rtl::reg, init_expmed_rtl::sdiv, init_expmed_rtl::sdiv_32, set_alg_hash_used_p(), set_src_cost(), set_zero_cost(), init_expmed_rtl::shift, init_expmed_rtl::shift_add, init_expmed_rtl::shift_mult, init_expmed_rtl::shift_sub0, init_expmed_rtl::shift_sub1, init_expmed_rtl::smod_32, init_expmed_rtl::trunc, init_expmed_rtl::udiv, init_expmed_rtl::wide_lshr, init_expmed_rtl::wide_mult, init_expmed_rtl::wide_trunc, and init_expmed_rtl::zext.
Referenced by backend_init_target().
|
static |
References GET_MODE_CLASS, GET_MODE_PRECISION(), pow2p_hwi(), PUT_MODE(), init_expmed_rtl::reg, set_convert_cost(), set_src_cost(), init_expmed_rtl::trunc, and init_expmed_rtl::zext.
Referenced by init_expmed_one_mode().
|
static |
References add_cost(), as_a(), init_expmed_rtl::cint, gen_int_shift_amount(), GET_MODE_CLASS, GET_MODE_UNIT_BITSIZE, GET_MODE_WIDER_MODE(), init_expmed_one_conv(), is_a(), MAX_BITS_PER_WORD, MIN, init_expmed_rtl::mult, init_expmed_rtl::neg, init_expmed_rtl::plus, init_expmed_rtl::pow2, PUT_MODE(), init_expmed_rtl::reg, init_expmed_rtl::sdiv, init_expmed_rtl::sdiv_32, set_add_cost(), set_mul_cost(), set_mul_highpart_cost(), set_mul_widen_cost(), set_neg_cost(), set_sdiv_cost(), set_sdiv_pow2_cheap(), set_shift_cost(), set_shiftadd_cost(), set_shiftsub0_cost(), set_shiftsub1_cost(), set_smod_pow2_cheap(), set_src_cost(), set_udiv_cost(), init_expmed_rtl::shift, init_expmed_rtl::shift_add, init_expmed_rtl::shift_mult, init_expmed_rtl::shift_sub0, init_expmed_rtl::shift_sub1, init_expmed_rtl::smod_32, init_expmed_rtl::trunc, init_expmed_rtl::udiv, init_expmed_rtl::wide_lshr, init_expmed_rtl::wide_mult, init_expmed_rtl::wide_trunc, XEXP, and init_expmed_rtl::zext.
Referenced by init_expmed().
|
static |
Compute the inverse of X mod 2**N, i.e., find Y such that X * Y is congruent to 1 modulo 2**N, assuming that X is odd. Bézout's lemma guarantees that Y exists for any given positive N.
References gcc_assert, HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, HOST_WIDE_INT_M1U, and y.
Referenced by expand_divmod().
|
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.
References GET_MODE_BITSIZE(), known_eq, and REGMODE_NATURAL_SIZE.
Referenced by extract_bit_field_as_subreg(), and store_integral_bit_field().
|
static |
Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value VALUE << BITPOS.
References immed_wide_int_const(), wi::lshift(), expand_operand::mode, and expand_operand::value.
Referenced by store_fixed_bit_field_1().
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 tree_vector_builder::build(), build2(), build_decl(), build_fold_addr_expr, build_real(), CONST_DOUBLE_LOW, CONST_DOUBLE_REAL_VALUE, CONST_POLY_INT_P, const_poly_int_value(), CONST_VECTOR_ELT, CONST_VECTOR_NELTS_PER_PATTERN, CONST_VECTOR_NPATTERNS, convert_memory_address_addr_space(), count, vector_builder< T, Shape, Derived >::encoded_nelts(), fold_build1, fold_build2, fold_convert, wide_int_storage::from_array(), GET_CODE, GET_MODE, HOST_BITS_PER_WIDE_INT, i, make_tree(), NULL_TREE, POINTER_TYPE_P, RTL_LOCATION, SCALAR_INT_TYPE_MODE, signed_type_for(), STATIC_ASSERT, SYMBOL_REF_DECL, TARGET_SUPPORTS_WIDE_INT, TREE_CODE, TREE_TYPE, type(), TYPE_ADDR_SPACE, lang_hooks_for_types::type_for_mode, TYPE_MODE, lang_hooks::types, unsigned_type_for(), wide_int_to_tree(), and XEXP.
Referenced by assign_parm_setup_reg(), emit_block_op_via_libcall(), expand_asm_stmt(), expand_builtin_cexpi(), expand_call(), expand_DIVMOD(), expand_doubleword_mod(), expand_ifn_atomic_bit_test_and(), expand_ifn_atomic_compare_exchange_into_call(), expand_mul_overflow(), expand_sjlj_dispatch_table(), expand_vector_ubsan_overflow(), initialize_argument_information(), make_tree(), maybe_optimize_mod_cmp(), maybe_optimize_pow2p_mod_cmp(), set_storage_via_libcall(), sjlj_emit_function_enter(), and store_expr().
|
inlinestatic |
Return a constant integer 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 GET_MODE_PRECISION(), immed_wide_int_const(), and wi::shifted_mask().
Referenced by add_mask_and_len_args(), extract_fixed_bit_field_1(), simplify_shift_const_1(), and store_fixed_bit_field_1().
rtx maybe_expand_shift | ( | enum tree_code | code, |
machine_mode | mode, | ||
rtx | shifted, | ||
int | amount, | ||
rtx | target, | ||
int | unsignedp ) |
Likewise, but return 0 if that cannot be done.
References expand_shift_1(), GEN_INT, expand_operand::mode, and expand_operand::target.
Referenced by convert_mode_scalar(), and emit_store_flag_int().
int mult_by_coeff_cost | ( | HOST_WIDE_INT | coeff, |
machine_mode | mode, | ||
bool | speed ) |
Return a cost estimate for multiplying a register by the given COEFFicient in the given MODE and SPEED.
References choose_mult_variant(), algorithm::cost, mult_cost::cost, gen_raw_REG(), LAST_VIRTUAL_REGISTER, and set_src_cost().
Referenced by analyze_increments(), force_expr_to_var_cost(), get_address_cost(), get_computation_cost(), most_expensive_mult_to_index(), and stmt_cost().
|
static |
If MODE is set, 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 not set, return a BLKmode reference to every byte in the bitfield. Set *NEW_BITNUM to the bit position of the field within the new memory.
References adjust_bitfield_address, adjust_bitfield_address_size, GET_MODE_BITSIZE(), alg_hash_entry::mode, and offset.
Referenced by adjust_bit_field_mem_for_reg(), extract_bit_field(), extract_bit_field_using_extv(), extract_fixed_bit_field(), store_bit_field(), store_bit_field_using_insv(), and store_fixed_bit_field().
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(), alg_hash_entry::mode, NULL_RTX, 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 |
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. Store the byte offset in *BYTENUM if so.
References GET_MODE_ALIGNMENT, GET_MODE_BITSIZE(), known_eq, MEM_ALIGN, MEM_P, alg_hash_entry::mode, and targetm.
Referenced by extract_bit_field_1(), and store_bit_field_1().
void store_bit_field | ( | rtx | str_rtx, |
poly_uint64 | bitsize, | ||
poly_uint64 | bitnum, | ||
poly_uint64 | bitregion_start, | ||
poly_uint64 | bitregion_end, | ||
machine_mode | fieldmode, | ||
rtx | value, | ||
bool | reverse, | ||
bool | undefined_p ) |
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. If REVERSE is true, the store is to be done in reverse order. If UNDEFINED_P is true then STR_RTX is currently undefined.
References adjust_bitfield_address, adjust_bitfield_address_size, bits_to_bytes_round_up, copy_to_reg(), emit_move_insn(), flip_storage_order(), gcc_assert, gcc_unreachable, get_best_mode(), GET_MODE_BITSIZE(), INT_MAX, is_a(), poly_int< N, C >::is_constant(), MEM_ALIGN, MEM_P, MEM_VOLATILE_P, narrow_bit_field_mem(), offset, store_bit_field_1(), strict_volatile_bitfield_p(), and expand_operand::value.
Referenced by copy_blkmode_from_reg(), copy_blkmode_to_reg(), emit_group_store(), expand_assignment(), expand_expr_real_2(), noce_emit_move_insn(), store_expr(), store_field(), store_unaligned_arguments_into_pseudos(), and write_complex_part().
|
static |
A subroutine of store_bit_field, with the same arguments. Return true if the operation could be implemented. If FALLBACK_P is true, fall back to store_fixed_bit_field if we have no other way of implementing the operation. If FALLBACK_P is false, return false instead. if UNDEFINED_P is true then STR_RTX is undefined and may be set using a subreg instead.
References adjust_address, adjust_bitfield_address, adjust_bitfield_address_size, assign_stack_temp(), create_fixed_operand(), create_input_operand(), create_integer_operand(), opt_mode< T >::else_blk(), emit_move_insn(), opt_mode< T >::exists(), flip_storage_order(), force_subreg(), gen_lowpart, GET_CODE, GET_MODE, GET_MODE_BITSIZE(), GET_MODE_INNER, GET_MODE_PRECISION(), GET_MODE_SIZE(), int_mode_for_mode(), known_eq, known_ge, maybe_expand_insn(), MEM_P, MEM_SIZE, optab_handler(), REG_P, REGMODE_NATURAL_SIZE, opt_mode< T >::require(), simple_mem_bitfield_p(), simplify_gen_subreg(), store_bit_field_1(), store_integral_bit_field(), subreg_memory_offset(), SUBREG_REG, poly_int< N, C >::to_constant(), expand_operand::value, and VECTOR_MODE_P.
Referenced by store_bit_field(), store_bit_field_1(), and store_integral_bit_field().
|
static |
Try to use instruction INSV to store VALUE into a field of OP0. If OP0_MODE is defined, it is the mode of OP0, otherwise OP0 is a BLKmode MEM. VALUE_MODE is the mode of VALUE. BITSIZE and BITNUM are as for store_bit_field.
References CONST_INT_P, CONSTANT_P, convert_move(), create_fixed_operand(), create_input_operand(), create_integer_operand(), delete_insns_since(), emit_move_insn(), extraction_insn::field_mode, force_reg(), gcc_assert, gen_int_mode(), gen_lowpart, gen_lowpart_if_possible(), gen_lowpart_SUBREG(), gen_reg_rtx(), gen_rtx_SUBREG(), GET_CODE, get_last_insn(), GET_MODE, GET_MODE_BITSIZE(), GET_MODE_SIZE(), extraction_insn::icode, INTVAL, last, maybe_expand_insn(), MEM_P, narrow_bit_field_mem(), REG_P, opt_mode< T >::require(), simplify_gen_subreg(), simplify_gen_unary(), simplify_subreg(), extraction_insn::struct_mode, SUBREG_BYTE, SUBREG_REG, targetm, TRULY_NOOP_TRUNCATION_MODES_P, validate_subreg(), expand_operand::value, and warning().
Referenced by store_integral_bit_field().
|
static |
Use shifts and boolean operations to store VALUE into a bit field of width BITSIZE in OP0, starting at bit BITNUM. If OP0_MODE is defined, it is the mode of OP0, otherwise OP0 is a BLKmode MEM. VALUE_MODE is the mode of VALUE. If REVERSE is true, the store is to be done in reverse order.
References BITS_PER_WORD, opt_mode< T >::exists(), get_best_mode(), GET_MODE_BITSIZE(), MEM_ALIGN, MEM_P, MEM_VOLATILE_P, narrow_bit_field_mem(), opt_mode< T >::require(), store_fixed_bit_field_1(), store_split_bit_field(), and expand_operand::value.
Referenced by store_integral_bit_field(), and store_split_bit_field().
|
static |
Helper function for store_fixed_bit_field, stores the bit field always using MODE, which is the mode of OP0. The other arguments are as for store_fixed_bit_field.
References CONST_INT_P, convert_to_mode(), copy_rtx(), emit_move_insn(), expand_binop(), expand_shift(), flip_storage_order(), force_reg(), GET_MODE_BITSIZE(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, HOST_WIDE_INT_M1U, lshift_value(), mask_rtx(), expand_operand::mode, NULL_RTX, OPTAB_LIB_WIDEN, UINTVAL, and expand_operand::value.
Referenced by store_fixed_bit_field().
|
static |
Subroutine of store_bit_field_1, with the same arguments, except that BITSIZE and BITNUM are constant. Handle cases specific to integral modes. If OP0_MODE is defined, it is the mode of OP0, otherwise OP0 is a BLKmode MEM.
References adjust_bit_field_mem_for_reg(), as_a(), BITS_PER_WORD, copy_to_reg(), create_convert_operand_to(), create_fixed_operand(), delete_insns_since(), emit_move_insn(), EP_insv, extract_bit_field(), gcc_assert, gen_lowpart, gen_reg_rtx(), gen_rtx_SUBREG(), get_best_mem_extraction_insn(), get_best_reg_extraction_insn(), GET_CODE, get_last_insn(), GET_MODE, GET_MODE_BITSIZE(), GET_MODE_CLASS, GET_MODE_SIZE(), HARD_REGISTER_P, hard_regno_nregs(), i, int_mode_for_mode(), is_a(), known_eq, known_ge, last, lowpart_bit_field_p(), MAX, maybe_expand_insn(), MEM_P, MIN, NULL, NULL_RTX, operand_subword_force(), optab_handler(), paradoxical_subreg_p(), REG_P, REGNO, opt_mode< T >::require(), simplify_gen_subreg(), smallest_int_mode_for_size(), store_bit_field_1(), store_bit_field_using_insv(), store_fixed_bit_field(), store_split_bit_field(), SUBREG_REG, validate_subreg(), expand_operand::value, and word_mode.
Referenced by store_bit_field_1().
|
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, which has mode VALUE_MODE. If OP0_MODE is defined, it is the mode of OP0, otherwise OP0 is a BLKmode MEM. If REVERSE is true, the store is to be done in reverse order. This does not yet handle fields wider than BITS_PER_WORD.
References BITS_PER_WORD, const0_rtx, CONST_INT_P, CONSTANT_P, opt_mode< T >::exists(), extract_fixed_bit_field(), force_reg(), GEN_INT, gen_lowpart_common(), GET_CODE, GET_MODE, GET_MODE_BITSIZE(), GET_MODE_SIZE(), HOST_WIDE_INT_1, INTVAL, maybe_gt, MEM_ALIGN, MEM_P, MIN, NULL_RTX, offset, operand_subword_force(), REG_P, opt_mode< T >::require(), store_fixed_bit_field(), SUBREG_P, SUBREG_REG, expand_operand::value, and word_mode.
Referenced by store_fixed_bit_field(), and store_integral_bit_field().
|
static |
Return true if -fstrict-volatile-bitfields applies to an access of OP0 containing BITSIZE bits starting at BITNUM, with field mode FIELDMODE. Return false if the access would touch memory outside the range BITREGION_START to BITREGION_END for conformance to the C++ memory model.
References BITS_PER_WORD, GET_MODE_BITSIZE(), maybe_gt, MEM_ALIGN, MEM_P, and MEM_VOLATILE_P.
Referenced by extract_bit_field(), and store_bit_field().
|
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, as_a(), BITS_PER_WORD, CHEAPER_MULT_COST, alg_hash_entry::cost, algorithm::cost, mult_cost::cost, ctz_hwi(), ctz_or_zero(), exact_log2(), floor_log2(), gcc_unreachable, GET_MODE_BITSIZE(), GET_MODE_INNER, GET_MODE_MASK, HOST_WIDE_INT_1U, mult_cost::latency, algorithm::log, MAX_BITS_PER_WORD, MIN, alg_hash_entry::mode, MULT_COST_LESS, NUM_ALG_HASH_ENTRIES, algorithm::op, algorithm::ops, optimize_insn_for_speed_p(), shift_cost(), shiftadd_cost(), shiftsub0_cost(), shiftsub1_cost(), alg_hash_entry::speed, synth_mult(), alg_hash_entry::t, and zero_cost().
Referenced by choose_mult_variant(), and synth_mult().
struct target_expmed default_target_expmed |
Medium-level subroutines: convert bit-field store and extract and shifts, multiplies and divides to rtl instructions. Copyright (C) 1987-2024 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/>.
Work around tree-optimization/91825.
|
static |
Whether reverse FP storage order is supported on the target.
Referenced by check_reverse_float_storage_order_support(), and flip_storage_order().
|
static |
Whether reverse storage order is supported on the target.
Referenced by check_reverse_storage_order_support(), and flip_storage_order().