/* 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.
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
/* 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);
static rtx
mask_rtx (enum machine_mode mode, int bitpos, int bitsize, int complement)
{
- HOST_WIDE_INT masklow, maskhigh;
+ double_int mask;
- if (bitsize == 0)
- masklow = 0;
- else if (bitpos < HOST_BITS_PER_WIDE_INT)
- masklow = (HOST_WIDE_INT) -1 << bitpos;
- else
- masklow = 0;
-
- if (bitpos + bitsize < HOST_BITS_PER_WIDE_INT)
- masklow &= ((unsigned HOST_WIDE_INT) -1
- >> (HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
-
- if (bitpos <= HOST_BITS_PER_WIDE_INT)
- maskhigh = -1;
- else
- maskhigh = (HOST_WIDE_INT) -1 << (bitpos - HOST_BITS_PER_WIDE_INT);
-
- if (bitsize == 0)
- maskhigh = 0;
- else if (bitpos + bitsize > HOST_BITS_PER_WIDE_INT)
- maskhigh &= ((unsigned HOST_WIDE_INT) -1
- >> (2 * HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
- else
- maskhigh = 0;
+ mask = double_int_mask (bitsize);
+ mask = double_int_lshift (mask, bitpos, HOST_BITS_PER_DOUBLE_INT, false);
if (complement)
- {
- maskhigh = ~maskhigh;
- masklow = ~masklow;
- }
+ mask = double_int_not (mask);
- return immed_double_const (masklow, maskhigh, mode);
+ return immed_double_int_const (mask, mode);
}
/* Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value
static rtx
lshift_value (enum machine_mode mode, rtx value, int bitpos, int bitsize)
{
- unsigned HOST_WIDE_INT v = INTVAL (value);
- HOST_WIDE_INT low, high;
-
- if (bitsize < HOST_BITS_PER_WIDE_INT)
- v &= ~((HOST_WIDE_INT) -1 << bitsize);
-
- if (bitpos < HOST_BITS_PER_WIDE_INT)
- {
- low = v << bitpos;
- high = (bitpos > 0 ? (v >> (HOST_BITS_PER_WIDE_INT - bitpos)) : 0);
- }
- else
- {
- low = 0;
- high = v << (bitpos - HOST_BITS_PER_WIDE_INT);
- }
+ double_int val;
+
+ val = double_int_zext (uhwi_to_double_int (INTVAL (value)), bitsize);
+ val = double_int_lshift (val, bitpos, HOST_BITS_PER_DOUBLE_INT, false);
- return immed_double_const (low, high, mode);
+ return immed_double_int_const (val, mode);
}
\f
/* Extract a bit field that is split across two words
else if (d == -1)
quotient = expand_unop (compute_mode, neg_optab, op0,
tquotient, 0);
- else if (abs_d == (unsigned HOST_WIDE_INT) 1 << (size - 1))
+ else if (HOST_BITS_PER_WIDE_INT >= size
+ && abs_d == (unsigned HOST_WIDE_INT) 1 << (size - 1))
{
/* This case is not handled correctly below. */
quotient = emit_store_flag (tquotient, EQ, op0, op1,
{
label = gen_label_rtx ();
do_compare_rtx_and_jump (target, const0_rtx, EQ, unsignedp,
- mode, NULL_RTX, NULL_RTX, label);
+ mode, NULL_RTX, NULL_RTX, label, -1);
emit_move_insn (target, trueval);
emit_label (label);
return target;
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, falseval);
emit_label (label);
{
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);
}