Commit 2d70f6d4 by Nick Clifton Committed by Nick Clifton

rl78.c (register_sizes): Make the "upper half" of %fp 2 to keep registers after…

rl78.c (register_sizes): Make the "upper half" of %fp 2 to keep registers after it properly word-aligned.

	* config/rl78/rl78.c (register_sizes): Make the "upper half" of
	%fp 2 to keep registers after it properly word-aligned.
	(rl78_alloc_physical_registers_umul): Handle the case where both
	input operands are the same.

Co-Authored-By: DJ Delorie <dj@redhat.com>

From-SVN: r207308
parent c972624e
2014-01-30 Nick Clifton <nickc@redhat.com>
DJ Delorie <dj@redhat.com>
* config/rl78/rl78.c (register_sizes): Make the "upper half" of
%fp 2 to keep registers after it properly word-aligned.
(rl78_alloc_physical_registers_umul): Handle the case where both
input operands are the same.
2014-01-30 Richard Biener <rguenther@suse.de> 2014-01-30 Richard Biener <rguenther@suse.de>
PR tree-optimization/59903 PR tree-optimization/59903
......
...@@ -327,13 +327,15 @@ rl78_option_override (void) ...@@ -327,13 +327,15 @@ rl78_option_override (void)
} }
/* Most registers are 8 bits. Some are 16 bits because, for example, /* Most registers are 8 bits. Some are 16 bits because, for example,
gcc doesn't like dealing with $FP as a register pair. This table gcc doesn't like dealing with $FP as a register pair (the second
maps register numbers to size in bytes. */ half of $fp is also 2 to keep reload happy wrt register pairs, but
no register class includes it). This table maps register numbers
to size in bytes. */
static const int register_sizes[] = static const int register_sizes[] =
{ {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 1, 1, 1 2, 2, 1, 1, 1
}; };
...@@ -381,7 +383,7 @@ rl78_hard_regno_mode_ok (int regno, enum machine_mode mode) ...@@ -381,7 +383,7 @@ rl78_hard_regno_mode_ok (int regno, enum machine_mode mode)
/* These are not to be used by gcc. */ /* These are not to be used by gcc. */
if (regno == 23 || regno == ES_REG || regno == CS_REG) if (regno == 23 || regno == ES_REG || regno == CS_REG)
return 0; return 0;
/* $fp can alway sbe accessed as a 16-bit value. */ /* $fp can always be accessed as a 16-bit value. */
if (regno == FP_REG && s == 2) if (regno == FP_REG && s == 2)
return 1; return 1;
if (regno < SP_REG) if (regno < SP_REG)
...@@ -820,7 +822,7 @@ rl78_far_p (rtx x) ...@@ -820,7 +822,7 @@ rl78_far_p (rtx x)
if (! MEM_P (x)) if (! MEM_P (x))
return 0; return 0;
#if DEBUG0 #if DEBUG0
fprintf (stderr, "\033[35mrl78_far_p: "); debug_rtx(x); fprintf (stderr, "\033[35mrl78_far_p: "); debug_rtx (x);
fprintf (stderr, " = %d\033[0m\n", MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR); fprintf (stderr, " = %d\033[0m\n", MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR);
#endif #endif
return MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR; return MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR;
...@@ -1796,7 +1798,7 @@ rl78_peep_movhi_p (rtx *operands) ...@@ -1796,7 +1798,7 @@ rl78_peep_movhi_p (rtx *operands)
{ {
#if DEBUG_PEEP #if DEBUG_PEEP
fprintf (stderr, "no peep: wrong mem %d\n", i); fprintf (stderr, "no peep: wrong mem %d\n", i);
debug_rtx(m); debug_rtx (m);
debug_rtx (operands[i+2]); debug_rtx (operands[i+2]);
#endif #endif
return false; return false;
...@@ -1832,7 +1834,7 @@ rl78_setup_peep_movhi (rtx *operands) ...@@ -1832,7 +1834,7 @@ rl78_setup_peep_movhi (rtx *operands)
break; break;
case CONST_INT: case CONST_INT:
operands[i+4] = GEN_INT ((INTVAL (operands[i]) & 0xff) + ((char)INTVAL (operands[i+2])) * 256); operands[i+4] = GEN_INT ((INTVAL (operands[i]) & 0xff) + ((char) INTVAL (operands[i+2])) * 256);
break; break;
case MEM: case MEM:
...@@ -2269,7 +2271,7 @@ EM2 (int line ATTRIBUTE_UNUSED, rtx r) ...@@ -2269,7 +2271,7 @@ EM2 (int line ATTRIBUTE_UNUSED, rtx r)
{ {
#if DEBUG_ALLOC #if DEBUG_ALLOC
fprintf (stderr, "\033[36m%d: ", line); fprintf (stderr, "\033[36m%d: ", line);
debug_rtx(r); debug_rtx (r);
fprintf (stderr, "\033[0m"); fprintf (stderr, "\033[0m");
#endif #endif
/*SCHED_GROUP_P (r) = 1;*/ /*SCHED_GROUP_P (r) = 1;*/
...@@ -2750,7 +2752,7 @@ rl78_alloc_physical_registers_op2 (rtx insn) ...@@ -2750,7 +2752,7 @@ rl78_alloc_physical_registers_op2 (rtx insn)
} }
/* Make a note of whether (H)L is being used. It matters /* Make a note of whether (H)L is being used. It matters
because if OP (2) alsoneeds reloading, then we must take because if OP (2) also needs reloading, then we must take
care not to corrupt HL. */ care not to corrupt HL. */
hl_used = reg_mentioned_p (L, OP (0)) || reg_mentioned_p (L, OP (1)); hl_used = reg_mentioned_p (L, OP (0)) || reg_mentioned_p (L, OP (1));
...@@ -2967,7 +2969,7 @@ rl78_alloc_physical_registers_cmp (rtx insn) ...@@ -2967,7 +2969,7 @@ rl78_alloc_physical_registers_cmp (rtx insn)
MUST_BE_OK (insn); MUST_BE_OK (insn);
} }
/* Like op2, but AX = A op X. */ /* Like op2, but AX = A * X. */
static void static void
rl78_alloc_physical_registers_umul (rtx insn) rl78_alloc_physical_registers_umul (rtx insn)
{ {
...@@ -2997,6 +2999,16 @@ rl78_alloc_physical_registers_umul (rtx insn) ...@@ -2997,6 +2999,16 @@ rl78_alloc_physical_registers_umul (rtx insn)
tmp_id = get_max_insn_count (); tmp_id = get_max_insn_count ();
saved_op1 = OP (1); saved_op1 = OP (1);
if (rtx_equal_p (OP (1), OP (2)))
{
gcc_assert (GET_MODE (OP (2)) == QImode);
/* The MULU instruction does not support duplicate arguments
but we know that if we copy OP (2) to X it will do so via
A and thus OP (1) will already be loaded into A. */
OP (2) = move_to_x (2, insn);
OP (1) = A;
}
else
OP (1) = move_to_acc (1, insn); OP (1) = move_to_acc (1, insn);
MAYBE_OK (insn); MAYBE_OK (insn);
......
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