Commit 2b54c30f by Ian Lance Taylor Committed by Ian Lance Taylor

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
parent 7fcc8dcf
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> 2007-02-03 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* pa.md (addvdi3, addvsi3, subvdi3, subvsi3, negvdi2, negvsi2): New * pa.md (addvdi3, addvsi3, subvdi3, subvsi3, negvdi2, negvsi2): New
......
...@@ -66,6 +66,31 @@ static bitmap non_decomposable_context; ...@@ -66,6 +66,31 @@ static bitmap non_decomposable_context;
copy from reg M to reg N. */ copy from reg M to reg N. */
static VEC(bitmap,heap) *reg_copy_graph; 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. /* If INSN is a single set between two objects, return the single set.
Such an insn can always be decomposed. INSN should have been Such an insn can always be decomposed. INSN should have been
passed to recog and extract_insn before this is called. */ passed to recog and extract_insn before this is called. */
...@@ -87,25 +112,16 @@ simple_move (rtx insn) ...@@ -87,25 +112,16 @@ simple_move (rtx insn)
x = SET_DEST (set); x = SET_DEST (set);
if (x != recog_data.operand[0] && x != recog_data.operand[1]) if (x != recog_data.operand[0] && x != recog_data.operand[1])
return NULL_RTX; return NULL_RTX;
if (GET_CODE (x) == SUBREG) if (!simple_move_operand (x))
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))))
return NULL_RTX; return NULL_RTX;
x = SET_SRC (set); x = SET_SRC (set);
if (x != recog_data.operand[0] && x != recog_data.operand[1]) if (x != recog_data.operand[0] && x != recog_data.operand[1])
return NULL_RTX; return NULL_RTX;
if (GET_CODE (x) == SUBREG) /* For the src we can handle ASM_OPERANDS, and it is beneficial for
x = SUBREG_REG (x); things like x86 rdtsc which returns a DImode value. */
if (!OBJECT_P (x) && GET_CODE (x) != ASM_OPERANDS) if (GET_CODE (x) != ASM_OPERANDS
return NULL_RTX; && !simple_move_operand (x))
if (MEM_P (x)
&& (MEM_VOLATILE_P (x)
|| mode_dependent_address_p (XEXP (x, 0))))
return NULL_RTX; return NULL_RTX;
/* We try to decompose in integer modes, to avoid generating /* We try to decompose in integer modes, to avoid generating
...@@ -259,7 +275,7 @@ find_decomposable_subregs (rtx *px, void *data) ...@@ -259,7 +275,7 @@ find_decomposable_subregs (rtx *px, void *data)
return -1; return -1;
} }
} }
else if (GET_CODE (x) == REG) else if (REG_P (x))
{ {
unsigned int regno; unsigned int regno;
...@@ -299,6 +315,16 @@ find_decomposable_subregs (rtx *px, void *data) ...@@ -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; return 0;
} }
...@@ -585,22 +611,23 @@ resolve_reg_notes (rtx insn) ...@@ -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 static bool
cannot_decompose_p (rtx x) can_decompose_p (rtx x)
{ {
if (REG_P (x)) if (REG_P (x))
{ {
unsigned int regno = REGNO (x); unsigned int regno = REGNO (x);
if (HARD_REGISTER_NUM_P (regno)) 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 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 /* Decompose the registers used in a simple move SET within INSN. If
...@@ -681,7 +708,7 @@ resolve_simple_move (rtx set, rtx insn) ...@@ -681,7 +708,7 @@ resolve_simple_move (rtx set, rtx insn)
/* If SRC is a register which we can't decompose, or has side /* If SRC is a register which we can't decompose, or has side
effects, we need to move via a temporary register. */ effects, we need to move via a temporary register. */
if (cannot_decompose_p (src) if (!can_decompose_p (src)
|| side_effects_p (src) || side_effects_p (src)
|| GET_CODE (src) == ASM_OPERANDS) || GET_CODE (src) == ASM_OPERANDS)
{ {
...@@ -701,7 +728,7 @@ resolve_simple_move (rtx set, rtx insn) ...@@ -701,7 +728,7 @@ resolve_simple_move (rtx set, rtx insn)
dest_mode = orig_mode; dest_mode = orig_mode;
pushing = push_operand (dest, dest_mode); pushing = push_operand (dest, dest_mode);
if (cannot_decompose_p (dest) if (!can_decompose_p (dest)
|| (side_effects_p (dest) && !pushing) || (side_effects_p (dest) && !pushing)
|| (!SCALAR_INT_MODE_P (dest_mode) || (!SCALAR_INT_MODE_P (dest_mode)
&& !resolve_reg_p (dest) && !resolve_reg_p (dest)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment