lower-subreg.c (simple_move_operand): New static function, broken out of simple_move.
* lower-subreg.c (simple_move_operand): New static function, broken out of simple_move. Reject LABEL_REF, SYMBOL_REF, and HIGH operands. (simple_move): Call simple_move_operand. (find_decomposable_subregs): Add special handling of MEMs. (can_decompose_p): Rename from cannot_decompose_p. Reverse meaning of return value. If we see a hard register, test whether it can store a word_mode value. Change all callers. From-SVN: r121553
This commit is contained in:
parent
7fcc8dcf4a
commit
2b54c30fb0
2 changed files with 60 additions and 22 deletions
|
@ -1,3 +1,14 @@
|
|||
2007-02-03 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* lower-subreg.c (simple_move_operand): New static function,
|
||||
broken out of simple_move. Reject LABEL_REF, SYMBOL_REF, and HIGH
|
||||
operands.
|
||||
(simple_move): Call simple_move_operand.
|
||||
(find_decomposable_subregs): Add special handling of MEMs.
|
||||
(can_decompose_p): Rename from cannot_decompose_p. Reverse
|
||||
meaning of return value. If we see a hard register, test whether
|
||||
it can store a word_mode value. Change all callers.
|
||||
|
||||
2007-02-03 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
|
||||
|
||||
* pa.md (addvdi3, addvsi3, subvdi3, subvsi3, negvdi2, negvsi2): New
|
||||
|
|
|
@ -66,6 +66,31 @@ static bitmap non_decomposable_context;
|
|||
copy from reg M to reg N. */
|
||||
static VEC(bitmap,heap) *reg_copy_graph;
|
||||
|
||||
/* Return whether X is a simple object which we can take a word_mode
|
||||
subreg of. */
|
||||
|
||||
static bool
|
||||
simple_move_operand (rtx x)
|
||||
{
|
||||
if (GET_CODE (x) == SUBREG)
|
||||
x = SUBREG_REG (x);
|
||||
|
||||
if (!OBJECT_P (x))
|
||||
return false;
|
||||
|
||||
if (GET_CODE (x) == LABEL_REF
|
||||
|| GET_CODE (x) == SYMBOL_REF
|
||||
|| GET_CODE (x) == HIGH)
|
||||
return false;
|
||||
|
||||
if (MEM_P (x)
|
||||
&& (MEM_VOLATILE_P (x)
|
||||
|| mode_dependent_address_p (XEXP (x, 0))))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If INSN is a single set between two objects, return the single set.
|
||||
Such an insn can always be decomposed. INSN should have been
|
||||
passed to recog and extract_insn before this is called. */
|
||||
|
@ -87,25 +112,16 @@ simple_move (rtx insn)
|
|||
x = SET_DEST (set);
|
||||
if (x != recog_data.operand[0] && x != recog_data.operand[1])
|
||||
return NULL_RTX;
|
||||
if (GET_CODE (x) == SUBREG)
|
||||
x = SUBREG_REG (x);
|
||||
if (!OBJECT_P (x))
|
||||
return NULL_RTX;
|
||||
if (MEM_P (x)
|
||||
&& (MEM_VOLATILE_P (x)
|
||||
|| mode_dependent_address_p (XEXP (x, 0))))
|
||||
if (!simple_move_operand (x))
|
||||
return NULL_RTX;
|
||||
|
||||
x = SET_SRC (set);
|
||||
if (x != recog_data.operand[0] && x != recog_data.operand[1])
|
||||
return NULL_RTX;
|
||||
if (GET_CODE (x) == SUBREG)
|
||||
x = SUBREG_REG (x);
|
||||
if (!OBJECT_P (x) && GET_CODE (x) != ASM_OPERANDS)
|
||||
return NULL_RTX;
|
||||
if (MEM_P (x)
|
||||
&& (MEM_VOLATILE_P (x)
|
||||
|| mode_dependent_address_p (XEXP (x, 0))))
|
||||
/* For the src we can handle ASM_OPERANDS, and it is beneficial for
|
||||
things like x86 rdtsc which returns a DImode value. */
|
||||
if (GET_CODE (x) != ASM_OPERANDS
|
||||
&& !simple_move_operand (x))
|
||||
return NULL_RTX;
|
||||
|
||||
/* We try to decompose in integer modes, to avoid generating
|
||||
|
@ -259,7 +275,7 @@ find_decomposable_subregs (rtx *px, void *data)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
else if (GET_CODE (x) == REG)
|
||||
else if (REG_P (x))
|
||||
{
|
||||
unsigned int regno;
|
||||
|
||||
|
@ -299,6 +315,16 @@ find_decomposable_subregs (rtx *px, void *data)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (MEM_P (x))
|
||||
{
|
||||
enum classify_move_insn cmi_mem = NOT_SIMPLE_MOVE;
|
||||
|
||||
/* Any registers used in a MEM do not participate in a
|
||||
SIMPLE_MOVE or SIMPLE_PSEUDO_REG_MOVE. Do our own recursion
|
||||
here, and return -1 to block the parent's recursion. */
|
||||
for_each_rtx (&XEXP (x, 0), find_decomposable_subregs, &cmi_mem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -585,22 +611,23 @@ resolve_reg_notes (rtx insn)
|
|||
}
|
||||
}
|
||||
|
||||
/* Return whether X can not be decomposed into subwords. */
|
||||
/* Return whether X can be decomposed into subwords. */
|
||||
|
||||
static bool
|
||||
cannot_decompose_p (rtx x)
|
||||
can_decompose_p (rtx x)
|
||||
{
|
||||
if (REG_P (x))
|
||||
{
|
||||
unsigned int regno = REGNO (x);
|
||||
|
||||
if (HARD_REGISTER_NUM_P (regno))
|
||||
return !validate_subreg (word_mode, GET_MODE (x), x, UNITS_PER_WORD);
|
||||
return (validate_subreg (word_mode, GET_MODE (x), x, UNITS_PER_WORD)
|
||||
&& HARD_REGNO_MODE_OK (regno, word_mode));
|
||||
else
|
||||
return bitmap_bit_p (non_decomposable_context, regno);
|
||||
return !bitmap_bit_p (non_decomposable_context, regno);
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Decompose the registers used in a simple move SET within INSN. If
|
||||
|
@ -681,7 +708,7 @@ resolve_simple_move (rtx set, rtx insn)
|
|||
/* If SRC is a register which we can't decompose, or has side
|
||||
effects, we need to move via a temporary register. */
|
||||
|
||||
if (cannot_decompose_p (src)
|
||||
if (!can_decompose_p (src)
|
||||
|| side_effects_p (src)
|
||||
|| GET_CODE (src) == ASM_OPERANDS)
|
||||
{
|
||||
|
@ -701,7 +728,7 @@ resolve_simple_move (rtx set, rtx insn)
|
|||
|
||||
dest_mode = orig_mode;
|
||||
pushing = push_operand (dest, dest_mode);
|
||||
if (cannot_decompose_p (dest)
|
||||
if (!can_decompose_p (dest)
|
||||
|| (side_effects_p (dest) && !pushing)
|
||||
|| (!SCALAR_INT_MODE_P (dest_mode)
|
||||
&& !resolve_reg_p (dest)
|
||||
|
|
Loading…
Add table
Reference in a new issue