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:
parent
c972624e48
commit
2d70f6d435
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue