mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-30 04:19:46 +08:00
Simplify movqi, add more !TARGET_5200 cases
From-SVN: r12533
This commit is contained in:
parent
4431168e14
commit
a418b6c5ae
@ -946,8 +946,8 @@
|
||||
}")
|
||||
|
||||
(define_insn "movqi"
|
||||
[(set (match_operand:QI 0 "general_operand" "=d,*a,m,m,?*a")
|
||||
(match_operand:QI 1 "general_operand" "dmi*a,di*a,dmi,?*a,m"))]
|
||||
[(set (match_operand:QI 0 "general_operand" "=d,*a,m")
|
||||
(match_operand:QI 1 "general_operand" "dmi*a,di*a,dmi"))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
@ -970,106 +970,6 @@
|
||||
return \"\";
|
||||
}
|
||||
|
||||
/* Moving a byte into an address register is not possible. */
|
||||
/* Use d0 as an intermediate, but don't clobber its contents. */
|
||||
if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM)
|
||||
{
|
||||
/* ??? For 2.5, don't allow this choice and use secondary reloads
|
||||
instead.
|
||||
|
||||
See if the address register is used in the address. If it
|
||||
is, we have to generate a more complex sequence than those below. */
|
||||
CC_STATUS_INIT;
|
||||
if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
|
||||
operands[1], NULL_RTX))
|
||||
{
|
||||
/* See if the stack pointer is used in the address. If it isn't,
|
||||
we can push d0 or d1 (the insn can't use both of them) on
|
||||
the stack, perform our move into d0/d1, copy the byte from d0/1,
|
||||
and pop d0/1. */
|
||||
if (! reg_mentioned_p (stack_pointer_rtx, operands[1]))
|
||||
{
|
||||
if (! refers_to_regno_p (0, 1, operands[1], NULL_RTX))
|
||||
return \"move%.l %/d0,%-\;move%.b %1,%/d0\;move%.l %/d0,%0\;move%.l %+,%/d0\";
|
||||
else
|
||||
return \"move%.l %/d1,%-\;move%.b %1,%/d1\;move%.l %/d1,%0\;move%.l %+,%/d1\";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, we know that d0 cannot be used in the address
|
||||
(since sp and one address register is). Assume that sp is
|
||||
being used as a base register and replace the address
|
||||
register that is our operand[0] with d0. */
|
||||
rtx reg_map[FIRST_PSEUDO_REGISTER];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
reg_map[i] = 0;
|
||||
|
||||
reg_map[REGNO (operands[0])] = gen_rtx (REG, Pmode, 0);
|
||||
operands[1] = copy_rtx (operands[1]);
|
||||
replace_regs (operands[1], reg_map, FIRST_PSEUDO_REGISTER, 0);
|
||||
return \"exg %/d0,%0\;move%.b %1,%/d0\;exg %/d0,%0\";
|
||||
}
|
||||
}
|
||||
|
||||
/* If the address of operand 1 uses d0, choose d1 as intermediate. */
|
||||
if (refers_to_regno_p (0, 1, operands[1], NULL_RTX))
|
||||
return \"exg %/d1,%0\;move%.b %1,%/d1\;exg %/d1,%0\";
|
||||
/* Otherwise d0 is usable.
|
||||
(An effective address on the 68k can't use two d-regs.) */
|
||||
else
|
||||
return \"exg %/d0,%0\;move%.b %1,%/d0\;exg %/d0,%0\";
|
||||
}
|
||||
|
||||
/* Likewise for moving from an address reg. */
|
||||
if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM)
|
||||
{
|
||||
/* ??? For 2.5, don't allow this choice and use secondary reloads
|
||||
instead.
|
||||
|
||||
See if the address register is used in the address. If it
|
||||
is, we have to generate a more complex sequence than those below. */
|
||||
CC_STATUS_INIT;
|
||||
if (refers_to_regno_p (REGNO (operands[1]), REGNO (operands[1]) + 1,
|
||||
operands[0], NULL_RTX))
|
||||
{
|
||||
/* See if the stack pointer is used in the address. If it isn't,
|
||||
we can push d0 or d1 (the insn can't use both of them) on
|
||||
the stack, copy the byte to d0/1, perform our move from d0/d1,
|
||||
and pop d0/1. */
|
||||
if (! reg_mentioned_p (stack_pointer_rtx, operands[0]))
|
||||
{
|
||||
if (! refers_to_regno_p (0, 1, operands[0], NULL_RTX))
|
||||
return \"move%.l %/d0,%-\;move%.l %1,%/d0\;move%.b %/d0,%0\;move%.l %+,%/d0\";
|
||||
else
|
||||
return \"move%.l %/d1,%-\;move%.l %1,%/d1\;move%.b %/d1,%0\;move%.l %+,%/d1\";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, we know that d0 cannot be used in the address
|
||||
(since sp and one address register is). Assume that sp is
|
||||
being used as a base register and replace the address
|
||||
register that is our operand[1] with d0. */
|
||||
rtx reg_map[FIRST_PSEUDO_REGISTER];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
reg_map[i] = 0;
|
||||
|
||||
reg_map[REGNO (operands[1])] = gen_rtx (REG, Pmode, 0);
|
||||
operands[0] = copy_rtx (operands[0]);
|
||||
replace_regs (operands[0], reg_map, FIRST_PSEUDO_REGISTER, 0);
|
||||
return \"exg %/d0,%1\;move%.b %/d0,%0\;exg %/d0,%1\";
|
||||
}
|
||||
}
|
||||
|
||||
if (refers_to_regno_p (0, 1, operands[0], NULL_RTX))
|
||||
return \"exg %/d1,%1\;move%.b %/d1,%0\;exg %/d1,%1\";
|
||||
else
|
||||
return \"exg %/d0,%1\;move%.b %/d0,%0\;exg %/d0,%1\";
|
||||
}
|
||||
|
||||
/* clr and st insns on 68000 read before writing.
|
||||
This isn't so on the 68010, but we have no TARGET_68010. */
|
||||
if (!ADDRESS_REG_P (operands[0])
|
||||
@ -2051,7 +1951,7 @@
|
||||
(const_int 32))
|
||||
(match_operand:DI 2 "general_operand" "0,0,0,0")))
|
||||
(clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
|
||||
""
|
||||
"!TARGET_5200"
|
||||
"*
|
||||
{
|
||||
CC_STATUS_INIT;
|
||||
@ -2660,7 +2560,7 @@
|
||||
(ashift:DI (sign_extend:DI (match_operand:HI 2 "general_operand" "rm,rm,rm,rm"))
|
||||
(const_int 32))))
|
||||
(clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
|
||||
""
|
||||
"!TARGET_5200"
|
||||
"*
|
||||
{
|
||||
CC_STATUS_INIT;
|
||||
@ -3784,10 +3684,23 @@
|
||||
|
||||
;; negation instructions
|
||||
|
||||
(define_insn "negdi2"
|
||||
(define_expand "negdi2"
|
||||
[(set (match_operand:DI 0 "general_operand" "")
|
||||
(neg:DI (match_operand:DI 1 "general_operand" "")))]
|
||||
""
|
||||
"
|
||||
{
|
||||
if (TARGET_5200)
|
||||
emit_insn (gen_negdi2_5200 (operands[0], operands[1]));
|
||||
else
|
||||
emit_insn (gen_negdi2_internal (operands[0], operands[1]));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "negdi2_internal"
|
||||
[(set (match_operand:DI 0 "general_operand" "=<,do,!*a")
|
||||
(neg:DI (match_operand:DI 1 "general_operand" "0,0,0")))]
|
||||
""
|
||||
"!TARGET_5200"
|
||||
"*
|
||||
{
|
||||
if (which_alternative == 0)
|
||||
@ -3802,6 +3715,21 @@
|
||||
return \"neg%.l %1\;negx%.l %0\";
|
||||
} ")
|
||||
|
||||
(define_insn "negdi2_5200"
|
||||
[(set (match_operand:DI 0 "general_operand" "=<,do")
|
||||
(neg:DI (match_operand:DI 1 "general_operand" "0,0")))]
|
||||
"TARGET_5200"
|
||||
"*
|
||||
{
|
||||
if (which_alternative == 0)
|
||||
return \"neg%.l %0\;negx%.l %0\";
|
||||
if (GET_CODE (operands[0]) == REG)
|
||||
operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
|
||||
else
|
||||
operands[1] = adj_offsettable_operand (operands[0], 4);
|
||||
return \"neg%.l %1\;negx%.l %0\";
|
||||
} ")
|
||||
|
||||
(define_insn "negsi2"
|
||||
[(set (match_operand:SI 0 "general_operand" "=dm")
|
||||
(neg:SI (match_operand:SI 1 "general_operand" "0")))]
|
||||
@ -4411,7 +4339,7 @@
|
||||
[(set (match_operand:DI 0 "general_operand" "")
|
||||
(ashiftrt:DI (match_operand:DI 1 "general_operand" "")
|
||||
(match_operand 2 "const_int_operand" "")))]
|
||||
""
|
||||
"!TARGET_5200"
|
||||
"
|
||||
{
|
||||
if (GET_CODE (operands[2]) != CONST_INT
|
||||
@ -4445,7 +4373,7 @@
|
||||
[(set (match_operand:HI 0 "register_operand" "=d")
|
||||
(ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
|
||||
(match_operand:HI 2 "general_operand" "dI")))]
|
||||
""
|
||||
"!TARGET_5200"
|
||||
"asr%.w %2,%0")
|
||||
|
||||
(define_insn ""
|
||||
|
Loading…
Reference in New Issue
Block a user