Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(295)

Unified Diff: gcc/gcc/expmed.c

Issue 3050029: [gcc] GCC 4.5.0=>4.5.1 (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/nacl-toolchain.git
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gcc/gcc/et-forest.c ('k') | gcc/gcc/expr.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gcc/gcc/expmed.c
diff --git a/gcc/gcc/expmed.c b/gcc/gcc/expmed.c
index 2ce0e31ef2dd7a008b70015c3efd1cda530ceae4..aa2409942d9dd9d070d7dc2443d0bc1ac0806920 100644
--- a/gcc/gcc/expmed.c
+++ b/gcc/gcc/expmed.c
@@ -1,7 +1,7 @@
/* Medium-level subroutines: convert bit-field store and extract
and shifts, multiplies and divides to rtl instructions.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
This file is part of GCC.
@@ -103,7 +103,8 @@ static int add_cost[2][NUM_MACHINE_MODES];
static int neg_cost[2][NUM_MACHINE_MODES];
static int shift_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
static int shiftadd_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
-static int shiftsub_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
+static int shiftsub0_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
+static int shiftsub1_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
static int mul_cost[2][NUM_MACHINE_MODES];
static int sdiv_cost[2][NUM_MACHINE_MODES];
static int udiv_cost[2][NUM_MACHINE_MODES];
@@ -130,7 +131,8 @@ init_expmed (void)
struct rtx_def shift; rtunion shift_fld1;
struct rtx_def shift_mult; rtunion shift_mult_fld1;
struct rtx_def shift_add; rtunion shift_add_fld1;
- struct rtx_def shift_sub; rtunion shift_sub_fld1;
+ struct rtx_def shift_sub0; rtunion shift_sub0_fld1;
+ struct rtx_def shift_sub1; rtunion shift_sub1_fld1;
} all;
rtx pow2[MAX_BITS_PER_WORD];
@@ -201,14 +203,18 @@ init_expmed (void)
XEXP (&all.shift_add, 0) = &all.shift_mult;
XEXP (&all.shift_add, 1) = &all.reg;
- PUT_CODE (&all.shift_sub, MINUS);
- XEXP (&all.shift_sub, 0) = &all.shift_mult;
- XEXP (&all.shift_sub, 1) = &all.reg;
+ PUT_CODE (&all.shift_sub0, MINUS);
+ XEXP (&all.shift_sub0, 0) = &all.shift_mult;
+ XEXP (&all.shift_sub0, 1) = &all.reg;
+
+ PUT_CODE (&all.shift_sub1, MINUS);
+ XEXP (&all.shift_sub1, 0) = &all.reg;
+ XEXP (&all.shift_sub1, 1) = &all.shift_mult;
for (speed = 0; speed < 2; speed++)
{
crtl->maybe_hot_insn_p = speed;
- zero_cost[speed] = rtx_cost (const0_rtx, 0, speed);
+ zero_cost[speed] = rtx_cost (const0_rtx, SET, speed);
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
mode != VOIDmode;
@@ -226,7 +232,8 @@ init_expmed (void)
PUT_MODE (&all.shift, mode);
PUT_MODE (&all.shift_mult, mode);
PUT_MODE (&all.shift_add, mode);
- PUT_MODE (&all.shift_sub, mode);
+ PUT_MODE (&all.shift_sub0, mode);
+ PUT_MODE (&all.shift_sub1, mode);
add_cost[speed][mode] = rtx_cost (&all.plus, SET, speed);
neg_cost[speed][mode] = rtx_cost (&all.neg, SET, speed);
@@ -254,8 +261,8 @@ init_expmed (void)
}
shift_cost[speed][mode][0] = 0;
- shiftadd_cost[speed][mode][0] = shiftsub_cost[speed][mode][0]
- = add_cost[speed][mode];
+ shiftadd_cost[speed][mode][0] = shiftsub0_cost[speed][mode][0]
+ = shiftsub1_cost[speed][mode][0] = add_cost[speed][mode];
n = MIN (MAX_BITS_PER_WORD, GET_MODE_BITSIZE (mode));
for (m = 1; m < n; m++)
@@ -265,7 +272,8 @@ init_expmed (void)
shift_cost[speed][mode][m] = rtx_cost (&all.shift, SET, speed);
shiftadd_cost[speed][mode][m] = rtx_cost (&all.shift_add, SET, speed);
- shiftsub_cost[speed][mode][m] = rtx_cost (&all.shift_sub, SET, speed);
+ shiftsub0_cost[speed][mode][m] = rtx_cost (&all.shift_sub0, SET, speed);
+ shiftsub1_cost[speed][mode][m] = rtx_cost (&all.shift_sub1, SET, speed);
}
}
}
@@ -382,7 +390,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
always get higher addresses. */
int inner_mode_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)));
int outer_mode_size = GET_MODE_SIZE (GET_MODE (op0));
-
+
byte_offset = 0;
/* Paradoxical subregs need special handling on big endian machines. */
@@ -535,7 +543,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
rtx arg0 = op0;
/* Get appropriate low part of the value being stored. */
- if (GET_CODE (value) == CONST_INT || REG_P (value))
+ if (CONST_INT_P (value) || REG_P (value))
value = gen_lowpart (fieldmode, value);
else if (!(GET_CODE (value) == SYMBOL_REF
|| GET_CODE (value) == LABEL_REF
@@ -677,6 +685,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
rtx xop0 = op0;
rtx last = get_last_insn ();
rtx pat;
+ bool copy_back = false;
/* Add OFFSET into OP0's address. */
if (MEM_P (xop0))
@@ -689,7 +698,24 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
and we will need the original value of op0 if insv fails. */
xop0 = gen_rtx_SUBREG (op_mode, SUBREG_REG (xop0), SUBREG_BYTE (xop0));
if (REG_P (xop0) && GET_MODE (xop0) != op_mode)
- xop0 = gen_rtx_SUBREG (op_mode, xop0, 0);
+ xop0 = gen_lowpart_SUBREG (op_mode, xop0);
+
+ /* If the destination is a paradoxical subreg such that we need a
+ truncate to the inner mode, perform the insertion on a temporary and
+ truncate the result to the original destination. Note that we can't
+ just truncate the paradoxical subreg as (truncate:N (subreg:W (reg:N
+ X) 0)) is (reg:N X). */
+ if (GET_CODE (xop0) == SUBREG
+ && REG_P (SUBREG_REG (xop0))
+ && (!TRULY_NOOP_TRUNCATION
+ (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (xop0))),
+ GET_MODE_BITSIZE (op_mode))))
+ {
+ rtx tem = gen_reg_rtx (op_mode);
+ emit_move_insn (tem, xop0);
+ xop0 = tem;
+ copy_back = true;
+ }
/* On big-endian machines, we count bits from the most significant.
If the bit field insn does not, we must invert. */
@@ -729,7 +755,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
else
value1 = gen_lowpart (op_mode, value1);
}
- else if (GET_CODE (value) == CONST_INT)
+ else if (CONST_INT_P (value))
value1 = gen_int_mode (INTVAL (value), op_mode);
else
/* Parse phase is supposed to make VALUE's data type
@@ -750,15 +776,8 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
{
emit_insn (pat);
- /* If the mode of the insertion is wider than the mode of the
- target register we created a paradoxical subreg for the
- target. Truncate the paradoxical subreg of the target to
- itself properly. */
- if (!TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (op0)),
- GET_MODE_BITSIZE (op_mode))
- && (REG_P (xop0)
- || GET_CODE (xop0) == SUBREG))
- convert_move (op0, xop0, true);
+ if (copy_back)
+ convert_move (op0, xop0, true);
return true;
}
delete_insns_since (last);
@@ -938,7 +957,7 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT offset,
/* Shift VALUE left by BITPOS bits. If VALUE is not constant,
we must first convert its mode to MODE. */
- if (GET_CODE (value) == CONST_INT)
+ if (CONST_INT_P (value))
{
HOST_WIDE_INT v = INTVAL (value);
@@ -1028,7 +1047,7 @@ store_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
/* If VALUE is a constant other than a CONST_INT, get it into a register in
WORD_MODE. If we can do this using gen_lowpart_common, do so. Note
that VALUE might be a floating-point constant. */
- if (CONSTANT_P (value) && GET_CODE (value) != CONST_INT)
+ if (CONSTANT_P (value) && !CONST_INT_P (value))
{
rtx word = gen_lowpart_common (word_mode, value);
@@ -1070,7 +1089,7 @@ store_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
total_bits = GET_MODE_BITSIZE (GET_MODE (value));
/* Fetch successively less significant portions. */
- if (GET_CODE (value) == CONST_INT)
+ if (CONST_INT_P (value))
part = GEN_INT (((unsigned HOST_WIDE_INT) (INTVAL (value))
>> (bitsize - bitsdone - thissize))
& (((HOST_WIDE_INT) 1 << thissize) - 1));
@@ -1085,7 +1104,7 @@ store_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
else
{
/* Fetch successively more significant portions. */
- if (GET_CODE (value) == CONST_INT)
+ if (CONST_INT_P (value))
part = GEN_INT (((unsigned HOST_WIDE_INT) (INTVAL (value))
>> bitsdone)
& (((HOST_WIDE_INT) 1 << thissize) - 1));
@@ -1523,7 +1542,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
/* If op0 is a register, we need it in EXT_MODE to make it
acceptable to the format of ext(z)v. */
if (REG_P (xop0) && GET_MODE (xop0) != ext_mode)
- xop0 = gen_rtx_SUBREG (ext_mode, xop0, 0);
+ xop0 = gen_lowpart_SUBREG (ext_mode, xop0);
if (MEM_P (xop0))
/* Get ref to first byte containing part of the field. */
xop0 = adjust_address (xop0, byte_mode, xoffset);
@@ -2130,7 +2149,7 @@ expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
if (SHIFT_COUNT_TRUNCATED)
{
- if (GET_CODE (op1) == CONST_INT
+ if (CONST_INT_P (op1)
&& ((unsigned HOST_WIDE_INT) INTVAL (op1) >=
(unsigned HOST_WIDE_INT) GET_MODE_BITSIZE (mode)))
op1 = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (op1)
@@ -2147,7 +2166,7 @@ expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
/* Check whether its cheaper to implement a left shift by a constant
bit count by a sequence of additions. */
if (code == LSHIFT_EXPR
- && GET_CODE (op1) == CONST_INT
+ && CONST_INT_P (op1)
&& INTVAL (op1) > 0
&& INTVAL (op1) < GET_MODE_BITSIZE (mode)
&& INTVAL (op1) < MAX_BITS_PER_WORD
@@ -2346,7 +2365,7 @@ struct alg_hash_entry {
Otherwise, the cost within which multiplication by T is
impossible. */
struct mult_cost cost;
-
+
/* OPtimized for speed? */
bool speed;
};
@@ -2397,6 +2416,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
struct mult_cost best_cost;
struct mult_cost new_limit;
int op_cost, op_latency;
+ unsigned HOST_WIDE_INT orig_t = t;
unsigned HOST_WIDE_INT q;
int maxm = MIN (BITS_PER_WORD, GET_MODE_BITSIZE (mode));
int hash_index;
@@ -2542,6 +2562,38 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
best_alg->log[best_alg->ops] = m;
best_alg->op[best_alg->ops] = alg_shift;
}
+
+ /* See if treating ORIG_T as a signed number yields a better
+ sequence. Try this sequence only for a negative ORIG_T
+ as it would be useless for a non-negative ORIG_T. */
+ if ((HOST_WIDE_INT) orig_t < 0)
+ {
+ /* Shift ORIG_T as follows because a right shift of a
+ negative-valued signed type is implementation
+ defined. */
+ q = ~(~orig_t >> m);
+ /* The function expand_shift will choose between a shift
+ and a sequence of additions, so the observed cost is
+ given as MIN (m * add_cost[speed][mode],
+ shift_cost[speed][mode][m]). */
+ op_cost = m * add_cost[speed][mode];
+ if (shift_cost[speed][mode][m] < op_cost)
+ op_cost = shift_cost[speed][mode][m];
+ new_limit.cost = best_cost.cost - op_cost;
+ new_limit.latency = best_cost.latency - op_cost;
+ synth_mult (alg_in, q, &new_limit, mode);
+
+ alg_in->cost.cost += op_cost;
+ alg_in->cost.latency += op_cost;
+ if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
+ {
+ struct algorithm *x;
+ best_cost = alg_in->cost;
+ x = alg_in, alg_in = best_alg, best_alg = x;
+ best_alg->log[best_alg->ops] = m;
+ best_alg->op[best_alg->ops] = alg_shift;
+ }
+ }
}
if (cache_hit)
goto done;
@@ -2604,6 +2656,29 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
best_alg->op[best_alg->ops] = alg_add_t_m2;
}
}
+
+ /* We may be able to calculate a * -7, a * -15, a * -31, etc
+ quickly with a - a * n for some appropriate constant n. */
+ m = exact_log2 (-orig_t + 1);
+ if (m >= 0 && m < maxm)
+ {
+ op_cost = shiftsub1_cost[speed][mode][m];
+ new_limit.cost = best_cost.cost - op_cost;
+ new_limit.latency = best_cost.latency - op_cost;
+ synth_mult (alg_in, (unsigned HOST_WIDE_INT) (-orig_t + 1) >> m, &new_limit, mode);
+
+ alg_in->cost.cost += op_cost;
+ alg_in->cost.latency += op_cost;
+ if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
+ {
+ struct algorithm *x;
+ best_cost = alg_in->cost;
+ x = alg_in, alg_in = best_alg, best_alg = x;
+ best_alg->log[best_alg->ops] = m;
+ best_alg->op[best_alg->ops] = alg_sub_t_m2;
+ }
+ }
+
if (cache_hit)
goto done;
}
@@ -2673,9 +2748,9 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
hardware the shift may be executed concurrently with the
earlier steps in the algorithm. */
op_cost = add_cost[speed][mode] + shift_cost[speed][mode][m];
- if (shiftsub_cost[speed][mode][m] < op_cost)
+ if (shiftsub0_cost[speed][mode][m] < op_cost)
{
- op_cost = shiftsub_cost[speed][mode][m];
+ op_cost = shiftsub0_cost[speed][mode][m];
op_latency = op_cost;
}
else
@@ -2738,7 +2813,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
m = exact_log2 (q);
if (m >= 0 && m < maxm)
{
- op_cost = shiftsub_cost[speed][mode][m];
+ op_cost = shiftsub0_cost[speed][mode][m];
new_limit.cost = best_cost.cost - op_cost;
new_limit.latency = best_cost.latency - op_cost;
synth_mult (alg_in, (t + 1) >> m, &new_limit, mode);
@@ -3080,7 +3155,7 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
any truncation. This means that multiplying by negative values does
not work; results are off by 2^32 on a 32 bit machine. */
- if (GET_CODE (op1) == CONST_INT)
+ if (CONST_INT_P (op1))
{
/* Attempt to handle multiplication of DImode values by negative
coefficients, by performing the multiplication by a positive
@@ -3123,7 +3198,7 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
target, unsignedp);
}
}
-
+
/* We used to test optimize here, on the grounds that it's better to
produce a smaller program when -O is not used. But this causes
such a terrible slowdown sometimes that it seems better to always
@@ -3502,8 +3577,8 @@ expand_mult_highpart (enum machine_mode mode, rtx op0, rtx op1,
cnst1 = INTVAL (op1) & GET_MODE_MASK (mode);
- /* We can't optimize modes wider than BITS_PER_WORD.
- ??? We might be able to perform double-word arithmetic if
+ /* We can't optimize modes wider than BITS_PER_WORD.
+ ??? We might be able to perform double-word arithmetic if
mode == word_mode, however all the cost calculations in
synth_mult etc. assume single-word operations. */
if (GET_MODE_BITSIZE (wider_mode) > BITS_PER_WORD)
@@ -3782,7 +3857,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
static HOST_WIDE_INT ext_op1;
bool speed = optimize_insn_for_speed_p ();
- op1_is_constant = GET_CODE (op1) == CONST_INT;
+ op1_is_constant = CONST_INT_P (op1);
if (op1_is_constant)
{
ext_op1 = INTVAL (op1);
@@ -3926,7 +4001,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
/* convert_modes may have placed op1 into a register, so we
must recompute the following. */
- op1_is_constant = GET_CODE (op1) == CONST_INT;
+ op1_is_constant = CONST_INT_P (op1);
op1_is_pow2 = (op1_is_constant
&& ((EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1))
|| (! unsignedp
@@ -3998,10 +4073,8 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
{
/* Most significant bit of divisor is set; emit an scc
insn. */
- quotient = emit_store_flag (tquotient, GEU, op0, op1,
- compute_mode, 1, 1);
- if (quotient == 0)
- goto fail1;
+ quotient = emit_store_flag_force (tquotient, GEU, op0, op1,
+ compute_mode, 1, 1);
}
else
{
@@ -4872,7 +4945,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
if (!remainder)
{
remainder = gen_reg_rtx (compute_mode);
- if (!expand_twoval_binop_libfunc
+ if (!expand_twoval_binop_libfunc
(unsignedp ? udivmod_optab : sdivmod_optab,
op0, op1,
NULL_RTX, remainder,
@@ -4915,12 +4988,12 @@ make_tree (tree type, rtx x)
&& (GET_MODE_BITSIZE (TYPE_MODE (type))
< HOST_BITS_PER_WIDE_INT)))
hi = -1;
-
+
t = build_int_cst_wide (type, INTVAL (x), hi);
-
+
return t;
}
-
+
case CONST_DOUBLE:
if (GET_MODE (x) == VOIDmode)
t = build_int_cst_wide (type,
@@ -5015,12 +5088,13 @@ make_tree (tree type, rtx x)
/* else fall through. */
default:
- t = build_decl (VAR_DECL, NULL_TREE, type);
+ t = build_decl (RTL_LOCATION (x), VAR_DECL, NULL_TREE, type);
- /* If TYPE is a POINTER_TYPE, X might be Pmode with TYPE_MODE being
- ptr_mode. So convert. */
+ /* If TYPE is a POINTER_TYPE, we might need to convert X from
+ address mode to pointer mode. */
if (POINTER_TYPE_P (type))
- x = convert_memory_address (TYPE_MODE (type), x);
+ x = convert_memory_address_addr_space
+ (TYPE_MODE (type), x, TYPE_ADDR_SPACE (TREE_TYPE (type)));
/* Note that we do *not* use SET_DECL_RTL here, because we do not
want set_decl_rtl to go adjusting REG_ATTRS for this temporary. */
@@ -5051,15 +5125,48 @@ expand_and (enum machine_mode mode, rtx op0, rtx op1, rtx target)
emit_move_insn (target, tem);
return target;
}
-
+
/* Helper function for emit_store_flag. */
static rtx
-emit_store_flag_1 (rtx target, rtx subtarget, enum machine_mode mode,
- int normalizep)
+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)
{
- rtx op0;
- enum machine_mode target_mode = GET_MODE (target);
-
+ rtx op0, last, comparison, subtarget, pattern;
+ enum machine_mode result_mode = insn_data[(int) icode].operand[0].mode;
+
+ last = get_last_insn ();
+ x = prepare_operand (icode, x, 2, mode, compare_mode, unsignedp);
+ y = prepare_operand (icode, y, 3, mode, compare_mode, unsignedp);
+ comparison = gen_rtx_fmt_ee (code, result_mode, x, y);
+ if (!x || !y
+ || !insn_data[icode].operand[2].predicate
+ (x, insn_data[icode].operand[2].mode)
+ || !insn_data[icode].operand[3].predicate
+ (y, insn_data[icode].operand[3].mode)
+ || !insn_data[icode].operand[1].predicate (comparison, VOIDmode))
+ {
+ delete_insns_since (last);
+ return NULL_RTX;
+ }
+
+ if (target_mode == VOIDmode)
+ target_mode = result_mode;
+ if (!target)
+ target = gen_reg_rtx (target_mode);
+
+ if (optimize
+ || !(insn_data[(int) icode].operand[0].predicate (target, result_mode)))
+ subtarget = gen_reg_rtx (result_mode);
+ else
+ subtarget = target;
+
+ pattern = GEN_FCN (icode) (subtarget, comparison, x, y);
+ if (!pattern)
+ return NULL_RTX;
+ emit_insn (pattern);
+
/* If we are converting to a wider mode, first convert to
TARGET_MODE, then normalize. This produces better combining
opportunities on machines that have a SIGN_EXTRACT when we are
@@ -5068,15 +5175,15 @@ emit_store_flag_1 (rtx target, rtx subtarget, enum machine_mode mode,
If STORE_FLAG_VALUE does not have the sign bit set when
interpreted in MODE, we can do this conversion as unsigned, which
is usually more efficient. */
- if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (mode))
+ if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (result_mode))
{
convert_move (target, subtarget,
- (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
+ (GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT)
&& 0 == (STORE_FLAG_VALUE
& ((HOST_WIDE_INT) 1
- << (GET_MODE_BITSIZE (mode) -1))));
+ << (GET_MODE_BITSIZE (result_mode) -1))));
op0 = target;
- mode = target_mode;
+ result_mode = target_mode;
}
else
op0 = subtarget;
@@ -5093,28 +5200,28 @@ emit_store_flag_1 (rtx target, rtx subtarget, enum machine_mode mode,
/* STORE_FLAG_VALUE might be the most negative number, so write
the comparison this way to avoid a compiler-time warning. */
else if (- normalizep == STORE_FLAG_VALUE)
- op0 = expand_unop (mode, neg_optab, op0, subtarget, 0);
+ op0 = expand_unop (result_mode, neg_optab, op0, subtarget, 0);
/* We don't want to use STORE_FLAG_VALUE < 0 below since this makes
it hard to use a value of just the sign bit due to ANSI integer
constant typing rules. */
- else if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
+ else if (GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
&& (STORE_FLAG_VALUE
- & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))))
- op0 = expand_shift (RSHIFT_EXPR, mode, op0,
- size_int (GET_MODE_BITSIZE (mode) - 1), subtarget,
+ & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (result_mode) - 1))))
+ op0 = expand_shift (RSHIFT_EXPR, result_mode, op0,
+ size_int (GET_MODE_BITSIZE (result_mode) - 1), subtarget,
normalizep == 1);
else
{
gcc_assert (STORE_FLAG_VALUE & 1);
- op0 = expand_and (mode, op0, const1_rtx, subtarget);
+ op0 = expand_and (result_mode, op0, const1_rtx, subtarget);
if (normalizep == -1)
- op0 = expand_unop (mode, neg_optab, op0, op0, 0);
+ op0 = expand_unop (result_mode, neg_optab, op0, op0, 0);
}
/* If we were converting to a smaller mode, do the conversion now. */
- if (target_mode != mode)
+ if (target_mode != result_mode)
{
convert_move (target, op0, 0);
return target;
@@ -5123,35 +5230,26 @@ emit_store_flag_1 (rtx target, rtx subtarget, enum machine_mode mode,
return op0;
}
-/* 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.
+/* A subroutine of emit_store_flag only including "tricks" that do not
+ need a recursive call. These are kept separate to avoid infinite
+ loops. */
- 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. */
-
-rtx
-emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
- enum machine_mode mode, int unsignedp, int normalizep)
+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 subtarget;
enum insn_code icode;
enum machine_mode compare_mode;
- enum machine_mode target_mode = GET_MODE (target);
+ enum mode_class mclass;
+ enum rtx_code scode;
rtx tem;
- rtx last = get_last_insn ();
- rtx pattern, comparison;
if (unsignedp)
code = unsigned_condition (code);
+ scode = swap_condition (code);
/* If one operand is constant, make it the second one. Only do this
if the other operand is not constant as well. */
@@ -5210,20 +5308,20 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
if ((code == EQ || code == NE)
&& (op1 == const0_rtx || op1 == constm1_rtx))
{
- rtx op00, op01, op0both;
+ rtx op00, op01;
/* Do a logical OR or AND of the two words and compare the
result. */
op00 = simplify_gen_subreg (word_mode, op0, mode, 0);
op01 = simplify_gen_subreg (word_mode, op0, mode, UNITS_PER_WORD);
- op0both = expand_binop (word_mode,
- op1 == const0_rtx ? ior_optab : and_optab,
- op00, op01, NULL_RTX, unsignedp,
- OPTAB_DIRECT);
-
- if (op0both != 0)
- return emit_store_flag (target, code, op0both, op1, word_mode,
- unsignedp, normalizep);
+ tem = expand_binop (word_mode,
+ op1 == const0_rtx ? ior_optab : and_optab,
+ op00, op01, NULL_RTX, unsignedp,
+ OPTAB_DIRECT);
+
+ if (tem != 0)
+ tem = emit_store_flag (NULL_RTX, code, tem, op1, word_mode,
+ unsignedp, normalizep);
}
else if ((code == LT || code == GE) && op1 == const0_rtx)
{
@@ -5233,8 +5331,24 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
op0h = simplify_gen_subreg (word_mode, op0, mode,
subreg_highpart_offset (word_mode,
mode));
- return emit_store_flag (target, code, op0h, op1, word_mode,
- unsignedp, normalizep);
+ tem = emit_store_flag (NULL_RTX, code, op0h, op1, word_mode,
+ unsignedp, normalizep);
+ }
+ else
+ tem = NULL_RTX;
+
+ if (tem)
+ {
+ if (target_mode == VOIDmode || GET_MODE (tem) == target_mode)
+ return tem;
+ if (!target)
+ target = gen_reg_rtx (target_mode);
+
+ convert_move (target, tem,
+ 0 == ((normalizep ? normalizep : STORE_FLAG_VALUE)
+ & ((HOST_WIDE_INT) 1
+ << (GET_MODE_BITSIZE (word_mode) -1))));
+ return target;
}
}
@@ -5250,10 +5364,13 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
{
subtarget = target;
+ if (!target)
+ target_mode = mode;
+
/* If the result is to be wider than OP0, it is best to convert it
first. If it is to be narrower, it is *incorrect* to convert it
first. */
- if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (mode))
+ else if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (mode))
{
op0 = convert_modes (target_mode, mode, op0, 0);
mode = target_mode;
@@ -5281,146 +5398,185 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
return op0;
}
- icode = setcc_gen_code[(int) code];
-
- if (icode != CODE_FOR_nothing)
+ mclass = GET_MODE_CLASS (mode);
+ for (compare_mode = mode; compare_mode != VOIDmode;
+ compare_mode = GET_MODE_WIDER_MODE (compare_mode))
{
- insn_operand_predicate_fn pred;
-
- /* We think we may be able to do this with a scc insn. Emit the
- comparison and then the scc insn. */
-
- do_pending_stack_adjust ();
- last = get_last_insn ();
-
- comparison
- = compare_from_rtx (op0, op1, code, unsignedp, mode, NULL_RTX);
- if (CONSTANT_P (comparison))
+ enum machine_mode optab_mode = mclass == MODE_CC ? CCmode : compare_mode;
+ icode = optab_handler (cstore_optab, optab_mode)->insn_code;
+ if (icode != CODE_FOR_nothing)
{
- switch (GET_CODE (comparison))
+ do_pending_stack_adjust ();
+ tem = emit_cstore (target, icode, code, mode, compare_mode,
+ unsignedp, op0, op1, normalizep, target_mode);
+ if (tem)
+ return tem;
+
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
{
- case CONST_INT:
- if (comparison == const0_rtx)
- return const0_rtx;
- break;
-
-#ifdef FLOAT_STORE_FLAG_VALUE
- case CONST_DOUBLE:
- if (comparison == CONST0_RTX (GET_MODE (comparison)))
- return const0_rtx;
- break;
-#endif
- default:
- gcc_unreachable ();
+ tem = emit_cstore (target, icode, scode, mode, compare_mode,
+ unsignedp, op1, op0, normalizep, target_mode);
+ if (tem)
+ return tem;
}
-
- if (normalizep == 1)
- return const1_rtx;
- if (normalizep == -1)
- return constm1_rtx;
- return const_true_rtx;
+ break;
}
+ }
- /* The code of COMPARISON may not match CODE if compare_from_rtx
- decided to swap its operands and reverse the original code.
-
- We know that compare_from_rtx returns either a CONST_INT or
- a new comparison code, so it is safe to just extract the
- code from COMPARISON. */
- code = GET_CODE (comparison);
-
- /* Get a reference to the target in the proper mode for this insn. */
- compare_mode = insn_data[(int) icode].operand[0].mode;
- subtarget = target;
- pred = insn_data[(int) icode].operand[0].predicate;
- if (optimize || ! (*pred) (subtarget, compare_mode))
- subtarget = gen_reg_rtx (compare_mode);
+ return 0;
+}
- pattern = GEN_FCN (icode) (subtarget);
- if (pattern)
- {
- emit_insn (pattern);
- return emit_store_flag_1 (target, subtarget, compare_mode,
- normalizep);
- }
- }
- else
- {
- /* We don't have an scc insn, so try a cstore insn. */
+/* 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.
- for (compare_mode = mode; compare_mode != VOIDmode;
- compare_mode = GET_MODE_WIDER_MODE (compare_mode))
- {
- icode = optab_handler (cstore_optab, compare_mode)->insn_code;
- if (icode != CODE_FOR_nothing)
- break;
- }
+ 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.
- if (icode != CODE_FOR_nothing)
- {
- enum machine_mode result_mode
- = insn_data[(int) icode].operand[0].mode;
- rtx cstore_op0 = op0;
- rtx cstore_op1 = op1;
+ UNSIGNEDP is for the case where we have to widen the operands
+ to perform the operation. It says to use zero-extension.
- do_pending_stack_adjust ();
- last = get_last_insn ();
+ NORMALIZEP is 1 if we should convert the result to be either zero
+ or one. Normalize is -1 if we should convert the result to be
+ either zero or -1. If NORMALIZEP is zero, the result will be left
+ "raw" out of the scc insn. */
- if (compare_mode != mode)
- {
- cstore_op0 = convert_modes (compare_mode, mode, cstore_op0,
- unsignedp);
- cstore_op1 = convert_modes (compare_mode, mode, cstore_op1,
- unsignedp);
- }
-
- if (!insn_data[(int) icode].operand[2].predicate (cstore_op0,
- compare_mode))
- cstore_op0 = copy_to_mode_reg (compare_mode, cstore_op0);
+rtx
+emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
+ enum machine_mode mode, int unsignedp, int normalizep)
+{
+ enum machine_mode target_mode = target ? GET_MODE (target) : VOIDmode;
+ enum rtx_code rcode;
+ rtx subtarget;
+ rtx tem, last, trueval;
- if (!insn_data[(int) icode].operand[3].predicate (cstore_op1,
- compare_mode))
- cstore_op1 = copy_to_mode_reg (compare_mode, cstore_op1);
+ tem = emit_store_flag_1 (target, code, op0, op1, mode, unsignedp, normalizep,
+ target_mode);
+ if (tem)
+ return tem;
- comparison = gen_rtx_fmt_ee (code, result_mode, cstore_op0,
- cstore_op1);
- subtarget = target;
+ /* If we reached here, we can't do this with a scc insn, however there
+ are some comparisons that can be done in other ways. Don't do any
+ of these cases if branches are very cheap. */
+ if (BRANCH_COST (optimize_insn_for_speed_p (), false) == 0)
+ return 0;
- if (optimize || !(insn_data[(int) icode].operand[0].predicate
- (subtarget, result_mode)))
- subtarget = gen_reg_rtx (result_mode);
+ /* See what we need to return. We can only return a 1, -1, or the
+ sign bit. */
- pattern = GEN_FCN (icode) (subtarget, comparison, cstore_op0,
- cstore_op1);
+ if (normalizep == 0)
+ {
+ if (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
+ normalizep = STORE_FLAG_VALUE;
- if (pattern)
- {
- emit_insn (pattern);
- return emit_store_flag_1 (target, subtarget, result_mode,
- normalizep);
- }
- }
+ else if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
+ && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
+ == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))
+ ;
+ else
+ return 0;
}
- delete_insns_since (last);
+ last = get_last_insn ();
/* If optimizing, use different pseudo registers for each insn, instead
of reusing the same pseudo. This leads to better CSE, but slows
down the compiler, since there are more pseudos */
subtarget = (!optimize
&& (target_mode == mode)) ? target : NULL_RTX;
+ trueval = GEN_INT (normalizep ? normalizep : STORE_FLAG_VALUE);
+
+ /* For floating-point comparisons, try the reverse comparison or try
+ changing the "orderedness" of the comparison. */
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ enum rtx_code first_code;
+ bool and_them;
+
+ rcode = reverse_condition_maybe_unordered (code);
+ if (can_compare_p (rcode, mode, ccp_store_flag)
+ && (code == ORDERED || code == UNORDERED
+ || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
+ || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
+ {
+ int want_add = ((STORE_FLAG_VALUE == 1 && normalizep == -1)
+ || (STORE_FLAG_VALUE == -1 && normalizep == 1));
+
+ /* For the reverse comparison, use either an addition or a XOR. */
+ if (want_add
+ && rtx_cost (GEN_INT (normalizep), PLUS,
+ optimize_insn_for_speed_p ()) == 0)
+ {
+ tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
+ STORE_FLAG_VALUE, target_mode);
+ if (tem)
+ return expand_binop (target_mode, add_optab, tem,
+ GEN_INT (normalizep),
+ target, 0, OPTAB_WIDEN);
+ }
+ else if (!want_add
+ && rtx_cost (trueval, XOR,
+ optimize_insn_for_speed_p ()) == 0)
+ {
+ tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
+ normalizep, target_mode);
+ if (tem)
+ return expand_binop (target_mode, xor_optab, tem, trueval,
+ target, INTVAL (trueval) >= 0, OPTAB_WIDEN);
+ }
+ }
+
+ delete_insns_since (last);
+
+ /* Cannot split ORDERED and UNORDERED, only try the above trick. */
+ if (code == ORDERED || code == UNORDERED)
+ return 0;
+
+ and_them = split_comparison (code, mode, &first_code, &code);
+
+ /* If there are no NaNs, the first comparison should always fall through.
+ Effectively change the comparison to the other one. */
+ if (!HONOR_NANS (mode))
+ {
+ gcc_assert (first_code == (and_them ? ORDERED : UNORDERED));
+ return emit_store_flag_1 (target, code, op0, op1, mode, 0, normalizep,
+ target_mode);
+ }
+
+#ifdef HAVE_conditional_move
+ /* Try using a setcc instruction for ORDERED/UNORDERED, followed by a
+ conditional move. */
+ tem = emit_store_flag_1 (subtarget, first_code, op0, op1, mode, 0,
+ normalizep, target_mode);
+ if (tem == 0)
+ return 0;
+
+ if (and_them)
+ tem = emit_conditional_move (target, code, op0, op1, mode,
+ tem, const0_rtx, GET_MODE (tem), 0);
+ else
+ tem = emit_conditional_move (target, code, op0, op1, mode,
+ trueval, tem, GET_MODE (tem), 0);
+
+ if (tem == 0)
+ delete_insns_since (last);
+ return tem;
+#else
+ return 0;
+#endif
+ }
- /* If we reached here, we can't do this with a scc insn. However, there
- are some comparisons that can be done directly. For example, if
- this is an equality comparison of integers, we can try to exclusive-or
+ /* The remaining tricks only apply to integer comparisons. */
+
+ if (GET_MODE_CLASS (mode) != MODE_INT)
+ return 0;
+
+ /* If this is an equality comparison of integers, we can try to exclusive-or
(or subtract) the two operands and use a recursive call to try the
comparison with zero. Don't do any of these cases if branches are
very cheap. */
- if (BRANCH_COST (optimize_insn_for_speed_p (),
- false) > 0
- && GET_MODE_CLASS (mode) == MODE_INT && (code == EQ || code == NE)
- && op1 != const0_rtx)
+ if ((code == EQ || code == NE) && op1 != const0_rtx)
{
tem = expand_binop (mode, xor_optab, op0, op1, subtarget, 1,
OPTAB_WIDEN);
@@ -5431,9 +5587,50 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
if (tem != 0)
tem = emit_store_flag (target, code, tem, const0_rtx,
mode, unsignedp, normalizep);
- if (tem == 0)
- delete_insns_since (last);
- return tem;
+ if (tem != 0)
+ return tem;
+
+ delete_insns_since (last);
+ }
+
+ /* For integer comparisons, try the reverse comparison. However, for
+ small X and if we'd have anyway to extend, implementing "X != 0"
+ as "-(int)X >> 31" is still cheaper than inverting "(int)X == 0". */
+ rcode = reverse_condition (code);
+ if (can_compare_p (rcode, mode, ccp_store_flag)
+ && ! (optab_handler (cstore_optab, mode)->insn_code == CODE_FOR_nothing
+ && code == NE
+ && GET_MODE_SIZE (mode) < UNITS_PER_WORD
+ && op1 == const0_rtx))
+ {
+ int want_add = ((STORE_FLAG_VALUE == 1 && normalizep == -1)
+ || (STORE_FLAG_VALUE == -1 && normalizep == 1));
+
+ /* Again, for the reverse comparison, use either an addition or a XOR. */
+ if (want_add
+ && rtx_cost (GEN_INT (normalizep), PLUS,
+ optimize_insn_for_speed_p ()) == 0)
+ {
+ tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
+ STORE_FLAG_VALUE, target_mode);
+ if (tem != 0)
+ tem = expand_binop (target_mode, add_optab, tem,
+ GEN_INT (normalizep), target, 0, OPTAB_WIDEN);
+ }
+ else if (!want_add
+ && rtx_cost (trueval, XOR,
+ optimize_insn_for_speed_p ()) == 0)
+ {
+ tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
+ normalizep, target_mode);
+ if (tem != 0)
+ tem = expand_binop (target_mode, xor_optab, tem, trueval, target,
+ INTVAL (trueval) >= 0, OPTAB_WIDEN);
+ }
+
+ if (tem != 0)
+ return tem;
+ delete_insns_since (last);
}
/* Some other cases we can do are EQ, NE, LE, and GT comparisons with
@@ -5441,30 +5638,12 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
do LE and GT if branches are expensive since they are expensive on
2-operand machines. */
- if (BRANCH_COST (optimize_insn_for_speed_p (),
- false) == 0
- || GET_MODE_CLASS (mode) != MODE_INT || op1 != const0_rtx
+ if (op1 != const0_rtx
|| (code != EQ && code != NE
&& (BRANCH_COST (optimize_insn_for_speed_p (),
false) <= 1 || (code != LE && code != GT))))
return 0;
- /* See what we need to return. We can only return a 1, -1, or the
- sign bit. */
-
- if (normalizep == 0)
- {
- if (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
- normalizep = STORE_FLAG_VALUE;
-
- else if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
- && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
- == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))
- ;
- else
- return 0;
- }
-
/* Try to put the result of the comparison in the sign bit. Assume we can't
do the necessary operation below. */
@@ -5566,7 +5745,9 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
if (tem)
{
- if (GET_MODE (tem) != target_mode)
+ if (!target)
+ ;
+ else if (GET_MODE (tem) != target_mode)
{
convert_move (target, tem, 0);
tem = target;
@@ -5590,27 +5771,68 @@ emit_store_flag_force (rtx target, enum rtx_code code, rtx op0, rtx op1,
enum machine_mode mode, int unsignedp, int normalizep)
{
rtx tem, label;
+ rtx trueval, falseval;
/* First see if emit_store_flag can do the job. */
tem = emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep);
if (tem != 0)
return tem;
- if (normalizep == 0)
- normalizep = 1;
+ if (!target)
+ target = gen_reg_rtx (word_mode);
- /* If this failed, we have to do this with set/compare/jump/set code. */
+ /* If this failed, we have to do this with set/compare/jump/set code.
+ For foo != 0, if foo is in OP0, just replace it with 1 if nonzero. */
+ trueval = normalizep ? GEN_INT (normalizep) : const1_rtx;
+ if (code == NE
+ && GET_MODE_CLASS (mode) == MODE_INT
+ && REG_P (target)
+ && op0 == target
+ && op1 == const0_rtx)
+ {
+ label = gen_label_rtx ();
+ do_compare_rtx_and_jump (target, const0_rtx, EQ, unsignedp,
+ mode, NULL_RTX, NULL_RTX, label, -1);
+ emit_move_insn (target, trueval);
+ emit_label (label);
+ return target;
+ }
if (!REG_P (target)
|| reg_mentioned_p (target, op0) || reg_mentioned_p (target, op1))
target = gen_reg_rtx (GET_MODE (target));
- emit_move_insn (target, const1_rtx);
+ /* Jump in the right direction if the target cannot implement CODE
+ but can jump on its reverse condition. */
+ falseval = const0_rtx;
+ if (! can_compare_p (code, mode, ccp_jump)
+ && (! FLOAT_MODE_P (mode)
+ || code == ORDERED || code == UNORDERED
+ || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
+ || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
+ {
+ enum rtx_code rcode;
+ if (FLOAT_MODE_P (mode))
+ rcode = reverse_condition_maybe_unordered (code);
+ else
+ rcode = reverse_condition (code);
+
+ /* Canonicalize to UNORDERED for the libcall. */
+ if (can_compare_p (rcode, mode, ccp_jump)
+ || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump)))
+ {
+ falseval = trueval;
+ trueval = const0_rtx;
+ code = rcode;
+ }
+ }
+
+ emit_move_insn (target, trueval);
label = gen_label_rtx ();
do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode, NULL_RTX,
- NULL_RTX, label);
+ NULL_RTX, label, -1);
- emit_move_insn (target, const0_rtx);
+ emit_move_insn (target, falseval);
emit_label (label);
return target;
@@ -5626,5 +5848,5 @@ do_cmp_and_jump (rtx arg1, rtx arg2, enum rtx_code op, enum machine_mode mode,
{
int unsignedp = (op == LTU || op == LEU || op == GTU || op == GEU);
do_compare_rtx_and_jump (arg1, arg2, op, unsignedp, mode,
- NULL_RTX, NULL_RTX, label);
+ NULL_RTX, NULL_RTX, label, -1);
}
« no previous file with comments | « gcc/gcc/et-forest.c ('k') | gcc/gcc/expr.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698