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
This commit is contained in:
Nick Clifton 2014-01-30 16:01:43 +00:00 committed by Nick Clifton
parent c972624e48
commit 2d70f6d435
2 changed files with 51 additions and 31 deletions

View File

@ -1,3 +1,11 @@
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>
PR tree-optimization/59903

View File

@ -327,13 +327,15 @@ rl78_option_override (void)
}
/* 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
maps register numbers to size in bytes. */
gcc doesn't like dealing with $FP as a register pair (the second
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[] =
{
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,
2, 2, 1, 1, 1
};
@ -381,7 +383,7 @@ rl78_hard_regno_mode_ok (int regno, enum machine_mode mode)
/* These are not to be used by gcc. */
if (regno == 23 || regno == ES_REG || regno == CS_REG)
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)
return 1;
if (regno < SP_REG)
@ -659,10 +661,10 @@ is_brk_interrupt_func (const_tree decl)
/* Check "interrupt" attributes. */
static tree
rl78_handle_func_attribute (tree * node,
tree name,
tree args,
int flags ATTRIBUTE_UNUSED,
bool * no_add_attrs)
tree name,
tree args,
int flags ATTRIBUTE_UNUSED,
bool * no_add_attrs)
{
gcc_assert (DECL_P (* node));
gcc_assert (args == NULL_TREE);
@ -820,14 +822,14 @@ rl78_far_p (rtx x)
if (! MEM_P (x))
return 0;
#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);
#endif
return MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR;
}
/* Return the appropriate mode for a named address pointer. */
#undef TARGET_ADDR_SPACE_POINTER_MODE
#undef TARGET_ADDR_SPACE_POINTER_MODE
#define TARGET_ADDR_SPACE_POINTER_MODE rl78_addr_space_pointer_mode
static enum machine_mode
rl78_addr_space_pointer_mode (addr_space_t addrspace)
@ -844,7 +846,7 @@ rl78_addr_space_pointer_mode (addr_space_t addrspace)
}
/* Returns TRUE for valid addresses. */
#undef TARGET_VALID_POINTER_MODE
#undef TARGET_VALID_POINTER_MODE
#define TARGET_VALID_POINTER_MODE rl78_valid_pointer_mode
static bool
rl78_valid_pointer_mode (enum machine_mode m)
@ -853,7 +855,7 @@ rl78_valid_pointer_mode (enum machine_mode m)
}
/* Return the appropriate mode for a named address address. */
#undef TARGET_ADDR_SPACE_ADDRESS_MODE
#undef TARGET_ADDR_SPACE_ADDRESS_MODE
#define TARGET_ADDR_SPACE_ADDRESS_MODE rl78_addr_space_address_mode
static enum machine_mode
rl78_addr_space_address_mode (addr_space_t addrspace)
@ -1796,7 +1798,7 @@ rl78_peep_movhi_p (rtx *operands)
{
#if DEBUG_PEEP
fprintf (stderr, "no peep: wrong mem %d\n", i);
debug_rtx(m);
debug_rtx (m);
debug_rtx (operands[i+2]);
#endif
return false;
@ -1832,7 +1834,7 @@ rl78_setup_peep_movhi (rtx *operands)
break;
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;
case MEM:
@ -2031,7 +2033,7 @@ update_content (unsigned char index, unsigned char val, enum machine_mode mode)
else
fprintf (dump_file, "%s and vice versa\n", get_content_name (val, mode));
}
if (mode == HImode)
{
val = val == NOT_KNOWN ? val : val + 1;
@ -2054,7 +2056,7 @@ update_content (unsigned char index, unsigned char val, enum machine_mode mode)
++ i;
continue;
}
if (content_memory[i] == index
|| (val != NOT_KNOWN && content_memory[i] == val))
{
@ -2269,7 +2271,7 @@ EM2 (int line ATTRIBUTE_UNUSED, rtx r)
{
#if DEBUG_ALLOC
fprintf (stderr, "\033[36m%d: ", line);
debug_rtx(r);
debug_rtx (r);
fprintf (stderr, "\033[0m");
#endif
/*SCHED_GROUP_P (r) = 1;*/
@ -2363,7 +2365,7 @@ gen_and_emit_move (rtx to, rtx from, rtx where, bool before)
else
{
rtx move = mode == QImode ? gen_movqi (to, from) : gen_movhi (to, from);
EM (move);
if (where == NULL_RTX)
@ -2521,7 +2523,7 @@ force_into_acc (rtx src, rtx before)
return;
move = mode == QImode ? gen_movqi (A, src) : gen_movhi (AX, src);
EM (move);
emit_insn_before (move, before);
@ -2683,7 +2685,7 @@ has_constraint (unsigned int opnum, enum constraint_num constraint)
/* No constraints means anything is accepted. */
if (p == NULL || *p == 0 || *p == ',')
return true;
do
{
char c;
@ -2750,7 +2752,7 @@ rl78_alloc_physical_registers_op2 (rtx insn)
}
/* 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. */
hl_used = reg_mentioned_p (L, OP (0)) || reg_mentioned_p (L, OP (1));
@ -2764,7 +2766,7 @@ rl78_alloc_physical_registers_op2 (rtx insn)
/* If op0 is a Ws1 type memory address then switching the base
address register to HL might allow us to perform an in-memory
operation. (eg for the INCW instruction).
FIXME: Adding the move into HL is costly if this optimization is not
going to work, so for now, make sure that we know that the new insn will
match the requirements of the addhi3_real pattern. Really we ought to
@ -2786,7 +2788,7 @@ rl78_alloc_physical_registers_op2 (rtx insn)
newbase = gen_and_emit_move (HL, base, insn, true);
record_content (newbase, NULL_RTX);
newbase = gen_rtx_PLUS (HImode, newbase, addend);
OP (0) = OP (1) = change_address (OP (0), VOIDmode, newbase);
/* We do not want to fail here as this means that
@ -2817,7 +2819,7 @@ rl78_alloc_physical_registers_op2 (rtx insn)
record_content (HL, NULL_RTX);
newbase = gen_rtx_PLUS (HImode, HL, addend);
OP (2) = change_address (OP (2), VOIDmode, newbase);
/* We do not want to fail here as this means that
@ -2857,7 +2859,7 @@ rl78_alloc_physical_registers_op2 (rtx insn)
;
OP (2) = hl_used ? move_to_de (2, first) : move_to_hl (2, first);
MUST_BE_OK (insn);
}
@ -2923,7 +2925,7 @@ rl78_alloc_physical_registers_cmp (rtx insn)
default:
gcc_unreachable ();
}
if (GET_CODE (cmp) == EQ || GET_CODE (cmp) == NE)
PATTERN (insn) = gen_cbranchhi4_real (cmp, OP (2), OP (1), OP (3));
else
@ -2939,7 +2941,7 @@ rl78_alloc_physical_registers_cmp (rtx insn)
OP (1) = OP (2) = BC;
MUST_BE_OK (insn);
}
tmp_id = get_max_insn_count ();
saved_op1 = OP (1);
@ -2967,7 +2969,7 @@ rl78_alloc_physical_registers_cmp (rtx insn)
MUST_BE_OK (insn);
}
/* Like op2, but AX = A op X. */
/* Like op2, but AX = A * X. */
static void
rl78_alloc_physical_registers_umul (rtx insn)
{
@ -2996,8 +2998,18 @@ rl78_alloc_physical_registers_umul (rtx insn)
tmp_id = get_max_insn_count ();
saved_op1 = OP (1);
OP (1) = move_to_acc (1, insn);
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);
MAYBE_OK (insn);
@ -3129,7 +3141,7 @@ rl78_alloc_physical_registers (void)
{
if (LABEL_P (insn))
clear_content_memory ();
continue;
}