Simplify movqi, add more !TARGET_5200 cases

From-SVN: r12533
This commit is contained in:
Ian Lance Taylor 1996-07-19 20:01:07 +00:00
parent 4431168e14
commit a418b6c5ae
1 changed files with 36 additions and 108 deletions

View File

@ -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 ""