#include "config.h"
#include "system.h"
+#include "toplev.h"
#include "rtl.h"
#include "tree.h"
+#include "tm_p.h"
#include "flags.h"
#include "insn-flags.h"
#include "insn-codes.h"
#define MAX_BITS_PER_WORD BITS_PER_WORD
#endif
-/* Cost of various pieces of RTL. Note that some of these are indexed by shift count,
- and some by mode. */
+/* Cost of various pieces of RTL. Note that some of these are indexed by
+ shift count and some by mode. */
static int add_cost, negate_cost, zero_cost;
static int shift_cost[MAX_BITS_PER_WORD];
static int shiftadd_cost[MAX_BITS_PER_WORD];
makes. */
free_point = (char *) oballoc (0);
- reg = gen_rtx (REG, word_mode, 10000);
+ reg = gen_rtx_REG (word_mode, 10000);
zero_cost = rtx_cost (const0_rtx, 0);
add_cost = rtx_cost (gen_rtx_PLUS (word_mode, reg, reg), SET);
mul_highpart_cost[(int) mode]
= rtx_cost (gen_rtx_TRUNCATE
(mode,
- gen_rtx_LSHIFTRT
- (wider_mode,
- gen_rtx_MULT (wider_mode,
- gen_rtx_ZERO_EXTEND (wider_mode, reg),
- gen_rtx_ZERO_EXTEND (wider_mode, reg)),
- GEN_INT (GET_MODE_BITSIZE (mode)))),
+ gen_rtx_LSHIFTRT (wider_mode,
+ gen_rtx_MULT (wider_mode,
+ gen_rtx_ZERO_EXTEND
+ (wider_mode, reg),
+ gen_rtx_ZERO_EXTEND
+ (wider_mode, reg)),
+ GEN_INT (GET_MODE_BITSIZE (mode)))),
SET);
}
}
register rtx op0 = str_rtx;
#ifdef HAVE_insv
int insv_bitsize;
+ enum machine_mode op_mode;
- if (insn_operand_mode[(int) CODE_FOR_insv][3] == VOIDmode)
- insv_bitsize = GET_MODE_BITSIZE (word_mode);
- else
- insv_bitsize = GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3]);
+ op_mode = insn_data[(int) CODE_FOR_insv].operand[3].mode;
+ if (op_mode == VOIDmode)
+ op_mode = word_mode;
+ insv_bitsize = GET_MODE_BITSIZE (op_mode);
#endif
if (GET_CODE (str_rtx) == MEM && ! MEM_IN_STRUCT_P (str_rtx))
else
{
int icode = movstrict_optab->handlers[(int) fieldmode].insn_code;
- if (! (*insn_operand_predicate[icode][1]) (value, fieldmode))
+ if (! (*insn_data[icode].operand[1].predicate) (value, fieldmode))
value = copy_to_mode_reg (fieldmode, value);
if (GET_CODE (op0) == SUBREG)
}
emit_insn (GEN_FCN (icode)
- (gen_rtx_SUBREG (fieldmode, op0, offset), value));
+ (gen_rtx_SUBREG (fieldmode, op0, offset), value));
}
return value;
}
enum machine_mode maxmode;
int save_volatile_ok = volatile_ok;
- maxmode = insn_operand_mode[(int) CODE_FOR_insv][3];
+ maxmode = insn_data[(int) CODE_FOR_insv].operand[3].mode;
if (maxmode == VOIDmode)
maxmode = word_mode;
/* This used to check flag_force_mem, but that was a serious
de-optimization now that flag_force_mem is enabled by -O2. */
if (GET_CODE (op0) == MEM
- && ! ((*insn_operand_predicate[(int) CODE_FOR_insv][0])
+ && ! ((*insn_data[(int) CODE_FOR_insv].operand[0].predicate)
(op0, VOIDmode)))
{
rtx tempreg;
/* If this machine's insv insists on a register,
get VALUE1 into a register. */
- if (! ((*insn_operand_predicate[(int) CODE_FOR_insv][3])
+ if (! ((*insn_data[(int) CODE_FOR_insv].operand[3].predicate)
(value1, maxmode)))
value1 = force_reg (maxmode, value1);
rtx spec_target_subreg = 0;
#ifdef HAVE_extv
int extv_bitsize;
+ enum machine_mode extv_mode;
#endif
#ifdef HAVE_extzv
int extzv_bitsize;
+ enum machine_mode extzv_mode;
#endif
#ifdef HAVE_extv
- if (insn_operand_mode[(int) CODE_FOR_extv][0] == VOIDmode)
- extv_bitsize = GET_MODE_BITSIZE (word_mode);
- else
- extv_bitsize = GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0]);
+ extv_mode = insn_data[(int) CODE_FOR_extv].operand[0].mode;
+ if (extv_mode == VOIDmode)
+ extv_mode = word_mode;
+ extv_bitsize = GET_MODE_BITSIZE (extv_mode);
#endif
#ifdef HAVE_extzv
- if (insn_operand_mode[(int) CODE_FOR_extzv][0] == VOIDmode)
- extzv_bitsize = GET_MODE_BITSIZE (word_mode);
- else
- extzv_bitsize
- = GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0]);
+ extzv_mode = insn_data[(int) CODE_FOR_extzv].operand[0].mode;
+ if (extzv_mode == VOIDmode)
+ extzv_mode = word_mode;
+ extzv_bitsize = GET_MODE_BITSIZE (extzv_mode);
#endif
/* Discount the part of the structure before the desired byte.
rtx pat;
enum machine_mode maxmode;
- maxmode = insn_operand_mode[(int) CODE_FOR_extzv][0];
+ maxmode = insn_data[(int) CODE_FOR_extzv].operand[0].mode;
if (maxmode == VOIDmode)
maxmode = word_mode;
volatile_ok = 1;
/* Is the memory operand acceptable? */
- if (! ((*insn_operand_predicate[(int) CODE_FOR_extzv][1])
+ if (! ((*insn_data[(int) CODE_FOR_extzv].operand[1].predicate)
(xop0, GET_MODE (xop0))))
{
/* No, load into a reg and extract from there. */
/* If this machine's extzv insists on a register target,
make sure we have one. */
- if (! ((*insn_operand_predicate[(int) CODE_FOR_extzv][0])
+ if (! ((*insn_data[(int) CODE_FOR_extzv].operand[0].predicate)
(xtarget, maxmode)))
xtarget = gen_reg_rtx (maxmode);
rtx pat;
enum machine_mode maxmode;
- maxmode = insn_operand_mode[(int) CODE_FOR_extv][0];
+ maxmode = insn_data[(int) CODE_FOR_extv].operand[0].mode;
if (maxmode == VOIDmode)
maxmode = word_mode;
if (GET_CODE (xop0) == MEM)
{
/* Is the memory operand acceptable? */
- if (! ((*insn_operand_predicate[(int) CODE_FOR_extv][1])
+ if (! ((*insn_data[(int) CODE_FOR_extv].operand[1].predicate)
(xop0, GET_MODE (xop0))))
{
/* No, load into a reg and extract from there. */
/* If this machine's extv insists on a register target,
make sure we have one. */
- if (! ((*insn_operand_predicate[(int) CODE_FOR_extv][0])
+ if (! ((*insn_data[(int) CODE_FOR_extv].operand[0].predicate)
(xtarget, maxmode)))
xtarget = gen_reg_rtx (maxmode);
tem = expand_shift (LSHIFT_EXPR, mode, op0,
build_int_2 (log, 0), NULL_RTX, 0);
accum = force_operand (gen_rtx_PLUS (mode, accum, tem),
- add_target ? add_target : accum_target);
+ add_target
+ ? add_target : accum_target);
val_so_far += (HOST_WIDE_INT) 1 << log;
break;
tem = expand_shift (LSHIFT_EXPR, mode, op0,
build_int_2 (log, 0), NULL_RTX, 0);
accum = force_operand (gen_rtx_MINUS (mode, accum, tem),
- add_target ? add_target : accum_target);
+ add_target
+ ? add_target : accum_target);
val_so_far -= (HOST_WIDE_INT) 1 << log;
break;
build_int_2 (log, 0), shift_subtarget,
0);
accum = force_operand (gen_rtx_PLUS (mode, accum, op0),
- add_target ? add_target : accum_target);
+ add_target
+ ? add_target : accum_target);
val_so_far = (val_so_far << log) + 1;
break;
build_int_2 (log, 0), shift_subtarget,
0);
accum = force_operand (gen_rtx_MINUS (mode, accum, op0),
- add_target ? add_target : accum_target);
+ add_target
+ ? add_target : accum_target);
val_so_far = (val_so_far << log) - 1;
break;
tem = expand_shift (LSHIFT_EXPR, mode, accum,
build_int_2 (log, 0), NULL_RTX, 0);
accum = force_operand (gen_rtx_PLUS (mode, accum, tem),
- add_target ? add_target : accum_target);
+ add_target
+ ? add_target : accum_target);
val_so_far += val_so_far << log;
break;
break;
default:
- abort ();;
+ abort ();
}
/* Write a REG_EQUAL note on the last insn so that we can cse
multiplication sequences. */
insn = get_last_insn ();
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_MULT (mode, op0, GEN_INT (val_so_far)),
- REG_NOTES (insn));
+ set_unique_reg_note (insn,
+ REG_EQUAL,
+ gen_rtx_MULT (mode, op0,
+ GEN_INT (val_so_far)));
}
if (variant == negate_variant)
if (insn != last
&& (set = single_set (insn)) != 0
&& SET_DEST (set) == quotient)
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_UDIV (compute_mode, op0, op1),
- REG_NOTES (insn));
+ set_unique_reg_note (insn,
+ REG_EQUAL,
+ gen_rtx_UDIV (compute_mode, op0, op1));
}
else /* TRUNC_DIV, signed */
{
insn = get_last_insn ();
if (insn != last
&& (set = single_set (insn)) != 0
- && SET_DEST (set) == quotient)
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_DIV (compute_mode,
- op0,
- GEN_INT (abs_d)),
- REG_NOTES (insn));
+ && SET_DEST (set) == quotient
+ && abs_d < ((unsigned HOST_WIDE_INT) 1
+ << (HOST_BITS_PER_WIDE_INT - 1)))
+ set_unique_reg_note (insn,
+ REG_EQUAL,
+ gen_rtx_DIV (compute_mode,
+ op0,
+ GEN_INT (abs_d)));
quotient = expand_unop (compute_mode, neg_optab,
quotient, quotient, 0);
t3 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
build_int_2 (size - 1, 0), NULL_RTX, 0);
if (d < 0)
- quotient = force_operand (gen_rtx_MINUS (compute_mode, t3, t2),
- tquotient);
+ quotient
+ = force_operand (gen_rtx_MINUS (compute_mode,
+ t3, t2),
+ tquotient);
else
- quotient = force_operand (gen_rtx_MINUS (compute_mode, t2, t3),
- tquotient);
+ quotient
+ = force_operand (gen_rtx_MINUS (compute_mode,
+ t2, t3),
+ tquotient);
}
else
{
max_cost - extra_cost);
if (t1 == 0)
goto fail1;
- t2 = force_operand (gen_rtx_PLUS (compute_mode, t1, op0),
+ t2 = force_operand (gen_rtx_PLUS (compute_mode,
+ t1, op0),
NULL_RTX);
t3 = expand_shift (RSHIFT_EXPR, compute_mode, t2,
- build_int_2 (post_shift, 0), NULL_RTX, 0);
+ build_int_2 (post_shift, 0),
+ NULL_RTX, 0);
t4 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
- build_int_2 (size - 1, 0), NULL_RTX, 0);
+ build_int_2 (size - 1, 0),
+ NULL_RTX, 0);
if (d < 0)
- quotient = force_operand (gen_rtx_MINUS (compute_mode, t4, t3),
- tquotient);
+ quotient
+ = force_operand (gen_rtx_MINUS (compute_mode,
+ t4, t3),
+ tquotient);
else
- quotient = force_operand (gen_rtx_MINUS (compute_mode, t3, t4),
- tquotient);
+ quotient
+ = force_operand (gen_rtx_MINUS (compute_mode,
+ t3, t4),
+ tquotient);
}
}
else /* Too wide mode to use tricky code */
if (insn != last
&& (set = single_set (insn)) != 0
&& SET_DEST (set) == quotient)
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_DIV (compute_mode, op0, op1),
- REG_NOTES (insn));
+ set_unique_reg_note (insn,
+ REG_EQUAL,
+ gen_rtx_DIV (compute_mode, op0, op1));
}
break;
}
NULL_RTX, unsignedp);
insn = get_last_insn ();
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_fmt_ee (unsignedp ? UDIV : DIV,
- compute_mode,
- op0, op1),
- REG_NOTES (insn));
+ set_unique_reg_note (insn,
+ REG_EQUAL,
+ gen_rtx_fmt_ee (unsignedp ? UDIV : DIV,
+ compute_mode,
+ op0, op1));
}
break;
rtx last = get_last_insn ();
rtx pattern, comparison;
+ if (unsignedp)
+ code = unsigned_condition (code);
+
/* If one operand is constant, make it the second one. Only do this
if the other operand is not constant as well. */
if (icode != CODE_FOR_nothing)
{
+ 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.
abort ();
/* Get a reference to the target in the proper mode for this insn. */
- compare_mode = insn_operand_mode[(int) icode][0];
+ compare_mode = insn_data[(int) icode].operand[0].mode;
subtarget = target;
+ pred = insn_data[(int) icode].operand[0].predicate;
if (preserve_subexpressions_p ()
- || ! (*insn_operand_predicate[(int) icode][0]) (subtarget, compare_mode))
+ || ! (*pred) (subtarget, compare_mode))
subtarget = gen_reg_rtx (compare_mode);
pattern = GEN_FCN (icode) (subtarget);
we don't have to do anything. */
if (normalizep == 0 || normalizep == STORE_FLAG_VALUE)
;
- else if (normalizep == - STORE_FLAG_VALUE)
+ /* 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 (compare_mode, neg_optab, op0, subtarget, 0);
/* We don't want to use STORE_FLAG_VALUE < 0 below since this
target = gen_reg_rtx (GET_MODE (target));
emit_move_insn (target, const1_rtx);
- tem = compare_from_rtx (op0, op1, code, unsignedp, mode, NULL_RTX, 0);
- if (GET_CODE (tem) == CONST_INT)
- return tem;
-
label = gen_label_rtx ();
- if (bcc_gen_fctn[(int) code] == 0)
- abort ();
+ do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode, NULL_RTX, 0,
+ NULL_RTX, label);
- emit_jump_insn ((*bcc_gen_fctn[(int) code]) (label));
emit_move_insn (target, const0_rtx);
emit_label (label);
static void
do_cmp_and_jump (arg1, arg2, op, mode, label)
rtx arg1, arg2, label;
- enum rtx_code op;
- enum machine_mode mode;
+ enum rtx_code op;
+ enum machine_mode mode;
{
/* If this mode is an integer too wide to compare properly,
compare word by word. Rely on cse to optimize constant cases. */
- if (GET_MODE_CLASS (mode) == MODE_INT && !can_compare_p (mode))
+ if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
{
rtx label2 = gen_label_rtx ();